diff --git a/go.mod b/go.mod index a0e4cbe012..725c185a68 100644 --- a/go.mod +++ b/go.mod @@ -11,94 +11,72 @@ require ( github.com/grpc-ecosystem/grpc-health-probe v0.4.11 github.com/maxbrunsfeld/counterfeiter/v6 v6.4.1 github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37 - github.com/onsi/ginkgo/v2 v2.1.6 + github.com/onsi/ginkgo/v2 v2.6.0 github.com/openshift/api v3.9.0+incompatible github.com/operator-framework/api v0.17.3 github.com/operator-framework/operator-lifecycle-manager v0.0.0-00010101000000-000000000000 github.com/operator-framework/operator-registry v1.17.5 - github.com/sirupsen/logrus v1.8.1 - github.com/spf13/cobra v1.4.0 - github.com/stretchr/testify v1.8.0 + github.com/sirupsen/logrus v1.9.0 + github.com/spf13/cobra v1.6.1 + github.com/stretchr/testify v1.8.2 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.28.0 + google.golang.org/protobuf v1.29.1 gopkg.in/yaml.v2 v2.4.0 - helm.sh/helm/v3 v3.9.0 - k8s.io/api v0.25.3 - k8s.io/apimachinery v0.25.3 - k8s.io/client-go v0.25.3 - k8s.io/code-generator v0.25.3 - k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 - k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 - sigs.k8s.io/controller-runtime v0.13.0 + helm.sh/helm/v3 v3.11.1 + k8s.io/api v0.26.1 + k8s.io/apimachinery v0.26.1 + k8s.io/client-go v0.26.1 + k8s.io/code-generator v0.26.1 + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 + k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 + sigs.k8s.io/controller-runtime v0.14.5 sigs.k8s.io/controller-tools v0.8.0 ) -replace google.golang.org/grpc => google.golang.org/grpc v1.40.0 - -replace ( - go.opentelemetry.io/contrib => go.opentelemetry.io/contrib v0.20.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 - go.opentelemetry.io/otel/exporters/otlp => go.opentelemetry.io/otel/exporters/otlp v0.20.0 - go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v0.20.0 - go.opentelemetry.io/otel/oteltest => go.opentelemetry.io/otel/oteltest v0.20.0 - go.opentelemetry.io/otel/sdk/export/metric => go.opentelemetry.io/otel/sdk/export/metric v0.20.0 - go.opentelemetry.io/otel/sdk/metric => go.opentelemetry.io/otel/sdk/metric v0.20.0 - go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v0.20.0 - go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v0.7.0 -) - require ( - cloud.google.com/go v0.99.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.27 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/BurntSushi/toml v1.0.0 // indirect - github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.2 // indirect - github.com/Masterminds/squirrel v1.5.2 // indirect + github.com/Masterminds/semver/v3 v3.2.0 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/squirrel v1.5.3 // indirect github.com/Masterminds/vcs v1.13.3 // indirect - github.com/Microsoft/go-winio v0.5.1 // indirect - github.com/Microsoft/hcsshim v0.9.2 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/Microsoft/hcsshim v0.9.6 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/adrg/xdg v0.4.0 // indirect - github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect + github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver v3.5.1+incompatible // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect - github.com/containerd/cgroups v1.0.3 // indirect - github.com/containerd/containerd v1.6.3 // indirect - github.com/containerd/continuity v0.2.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/containerd v1.6.18 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/ttrpc v1.1.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/distribution v2.7.1+incompatible // indirect - github.com/docker/cli v20.10.12+incompatible // indirect + github.com/docker/cli v20.10.21+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.14+incompatible // indirect - github.com/docker/docker-credential-helpers v0.6.4 // indirect + github.com/docker/docker v20.10.21+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/emicklei/go-restful/v3 v3.8.0 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.10.2 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/color v1.13.0 // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fvbommel/sortorder v1.0.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-air/gini v1.0.4 // indirect github.com/go-errors/errors v1.0.1 // indirect @@ -106,42 +84,42 @@ require ( github.com/go-git/go-billy/v5 v5.1.0 // indirect github.com/go-git/go-git/v5 v5.3.0 // indirect github.com/go-gorp/gorp/v3 v3.0.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.2.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.5 // indirect - github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/gobuffalo/flect v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-yaml v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.2.0 // indirect github.com/golang-migrate/migrate/v4 v4.6.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/cel-go v0.12.5 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/cel-go v0.12.6 // indirect + github.com/google/gnostic v0.6.9 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/h2non/filetype v1.1.1 // indirect github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // indirect - github.com/huandu/xstrings v1.3.2 // indirect - github.com/imdario/mergo v0.3.12 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/huandu/xstrings v1.3.3 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645 // indirect github.com/itchyny/gojq v0.11.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jmoiron/sqlx v1.3.4 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -151,14 +129,14 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lestrrat-go/strftime v1.0.1 // indirect - github.com/lib/pq v1.10.4 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/mattn/go-sqlite3 v1.14.10 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mattn/go-sqlite3 v1.14.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/hashstructure v1.0.0 // indirect @@ -167,15 +145,15 @@ require ( github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/sys/mountinfo v0.5.0 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/gomega v1.20.1 // indirect + github.com/onsi/gomega v1.24.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a // indirect github.com/openshift/cluster-policy-controller v0.0.0-20230217170320-ac01e3463245 // indirect github.com/otiai10/copy v1.2.0 // indirect @@ -183,12 +161,11 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.2 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rubenv/sql-migrate v1.1.1 // indirect - github.com/russross/blackfriday v1.5.2 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rubenv/sql-migrate v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/cast v1.4.1 // indirect @@ -198,64 +175,64 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect + github.com/xlab/treeprint v1.1.0 // indirect github.com/zeebo/errs v1.3.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.etcd.io/etcd/api/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/v3 v3.5.4 // indirect + go.etcd.io/etcd/api/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/v3 v3.5.5 // indirect go.opencensus.io v0.23.0 // indirect - go.opentelemetry.io/contrib v1.3.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect - go.opentelemetry.io/otel v1.3.0 // indirect - go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect - go.opentelemetry.io/otel/metric v0.20.0 // indirect - go.opentelemetry.io/otel/sdk v1.3.0 // indirect - go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect - go.opentelemetry.io/otel/trace v1.3.0 // indirect - go.opentelemetry.io/proto/otlp v0.12.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 // indirect + go.opentelemetry.io/otel v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0 // indirect + go.opentelemetry.io/otel/metric v0.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.10.0 // indirect + go.opentelemetry.io/otel/trace v1.10.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.5.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect - golang.org/x/tools v0.1.12 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect - google.golang.org/grpc v1.47.0 // indirect + google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect + google.golang.org/grpc v1.52.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.25.3 // indirect - k8s.io/apiserver v0.25.3 // indirect - k8s.io/cli-runtime v0.24.0 // indirect - k8s.io/component-base v0.25.3 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect + k8s.io/apiextensions-apiserver v0.26.1 // indirect + k8s.io/apiserver v0.26.1 // indirect + k8s.io/cli-runtime v0.26.0 // indirect + k8s.io/component-base v0.26.1 // indirect + k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4 // indirect k8s.io/klog v1.0.0 // indirect - k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/kms v0.26.2 // indirect k8s.io/kube-aggregator v0.25.3 // indirect - k8s.io/kubectl v0.24.0 // indirect - oras.land/oras-go v1.1.0 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/kustomize/api v0.11.4 // indirect - sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect + k8s.io/kubectl v0.26.0 // indirect + oras.land/oras-go v1.2.2 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.12.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) @@ -264,9 +241,6 @@ replace ( // latest tag resolves to a very old version. this is only used for spinning up local test registries github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d - // pin to ginkgo v1 version of gomega (v1.18+ relies on ginkgo v2) - github.com/onsi/gomega => github.com/onsi/gomega v1.17.0 - // controller runtime github.com/openshift/api => github.com/openshift/api v0.0.0-20210517065120-b325f58df679 github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 // release-4.5 @@ -276,9 +250,6 @@ replace ( github.com/operator-framework/operator-lifecycle-manager => ./staging/operator-lifecycle-manager github.com/operator-framework/operator-registry => ./staging/operator-registry - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 - go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0 // this should be removeable once https://issues.redhat.com/browse/CLOUDBLD-11068 is resolved k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.25.0 diff --git a/go.sum b/go.sum index 9e642c1abc..0b67673f6a 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -20,21 +20,15 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW 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/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/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/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= 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= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= 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= @@ -53,54 +47,40 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg= -github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= -github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE= -github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc= +github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Masterminds/vcs v1.13.3 h1:IIA2aBdXvfbIM+yl/eTnL4hb1XwdpvuQLglAix1gweE= github.com/Masterminds/vcs v1.13.3/go.mod h1:TiE7xuEjl1N4j016moRd6vezp6e6Lz23gypeXfzXeW8= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -111,8 +91,8 @@ 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.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 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= @@ -121,8 +101,8 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= -github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY= +github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= 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= @@ -131,10 +111,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -151,8 +129,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -165,7 +143,6 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -179,7 +156,6 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= 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= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= @@ -187,19 +163,23 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v1.5.3 h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= 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/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= 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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -210,8 +190,15 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI 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/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-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/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= 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/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -229,8 +216,8 @@ github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4S github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= @@ -251,8 +238,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.6.3 h1:JfgUEIAH07xDWk6kqz0P3ArZt+KJ9YeihSC9uyFtSKg= -github.com/containerd/containerd v1.6.3/go.mod h1:gCVGrYRYFm2E8GmuUIbj/NGD7DLZQLzSJQazjVKDOig= +github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns= +github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw= 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= @@ -260,8 +247,8 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -327,12 +314,11 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 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/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/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/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= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= @@ -350,11 +336,9 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= -github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= @@ -364,21 +348,21 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= github.com/distribution/distribution v2.7.1+incompatible h1:aGFx4EvJWKEh//lHPLwFhFgwFHKH06TzNVPamrMn04M= github.com/distribution/distribution v2.7.1+incompatible/go.mod h1:EgLm2NgWtdKgzF9NpMzUKgzmR7AMmb0VQi2B+ZzDRjc= -github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684 h1:DBZ2sN7CK6dgvHVpQsQj4sRMCbWTmd17l+5SUCjnQSY= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA= -github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= +github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20191216044856-a8371794149d h1:jC8tT/S0OGx2cswpeUTn4gOIea8P08lD3VFQT0cOZ50= github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.14+incompatible h1:+T9/PRYWNDo5SZl5qS1r9Mo/0Q8AwxKKPtu9S1yxM0w= -github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= +github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= -github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -405,45 +389,50 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7fo 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= -github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= -github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +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.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/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.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= 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 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= 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= @@ -471,9 +460,11 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 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/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -481,32 +472,34 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -542,13 +535,12 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -556,6 +548,7 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= @@ -582,22 +575,21 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 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/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8= -github.com/google/cel-go v0.12.5/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M= +github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -610,8 +602,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -622,7 +614,6 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ 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= @@ -634,26 +625,22 @@ 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 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ= +github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= 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= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= @@ -684,6 +671,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-health-probe v0.4.11 h1:eKVQDIIJhRkfJHjQzTmu+RangfB8/MyrthCCnsvne/s= github.com/grpc-ecosystem/grpc-health-probe v0.4.11/go.mod h1:Ew6du240dK067iM38yVbni1pLpWUFnuyc0PefrB81Uc= github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4= @@ -708,6 +697,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= 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= @@ -716,18 +706,21 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645 h1:3gyXljUyTWWTv/NMFPvwgxJSdE9Mamg2r3x8HMBl+Uo= github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645/go.mod h1:296z3W7Xsrp2mlIY88ruDKscuvrkL6zXCNRtaYVshzw= github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA= @@ -745,14 +738,13 @@ github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= -github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d h1:A2/B900ip/Z20TzkLeGRNy1s6J2HmH9AmGt+dHyqb4I= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d/go.mod h1:7HQupe4vyNxMKXmM5DFuwXHsqwMyglcYmZBtlDPIcZ8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= 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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -812,20 +804,19 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= @@ -850,7 +841,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -859,11 +849,12 @@ github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebG github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= -github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/maxbrunsfeld/counterfeiter/v6 v6.4.1 h1:hZD/8vBuw7x1WqRXD/WGjVjipbbo/HcDBgySYYbrUSk= github.com/maxbrunsfeld/counterfeiter/v6 v6.4.1/go.mod h1:DK1Cjkc0E49ShgRVs5jy5ASrM15svSnem3K/hiSGD8o= @@ -873,7 +864,7 @@ github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37 h1:lPmsut5Sk7eK2Bm github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37/go.mod h1:dYWq+UWoFCDY1TndvFUQuhBbIYmZpjreC8adEAx93zE= 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.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -904,8 +895,8 @@ github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9 github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -930,13 +921,12 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -944,13 +934,20 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= +github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= +github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -959,8 +956,8 @@ 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.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= 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= @@ -1001,7 +998,7 @@ github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrap github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 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-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1026,15 +1023,16 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1043,8 +1041,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= 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= @@ -1057,18 +1056,17 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY= -github.com/rubenv/sql-migrate v1.1.1/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rubenv/sql-migrate v1.2.0 h1:fOXMPLMd41sK7Tg75SXDec15k3zg5WNV6SjuDRiNfcU= +github.com/rubenv/sql-migrate v1.2.0/go.mod h1:Z5uVnq7vrIrPmHbVFfR4YLHRZquxeHpckCnRq0P/K9Y= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1093,8 +1091,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -1103,7 +1102,6 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= 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/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -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/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1113,8 +1111,8 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1134,8 +1132,9 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1145,8 +1144,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1158,7 +1159,6 @@ github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1C github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -1185,8 +1185,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1194,7 +1194,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= @@ -1215,18 +1215,18 @@ go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao= -go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/pkg/v3 v3.5.4 h1:V5Dvl7S39ZDwjkKqJG2BfXgxZ3QREqqKifWQgIw5IM0= -go.etcd.io/etcd/raft/v3 v3.5.4 h1:YGrnAgRfgXloBNuqa+oBI/aRZMcK/1GS6trJePJ/Gqc= -go.etcd.io/etcd/server/v3 v3.5.4 h1:CMAZd0g8Bn5NRhynW6pKhc4FRg41/0QYy3d7aNm9874= +go.etcd.io/etcd/client/v2 v2.305.5 h1:DktRP60//JJpnPC0VBymAN/7V71GHMdjDCBt4ZPXDjI= +go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI= +go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= +go.etcd.io/etcd/pkg/v3 v3.5.5 h1:Ablg7T7OkR+AeeeU32kdVhw/AGDsitkKPl7aW73ssjU= +go.etcd.io/etcd/raft/v3 v3.5.5 h1:Ibz6XyZ60OYyRopu73lLM/P+qco3YtlZMOhnXNS051I= +go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1238,30 +1238,27 @@ 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/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 h1:xFSRQBbXF6VvYRf2lqMJXxoB72XI1K/azav8TekHHSw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 h1:Ajldaqhxqw/gNzQA45IKFWLdG7jZuXX/wBW1d5qvbUI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0 h1:TaB+1rQhddO1sF71MpZOZAuSPW1klK2M8XxfrBMfK7Y= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0 h1:pDDYmo0QadUPal5fwXoY1pmMpFcdyhXOmL5drCrI3vU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0 h1:KtiUEhQmj/Pa874bVYKGNVdq8NPKiacPbaRRtgXi+t4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= +go.opentelemetry.io/otel/metric v0.31.0 h1:6SiklT+gfWAwWUR0meEMxQBtihpiEs4c+vL9spDTqUs= +go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= +go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1269,8 +1266,6 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -1278,8 +1273,8 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= 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= @@ -1303,10 +1298,9 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 h1:iU7T1X1J6yxDr0rda54sWGkHgOp5XJrqm79gcNlC2VM= -golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= 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= @@ -1319,6 +1313,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -1343,11 +1338,12 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1387,9 +1383,11 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -1399,16 +1397,16 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/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-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1423,12 +1421,10 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= 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= @@ -1440,10 +1436,12 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1502,7 +1500,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1523,7 +1520,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1537,30 +1533,27 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210603081109-ebe580a85c40/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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= @@ -1571,21 +1564,23 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/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-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 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= @@ -1640,24 +1635,21 @@ golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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.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/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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= -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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -1685,15 +1677,7 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR 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/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.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.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 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= @@ -1750,29 +1734,41 @@ 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-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/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-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +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= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +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/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= @@ -1789,8 +1785,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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= @@ -1803,6 +1799,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= @@ -1838,6 +1835,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= @@ -1845,8 +1843,9 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -helm.sh/helm/v3 v3.9.0 h1:qDSWViuF6SzZX5s5AB/NVRGWmdao7T5j4S4ebIkMGag= -helm.sh/helm/v3 v3.9.0/go.mod h1:fzZfyslcPAWwSdkXrXlpKexFeE2Dei8N27FFQWt+PN0= +helm.sh/helm/v3 v3.11.1 h1:cmL9fFohOoNQf+wnp2Wa0OhNFH0KFnSzEkVxi3fcc3I= +helm.sh/helm/v3 v3.11.1/go.mod h1:z/Bu/BylToGno/6dtNGuSmjRqxKq5gaH+FU0BPO+AQ8= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1859,46 +1858,40 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.0-rc.0/go.mod h1:Dkc/ZauWJrgZhjOjeBgW89xZQiTBJA2RaBKYHXPsi2Y= -k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I= -k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ= -k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI= -k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= -k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= +k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= 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-rc.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= -k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.25.3 h1:m7+xGuG5+KYAnEsqaFtDyWMkmMMEOFYlu+NlWv5qSBI= -k8s.io/apiserver v0.25.3/go.mod h1:9bT47iM2fzRuhICJpM/RcQR9sqDDfZ7Yw60h0p3JW08= -k8s.io/cli-runtime v0.24.0 h1:ot3Qf49T852uEyNApABO1UHHpFIckKK/NqpheZYN2gM= -k8s.io/cli-runtime v0.24.0/go.mod h1:9XxoZDsEkRFUThnwqNviqzljtT/LdHtNWvcNFrAXl0A= +k8s.io/apiserver v0.26.1 h1:6vmnAqCDO194SVCPU3MU8NcDgSqsUA62tBUSWrFXhsc= +k8s.io/apiserver v0.26.1/go.mod h1:wr75z634Cv+sifswE9HlAo5FQ7UoUauIICRlOE+5dCg= +k8s.io/cli-runtime v0.26.0 h1:aQHa1SyUhpqxAw1fY21x2z2OS5RLtMJOCj7tN4oq8mw= +k8s.io/cli-runtime v0.26.0/go.mod h1:o+4KmwHzO/UK0wepE1qpRk6l3o60/txUZ1fEXWGIKTY= k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw= -k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0= -k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA= +k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= +k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/code-generator v0.21.0-rc.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= -k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/code-generator v0.25.3 h1:BEH+wDi90bGyrYcY4abGtUqaOX7G94RRrEu8l+SvIeo= -k8s.io/code-generator v0.25.3/go.mod h1:9F5fuVZOMWRme7MYj2YT3L9ropPWPokd9VRhVyD3+0w= +k8s.io/code-generator v0.26.1 h1:dusFDsnNSKlMFYhzIM0jAO1OlnTN5WYwQQ+Ai12IIlo= +k8s.io/code-generator v0.26.1/go.mod h1:OMoJ5Dqx1wgaQzKgc+ZWaZPfGjdRq/Y3WubFrZmeI3I= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA= -k8s.io/component-base v0.25.3 h1:UrsxciGdrCY03ULT1h/S/gXFCOPnLhUVwSyx+hM/zq4= -k8s.io/component-base v0.25.3/go.mod h1:WYoS8L+IlTZgU7rhAl5Ctpw0WdMxDfCC5dkxcEFa/TI= -k8s.io/component-helpers v0.24.0/go.mod h1:Q2SlLm4h6g6lPTC9GMMfzdywfLSvJT2f1hOnnjaWD8c= +k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= +k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -1909,9 +1902,8 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4 h1:aClvVG6GbX10ISHcc24J+tqbr0S7fEe1MWkFJ7cWWCI= +k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= @@ -1920,58 +1912,50 @@ 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.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.26.2 h1:GM1gg3tFK3OUU/QQFi93yGjG3lJT8s8l3Wkn2+VxBLM= +k8s.io/kms v0.26.2/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= k8s.io/kube-aggregator v0.25.3 h1:eOG9S4GPICAXWIFeQDHjnhqYaYPpgLIC1NunJu9pZCs= k8s.io/kube-aggregator v0.25.3/go.mod h1:w87nqmzJMf7S73FRYcnexqfYW0AFiLJiCkvVCwM3feE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= 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-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= -k8s.io/kubectl v0.24.0 h1:nA+WtMLVdXUs4wLogGd1mPTAesnLdBpCVgCmz3I7dXo= -k8s.io/kubectl v0.24.0/go.mod h1:pdXkmCyHiRTqjYfyUJiXtbVNURhv0/Q1TyRhy2d5ic0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kubectl v0.26.0 h1:xmrzoKR9CyNdzxBmXV7jW9Ln8WMrwRK6hGbbf69o4T0= +k8s.io/kubectl v0.26.0/go.mod h1:eInP0b+U9XUJWSYeU9XZnTA+cVYuWyl3iYPGtru0qhQ= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.24.0/go.mod h1:jrLlFGdKl3X+szubOXPG0Lf2aVxuV3QJcbsgVRAM6fI= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 h1:H9TCJUUx+2VA0ZiD9lvtaX8fthFsMoD+Izn93E/hm8U= -k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg= -oras.land/oras-go v1.1.0/go.mod h1:1A7vR/0KknT2UkJVWh+xMi95I/AhK8ZrxrnUSmXN0bQ= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go v1.2.2 h1:0E9tOHUfrNH7TCDk5KU0jVBEzCqbfdyuVfGmJ7ZeRPE= +oras.land/oras-go v1.2.2/go.mod h1:Apa81sKoZPpP7CDciE006tSZ0x3Q3+dOoBcMZ/aNxvw= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 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.33 h1:LYqFq+6Cj2D0gFfrJvL7iElD4ET6ir3VDdhDdTK7rgc= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33/go.mod h1:soWkSNf2tZC7aMibXEqVhCd73GOY5fJikn8qbdzemB0= -sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= -sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 h1:+xBL5uTc+BkPBwmMi3vYfUJjq+N3K+H6PXeETwf5cPI= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= +sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s= +sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/controller-tools v0.8.0 h1:uUkfTGEwrguqYYfcI2RRGUnC8mYdCFDqfwPKUcNJh1o= sigs.k8s.io/controller-tools v0.8.0/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo= -sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI= -sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= -sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVYCA4BzxeAaLI05Bg= -sigs.k8s.io/kustomize/kyaml v0.13.6 h1:eF+wsn4J7GOAXlvajv6OknSunxpcOBQQqsnPxObtkGs= -sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/manifests/0000_50_olm_00-catalogsources.crd.yaml b/manifests/0000_50_olm_00-catalogsources.crd.yaml index ee5d2eee3d..5e9bb35d0a 100644 --- a/manifests/0000_50_olm_00-catalogsources.crd.yaml +++ b/manifests/0000_50_olm_00-catalogsources.crd.yaml @@ -129,6 +129,9 @@ spec: type: integer publisher: type: string + runAsRoot: + description: RunAsRoot allows admins to indicate that they wish to run the CatalogSource pod in a privileged pod as root. This should only be enabled when running older catalog images which could not be run as non-root. + type: boolean secrets: description: Secrets represent set of secrets that can be used to access the contents of the catalog. It is best to keep this list small, since each will need to be tried for every catalog entry. type: array diff --git a/manifests/0000_50_olm_00-clusterserviceversions.crd.yaml b/manifests/0000_50_olm_00-clusterserviceversions.crd.yaml index dd46e2b939..9b76382957 100644 --- a/manifests/0000_50_olm_00-clusterserviceversions.crd.yaml +++ b/manifests/0000_50_olm_00-clusterserviceversions.crd.yaml @@ -1666,6 +1666,21 @@ spec: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object @@ -2478,6 +2493,21 @@ spec: description: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod. type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object @@ -3301,6 +3331,21 @@ spec: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object @@ -3619,6 +3664,31 @@ spec: conditionType: description: ConditionType refers to a condition in the pod's condition list with matching type. type: string + resourceClaims: + description: "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: PodResourceClaim references exactly one ResourceClaim through a ClaimSource. It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name. + type: object + required: + - name + properties: + name: + description: Name uniquely identifies this resource claim inside the pod. This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + type: object + properties: + resourceClaimName: + description: ResourceClaimName is the name of a ResourceClaim object in the same namespace as this pod. + type: string + resourceClaimTemplateName: + description: "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod. \n The template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The name of the ResourceClaim will be -, where is the PodResourceClaim.Name. Pod validation will reject the pod if the concatenated name is not valid for a ResourceClaim (e.g. too long). \n An existing ResourceClaim with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated resource by mistake. Scheduling and pod startup are then blocked until the unrelated ResourceClaim is removed. \n This field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim." + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map restartPolicy: description: 'Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' type: string @@ -3628,6 +3698,21 @@ spec: schedulerName: description: If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler. type: string + schedulingGates: + description: "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. \n This is an alpha-level feature enabled by PodSchedulingReadiness feature gate." + type: array + items: + description: PodSchedulingGate is associated to a Pod to guard its scheduling. + type: object + required: + - name + properties: + name: + description: Name of the scheduling gate. Each scheduling gate must have a unique name field. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map securityContext: description: 'SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.' type: object @@ -3679,7 +3764,7 @@ spec: description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." type: string supplementalGroups: - description: A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container. Note that this field cannot be set when spec.os.name is windows. + description: A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows. type: array items: type: integer @@ -3814,10 +3899,10 @@ spec: type: integer format: int32 nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." type: string nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." type: string topologyKey: description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. @@ -4103,7 +4188,7 @@ spec: items: type: string dataSource: - description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field.' + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' type: object required: - kind @@ -4119,7 +4204,7 @@ spec: description: Name is the name of resource being referenced type: string dataSourceRef: - description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While DataSource ignores disallowed values (dropping them), DataSourceRef preserves all values, and generates an error if a disallowed value is specified. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.' + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' type: object required: - kind @@ -4134,10 +4219,28 @@ spec: name: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string resources: description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object @@ -4992,22 +5095,26 @@ spec: type: array items: type: string + x-kubernetes-list-type: atomic apiVersions: description: APIVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required. type: array items: type: string + x-kubernetes-list-type: atomic operations: description: Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required. type: array items: description: OperationType specifies an operation for a request. type: string + x-kubernetes-list-type: atomic resources: description: "Resources is a list of resources this rule applies to. \n For example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources. \n If wildcard is present, the validation rule will ensure resources do not overlap with each other. \n Depending on the enclosing object, subresources might not be allowed. Required." type: array items: type: string + x-kubernetes-list-type: atomic scope: description: scope specifies the scope of this rule. Valid values are "Cluster", "Namespaced", and "*" "Cluster" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. "Namespaced" means that only namespaced resources will match this rule. "*" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is "*". type: string diff --git a/manifests/0000_50_olm_00-subscriptions.crd.yaml b/manifests/0000_50_olm_00-subscriptions.crd.yaml index 8618f9d66b..2a7b459245 100644 --- a/manifests/0000_50_olm_00-subscriptions.crd.yaml +++ b/manifests/0000_50_olm_00-subscriptions.crd.yaml @@ -645,6 +645,21 @@ spec: description: 'Resources represents compute resources required by this container. Immutable. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object @@ -1018,7 +1033,7 @@ spec: items: type: string dataSource: - description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field.' + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' type: object required: - kind @@ -1034,7 +1049,7 @@ spec: description: Name is the name of resource being referenced type: string dataSourceRef: - description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While DataSource ignores disallowed values (dropping them), DataSourceRef preserves all values, and generates an error if a disallowed value is specified. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.' + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' type: object required: - kind @@ -1049,10 +1064,28 @@ spec: name: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string resources: description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' type: object properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + type: array + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + type: object + required: + - name + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object diff --git a/staging/api/.github/workflows/go.yaml b/staging/api/.github/workflows/go.yaml index 3fa8fbcb6a..0b7e5802cc 100644 --- a/staging/api/.github/workflows/go.yaml +++ b/staging/api/.github/workflows/go.yaml @@ -13,9 +13,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 @@ -37,9 +37,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 id: go - name: Print out Go env run: go env diff --git a/staging/api/.github/workflows/verify.yml b/staging/api/.github/workflows/verify.yml index 11fa0edfe6..b5771af1c6 100644 --- a/staging/api/.github/workflows/verify.yml +++ b/staging/api/.github/workflows/verify.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version: '~1.19' - name: Run the verify target run: | export GOPATH=$(go env GOPATH) diff --git a/staging/api/Makefile b/staging/api/Makefile index b5fdf9d55c..65e207e994 100644 --- a/staging/api/Makefile +++ b/staging/api/Makefile @@ -22,7 +22,6 @@ help: ## Show this help screen @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) .PHONY: install - install: ## Build & install operator-verify $(Q)go install \ -gcflags "all=-trimpath=${GOPATH}" \ @@ -42,7 +41,7 @@ format: ## Format the source code $(Q)go fmt $(PKGS) tidy: ## Update dependencies - $(Q)go mod tidy -v + $(Q)go mod tidy $(Q)go mod verify clean: ## Clean up the build artifacts @@ -59,17 +58,17 @@ manifests: yq controller-gen ## Generate manifests e.g. CRD, RBAC etc $(CONTROLLER_GEN) schemapatch:manifests=./crds output:dir=./crds paths=./pkg/operators/... @# Add missing defaults in embedded core API schemas - $(Q)$(YQ) w --inplace ./crds/operators.coreos.com_clusterserviceversions.yaml spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.spec.properties.containers.items.properties.ports.items.properties.protocol.default TCP - $(Q)$(YQ) w --inplace ./crds/operators.coreos.com_clusterserviceversions.yaml spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.spec.properties.initContainers.items.properties.ports.items.properties.protocol.default TCP + $(YQ) --inplace '.spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.spec.properties.containers.items.properties.ports.items.properties.protocol.default="TCP"' ./crds/operators.coreos.com_clusterserviceversions.yaml + $(Q)$(YQ) --inplace '.spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.spec.properties.initContainers.items.properties.ports.items.properties.protocol.default="TCP"' ./crds/operators.coreos.com_clusterserviceversions.yaml @# Preserve fields for embedded metadata fields - $(Q)$(YQ) w --inplace ./crds/operators.coreos.com_clusterserviceversions.yaml spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.metadata.x-kubernetes-preserve-unknown-fields true + $(Q)$(YQ) --inplace '.spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.metadata.x-kubernetes-preserve-unknown-fields=true' ./crds/operators.coreos.com_clusterserviceversions.yaml @# Remove OperatorCondition.spec.overrides[*].lastTransitionTime requirement - $(Q)$(YQ) delete --inplace ./crds/operators.coreos.com_operatorconditions.yaml 'spec.versions[*].schema.openAPIV3Schema.properties.spec.properties.overrides.items.required(.==lastTransitionTime)' + $(Q)$(YQ) --inplace 'del(.spec.versions[].schema.openAPIV3Schema.properties.spec.properties.overrides.items.required[] | select(. == "lastTransitionTime"))' ./crds/operators.coreos.com_operatorconditions.yaml @# Remove status subresource from the CRD manifests to ensure server-side apply works - $(Q)for f in ./crds/*.yaml ; do $(YQ) d --inplace $$f status; done + $(Q)for f in ./crds/*.yaml ; do $(YQ) --inplace 'del(.status)' $$f; done @# Update embedded CRD files. $(Q)go generate ./crds/... @@ -102,7 +101,8 @@ CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen YQ ?= $(LOCALBIN)/yq ## Tool Versions -CONTROLLER_TOOLS_VERSION ?= v0.8.0 +CONTROLLER_TOOLS_VERSION ?= v0.9.0 +YQ_VERSION ?= v4.28.1 .PHONY: controller-gen controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. @@ -112,4 +112,4 @@ $(CONTROLLER_GEN): $(LOCALBIN) .PHONY: yq yq: $(YQ) ## Download yq locally if necessary. $(YQ): $(LOCALBIN) - GOBIN=$(LOCALBIN) go install $(GO_INSTALL_OPTS) github.com/mikefarah/yq/v3@latest + GOBIN=$(LOCALBIN) go install $(GO_INSTALL_OPTS) github.com/mikefarah/yq/v4@$(YQ_VERSION) \ No newline at end of file diff --git a/staging/api/crds/operators.coreos.com_catalogsources.yaml b/staging/api/crds/operators.coreos.com_catalogsources.yaml index 2836d66fed..6f03afbf22 100644 --- a/staging/api/crds/operators.coreos.com_catalogsources.yaml +++ b/staging/api/crds/operators.coreos.com_catalogsources.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: catalogsources.operators.coreos.com spec: @@ -127,6 +127,9 @@ spec: type: integer publisher: type: string + runAsRoot: + description: RunAsRoot allows admins to indicate that they wish to run the CatalogSource pod in a privileged pod as root. This should only be enabled when running older catalog images which could not be run as non-root. + type: boolean secrets: description: Secrets represent set of secrets that can be used to access the contents of the catalog. It is best to keep this list small, since each will need to be tried for every catalog entry. type: array @@ -152,7 +155,7 @@ spec: description: Represents the state of a CatalogSource. Note that Message and Reason represent the original status information, which may be migrated to be conditions based in the future. Any new features introduced will use conditions. type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/staging/api/crds/operators.coreos.com_clusterserviceversions.yaml b/staging/api/crds/operators.coreos.com_clusterserviceversions.yaml index 37b41c4608..7eb672aa5f 100644 --- a/staging/api/crds/operators.coreos.com_clusterserviceversions.yaml +++ b/staging/api/crds/operators.coreos.com_clusterserviceversions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: clusterserviceversions.operators.coreos.com spec: @@ -550,7 +550,7 @@ spec: - verbs properties: apiGroups: - description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. + description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. type: array items: type: string @@ -1528,7 +1528,7 @@ spec: description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. type: string ports: - description: List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated. + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. type: array items: description: ContainerPort represents a network port in a single container. @@ -1966,10 +1966,10 @@ spec: description: 'EnableServiceLinks indicates whether information about services should be injected into pod''s environment variables, matching the syntax of Docker links. Optional: Defaults to true.' type: boolean ephemeralContainers: - description: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. + description: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. type: array items: - description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted. \n This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate." + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." type: object required: - name @@ -2772,6 +2772,9 @@ spec: hostPID: description: 'Use the host''s pid namespace. Optional: Default to false.' type: boolean + hostUsers: + description: 'Use the host''s user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.' + type: boolean hostname: description: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value. type: string @@ -3160,7 +3163,7 @@ spec: description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. type: string ports: - description: List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated. + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. type: array items: description: ContainerPort represents a network port in a single container. @@ -3575,7 +3578,7 @@ spec: type: string x-kubernetes-map-type: atomic os: - description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. \n If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions \n If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature" + description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. \n If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions \n If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup" type: object required: - name @@ -3794,16 +3797,28 @@ spec: type: object additionalProperties: type: string + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + type: array + items: + type: string + x-kubernetes-list-type: atomic maxSkew: description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' type: integer format: int32 minDomains: - description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate." + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." type: integer format: int32 + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string topologyKey: - description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes match the node selector. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' @@ -4746,7 +4761,7 @@ spec: - verbs properties: apiGroups: - description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. + description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. type: array items: type: string diff --git a/staging/api/crds/operators.coreos.com_installplans.yaml b/staging/api/crds/operators.coreos.com_installplans.yaml index 8e9b85e371..b85b77c562 100644 --- a/staging/api/crds/operators.coreos.com_installplans.yaml +++ b/staging/api/crds/operators.coreos.com_installplans.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: installplans.operators.coreos.com spec: diff --git a/staging/api/crds/operators.coreos.com_olmconfigs.yaml b/staging/api/crds/operators.coreos.com_olmconfigs.yaml index 44dfcd937e..c6ebe96815 100644 --- a/staging/api/crds/operators.coreos.com_olmconfigs.yaml +++ b/staging/api/crds/operators.coreos.com_olmconfigs.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: olmconfigs.operators.coreos.com spec: @@ -50,7 +50,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/staging/api/crds/operators.coreos.com_operatorconditions.yaml b/staging/api/crds/operators.coreos.com_operatorconditions.yaml index aa6bd41955..ef4b7bef73 100644 --- a/staging/api/crds/operators.coreos.com_operatorconditions.yaml +++ b/staging/api/crds/operators.coreos.com_operatorconditions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operatorconditions.operators.coreos.com spec: @@ -45,7 +45,7 @@ spec: overrides: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - message @@ -95,7 +95,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime @@ -162,7 +162,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime @@ -209,7 +209,7 @@ spec: overrides: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - message @@ -259,7 +259,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/staging/api/crds/operators.coreos.com_operatorgroups.yaml b/staging/api/crds/operators.coreos.com_operatorgroups.yaml index b62f3996a9..f6794075b9 100644 --- a/staging/api/crds/operators.coreos.com_operatorgroups.yaml +++ b/staging/api/crds/operators.coreos.com_operatorgroups.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operatorgroups.operators.coreos.com spec: @@ -99,7 +99,7 @@ spec: description: Conditions is an array of the OperatorGroup's conditions. type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/staging/api/crds/operators.coreos.com_operators.yaml b/staging/api/crds/operators.coreos.com_operators.yaml index e7dce32925..73b202874f 100644 --- a/staging/api/crds/operators.coreos.com_operators.yaml +++ b/staging/api/crds/operators.coreos.com_operators.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operators.operators.coreos.com spec: diff --git a/staging/api/crds/operators.coreos.com_subscriptions.yaml b/staging/api/crds/operators.coreos.com_subscriptions.yaml index 3523401502..0ebb188ac0 100644 --- a/staging/api/crds/operators.coreos.com_subscriptions.yaml +++ b/staging/api/crds/operators.coreos.com_subscriptions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: subscriptions.operators.coreos.com spec: diff --git a/staging/api/crds/zz_defs.go b/staging/api/crds/zz_defs.go index ea65d5c73e..aaa0ea110d 100644 --- a/staging/api/crds/zz_defs.go +++ b/staging/api/crds/zz_defs.go @@ -85,7 +85,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _operatorsCoreosCom_catalogsourcesYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7b\x6b\x73\xdc\xb6\x92\xf6\x77\xff\x8a\x2e\xbd\x6f\x95\xa4\xec\x0c\x65\x25\xa7\xb2\x27\xb3\xb9\x94\x22\xdb\x59\x55\x62\x5b\x65\xd9\xde\xda\x63\x79\xd7\x18\xb2\x87\x83\x08\x04\x68\x00\x94\x34\x39\x75\xfe\xfb\x56\x37\x00\x92\x73\xe1\xcc\x48\x71\xf4\xc5\x16\x88\x6b\x5f\x9f\x7e\x00\x89\x5a\xbe\x47\xeb\xa4\xd1\x13\x10\xb5\xc4\x7b\x8f\x9a\x7e\x73\xd9\xcd\xdf\x5d\x26\xcd\xc9\xed\xe9\x93\x1b\xa9\x8b\x09\x9c\x37\xce\x9b\xea\x0d\x3a\xd3\xd8\x1c\x9f\xe1\x4c\x6a\xe9\xa5\xd1\x4f\x2a\xf4\xa2\x10\x5e\x4c\x9e\x00\x08\xad\x8d\x17\xd4\xec\xe8\x57\x80\xdc\x68\x6f\x8d\x52\x68\xc7\x25\xea\xec\xa6\x99\xe2\xb4\x91\xaa\x40\xcb\x93\xa7\xa5\x6f\x9f\x66\xdf\x65\x4f\x9f\x00\xe4\x16\x79\xf8\x5b\x59\xa1\xf3\xa2\xaa\x27\xa0\x1b\xa5\x9e\x00\x68\x51\xe1\x04\x72\xe1\x85\x32\x65\xd8\x84\xcb\x4c\x8d\x56\x78\x63\x5d\x96\x1b\x8b\x86\xfe\xa9\x9e\xb8\x1a\x73\x5a\xbd\xb4\xa6\xa9\x27\xb0\xb1\x4f\x98\x2f\x6d\x52\x78\x2c\x8d\x95\xe9\x77\x80\x31\x18\x55\xf1\xff\xe3\xe1\xc3\xb2\x57\xbc\x2c\xb7\x2b\xe9\xfc\xaf\xeb\xdf\x7e\x93\xce\xf3\xf7\x5a\x35\x56\xa8\xd5\x0d\xf3\x27\x37\x37\xd6\xbf\xea\x96\xa7\xe5\x72\xe1\x9d\xcd\xc3\x67\xa9\xcb\x46\x09\xbb\x32\xf6\x09\x80\xcb\x4d\x8d\x13\xe0\xa1\xb5\xc8\xb1\x78\x02\x10\x45\x18\xa7\x1a\x83\x28\x0a\x56\x8b\x50\x97\x56\x6a\x8f\xf6\xdc\xa8\xa6\xd2\xed\x52\xd4\xa7\x40\x97\x5b\x59\x7b\x16\xfd\xdb\x39\x42\x6d\xd1\xfb\x05\x8b\x04\xcc\x0c\xfc\x1c\xd3\xda\xed\x28\x80\xdf\x9d\xd1\x97\xc2\xcf\x27\x90\x91\x84\xb3\x42\xba\x5a\x89\x05\xed\xa6\xd7\x2b\xa8\xe9\x59\xf8\xd6\x6b\xf7\x0b\xda\xba\xf3\x56\xea\x72\xdb\x56\xa8\xdf\xfe\x7b\x08\xa2\x79\xbb\xa8\xd7\xb7\xb0\xd2\xb8\xef\xfa\x75\x33\x55\xd2\xcd\xd1\xee\xbf\x89\x76\xc8\xda\x1e\x2e\x37\x7c\x19\xd8\x48\x6f\xd2\xe4\x50\xd9\x9a\x33\xac\x2d\x70\x56\xae\x9f\xb1\x10\x3e\x35\x86\x4e\xb7\xa7\x42\xd5\x73\x71\x1a\x1b\x5d\x3e\xc7\x4a\x74\xf6\x60\x6a\xd4\x67\x97\x17\xef\xbf\xb9\x5a\xf9\x00\xcb\xd2\x59\xb2\x73\x90\x0e\x04\x58\xac\x8d\x93\xde\xd8\x05\x49\xeb\xfc\xea\xbd\x1b\xc1\xf9\x9b\x67\x6e\x04\x42\x17\xad\xe3\x41\x2d\xf2\x1b\x51\xa2\xcb\xd6\xf6\x6a\xa6\xbf\x63\xee\x7b\xcd\x16\x3f\x37\xd2\x62\xd1\xdf\x05\x89\x27\xc9\x64\xa5\x99\xe4\xdf\x6b\xaa\x2d\xad\xe9\x7b\x8e\x1c\x7e\x7a\x51\x6e\xa9\x7d\xe5\x84\x87\x24\x86\xd0\x0f\x0a\x0a\x70\xe8\xd8\x04\xa2\x8f\x61\x11\x65\x17\x4c\x43\x3a\x3a\xbf\x45\x87\x3a\x84\x3c\x6a\x16\x3a\x9e\x29\x83\x2b\xb4\x34\x90\xdc\xbd\x51\x05\x45\xc2\x5b\xb4\x1e\x2c\xe6\xa6\xd4\xf2\x8f\x76\x36\x07\xde\xf0\x32\x4a\x78\x74\x1e\xd8\x6b\xb5\x50\x70\x2b\x54\x83\x41\x94\x95\x58\x80\x45\x9a\x17\x1a\xdd\x9b\x81\xbb\xb8\x0c\x5e\x1a\x8b\x20\xf5\xcc\x4c\x60\xee\x7d\xed\x26\x27\x27\xa5\xf4\x29\x86\xe7\xa6\xaa\x1a\x2d\xfd\xe2\x84\xc3\xb1\x9c\x36\x14\x0e\x4f\x0a\xbc\x45\x75\xe2\x64\x39\x16\x36\x9f\x4b\x8f\xb9\x6f\x2c\x9e\x88\x5a\x8e\x79\xb3\x9a\xe3\x78\x56\x15\xff\xcf\xc6\xa8\xef\x0e\x57\xc4\xb7\xd1\x98\x21\x85\xcd\xad\xb2\xa6\xe0\x19\xac\x28\x0c\x0f\x67\xe9\x44\x4a\x4d\x24\x95\x37\xcf\xaf\xde\x42\xda\x40\x10\x7b\x90\x70\xd7\xd5\x75\xc2\x26\x41\x49\x3d\x43\x1b\x7a\xce\xac\xa9\x78\x16\xd4\x45\x6d\xa4\xf6\xc1\xa5\x95\x44\xed\xc1\x35\xd3\x4a\x7a\xc7\x36\x87\xce\x93\x1e\x32\x38\xe7\x14\x06\x53\x84\xa6\x26\x4f\x2a\x32\xb8\xd0\x70\x2e\x2a\x54\xe7\xc2\xe1\x5f\x2e\x6a\x92\xa8\x1b\x93\xf8\xf6\x17\x76\x3f\x03\xaf\x0f\x58\xf3\x31\x80\x94\x21\xf7\xea\x3c\xe4\x94\x10\x3c\x70\x53\x04\x86\x2d\xbe\x48\x3f\xa2\x28\x2c\xba\x0d\x1f\xd6\x1c\x32\x74\x0c\x76\x32\x37\x8e\xf4\x27\x3c\xbc\xfe\xed\x25\xe4\x42\x43\xe3\x90\x9c\x27\x37\x5a\x93\x41\x78\x03\x82\x72\xd9\x18\xef\xa5\x63\x03\xb2\x58\x4a\xe7\xed\x22\x83\x17\xc6\x56\xc2\x4f\xe0\xfb\xd4\x34\xe6\xe9\x8c\x05\x59\xff\x38\xf9\xbe\x36\xd6\xff\x08\xaf\xb5\x5a\xd0\xa4\x05\xdc\xcd\x51\xc3\x55\x7b\x36\xf8\xa1\xf7\xcb\x2f\xb6\xce\x33\xb8\x28\xb5\xb1\xa9\x27\x59\xd5\x45\x25\x4a\x84\x99\x44\xc5\x76\xed\xd0\x67\xab\x1a\xdc\xaa\x45\x08\x70\x69\x26\xcb\x97\xa2\xde\x29\x9a\xf3\xd4\x93\xd6\xa2\xe5\xfb\xc9\xbb\xfb\xe8\x0d\x9b\x32\x1d\x89\xfe\x2b\xf2\x1b\x10\x71\x95\x4a\xd4\x63\xc7\x6e\xd3\x13\xd3\x7e\x12\x38\x4f\x13\x90\xfc\xba\xe6\x8b\x18\xb9\xb2\x87\x1e\xbb\x7f\xb2\x07\x8f\xed\x60\xc8\x4e\xa1\xbd\xdc\x94\x45\xf6\x58\xa3\xb4\x75\x7e\x69\x8a\x70\xec\x9d\xab\xfc\xd2\xef\x0d\x78\x5f\x1b\x87\x0e\x0a\x39\x9b\xa1\xa5\xb8\x63\x6e\xd1\x5a\x59\xa0\x83\x99\xb1\xac\xaf\xda\x14\xec\x93\xad\xfe\x96\x52\xed\xa5\x29\xf6\x55\x0c\x2d\xcd\x09\x23\x18\x63\x34\xc3\xc1\xe3\x6e\xf4\x76\xd8\xe1\xbc\xf4\xa3\x4d\x81\x57\xa8\x30\xf7\xc6\x6e\xee\xb1\x22\x93\x57\xbd\x01\x31\xea\xa7\xdf\xee\xe6\x32\x9f\x43\xd5\x38\x8e\xba\xde\x36\xb8\x24\x17\x6f\x60\x26\x3d\x18\x0d\x82\x97\xa5\x58\xbf\x3e\xb2\x12\x3e\x9f\xc7\x1e\x87\x0e\x94\x98\xa2\x72\xab\xf3\x4c\x91\x53\x6e\xd1\x28\x2c\x68\x42\x8e\x25\x3c\xe7\xc0\x11\x76\x48\x09\x42\x28\x6b\xf1\xf6\x76\x99\xc1\x2e\x2b\x0b\x82\x97\xc6\x4a\xbf\x38\x57\xc2\xb9\x21\x9b\x5e\x93\xee\xc5\x8c\xcd\x47\xce\x24\x16\x23\x90\xba\x90\x54\xd2\xb8\x74\xf6\x43\xd7\xce\x9b\x51\x5f\x4a\x70\xbd\xfe\x49\x42\xa9\x0f\xdc\x49\xa5\x48\x58\x05\xce\x44\xa3\x38\x48\xfe\x81\xd6\x80\x64\xeb\xb4\x6c\x57\xda\xa4\xcf\xdb\x85\xb7\xe5\xac\x0e\xf3\x86\xcf\x6a\xb4\xc7\x7b\x3f\xec\x5d\x6b\xe7\x3d\xb8\xda\x34\x94\x53\xc2\x14\xc1\x68\x0e\x84\x9f\x14\x96\x22\x5f\x7c\xa2\xed\x7f\xb2\x48\x1b\xc9\x3d\x16\x9f\x32\xc6\xf9\x4b\x2e\x46\x02\x32\x1c\xb5\x51\xd2\x09\x41\x6a\x52\x39\x39\x9b\xf4\x73\x16\x90\x95\xe5\xdc\x53\xaf\x58\x78\x2c\x6f\x80\x7d\xae\xfd\x48\xa9\x5f\x48\x8d\xf6\xc3\x57\x1f\xd7\x7a\x06\xc8\xc6\xb9\x4a\x29\x73\xd7\xb7\x4f\xdb\x68\x90\x9a\xfc\x1d\xd2\x01\xe1\xac\xa8\xa4\x63\x44\x7a\x74\x79\x75\x76\xbc\x74\x12\xa8\x4c\x81\x23\x3a\x5f\x61\xd0\xe9\x43\x4f\xde\x4e\x13\x3a\x4c\xcb\x08\x4f\xcb\x90\x4d\x44\x6f\xc9\x05\xe5\xcc\xb8\x26\x09\xcc\x50\x60\x99\x62\xbb\xf8\xd5\x19\x7c\x9a\x0a\x87\x4a\x6a\x0c\xb2\xab\xad\xbc\x95\x0a\x4b\x5a\x51\xa7\xda\xd3\x65\x70\xde\x58\x8a\x67\x6a\x11\x0d\x03\x36\x6b\x45\x3a\x68\xf4\x8a\xb9\x25\xcb\x0a\x98\xaf\xaf\x2c\xea\xed\x08\x75\x5d\xf1\x88\x05\x65\x71\x91\xfa\xb1\x6e\xfc\x5c\xe8\x41\xe5\x12\x52\xa4\x89\xa5\x0e\xa3\x64\x11\xa0\x39\x5a\x6b\x6c\x06\xff\x45\xb1\xb3\xa1\x0a\x1b\x8c\x2a\xd0\xa6\xea\x0e\x24\xc5\x4b\x37\x4a\x42\x62\xc4\x1e\x71\x60\x14\xcc\x06\xc1\x0f\x9f\x39\x62\x7e\x0a\x38\xc8\xb8\x24\xed\x37\x83\x6b\x4d\x80\x52\xc0\xac\x21\x08\x98\x6a\x8b\xe0\x73\x7d\xd1\x24\x27\x4c\x13\xf4\x96\x1f\xb5\xdb\xae\x84\x8c\xa6\xd6\xd6\x19\x36\x10\x2c\x34\x97\x6c\xcf\xe7\x82\x21\x8b\x76\x39\x33\x03\x53\x57\x21\x02\xba\xa6\x26\xf8\xe3\xe8\xa4\x9a\x44\x93\x2f\xa5\x9f\xda\x14\x6e\xa3\x00\x68\x5b\xb5\xc5\x5a\xd8\x36\x62\x3b\x84\x7c\x2e\x34\xd5\x7a\x74\xd0\x16\x2b\x13\xf6\xa2\x65\xc5\xd4\x34\x9e\x6d\x2c\xfa\xea\xcc\x34\xba\x00\x0a\x2a\x1d\x9c\xbe\x69\xa6\x68\x35\x7a\x64\x44\x5d\x98\xdc\x11\x98\xce\xb1\xf6\xee\x24\x79\xd3\x49\x6d\x8a\x71\xfa\x65\x2c\x92\x93\x9c\x1c\x1e\x3c\x36\x1a\x41\x92\xfc\x04\x82\xae\x06\x7a\xa1\x6e\xaa\xe1\x00\x3f\xde\x3e\x98\x3a\x74\x62\xdc\xd8\xc9\x1b\x45\x65\x73\xc7\xe9\x6c\xda\x68\x9f\xb4\xe8\xfa\x03\x69\xa2\xc7\x59\x44\x70\x1e\xa2\xdb\xa1\xeb\x4f\xbd\x3d\x68\x0b\x6b\xc5\xd0\x11\xa4\xc7\x6a\x4b\x86\x5b\x27\x54\x28\xb6\x51\x2d\xd6\x6d\x94\x01\x80\xf7\x82\x72\x31\x17\xbf\xe1\x0b\x85\x2b\xbd\x00\xb2\xe7\x88\xf3\x39\xab\xc7\x3c\xe6\xad\xac\x15\xc2\xf7\x37\xb8\x18\x85\xca\x18\x67\x33\xcc\xfd\x8f\xd1\x9f\xa9\x0f\xf7\x67\xe7\x4e\xd4\xc3\xf7\xe9\x7f\x3f\x0e\x9d\x78\xaf\x2c\xbf\x1b\x11\x85\x9f\xb0\xa5\x6d\x3d\x56\x24\xf4\x9c\x07\xac\xa4\xec\x20\x81\x30\x17\xc9\x87\x8f\x95\xc1\xf3\xaa\xf6\x0b\xa8\x50\x68\x97\xf0\x0e\xc5\x8c\x5e\x67\x17\x23\x5c\x2f\xda\x72\x92\x69\x99\x02\xb6\x90\x57\xe6\x2a\xa2\xa0\x11\x5c\x5a\x9c\xa1\xed\x5a\x38\x91\xbd\x32\xcf\xef\x31\x6f\xfc\x20\x2e\xea\xcb\x6d\xab\x4b\xd1\xcf\x0d\x2e\x1e\x20\x90\x5f\x71\x91\x2a\x9a\x70\xb2\x1b\x5c\x04\x63\xe0\xa6\xce\x86\x44\x5d\x2b\x89\xa1\x68\xdf\x26\x99\x1b\x5c\x38\x46\x3d\x34\xfe\x26\xcc\x8e\xd4\x7f\xd4\x59\x49\x02\x9f\xcf\xa9\x6e\x74\xff\x11\xec\x35\x37\xd5\x54\xea\xb0\x58\x98\x3a\xa9\x82\x67\x4f\x02\xd5\x05\xff\xca\xcb\x7c\x09\x71\xa5\x4d\x3d\x40\x66\xaf\xd3\x39\x3a\x46\x04\x04\xed\xe8\xd0\x81\x45\x15\x3c\x7e\x2e\xeb\x44\x34\xf1\xd6\x33\x78\x4f\xe9\xb1\xa3\xc7\xd9\x36\x82\x04\xf8\x54\xcf\x3f\x37\x42\x65\xf0\x2c\x44\x45\x3e\x7d\x6c\x8a\x9d\x48\x90\x9f\x1b\x79\x2b\x14\x55\x35\xde\x50\xca\x2a\x72\x61\x0b\xce\x06\x91\xbd\x72\x26\x68\x4f\xb4\x80\x23\x79\x7b\xa7\x23\xc7\xcc\x19\xd4\xc2\x7a\x99\x37\x4a\xd8\xc4\xc8\x2f\xbe\x88\x44\x3b\xa3\xb9\xc2\xdc\xe8\x62\xab\x07\x0f\x46\xd7\x38\xb6\x2f\x63\x86\x51\x68\xa5\x29\xb8\x70\x93\x15\xae\x1a\xe9\xd1\x72\x71\x63\x66\xc9\xab\x5b\x17\x1b\x05\x54\x73\x27\x5d\x24\xb7\x5a\x02\x41\x06\x82\xe1\xb8\x17\x1e\x5b\xaf\xc8\xe0\xe7\x45\xca\x57\x23\x90\x3e\x20\x72\xc6\x7f\x09\xc3\x24\x93\x8d\xc2\xee\x1c\x6a\x66\x2c\x52\xd1\x7f\x54\x18\x1e\x83\xb7\x32\xf7\xc7\x19\xfc\x83\x20\x3e\x29\x5e\x63\x29\xbc\xbc\x6d\x31\x64\x42\x22\xde\xa2\x20\x4c\x2c\x1c\x3c\x85\x23\x1e\x06\xb2\xaa\xb0\x90\xc2\xa3\x5a\x1c\xc3\x74\xc1\xcb\xb8\x85\xf3\x58\xed\xa3\x3a\xa9\x3d\x96\x4b\xec\xf8\xfa\xcf\x2c\x12\x37\x52\xfb\x6f\xff\xb6\xa5\x27\x6f\xf6\x01\x9a\x7d\xcf\x90\x72\x29\xd4\x04\x94\xb9\xa2\xc2\x36\x07\x99\x36\x8a\xb4\x71\x43\xba\xe8\x0b\xa3\xce\xaf\x7a\xd8\x2f\x85\x99\x56\xc1\xbf\x93\x1d\x08\xb0\xc8\x17\x3c\xd1\x72\xff\x84\x8d\xcb\x7c\x1b\x61\x32\x98\xd1\x86\xf9\x3c\x60\x84\x42\xf0\xff\xdb\xbf\x0d\x10\x25\x81\x8d\x27\x9d\xaf\x73\x7e\xb0\x47\xa2\xec\x26\x1f\x52\xd6\x4e\xb7\x6e\x97\x7f\xd4\x0c\x0c\xf5\x77\x92\x38\x2d\x81\x42\x25\x52\xd4\xf7\x38\xf1\x64\xd0\x56\x78\x61\x36\x0a\x7e\x52\x3b\x2f\xb4\x97\x1c\xd9\x5a\x46\x2d\x31\x6c\x04\xbf\x1f\x42\xe2\xb0\xad\xc5\x40\x13\x8c\x2b\x72\xa6\x6b\xf1\xe1\xc1\x64\x5b\x2a\xf3\x77\xb3\xaf\x97\x89\x10\x08\x6b\x0a\xe7\x64\x49\x28\x13\xee\x90\xab\xe1\x98\x4e\x96\xd1\x66\xa8\x0a\x78\xa0\xfc\x83\xbd\xa9\x6a\x93\x80\xf4\x09\xf7\xe7\x46\xbb\xa6\xc2\x22\xc5\x8c\x02\x6b\xd4\x05\xea\x7c\xc1\x5c\xbf\xba\x45\x9b\xc1\x3b\x47\x9a\x82\xff\x94\x25\xd5\x7d\x71\xd1\x3e\x54\x62\x54\x40\xa9\x7a\x79\x07\xd2\x91\xe8\x66\x68\x2d\x16\xcc\xb6\x01\x61\xa0\x34\x03\x16\x2b\xfd\x1d\x14\x0d\xdf\x40\xac\x6e\xa2\x21\x39\x04\xba\xc0\x52\x51\x93\xe8\xb9\x96\x28\x09\x0e\x4f\x47\x2a\x4d\xb8\x6b\xe0\xfb\x30\x8a\x9d\xde\x74\x71\x54\x06\x82\xb8\x9d\x43\x6a\xff\xcd\xd7\x61\xde\xe5\x42\x98\x09\xec\x95\xc3\x70\xe1\xd6\xe8\x20\x7c\xec\xb3\x34\x29\xcc\x3c\x0d\x53\x6d\x1a\xc7\xe1\x58\x54\xab\x5b\xee\x62\xba\x15\xfa\x06\x0b\x50\x78\x2f\x73\x53\x5a\x51\xcf\x65\x2e\x94\x5a\xb0\x9b\x32\x49\x26\xbd\xe3\xaa\x7f\x0b\x99\x3d\x14\xc6\xdb\x8b\xd1\x07\x93\xba\x0e\x73\x8b\x7e\xf7\x05\xc1\x55\xe8\xd7\x25\x65\x2e\x97\xcd\x2c\x4d\x10\x6c\x24\xda\x5c\x62\xc1\x45\x9e\x93\x23\xb1\xe9\x52\xd5\x1e\x01\x48\xcf\x94\x33\xb8\xe0\x94\x3a\x45\xc7\x56\x7e\x83\x58\x07\x4b\x53\xd2\x79\x70\x15\x73\x2a\x4e\xea\x1c\x01\x45\x3e\x0f\xe2\xd4\x88\x89\x66\xf4\x56\x62\x80\x41\x94\x6a\x17\xad\x6e\x50\xfb\xcd\xa0\x66\x7b\xdd\xb5\xa5\xe6\xda\x2e\xc6\x36\xa6\xec\x96\x64\x17\x8b\x52\x4e\x8c\x37\xf1\xae\x7b\xf4\xf0\x80\xa5\xc3\xed\xd9\x95\x27\xf0\x51\xee\x8e\x35\xef\x96\xba\xb7\xb7\xaf\x73\x73\x97\xee\xe1\xd6\x9c\x9c\x19\x9b\xa4\xdb\x42\xba\x9c\x3c\x1d\x0b\x38\x37\xda\x31\x3e\x0d\xd7\xb1\x7c\x9d\x7a\x2b\x54\x30\x85\x34\x71\x6d\x94\x62\x97\x6f\x52\x39\x41\x38\x5e\x03\x56\x53\x2c\x0a\x2c\xe8\x58\x61\x2b\x03\x69\xee\x4f\x12\xe8\x29\x3f\x5c\x1a\xa5\xb6\x67\xb1\xad\x75\xe9\x3e\x55\x69\x12\xc0\x36\x6c\xb4\x9c\xfa\x92\xc4\x22\x17\x47\x36\x5d\xa0\x47\x5b\x49\x1d\xe1\x11\x41\xdd\x56\xb0\x53\xf4\x77\x88\x1a\xf2\x39\xe6\x37\xad\x2b\xc5\xdb\xec\x15\xad\x45\xfe\x69\x39\x62\x75\x0f\x05\x8c\x52\x5c\x68\x38\x44\x90\x54\x13\x68\xbc\xeb\x73\x56\x1b\xd2\x0d\xa5\xe8\x5b\x21\x95\x98\x2a\xe4\xac\xd9\xfe\x36\x5a\xba\x55\x4f\xf9\xbc\x6e\x94\x22\x10\xab\x0b\x28\xdf\x5c\x9e\x83\xb7\x62\x36\x93\x39\x7d\x2a\xa4\x0d\xac\xef\xf2\x85\xfc\xf2\x82\xdb\xe0\xda\xa0\x47\x38\x2f\x7c\xb3\xa6\xa3\x2d\x0a\xde\xa6\x58\xaa\x43\xe4\x20\x41\xb4\xa4\xca\x37\xcb\xc5\x0a\x6d\x03\x43\xb1\xb5\xc4\x7f\x67\xf0\xca\x70\x8d\x20\x3c\xbc\x44\x47\x69\x97\x05\xf4\x06\x85\x33\xba\x17\x5d\x19\xfd\x5a\x59\x4a\x2d\x54\x3c\x54\x9f\xdf\x6b\x6b\x0f\xc1\x94\x72\x25\x4b\x2b\x7c\x1b\x14\xbb\x7d\xc7\xec\x12\xf3\x62\x60\x42\x33\x38\xd3\x0b\xd6\xf7\x0c\x05\x35\xd0\xcc\xde\x9a\xa2\xc9\x99\x87\x57\x8a\xaf\x7b\xbb\x49\xbe\x68\x18\x5d\xbe\x5e\x38\x4f\x8b\x24\xa0\xe7\xc8\x01\x84\x8c\x57\x4a\x46\x23\x08\x57\x53\x1d\x97\x6c\x32\x50\xe1\x9d\x80\x39\x59\x9c\x5d\x5e\x40\x7a\x30\x97\xc1\x78\x3c\x86\xb7\xd4\xec\xbc\x6d\x72\xce\x2f\xe4\x42\xba\x88\x99\x22\x58\x1f\x1f\x52\x30\xec\xe4\x63\x40\x64\x3e\x02\x04\xab\x85\x9f\x43\x16\x04\x9f\xf5\x44\x01\xf0\x82\x72\xcd\xbd\xa8\x6a\xb2\xfb\x6b\x1d\xa2\xf7\x0b\x63\xae\x82\x92\xc2\x9a\xff\x84\x93\x93\x55\x9b\x30\x53\x82\xa8\x91\x40\x64\xd3\x98\x19\x73\xe8\x96\x8f\x94\xd1\xc0\x5f\xb5\xb9\xd3\x9b\x56\xe7\xb5\x84\xc5\x09\x5c\x1f\x9c\x25\xef\xbb\x3e\x18\xc1\xf5\xc1\xa5\x35\x25\xc1\x56\xa9\x4b\x6a\x20\xa3\xba\x3e\x78\x86\xa5\x15\x05\x16\xd7\x07\x34\xed\xbf\xd5\x54\x61\xbd\x44\x5b\xe2\xaf\xb8\xf8\x81\x27\x6b\x9b\x53\x46\xf8\xa1\xa2\xef\xdc\x4e\x29\x98\xf2\xd4\x0f\x95\xa8\xdb\x86\x97\xa2\x6e\x07\x9f\x77\x76\xf6\xe1\x63\x85\x5e\xdc\x9e\x66\x9d\x46\x3f\xfd\xee\x8c\x9e\x5c\x1f\x74\xfb\x1f\x99\x8a\x2c\xa3\xf6\x8b\xeb\x03\x58\x5a\x75\x72\x7d\xc0\xeb\xa6\xf6\xb4\xc9\xc9\xf5\x01\xad\x44\xcd\xd6\x78\x33\x6d\x66\x93\xeb\x83\xe9\xc2\xa3\x1b\x9d\x8e\x2c\xd6\x23\x02\x4c\x3f\x74\x2b\x5c\x1f\x7c\x22\x9d\x9c\x9c\xc4\x2b\x0c\x56\xa6\x83\x7f\x6d\x26\xab\x77\xc6\xfd\xed\xf5\x1b\x93\xd0\xc2\xf9\xb7\x56\x68\x27\xd3\xfb\xb1\xc1\xae\x55\xf0\xf7\xc1\xef\x96\x63\xc0\xe0\xe7\x60\x0d\x83\x9f\x07\xb2\xe7\x3e\x99\x6b\xfd\x0c\x7b\xb2\xce\xeb\x03\x13\xa4\xa1\x2f\x1d\x4f\xd3\xea\x87\x72\x40\xec\x4d\xbe\x48\x38\x9e\x5c\x3c\xc6\x37\x42\x8c\x9a\xf5\x96\x45\xff\x6d\x0b\xfc\xf6\xed\x47\xa3\x0b\xb4\x8a\x2f\xab\xba\x59\xc3\x4d\x48\x91\x41\xe0\x0d\x44\xcb\xd2\xdc\x90\x23\x71\x76\xd2\x3d\xf2\x9a\xf7\xd5\xce\x48\xb1\x23\xf8\x7c\x9c\x86\x13\x5d\x9e\x63\xed\x39\xd3\x3d\xfe\x8a\x19\x7a\xa4\x0a\x21\xab\xb1\x1f\x36\x8f\x68\x1c\x7b\x0a\x3e\xf6\x8e\xaf\x75\x9a\x4a\x50\xea\x10\x05\xed\xb7\xfb\x16\xca\xb7\x50\x6e\x85\x90\x1a\x2e\x85\x02\xc7\x9f\xf4\x10\x45\x1d\x13\x09\x03\xb3\xda\x2f\x76\x32\x26\x7b\x1d\xbe\x12\xf7\xbf\xa1\x2e\xfd\x7c\x02\xdf\x7c\xfd\xef\xdf\xfe\x7d\xa0\x63\x08\x8c\x58\xfc\x82\x3a\x72\x41\x7b\x8a\x61\x7d\xe0\x2a\x69\xd8\x3d\xf1\x2c\xbb\x3e\x2d\xc9\xdd\x59\xd0\x9d\xe0\x07\x1c\x31\x5d\x36\x35\xc9\x85\x02\x7d\xe0\x1a\x72\x1c\x11\x48\xda\x38\x99\x6c\x03\xb8\x5a\xc0\xe9\xd7\x23\x98\x46\x11\xaf\x87\xef\x0f\xf7\x1f\xb3\x0d\x5b\x96\x0e\xbe\x1b\xad\xec\x47\x3a\x20\x55\x99\x19\x1b\x4e\x28\x31\x2d\x86\x4c\x98\xc8\x80\xf5\x4c\x88\xed\x7e\x77\x29\x6e\x17\x1f\xb8\x1f\x17\x58\x49\x2d\xab\xa6\x9a\xc0\xd3\x81\x2e\x21\xa4\xed\xa9\xcd\xd0\xb9\x03\x02\x82\x42\x57\x69\x45\x45\x90\x27\x07\x59\xa0\xf6\x72\x26\xf9\xd1\x40\x6b\xda\x5c\xee\x87\x81\xe9\x0d\x4a\x2b\x45\x7e\x9e\x42\x71\xa8\x67\xec\x97\x01\xe7\x58\xce\xc0\xf1\xf6\x26\xef\x07\xa8\x45\x8d\xc1\x1b\x42\x01\x03\x78\x5f\x07\xa8\xda\xbb\x86\xa8\x50\x68\xa9\xcb\xf4\xec\x25\x71\xc9\x21\xeb\xde\xcd\x31\xde\x9e\x63\xff\x2e\x28\xa7\x62\xa9\xe0\xba\x49\x40\xd9\x08\x2b\xb4\xa7\x32\xf6\xec\xf2\x22\x60\xf4\x55\x4e\x53\x74\x6f\x21\x93\x37\x06\x57\x0d\xc1\x8a\xb6\x18\xef\xcd\xd9\x63\xbf\x9c\xab\x9e\x3e\xfd\x7a\xab\xca\xdb\x7e\xc3\x57\x78\xc2\x7b\xb4\x7a\x02\xff\xf3\xe1\x6c\xfc\x0f\x31\xfe\xe3\xe3\x51\xfc\xcf\xd3\xf1\x77\xff\x3b\x9a\x7c\xfc\xaa\xf7\xeb\xc7\xe3\x9f\xfe\xff\xc0\x4c\x9b\xc1\xfc\x80\xf9\xc4\x24\x92\x70\x62\xd2\xe8\x28\xbd\x52\x79\x6b\x1b\x1c\xc1\x0b\xa1\x1c\x8e\xe0\x9d\xe6\xd4\xf0\x27\x85\xb6\xfd\x86\x9a\xb2\xf2\x01\xad\x3a\x74\x53\x1e\xbb\xf0\x96\xb6\xf7\x89\xdb\xdd\x56\xbe\xee\x27\xa4\x44\x35\xf4\x22\x4d\xef\xcd\x2d\x3f\xd2\x24\x47\x32\x59\x44\xb8\x59\x6e\xaa\x93\xde\x9b\x5c\x82\xd6\x2f\x85\x5e\x40\x17\xd6\x02\x28\x5d\xb5\x74\xe7\x29\x36\x89\xdc\x1a\xe7\xda\x47\xc5\x0e\x94\xbc\x41\x38\xeb\xea\x46\x0a\x96\x53\xcc\x05\x63\x71\x3b\x95\xde\x8a\x40\xfa\x26\x5c\xd9\x31\x4a\xb3\x46\xc1\x11\x95\xab\x19\x3f\x24\x5b\x8b\xae\xc7\x91\xbd\x9d\x4a\x25\xfd\x22\x94\xd2\xb9\xd1\x33\x25\x63\x09\x50\xd5\xc6\x7a\xa1\x7d\xe4\x19\xb1\xc4\x7b\x90\xdd\xd5\xb7\x74\x70\x54\x68\x77\x7a\xfa\xf5\x37\x57\xcd\xb4\x30\x95\x90\xfa\x45\xe5\x4f\x8e\x7f\x3a\xfa\xdc\x08\xc5\xb7\xbc\xaf\x44\x85\x2f\x2a\x7f\xfc\xe5\xd2\xe2\xe9\xb7\x7b\x78\xd1\xd1\x87\xe0\x2b\x1f\x8f\x3e\x8c\xe3\xff\xbe\x4a\x4d\xc7\x3f\x1d\x5d\x67\x5b\xbf\x1f\x7f\x45\x67\xe8\x79\xe0\xc7\x0f\xe3\xce\xfd\xb2\x8f\x5f\x1d\xff\xd4\xfb\x76\xbc\xc9\x19\xef\xc7\xdd\x53\x91\x31\x55\x01\xe3\x4a\xd4\xe3\x1b\x5c\x0c\x38\xe7\x20\x1c\x5d\x9f\x28\x48\xac\x12\xf5\xa6\xea\x3b\xbc\xad\x7d\x83\xfc\x9e\x33\xdf\x68\xe4\x7f\xf2\x06\x46\x8b\x01\x48\x36\xee\x5e\x60\x3d\x82\x75\xa2\xbc\x13\x98\xb6\x6d\x70\x7a\x0f\x6b\xd9\x0f\x3f\xea\x2d\xef\x17\x77\x2e\xd2\x9e\xf3\xd1\x33\x24\xff\x1e\xf8\xd3\x8f\xbd\xe7\x69\xe4\x60\xa5\xb5\xcc\x61\x5e\x3c\x0b\xd0\x97\x43\x0f\xc3\xb9\xb9\xa1\x3a\xaf\xd1\xf2\x73\x83\x70\xf1\x2c\xc6\xa3\x11\x48\x9d\xab\xa6\x20\xa4\xf0\xee\xdd\xc5\x33\xaa\xdf\x7f\x8e\xe1\xe6\x0e\xa1\x30\xfa\xd0\xc3\xeb\x57\xbf\xfd\x37\x93\x01\xdc\x63\x14\x12\x7a\xb8\x8f\x12\x4a\x86\xbf\x1a\x49\x09\x18\x7e\xc6\xf0\x4e\x8e\x57\xce\x45\xdd\xf2\x27\x1c\xee\xf8\x85\x95\xaa\x09\x40\xdc\x20\xb8\xc6\xc6\xdd\xd1\xc4\xe1\xc6\x97\x64\x0d\xf1\x3e\xb8\x44\xcf\x46\xae\xf8\xaf\x1f\x1e\x23\xb4\xf8\x1e\x5f\x1a\x7d\x45\x28\xf0\x2f\xf0\x0f\x32\xe4\xd7\x11\xb3\xf2\x1a\x8f\x70\x86\x2d\x7f\x84\xb0\xf3\x84\x10\x9d\xe9\x3c\x9c\xf4\x2f\xf7\xa4\xb5\xf3\x3e\x6a\xc5\xc0\x67\xf2\xcd\xe6\x9b\x1d\xfc\xf3\xda\x33\xae\xe5\xd2\x79\xe5\x6f\xc1\x98\x5b\x6d\x2f\x47\xe7\xc2\xc1\x14\x51\x33\x9d\x1b\xd8\x3f\xd4\xd1\xea\xb0\x23\x62\x9b\x7a\xec\xcd\xb8\xd8\xac\xbc\x1d\x92\xdb\x2d\xb5\x2d\x95\xeb\xd2\xd9\xce\x1e\x5c\xa8\xde\xcd\x17\x9b\x64\xe0\x02\x9d\xc9\x0f\x87\x12\x06\x79\xe8\xc1\x86\x0b\x93\x15\x56\x97\x2b\x8b\x48\x6a\xc4\x3a\x63\x7d\x4b\x54\x3d\x2e\x31\x1b\xde\xf0\x6d\xde\x32\xb3\xf7\xf0\x3d\x06\x35\x5f\xa1\xbd\x95\x8f\x4a\x7e\xbb\x1c\x33\x0f\xef\x4c\xce\xfe\x7a\xb7\x22\xe8\xf5\xe8\x45\x98\xfa\xcb\xcd\x8e\xeb\x9b\xad\xef\xdf\x59\x82\xdb\x5e\xf9\x3f\x64\x8e\x87\x26\xcb\x10\x4d\x26\xfc\x17\x17\xa9\xc9\x1b\xcb\x57\xee\xfd\xb6\x66\xda\x02\xe5\x6e\xf6\x58\x03\xc1\x3f\xff\xf5\xe4\xff\x02\x00\x00\xff\xff\x4a\xcc\x94\x67\x43\x3e\x00\x00") +var _operatorsCoreosCom_catalogsourcesYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7b\x6b\x73\xdc\xb6\x92\xf6\x77\xff\x8a\x2e\xbd\x6f\x95\xa4\xec\x0c\x65\x39\xa7\xb2\x27\xb3\x71\x52\x8a\x6c\x67\x55\x89\x6d\x95\x65\x7b\x6b\x8f\xe5\x5d\x63\xc8\x1e\x0e\x22\x10\xa0\x01\x50\xd2\xe4\xd4\xf9\xef\x5b\xdd\x00\x48\xce\x8d\x33\x72\x1c\x7d\xb1\x05\xe2\xd2\xf7\x7e\xba\x01\x89\x5a\xbe\x47\xeb\xa4\xd1\x13\x10\xb5\xc4\x7b\x8f\x9a\x7e\x73\xd9\xcd\xdf\x5d\x26\xcd\xc9\xed\xe9\xa3\x1b\xa9\x8b\x09\x9c\x37\xce\x9b\xea\x0d\x3a\xd3\xd8\x1c\x9f\xe1\x4c\x6a\xe9\xa5\xd1\x8f\x2a\xf4\xa2\x10\x5e\x4c\x1e\x01\x08\xad\x8d\x17\x34\xec\xe8\x57\x80\xdc\x68\x6f\x8d\x52\x68\xc7\x25\xea\xec\xa6\x99\xe2\xb4\x91\xaa\x40\xcb\x9b\xa7\xa3\x6f\x1f\x67\xdf\x67\x8f\x1f\x01\xe4\x16\x79\xf9\x5b\x59\xa1\xf3\xa2\xaa\x27\xa0\x1b\xa5\x1e\x01\x68\x51\xe1\x04\x72\xe1\x85\x32\x65\x20\xc2\x65\xa6\x46\x2b\xbc\xb1\x2e\xcb\x8d\x45\x43\xff\x54\x8f\x5c\x8d\x39\x9d\x5e\x5a\xd3\xd4\x13\xd8\x38\x27\xec\x97\x88\x14\x1e\x4b\x63\x65\xfa\x1d\x60\x0c\x46\x55\xfc\xff\xc8\x7c\x38\xf6\x8a\x8f\xe5\x71\x25\x9d\xff\x75\xfd\xdb\x6f\xd2\x79\xfe\x5e\xab\xc6\x0a\xb5\x4a\x30\x7f\x72\x73\x63\xfd\xab\xee\x78\x3a\x2e\x17\xde\xd9\x3c\x7c\x96\xba\x6c\x94\xb0\x2b\x6b\x1f\x01\xb8\xdc\xd4\x38\x01\x5e\x5a\x8b\x1c\x8b\x47\x00\x51\x84\x71\xab\x31\x88\xa2\x60\xb5\x08\x75\x69\xa5\xf6\x68\xcf\x8d\x6a\x2a\xdd\x1e\x45\x73\x0a\x74\xb9\x95\xb5\x67\xd1\xbf\x9d\x23\xd4\x16\xbd\x5f\xb0\x48\xc0\xcc\xc0\xcf\x31\x9d\xdd\xae\x02\xf8\xdd\x19\x7d\x29\xfc\x7c\x02\x19\x49\x38\x2b\xa4\xab\x95\x58\x10\x35\xbd\x59\x41\x4d\xcf\xc2\xb7\xde\xb8\x5f\x10\xe9\xce\x5b\xa9\xcb\x21\x52\x68\xde\xfe\x34\x04\xd1\xbc\x5d\xd4\xeb\x24\xac\x0c\xee\x7b\x7e\xdd\x4c\x95\x74\x73\xb4\xfb\x13\xd1\x2e\x59\xa3\xe1\x72\xc3\x97\x2d\x84\xf4\x36\x4d\x0e\x95\xad\x39\xc3\xda\x01\x67\xe5\x3a\x8f\x85\xf0\x69\x30\x4c\xba\x3d\x15\xaa\x9e\x8b\xd3\x38\xe8\xf2\x39\x56\xa2\xb3\x07\x53\xa3\x3e\xbb\xbc\x78\xff\xed\xd5\xca\x07\x58\x96\xce\x92\x9d\x83\x74\x20\xc0\x62\x6d\x9c\xf4\xc6\x2e\x48\x5a\xe7\x57\xef\xdd\x08\xce\xdf\x3c\x73\x23\x10\xba\x68\x1d\x0f\x6a\x91\xdf\x88\x12\x5d\xb6\x46\xab\x99\xfe\x8e\xb9\xef\x0d\x5b\xfc\xdc\x48\x8b\x45\x9f\x0a\x12\x4f\x92\xc9\xca\x30\xc9\xbf\x37\x54\x5b\x3a\xd3\xf7\x1c\x39\xfc\xf4\xa2\xdc\xd2\xf8\x0a\x87\x87\x24\x86\x30\x0f\x0a\x0a\x70\xe8\xd8\x04\xa2\x8f\x61\x11\x65\x17\x4c\x43\x3a\xe2\xdf\xa2\x43\x1d\x42\x1e\x0d\x0b\x1d\x79\xca\xe0\x0a\x2d\x2d\x24\x77\x6f\x54\x41\x91\xf0\x16\xad\x07\x8b\xb9\x29\xb5\xfc\xa3\xdd\xcd\x81\x37\x7c\x8c\x12\x1e\x9d\x07\xf6\x5a\x2d\x14\xdc\x0a\xd5\x60\x10\x65\x25\x16\x60\x91\xf6\x85\x46\xf7\x76\xe0\x29\x2e\x83\x97\xc6\x22\x48\x3d\x33\x13\x98\x7b\x5f\xbb\xc9\xc9\x49\x29\x7d\x8a\xe1\xb9\xa9\xaa\x46\x4b\xbf\x38\xe1\x70\x2c\xa7\x0d\x85\xc3\x93\x02\x6f\x51\x9d\x38\x59\x8e\x85\xcd\xe7\xd2\x63\xee\x1b\x8b\x27\xa2\x96\x63\x26\x56\x73\x1c\xcf\xaa\xe2\xff\xd9\x18\xf5\xdd\xe1\x8a\xf8\x36\x1a\x33\xa4\xb0\x39\x28\x6b\x0a\x9e\xc1\x8a\xc2\xf2\xc0\x4b\x27\x52\x1a\x22\xa9\xbc\x79\x7e\xf5\x16\x12\x01\x41\xec\x41\xc2\xdd\x54\xd7\x09\x9b\x04\x25\xf5\x0c\x6d\x98\x39\xb3\xa6\xe2\x5d\x50\x17\xb5\x91\xda\x07\x97\x56\x12\xb5\x07\xd7\x4c\x2b\xe9\x1d\xdb\x1c\x3a\x4f\x7a\xc8\xe0\x9c\x53\x18\x4c\x11\x9a\x9a\x3c\xa9\xc8\xe0\x42\xc3\xb9\xa8\x50\x9d\x0b\x87\x7f\xb9\xa8\x49\xa2\x6e\x4c\xe2\xdb\x5f\xd8\xfd\x0c\xbc\xbe\x60\xcd\xc7\x00\x52\x86\xdc\x6b\xf2\x36\xa7\x84\xe0\x81\x9b\x22\x30\x0c\xf8\x22\xfd\x88\xa2\xb0\xe8\x36\x7c\x58\x73\xc8\x30\x31\xd8\xc9\xdc\x38\xd2\x9f\xf0\xf0\xfa\xb7\x97\x90\x0b\x0d\x8d\x43\x72\x9e\xdc\x68\x4d\x06\xe1\x0d\x08\xca\x65\x63\xbc\x97\x8e\x0d\xc8\x62\x29\x9d\xb7\x8b\x0c\x5e\x18\x5b\x09\x3f\x81\x1f\xd2\xd0\x98\xb7\x33\x16\x64\xfd\xe3\xe4\x87\xda\x58\xff\x23\xbc\xd6\x6a\x41\x9b\x16\x70\x37\x47\x0d\x57\x2d\x6f\xf0\xb4\xf7\xcb\x2f\xb6\xce\x33\xb8\x28\xb5\xb1\x69\x26\x59\xd5\x45\x25\x4a\x84\x99\x44\xc5\x76\xed\xd0\x67\xab\x1a\x1c\xd4\x22\x04\xb8\x34\x93\xe5\x4b\x51\xef\x14\xcd\x79\x9a\x49\x67\xd1\xf1\xfd\xe4\xdd\x7d\xf4\x86\x4d\x99\x58\xa2\xff\x8a\xfc\x06\x44\x3c\xa5\x12\xf5\xd8\xb1\xdb\xf4\xc4\xb4\x9f\x04\xce\xd3\x06\x24\xbf\x6e\xf8\x22\x46\xae\xec\xa1\x6c\xf7\x39\x7b\xf0\xda\x0e\x86\xec\x14\xda\xcb\x4d\x59\x64\x8f\x33\x4a\x5b\xe7\x97\xa6\x08\x6c\xef\x3c\xe5\x97\xfe\x6c\xc0\xfb\xda\x38\x74\x50\xc8\xd9\x0c\x2d\xc5\x1d\x73\x8b\xd6\xca\x02\x1d\xcc\x8c\x65\x7d\xd5\xa6\x60\x9f\x6c\xf5\xb7\x94\x6a\x2f\x4d\xb1\xaf\x62\xe8\x68\x4e\x18\xc1\x18\xa3\x19\x6e\x65\x77\xa3\xb7\xc3\x0e\xe7\xa5\x1f\x6d\x0a\xbc\x42\x85\xb9\x37\x76\xf3\x8c\x15\x99\xbc\xea\x2d\x88\x51\x3f\xfd\x76\x37\x97\xf9\x1c\xaa\xc6\x71\xd4\xf5\xb6\xc1\x25\xb9\x78\x03\x33\xe9\xc1\x68\x10\x7c\x2c\xc5\xfa\xf5\x95\x95\xf0\xf9\x3c\xce\x38\x74\xa0\xc4\x14\x95\x5b\xdd\x67\x8a\x9c\x72\x8b\x46\x61\x41\x1b\x72\x2c\xe1\x3d\xb7\xb0\xb0\x43\x4a\x10\x42\x59\x8b\xb7\x87\x65\x06\xbb\xac\x2c\x08\x5e\x1a\x2b\xfd\xe2\x5c\x09\xe7\xb6\xd9\xf4\x9a\x74\x2f\x66\x6c\x3e\x72\x26\xb1\x18\x81\xd4\x85\xa4\x92\xc6\x25\xde\x0f\x5d\xbb\x6f\x46\x73\x29\xc1\xf5\xe6\x27\x09\xa5\x39\x70\x27\x95\x22\x61\x15\x38\x13\x8d\xe2\x20\xf9\x07\x5a\x03\x92\xad\xd3\xb2\x5d\x69\x93\x3e\x0f\x0b\x6f\x80\x57\x87\x79\xc3\xbc\x1a\xed\xf1\xde\x6f\xf7\xae\x35\x7e\x0f\xaf\x36\x2d\xe5\x94\x30\x45\x30\x9a\x03\xe1\x27\x85\xa5\xc8\x17\x9f\x88\xfc\x4f\x16\x89\x90\xdc\x63\xf1\x29\x63\x9c\xbf\xe4\x62\x87\x24\x21\xc3\x61\x1b\x25\xb1\x08\x52\x93\xce\xc9\xdb\xa4\x9f\xb3\x84\xac\x2c\xe7\x9e\x66\xc5\xca\x63\x99\x02\x76\xba\xf6\x23\xe5\x7e\x21\x35\xda\x0f\xdf\x7c\x5c\x9b\x19\x30\x1b\x27\x2b\xa5\xcc\x5d\xdf\x40\x6d\xa3\x41\x6a\x72\x78\x48\x1c\xc2\x59\x51\x49\x47\xf0\xf3\xe8\xf2\xea\xec\xb8\x57\x50\x13\xd1\x7d\xbe\xa0\x32\x05\x8e\x88\xdb\xc2\xa0\xd3\x87\x87\x9e\x9c\x9f\xb6\x77\x98\x0e\x15\x9e\x0e\x25\x13\x89\xce\x93\x0b\x4a\xa1\x91\x02\x92\x9f\xa1\x38\x33\xc5\x96\x94\xab\x33\xf8\x34\x15\x0e\x95\xd4\x18\x44\x59\x5b\x79\x2b\x15\x96\x74\xa4\x4e\xa5\xa8\xcb\xe0\xe7\x45\xb2\x88\x11\x6c\xd6\x4f\x08\x47\xc4\xe8\xb2\x3e\x2e\x42\xd4\x0b\x00\x50\x3a\x68\xf4\x8a\x75\x26\x43\x0c\x33\x48\xb7\x7d\xbe\x69\x85\x23\xa0\x06\x57\xbc\x6c\x41\x99\x5f\xe8\x05\x18\x56\x65\x58\xc4\x36\x6d\xd1\xd1\x36\x92\x62\xc9\xad\x50\xb2\x08\xb8\x1d\xad\x35\x36\x83\xff\xa2\xc0\xda\x50\xf9\x0d\x46\x15\x68\x53\xe9\x07\x92\x82\xa9\x1b\x25\x91\x31\x9c\x8f\x20\x31\x8a\x69\x83\x1e\x88\xee\xcd\x62\x88\x05\x01\x45\xa3\x28\x8d\x68\xa9\x3d\x70\x49\x60\x85\x48\x13\x53\xd3\x78\xd6\x42\x34\xee\x99\x69\x74\x01\xe4\x85\x1d\xfe\xbc\x69\xa6\x68\x35\x7a\x64\x08\x5a\x98\xdc\x11\xfa\xcc\xb1\xf6\xee\x24\x59\xdf\x49\x6d\x8a\x71\xfa\x65\x2c\x92\x51\x9d\x1c\x1e\x6e\x02\x29\x7b\xf9\x2f\x24\xbd\x4c\xa0\x63\x7f\xcb\x4c\xd4\x4d\xb5\x3d\x2c\x8e\x21\x48\x60\x60\xc2\x8e\x13\xbc\x51\x54\x6c\x76\x9d\x90\x4d\xc4\xf6\x4b\xfd\x6e\x3e\x08\x8b\xfd\x4a\x3f\x42\xda\x10\x12\x0e\x5d\x7f\xeb\xe1\x50\x27\xac\x15\xdb\x58\x90\x1e\xab\x81\xbc\xb0\xde\x86\xa0\x80\x40\x15\x4c\x47\x28\xa7\x4d\xef\x05\x65\x30\x2e\x19\xc3\x17\xf2\x6a\xbd\x00\x8a\x37\x11\x1d\x73\x2e\x8c\xd1\xdf\x5b\x59\x2b\x84\x1f\x6e\x70\x31\x0a\xf5\x24\xce\x66\x98\xfb\x1f\xa3\xa1\xd3\x1c\x9e\xcf\x56\x9f\x0a\xf6\x1f\xd2\xff\x7e\xdc\xc6\xf1\x5e\xb9\x71\x37\x8e\x08\x3f\x81\xa4\xa1\x19\x2b\x12\x7a\xce\x0b\x56\x12\x5d\x90\x40\xd8\x8b\xe4\xc3\x6c\x65\xf0\xbc\xaa\xfd\x02\x2a\x14\xda\x25\x94\xa0\xd4\xd2\x64\x17\x5d\xbf\x17\x74\x38\x32\xb7\xf5\x35\x5b\xc8\x2b\x73\x15\xb1\xc3\x08\x2e\x2d\xce\xd0\x76\x23\x1c\xfd\x5f\x99\xe7\xf7\x98\x37\x7e\x2b\x9a\xe8\xcb\x6d\xd0\xad\xe8\xe7\x06\x17\x0f\x10\xc8\xaf\xb8\x48\x75\x40\xe0\xec\x06\x17\xc1\x18\x78\xa8\xb3\x21\x51\xd7\x4a\x62\x28\x75\x87\x24\x73\x83\x0b\xd7\x06\xe6\x9b\xb0\x3b\xd2\xfc\x51\x67\x25\x09\xb2\x3d\xa7\x6a\xcb\xfd\x47\xb0\xd7\xdc\x54\x53\xa9\xc3\x61\x61\xeb\xa4\x0a\xde\x3d\x09\x54\x17\xfc\x2b\x1f\xf3\x35\xc4\x95\x88\x7a\x80\xcc\x5e\x27\x3e\xba\x3e\x02\x08\xa2\xe8\xd0\x81\x45\x15\x3c\x7e\x2e\xeb\xd4\x9e\x61\xd2\x33\x78\x4f\x79\xa3\x6b\x2a\xb3\x6d\x04\x09\x30\x57\xcf\x3f\x37\x42\x65\xf0\x2c\x44\x46\xe6\x3e\x0e\xc5\x49\x24\xc8\xcf\x8d\xbc\x15\x8a\x6a\x01\x6f\x28\x33\x15\xb9\xb0\x05\xa3\xd5\xd8\xf3\x71\x26\x68\x4f\xb4\x79\x39\x79\x7b\xa7\x23\xc7\xfd\x26\xa8\x85\xf5\x32\x6f\x94\xb0\xa9\x8f\xbd\xf8\x2a\x12\xed\x8c\xe6\x0a\x73\xa3\x8b\x41\x0f\xde\x1a\x5d\xe3\xda\xbe\x8c\x19\x6d\xa0\x95\xa6\xe0\x72\x47\x56\xb8\x6a\xa4\x47\xcb\x25\x81\x99\x25\xaf\x6e\x5d\x6c\x14\x72\xfb\x9d\x74\xb1\x25\xd4\x96\xdd\x32\x94\xe5\xc7\xbd\xf0\xd8\x7a\xc5\x32\x46\x91\x3e\xe0\x58\x86\x49\x29\xb9\x27\x93\x8d\xc2\xee\x1c\x6a\x66\x2c\x52\xa9\x7c\x54\x18\x5e\x83\xb7\x32\xf7\xc7\x19\xfc\x83\x80\x31\x29\x5e\x63\x29\xbc\xbc\x6d\xa1\x56\x02\xd1\xde\xa2\x20\x20\x29\x1c\x3c\x86\x23\x5e\x06\xb2\xaa\xb0\x90\xc2\xa3\x5a\x1c\xc3\x74\xc1\xc7\xb8\x85\xf3\x58\xed\xa3\x3a\xa9\x3d\x96\x4b\x3d\xe5\xf5\x9f\x59\x6c\x77\x48\xed\xbf\xfb\xdb\xc0\x4c\x26\xf6\x01\x9a\x7d\x9f\x30\x5a\x27\x99\x80\xaf\x56\x54\xd8\xe6\x20\xd3\x46\x91\x36\x6e\x48\x17\x7d\x61\xd4\x83\x7d\x1d\x28\x4a\x61\xa6\x55\xf0\xef\x64\x07\x02\x2c\xf2\xb5\x48\xb4\xdc\x3f\x61\xe3\x32\x1f\x6a\x33\x6c\xcd\x68\xdb\xbb\x60\xc0\x08\x85\x50\xf2\x77\x7f\xdb\xd2\x5e\x08\x3d\x6c\xd2\xf9\x7a\xa7\x0c\xf6\x48\x94\xdd\xe6\xdb\x94\xb5\xd3\xad\xdb\xe3\xbf\x68\x07\xc6\xc0\x3b\x5b\x1f\x6d\xdb\x81\x2a\x89\xa8\xef\x71\xea\x2e\x41\x5b\x16\x85\xdd\x28\xf8\x49\xed\xbc\xd0\x5e\x72\x64\x6b\xfb\x50\xa9\x2f\x45\xc5\xd7\x43\x5a\x1f\x6c\x6b\x31\xd0\x04\xe3\x8a\x9d\xc6\xb5\xf8\xf0\xe0\x16\x55\x2a\x8e\x77\xf7\x2c\x2f\x53\x19\x1d\xce\x14\xce\xc9\x92\x50\x26\xdc\x21\x97\x90\x31\x9d\x2c\xa3\x4d\x1a\x8d\x47\xc8\x3f\xd8\x9b\xaa\x36\x09\x48\x9f\xc0\x7f\x6e\xb4\x6b\x2a\x2c\x52\xcc\x28\xb0\x46\x5d\xa0\xce\x17\xdc\x21\x57\xb7\x68\x33\x78\xe7\x48\x53\xf0\x9f\xb2\xa4\xea\x27\x1e\xda\x87\x4a\x8c\x0a\x28\x55\x2f\x53\x20\x1d\x89\x6e\x86\xd6\x62\xc1\x3d\x2a\x20\x0c\x94\x76\xc0\x62\x65\xbe\x83\xa2\xe1\xbe\xfd\x2a\x11\x0d\xc9\x21\x14\xd9\x56\xe8\xb2\x6d\x4a\xb6\xed\x85\xe0\xf0\xc4\x52\x69\x42\x87\x9e\x6f\x91\x28\x76\x7a\xd3\xc5\x51\x19\xda\xaa\xed\x1e\x52\xfb\x6f\x9f\x84\x7d\x97\xeb\x41\x6e\xfb\xae\x30\xc3\x65\x7b\xa3\x83\xf0\xb1\xdf\xdb\x48\x61\xe6\x71\xd8\x6a\xd3\x3a\x0e\xc7\xa2\x5a\x25\xb9\x8b\xe9\x56\xe8\x1b\x2c\x40\xe1\xbd\xcc\x4d\x69\x45\x3d\x97\xb9\x50\x54\x38\x0b\x17\x5a\x4b\xd2\x3b\x2e\x8e\x07\x5a\xc0\xdb\xc2\x78\x7b\x9d\xf8\xe0\x56\xa8\xc3\xdc\xa2\xdf\xdd\x56\xbf\x0a\xf3\xba\xa4\xcc\x85\xa8\x99\xa5\x0d\x82\x8d\x44\x9b\x4b\xbd\x63\x91\xe7\xe4\x48\x6c\xba\x54\xce\x46\x00\xd2\x33\xe5\x0c\x2e\x38\xa5\x4e\xd1\xb1\x95\xdf\x20\xd6\xc1\xd2\x94\x74\x1e\x5c\xc5\xad\x07\x27\x75\x8e\x80\x22\x9f\x07\x71\x6a\xc4\xd4\x9c\xf3\x56\x62\x80\x41\x94\x6a\x17\xad\x6e\x50\xfb\xcd\xa0\x66\xb8\xee\x1a\xa8\xb9\x86\xc5\xd8\xc6\x94\xdd\x92\xec\x62\x51\xca\x89\xf1\xfe\xda\x75\x4f\x05\x1e\x70\x74\xb8\x73\xba\xf2\x04\x3e\xca\xdd\xb1\xe6\xdd\xd2\xf4\xf6\xce\x72\x6e\xee\xd2\xed\xd5\x9a\x93\x73\x2b\x23\xe9\xb6\x90\x2e\x27\x4f\xc7\x02\xce\x8d\x76\x8c\x4f\xc3\x25\x26\x5f\x42\xde\x0a\x15\x4c\x21\x6d\x5c\x1b\xa5\xd8\xe5\x9b\x54\x4e\x10\x8e\xd7\x80\xd5\x14\x8b\x02\x0b\x62\x2b\x90\xb2\x25\xcd\xfd\xc9\xb6\x73\xca\x0f\x97\x46\xa9\xe1\x2c\x36\x58\x97\xee\x53\x95\x26\x01\x0c\x61\xa3\xe5\xd4\x97\x24\x16\xdb\x51\x64\xd3\x05\x7a\xb4\x95\xd4\x11\x1e\x11\xd4\x6d\x05\x3b\x45\x7f\x87\xa8\x21\x9f\x63\x7e\xd3\xba\x52\xbc\x03\x5e\xd1\x5a\xbc\x80\x5e\x8e\x58\xdd\xf5\xba\x51\x8a\x0b\x0d\x87\x08\x92\x6a\x02\x8d\x77\x69\xcd\x8a\x8f\xf6\x82\xbd\xb8\x15\x52\x89\xa9\x42\xce\x9a\xed\x6f\xa3\xa5\xbb\xe8\x94\xcf\xeb\x46\x29\x02\xb1\xba\x80\xf2\xcd\xe5\x39\x78\x2b\x66\x33\x99\xd3\xa7\x42\xda\xd0\x2a\x5d\xbe\xc6\x5e\x3e\x70\x08\xae\x6d\xf5\x08\xe7\x85\x6f\xd6\x74\x34\xa0\xe0\x21\xc5\x52\x1d\x22\xb7\x36\x88\x96\x54\xf9\x66\xb9\x58\x21\x32\x30\x14\x5b\x4b\x5d\xe3\x0c\x5e\x19\xae\x11\x84\x87\x97\xe8\x28\xed\xb2\x80\xde\xa0\x70\x46\xf7\xa2\x2b\xa3\x5f\x2b\x4b\xa9\x85\x8a\x4c\xf5\x9b\x7c\x6d\xed\x21\xb8\xf3\x5a\xc9\xd2\x0a\xdf\x06\xc5\x8e\xee\x98\x5d\x62\x5e\x9c\x35\xbe\xb1\x98\xc1\x99\x5e\xb0\xbe\x67\x28\x68\x80\x76\xf6\xd6\x14\x4d\xce\xcd\x6b\xa5\xf8\x92\xb4\xdb\xe4\xab\x86\xd1\x25\xa9\x1d\x9c\xa7\x43\x12\xd0\x73\xe4\x00\x42\xc6\x8b\x18\xa3\x11\x84\xab\xa9\x8e\x4b\x36\xd9\x58\xbe\x10\x6b\x05\xcc\xc9\xe2\xec\xf2\x02\xd2\x33\xb3\x0c\xc6\xe3\x31\xbc\xa5\x61\xe7\x6d\x93\x73\x7e\x21\x17\xd2\x45\xcc\x14\xc1\xfa\x98\x49\xc1\xb0\x93\xd9\x80\xd8\xf9\x08\x10\xac\x16\x7e\x0e\x59\x10\x7c\xd6\x13\x05\xc0\x0b\xca\x35\xf7\xa2\xaa\xc9\xee\xaf\x75\x88\xde\x2f\x8c\xb9\x0a\x4a\x0a\x67\xfe\x13\x4e\x4e\x56\x6d\xc2\x4c\x09\xa2\xc6\x06\x22\x9b\xc6\xcc\x98\x43\xb7\xcc\x52\x46\x0b\x7f\xd5\xe6\x4e\x6f\x3a\x9d\xcf\x12\x16\x27\x70\x7d\x70\x96\xbc\xef\xfa\x60\x04\xd7\x07\x97\xd6\x94\x04\x5b\xa5\x2e\x69\x80\x8c\xea\xfa\xe0\x19\x96\x56\x14\x58\x5c\x1f\xd0\xb6\xff\x56\x53\x85\xf5\x12\x6d\x89\xbf\xe2\xe2\x29\x6f\xd6\x0e\xa7\x8c\xf0\xb4\xa2\xef\x3c\x4e\x29\x98\xf2\xd4\xd3\x4a\xd4\xed\xc0\x4b\x51\xb7\x8b\xcf\x3b\x3b\xfb\xf0\xb1\x42\x2f\x6e\x4f\xb3\x4e\xa3\x9f\x7e\x77\x46\x4f\xae\x0f\x3a\xfa\x47\xa6\x22\xcb\xa8\xfd\xe2\xfa\x00\x96\x4e\x9d\x5c\x1f\xf0\xb9\x69\x3c\x11\x39\xb9\x3e\xa0\x93\x68\xd8\x1a\x6f\xa6\xcd\x6c\x72\x7d\x30\x5d\x78\x74\xa3\xd3\x91\xc5\x7a\x44\x80\xe9\x69\x77\xc2\xf5\xc1\x27\xd2\xc9\xc9\x49\x6c\xe4\xb3\x32\x1d\xfc\xeb\x60\x20\xa5\x0f\xc4\xfd\xe1\xfa\x8d\x9b\xd0\xc2\xf9\xb7\x56\x68\x27\xd3\xab\xab\xad\x53\xab\xe0\xef\x5b\xbf\x5b\x8e\x01\x5b\x3f\x07\x6b\xd8\xfa\x79\x4b\xf6\xdc\x27\x73\xad\xf3\xb0\x67\xd7\x79\x7d\x61\x82\x34\xf4\xa5\xeb\xd3\xb4\xfa\xa1\x1c\x10\x67\x93\x2f\x12\x8e\x27\x17\x8f\xf1\x8d\x10\xa3\x66\xbd\x65\xd1\x7f\xdb\x02\xbf\x7d\x31\xd1\xe8\x02\xad\xe2\xeb\x9a\x6e\xd7\x7c\x4e\x80\xbf\xc8\x20\xf4\x0d\x44\xdb\xa5\xb9\x21\x47\xe2\xec\xa4\x7b\xcd\x6b\xa6\xab\xdd\x91\x62\x47\xf0\xf9\xb8\x0d\x27\xba\x3c\xc7\xda\x73\xa6\xfb\xf2\x8b\x59\xe8\x35\x55\x08\x59\x8d\xfd\x76\xf3\x88\xc6\xb1\xa7\xe0\xe3\xec\xf8\xc6\xa5\xa9\x04\xa5\x0e\x51\x10\xbd\xdd\xb7\x50\xbe\x85\x72\x2b\x84\xd4\x70\x33\x14\x7a\xfc\x49\x0f\x51\xd4\x31\x91\x30\x30\xab\xfd\x62\x67\xc7\x64\x2f\xe6\x2b\x71\xff\x1b\xea\xd2\xcf\x27\xf0\xed\x93\x7f\xff\xee\xef\x5b\x26\x86\xc0\x88\xc5\x2f\xa8\x63\x2f\x68\x4f\x31\xac\x2f\x5c\x6d\x1a\x76\x0f\x23\xcb\x6e\x4e\xdb\xe4\xee\x2c\xe8\x4e\x84\x7b\xc6\x90\x2e\x9b\x9a\xe4\x42\x81\x3e\xf4\x1a\x72\x1c\x11\x48\xda\xb8\x99\x6c\x03\xb8\x5a\xc0\xe9\x93\x11\x4c\xa3\x88\xd7\xc3\xf7\x87\xfb\x8f\xd9\x06\x92\xa5\x83\xef\x47\x2b\xf4\x48\x07\xa4\x2a\x33\x63\xc3\x09\x25\xa6\xc5\x90\x09\x53\x33\x60\x3d\x13\x62\x4b\xef\x2e\xc5\xed\xea\x07\xee\xd7\x0b\xac\xa4\x96\x55\x53\x4d\xe0\xf1\x96\x29\x21\xa4\xed\xa9\xcd\x30\xb9\x03\x02\x82\x42\x57\x69\x45\x45\x90\x27\x07\x59\xa0\xf6\x72\x26\xf9\xa6\xbd\x35\x6d\x2e\xf7\xc3\xc2\xf4\x72\xa3\x95\x22\x3f\xea\xa0\x38\xd4\x33\xf6\xcb\x80\x73\x2c\x67\xe0\x78\x7b\x93\xf7\x03\xd4\xa2\xc6\xe0\x0d\xa1\x80\x01\xbc\xaf\x03\x54\xed\x5d\x43\x54\x28\xb4\xd4\x65\x7a\x2c\x92\x7a\xc9\x21\xeb\xde\xcd\x91\x53\x4f\xdb\xa7\x0c\xfd\xfe\x9c\x8a\xa5\x82\xeb\x26\x01\x65\x23\xac\xd0\x9e\xca\xd8\xb3\xcb\x8b\x80\xd1\x57\x7b\x9a\xa2\x7b\x41\x98\xbc\x31\xb8\x6a\x08\x56\x44\x62\xbc\x50\x66\x8f\xfd\x7a\xae\x7a\xfa\xf8\xc9\xa0\xca\xdb\x79\xdb\xaf\xf0\x84\xf7\x68\xf5\x04\xfe\xe7\xc3\xd9\xf8\x1f\x62\xfc\xc7\xc7\xa3\xf8\x9f\xc7\xe3\xef\xff\x77\x34\xf9\xf8\x4d\xef\xd7\x8f\xc7\x3f\xfd\xff\x2d\x3b\x6d\x06\xf3\x5b\xcc\x27\x26\x91\x84\x13\x93\x46\x47\xe9\x6d\xc7\x5b\xdb\xe0\x08\x5e\x08\xe5\x70\x04\xef\x34\xa7\x86\x3f\x29\xb4\xe1\x1b\x6a\xca\xca\x07\x74\xea\x66\xf0\xd1\x4e\x61\x92\x86\xe7\x44\x72\x87\xca\xd7\xfd\x84\x94\x5a\x0d\xbd\x48\xd3\x7b\xa9\xca\x4f\x1b\xc9\x91\x4c\x16\x11\x6e\x96\x9b\xea\xa4\xf7\x92\x95\xa0\xf5\x4b\xa1\x17\xd0\x85\xb5\x00\x4a\x57\x2d\xdd\x79\x8a\x4d\x22\xb7\xc6\xb9\xf6\x29\xae\x03\x25\x6f\x10\xce\xba\xba\x91\x82\xe5\x14\x73\xc1\x58\xdc\x4e\xa5\xb7\x22\x34\x7d\x13\xae\xec\x3a\x4a\xb3\x46\xc1\x11\x95\xab\x19\x3f\xbf\x5a\x8b\xae\xc7\xb1\x7b\x3b\x95\x4a\xfa\x45\x28\xa5\x73\xa3\x67\x4a\xc6\x12\xa0\xaa\x8d\xf5\x42\xfb\xd8\x67\xc4\x12\xef\x41\x76\x57\xdf\xd2\xc1\x51\xa1\xdd\xe9\xe9\x93\x6f\xaf\x9a\x69\x61\x2a\x21\xf5\x8b\xca\x9f\x1c\xff\x74\xf4\xb9\x11\x8a\x6f\x79\x5f\x89\x0a\x5f\x54\xfe\xf8\xeb\xa5\xc5\xd3\xef\xf6\xf0\xa2\xa3\x0f\xc1\x57\x3e\x1e\x7d\x18\xc7\xff\x7d\x93\x86\x8e\x7f\x3a\xba\xce\x06\xbf\x1f\x7f\x43\x3c\xf4\x3c\xf0\xe3\x87\x71\xe7\x7e\xd9\xc7\x6f\x8e\x7f\xea\x7d\x3b\xde\xe4\x8c\xf7\xe3\xee\xbd\xc8\x98\xaa\x80\x71\x25\xea\xf1\x0d\x2e\xb6\x38\xe7\x56\x38\xba\xbe\x51\x90\x58\x25\xea\x4d\xd5\x77\x78\x91\xfa\x06\xf9\x15\x64\xbe\xd1\xc8\xff\xe4\x0d\x8c\x16\x5b\x20\xd9\xb8\x7b\xa8\xf4\x05\x5d\x27\xca\x3b\xa1\xd3\x36\x04\xa7\xf7\xb0\x96\xfd\xf0\xa3\x1e\x78\xf5\xb7\xf3\x90\x96\xcf\x2f\xde\x21\xf9\xf7\x96\x3f\x98\xd8\x7b\x9f\x46\x6e\xad\xb4\x96\x7b\x98\x17\xcf\x02\xf4\xe5\xd0\xc3\x70\x6e\x6e\xa8\xce\x6b\xb4\xfc\xdc\x20\x5c\x3c\x8b\xf1\x68\x04\x52\xe7\xaa\x29\x08\x29\xbc\x7b\x77\xf1\x8c\xea\xf7\x9f\x63\xb8\xb9\x43\x28\x8c\x3e\xf4\xf0\xfa\xd5\x6f\xff\xcd\xcd\x00\x9e\x31\x0a\x09\x3d\xdc\x47\x09\x25\xc3\xdf\x5a\xa4\x04\x0c\x3f\x23\xbf\x14\x0b\x27\xe7\xa2\x6e\xfb\x27\x1c\xee\xf8\x99\x95\xaa\x09\x40\xdc\x20\xb8\xc6\x46\xea\x68\xe3\x70\xe3\x4b\xb2\x86\x78\x1f\x5c\xa2\x67\x23\x57\xfc\x37\x03\x5f\x22\xb4\xf8\x8a\x5d\x1a\x7d\x45\x28\xf0\x2f\xf0\x0f\x32\xe4\xd7\x11\xb3\xf2\x19\x5f\xe0\x0c\x03\x4f\xf7\x77\x72\x08\xd1\x99\xce\x03\xa7\x7f\xb9\x27\xad\xf1\xfb\x45\x27\x86\x7e\x26\xdf\x6c\xbe\xd9\xd1\x7f\x5e\x7b\xc6\xb5\x5c\x3a\xaf\xfc\x05\x15\xf7\x56\xdb\xcb\xd1\xb9\x70\x30\x45\xd4\xdc\xce\x0d\xdd\x3f\xd4\xd1\xea\xb0\x6b\xc4\x36\xf5\xd8\x9b\x71\xb1\x59\x79\x3b\x24\xb7\x5b\x6a\x03\x95\xeb\x12\x6f\x67\x0f\x2e\x54\xef\xe6\x8b\x4d\x32\x70\xa1\x9d\xc9\x0f\x87\x12\x06\x79\x28\x63\xdb\x0b\x93\x95\xae\x2e\x57\x16\xb1\xa9\x11\xeb\x8c\x75\x92\xa8\x7a\x5c\xea\x6c\x78\xc3\xb7\x79\xcb\x9d\xbd\x87\xd3\x18\xd4\x7c\x85\xf6\x56\x7e\x51\xf2\xdb\xe5\x98\x79\x78\x67\x72\xf6\xd7\xbb\x15\x41\xaf\x2f\x3e\x84\x5b\x7f\xb9\xd9\x71\x7d\x33\xf8\x6a\x9c\x25\x38\xf4\x36\xfe\x21\x7b\x3c\x34\x59\x86\x68\x32\xe1\xbf\x53\x48\x43\xde\x58\xbe\x72\xef\x8f\x35\xd3\x16\x28\x77\xbb\xc7\x1a\x08\xfe\xf9\xaf\x47\xff\x17\x00\x00\xff\xff\xc0\x4e\x52\xf2\x79\x3d\x00\x00") func operatorsCoreosCom_catalogsourcesYamlBytes() ([]byte, error) { return bindataRead( @@ -105,7 +105,7 @@ func operatorsCoreosCom_catalogsourcesYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_clusterserviceversionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x77\xe3\xb6\xb5\x30\x8c\xff\xdf\x4f\x81\xe5\xe4\x3c\xb2\x1b\x49\x9e\x69\x7b\xfa\x6b\xe7\xd7\xf7\x64\xf9\xd8\x4e\xe2\x37\x33\x1e\x2d\xdb\x99\x3c\x5d\x49\x4e\x0a\x91\x5b\x12\x6a\x12\x60\x01\x50\xb6\xfa\xe4\xf9\xee\xef\xc2\x06\xc0\x8b\x2e\xb6\x44\x72\xc6\xb2\x07\xe8\x5a\xcd\x58\x24\x41\x70\x63\x63\xdf\x2f\x34\x63\x1f\x40\x2a\x26\xf8\x1b\x42\x33\x06\xf7\x1a\xb8\xf9\x4b\x0d\x6f\xff\xa2\x86\x4c\x1c\xcf\x5f\xff\xee\x96\xf1\xf8\x0d\x39\xcd\x95\x16\xe9\x15\x28\x91\xcb\x08\xce\x60\xc2\x38\xd3\x4c\xf0\xdf\xa5\xa0\x69\x4c\x35\x7d\xf3\x3b\x42\x28\xe7\x42\x53\xf3\xb3\x32\x7f\x12\x12\x09\xae\xa5\x48\x12\x90\x83\x29\xf0\xe1\x6d\x3e\x86\x71\xce\x92\x18\x24\x4e\xee\x5f\x3d\x7f\x35\xfc\xcb\xf0\xd5\xef\x08\x89\x24\xe0\xe3\x37\x2c\x05\xa5\x69\x9a\xbd\x21\x3c\x4f\x92\xdf\x11\xc2\x69\x0a\x6f\x48\x94\xe4\x4a\x83\x54\x20\xe7\x2c\x02\xf7\xbc\x1a\x8a\x0c\x24\xd5\x42\xaa\x61\x24\x24\x08\xf3\x9f\xf4\x77\x2a\x83\xc8\xac\x62\x2a\x45\x9e\xbd\x21\x6b\xef\xb1\xf3\xfa\xc5\x52\x0d\x53\x21\x99\xff\x9b\x90\x01\x11\x49\x8a\xff\x76\x40\xb0\xaf\xbf\xb6\xaf\x77\x90\xc3\xeb\x09\x53\xfa\xfb\xcd\xf7\xbc\x65\x4a\xe3\x7d\x59\x92\x4b\x9a\x6c\xfa\x10\xbc\x45\xcd\x84\xd4\x97\xe5\xb2\xcc\x32\x22\x35\xaf\xfe\xdb\xdd\xc8\xf8\x34\x4f\xa8\xdc\x30\xdb\xef\x08\x51\x91\xc8\xe0\x0d\xc1\xc9\x32\x1a\x41\xfc\x3b\x42\xfc\xbb\xec\xe4\x03\x42\xe3\x18\x37\x92\x26\x23\xc9\xb8\x06\x79\x2a\x92\x3c\xe5\xc5\xcb\xcd\x3d\x31\xa8\x48\xb2\x4c\xe3\x66\xdd\xcc\x00\xa1\x46\xc4\x84\xe8\x19\x90\xd3\xeb\x0f\xc5\xad\x84\xfc\x53\x09\x3e\xa2\x7a\xf6\x86\x0c\xcd\x06\x0c\x63\xa6\xb2\x84\x2e\xcc\x12\x2a\x77\xd9\xdd\x3c\xb3\xd7\x2a\xbf\xeb\x85\x59\xaf\xd2\x92\xf1\xe9\x43\xef\x77\x1f\xb1\xdd\x12\xe6\x95\x7d\xaa\xbe\xfe\xc3\xca\xef\xdb\xbe\xde\x7f\x3e\x35\x6f\x26\x7a\x46\x35\xd1\x33\xa6\x88\xe0\x40\x24\x64\x09\x8d\x40\x3d\xb0\xa0\x35\xb7\xd8\x15\x5d\xad\x5e\xd8\xb0\xa4\xea\x94\x9a\xea\x5c\x0d\xb3\x19\x55\xab\x20\x1e\x2d\xfd\xba\x66\x3a\x7b\xe3\xfc\x35\x4d\xb2\x19\x7d\xed\x7e\x54\xd1\x0c\x52\x5a\xe2\x80\xc8\x80\x9f\x8c\x2e\x3e\xfc\xf1\x7a\xe9\x02\xa9\x43\x67\x2d\xf6\x13\xa6\x0c\xa8\x90\x82\x10\x4f\x42\x70\xef\x16\x19\x90\x7f\xac\x7d\xe6\x3a\x83\xe8\x1f\xc3\x95\x95\x8b\xf1\x3f\x21\xd2\x95\x9f\x25\xfc\x2b\x67\x12\xe2\xea\x8a\x0c\x80\x3c\x59\x5a\xfa\xd9\xc0\xbf\xf2\x53\x26\x0d\x59\xd0\x95\x23\x6f\x47\x85\x2e\xd6\x7e\x5f\xfa\xda\x9e\x01\x89\xfb\xc6\xd8\x90\x44\x50\x88\x8f\x0e\xe3\x20\x76\x70\xb4\x78\xca\x94\x41\x0e\x09\x0a\xb8\x25\x92\x88\x42\xdc\x7d\xd3\x90\x18\x00\x80\x54\x86\x00\xe4\x49\x6c\x68\xe7\x1c\xa4\x26\x12\x22\x31\xe5\xec\xdf\xc5\x6c\x8a\x68\x81\xaf\x49\xa8\x06\xa5\x09\x9e\x5a\x4e\x13\x32\xa7\x49\x0e\x7d\x42\x79\x4c\x52\xba\x20\x12\xcc\xbc\x24\xe7\x95\x19\xf0\x16\x35\x24\xef\x84\x04\xc2\xf8\x44\xbc\x21\x33\xad\x33\xf5\xe6\xf8\x78\xca\xb4\xa7\xfa\x91\x48\xd3\x9c\x33\xbd\x38\x46\x02\xce\xc6\xb9\x21\x9c\xc7\x31\xcc\x21\x39\x56\x6c\x3a\xa0\x32\x9a\x31\x0d\x91\xce\x25\x1c\xd3\x8c\x0d\x70\xb1\x1c\x29\xff\x30\x8d\xbf\x90\x6e\x93\x55\x6f\x09\x7c\x6b\xd1\x99\x78\x02\xfb\x20\xac\x0d\x79\xb5\x98\x64\x1f\xb7\xdf\x52\x82\xd4\xfc\x64\xa0\x72\x75\x7e\x7d\x43\xfc\x02\xdc\xb9\x44\x08\x97\xb7\xaa\x12\xd8\x06\x50\x8c\x4f\x40\xda\x3b\x27\x52\xa4\x38\x0b\xf0\x38\x13\x8c\x6b\xfc\x23\x4a\x18\x70\x4d\x54\x3e\x4e\x99\x56\x88\x73\xa0\xb4\xd9\x87\x21\x39\x45\xa6\x47\xc6\x40\xf2\x2c\xa6\x1a\xe2\x21\xb9\xe0\xe4\x94\xa6\x90\x9c\x52\x05\x1f\x1d\xd4\x06\xa2\x6a\x60\xc0\xb7\x3d\xb0\xab\x3c\x7b\xf5\x81\x95\x33\x46\x88\xe7\xa5\x1b\x77\x67\xe3\x19\x26\x31\x44\x09\x95\x56\x28\x20\x1a\x92\x84\xbc\x7f\xfb\x8e\xcc\xc4\x9d\xc1\x62\xc6\x95\xa6\x49\x82\xa7\xc0\xf1\x67\x4b\x4e\x23\xca\x49\x4a\x39\x9d\x02\xa1\x59\xa6\xc8\x44\x48\x42\xc9\x94\xcd\x81\xfb\xd3\x35\xdc\x76\xf1\x9b\x88\x04\xb1\xc4\x7d\x2d\x83\xf2\x57\xdd\x02\x97\xae\x6c\x22\x1b\x66\xac\xc8\x40\x0f\x40\xed\xa4\xbc\x17\x31\x9b\x93\x9c\x2b\x2d\x73\xdc\xec\x98\xdc\xc2\xc2\x21\x79\x4a\x33\xa2\xb4\x30\x3f\xde\x31\x3d\x23\xb4\x8a\xe0\x54\x23\x16\x8f\x81\x28\xd0\x64\xbc\x20\x46\x8c\x43\x82\xa0\x85\x48\x90\x5a\xe0\xb3\x48\x18\x24\x68\xc9\x60\x0e\x84\xca\x31\xd3\x92\xca\x45\x81\x0d\xcb\x00\x7d\x04\xa8\xf8\xb1\x15\xe1\x61\x33\x48\xc8\x43\xb8\x48\x2c\xb9\x75\xb2\x4b\x5c\x08\x96\x5b\x40\x6f\x74\xe1\xf0\xad\x14\x47\x95\xc3\x37\x50\xc4\xe0\x95\x93\x0f\x0a\xb9\x16\xdf\xe4\x10\x2b\x26\x42\x16\x98\x61\xc0\x56\x45\xc2\x31\x18\x72\x22\x29\x37\x17\xd6\x22\x77\x03\x68\x3d\x84\x36\x66\x88\x3b\xbe\x0e\x47\xab\x73\x53\x29\x6b\x02\x53\x75\x30\x0d\xe9\x86\x99\x1f\x84\x5d\xf1\xb3\x59\xe0\x9c\xc5\x60\x80\xa8\x29\xb3\xa8\x63\x4e\x2b\x1d\x8b\x5c\x5b\xd8\xb9\x5b\x62\x32\x67\x94\xd0\xe9\x54\xc2\x14\x11\x78\xe3\x6b\x1f\x81\x89\x1d\x9b\x0f\x68\x39\x06\x56\x92\x7f\xf0\x0e\x43\x06\x1f\xbc\x81\xaf\x3b\xe6\xd5\x1b\x56\x85\xc5\xfa\x78\x6c\x0f\xed\xa0\x91\x81\x89\x07\xad\x90\x0f\xde\xbc\xcd\xde\xda\xf1\xc8\x0e\xdb\x51\xdf\xe7\xa5\x85\xb8\xab\x63\x73\x3e\x4a\xd2\x6c\xc8\x01\xde\x58\x12\xdf\x31\x90\x0c\xe4\x44\xc8\xd4\x1c\x14\x4e\x28\x89\xac\xfc\x56\x10\x1e\x24\x8d\x3c\x7a\x08\x9c\x64\xdb\xfd\xb7\x63\x1b\x2c\xb0\x63\x40\x32\xaa\x67\x8f\xdc\xb6\xdd\x56\xd9\x51\x05\xda\xa3\x37\x3f\x42\xcd\x56\xe6\x2e\x39\x4c\xe7\x73\x1b\x30\x74\x3e\x29\xf2\x9c\x6d\x66\xad\xa1\xda\x15\xbd\x7b\x07\x4a\x19\x96\x8d\x52\x9a\xa4\x77\x04\x78\x24\x0c\xb1\xf8\x7f\xaf\xdf\x5f\xda\x69\x87\xe4\x42\x13\x96\x66\x09\xa4\x46\x10\x23\xef\xa8\x54\x33\x9a\x80\x44\xee\xf4\x03\x4f\x6b\x7f\x3b\x4c\xcc\x15\xc4\x86\x16\xc5\x90\xd0\x85\x9d\x2c\x86\x48\xc4\x86\x46\x0b\x49\x32\x23\xe0\xa6\x59\xae\x81\x50\x7b\x15\xdf\xcb\xf8\x74\x1d\x91\x6e\x05\x1a\x62\x24\x91\x94\xea\x37\x64\xbc\xd0\x8f\xa1\x3e\x21\xf7\x83\x78\x5b\x1a\x50\x5d\xcc\xe3\x94\xc0\x8e\xad\xe8\x41\x75\xe2\x47\xbf\xd2\x08\xa1\x94\x71\x90\x23\x21\xf5\x36\x44\xcb\x28\x1f\x53\x90\x0f\xde\xe9\x41\xc6\xb8\xfe\xe3\x1f\x1e\xb8\x33\x86\x2c\x11\x0b\x83\x17\x8f\x9f\x95\x2d\xbf\x67\xeb\x73\xbd\xed\x7c\xdb\x9e\xe5\x2d\xe7\xb3\xc6\xa9\x2e\x66\x5a\xa7\x40\x35\x9a\x88\x77\xf5\x6d\x85\x12\xf8\x64\xcc\x6f\x74\xe1\xad\x0d\x57\x30\x01\x09\x3c\x72\xb4\xe9\xfb\x7c\x0c\x92\x83\x06\x55\x11\xa4\x17\x99\xa3\x34\x46\x16\x5c\x66\x77\x4f\xc3\xe5\x1e\x91\x67\xfc\x6d\x8f\x48\x35\xfe\xb6\xc7\x64\x1b\x3b\x76\x61\x9b\x8f\x23\x9d\x1d\x3b\xd1\xd8\xc7\x11\xb0\xc1\xa4\xf3\xf5\xe6\x9c\x16\xf3\x1a\x9d\x78\x0f\x24\xbc\xeb\xda\x32\x6a\xf2\xdd\x84\x41\x12\x13\x66\x84\x37\xb3\x58\x32\x4e\x44\x74\xeb\xec\x96\x57\x67\x44\x09\x2b\xee\x19\x09\xdf\x30\xda\x48\x70\x95\xa7\x40\xd8\x63\x18\x1c\x44\xba\x20\xd2\x05\x91\xee\xb9\x88\x74\xd6\x3f\xb0\x0f\x94\x6a\x69\x21\x1b\x69\x15\xde\x17\xa8\xd5\x43\x23\x50\x2b\x1c\x81\x5a\x3d\x32\x9e\x1d\xb5\xda\x4a\x4e\x7b\x74\xae\xc7\x0e\x72\x30\xa6\x06\x63\x6a\x30\xa6\xba\x11\x78\x99\x1b\x81\x97\x05\x5e\x16\x8c\xa9\x0f\x4d\x19\x8c\xa9\x3b\x4e\x14\x8c\xa9\xc1\x98\x1a\x8c\xa9\xc1\x98\xfa\xd8\xc7\x04\x91\x2e\x88\x74\x41\xa4\xdb\x76\x31\xc1\x98\x1a\x8c\xa9\x0f\x8d\x40\xad\x2a\x23\x50\xab\x07\xc6\xcb\xa6\x56\xed\x8d\xa9\x51\x02\x94\xaf\x57\xaa\x96\xe2\xbf\xf1\x3e\x14\x8d\xd8\x84\xb9\x3c\x08\xf7\x34\x19\xc3\x8c\xce\x99\xc8\x25\xb9\x9b\x01\xf7\x29\x3b\x64\x0a\x5a\x19\x2c\x00\x0d\xeb\x04\xf3\x47\x68\xcd\xc3\xf4\x65\x40\x80\xd3\x71\xb2\x76\xe2\xc7\x48\x89\x7b\xf2\x61\xe3\xf1\x58\x08\xf3\x75\xab\x10\x43\x55\xc7\x6b\x3a\xbb\xc4\x33\x1f\x6c\xca\xb1\x5b\x1f\xd4\x7c\x7a\x75\xd6\x55\x28\x33\xf9\x99\x93\x8b\x62\x56\x82\x96\x69\x4c\x94\x30\x3c\xc4\xfc\xfa\xfe\x8e\x43\x8c\x49\x6e\x7d\xc2\xb4\xb9\xc1\x1c\x7a\x16\x31\x9d\x2c\x8a\x17\x0f\x0f\x76\xdf\xc4\x3d\x0a\x89\x3e\xbd\x3a\xdb\xde\x7c\xef\x37\xe0\x53\x58\xea\x83\x1d\x3e\xd8\xe1\x8b\x11\xc4\xa0\x86\x93\x06\x31\xe8\x81\xf1\xb2\xc5\xa0\x7d\xb7\x5b\x07\x6b\x33\x09\xd6\xe6\x87\x6f\x0b\xd6\xe6\x60\x6d\x0e\xf6\x9b\x0d\x23\x08\x2e\x38\x82\xe0\xf2\xc8\x78\x76\x82\x4b\xb0\x36\x07\x6a\x15\xa8\x55\xa0\x56\xcf\x83\x5a\x3d\xc7\xd0\xdd\x60\xf4\x0b\x46\xbf\x60\xf4\x0b\xdc\x28\x70\xa3\x47\xc6\xb3\xe3\x46\xc1\xe8\xb7\xeb\x44\xc1\xe8\xb7\x76\x04\xa3\xdf\x23\x23\x18\xfd\x82\xd1\x6f\xc3\x08\x82\x4b\xc3\x49\x83\xe0\xf2\xc0\x78\xd9\x82\x4b\x30\xfa\x05\x6a\x15\xa8\x55\xa0\x56\xcf\x83\x5a\xb5\x37\xfa\x3d\x72\x92\x1e\x7e\xf6\xe1\x93\xf2\xe0\xb3\x2c\x7a\xe8\x85\x9b\x20\xfa\x00\x04\x1f\x25\x5c\x8f\x91\xab\x01\x19\x53\x05\x7f\xfe\xd3\x4a\xdd\xf2\xea\x2d\x29\xc4\x8c\x9a\x57\xad\xbd\xe3\x71\x12\x56\xbe\x62\xf3\x9e\x6d\xb1\xf7\xc5\x32\x1a\xce\xe2\x0a\x2b\x3f\x1a\x14\x6b\xb6\x36\xbe\xb0\x37\x5f\x6b\x49\x35\x4c\x17\x95\x42\xde\x68\x93\x2d\x39\x0f\xdf\x50\x80\xbe\x50\x1a\xef\x66\x20\x01\x1f\xf2\xa5\xa7\x95\x9f\x94\xa9\x22\x7a\x39\x6e\x50\xdc\xf7\xb1\x70\x64\xff\x9e\x35\x97\x1f\xdb\xb4\x75\xd5\xb7\xd7\x02\xcb\x03\xe8\xcc\x5a\xaf\xcf\x8a\x14\xe0\x65\x88\x65\x54\x1a\x0a\xe9\xad\xdc\xc8\xb4\x2b\x77\x2f\xc1\x7b\x13\x51\xdc\x82\x53\x3f\xce\xa1\x07\x95\x4c\xe5\x4d\x96\xf5\x6d\x18\xb3\xeb\x81\x31\x02\x99\x32\xa5\x36\x05\x5c\xd7\x97\xfe\x18\xd9\xdc\x82\x5c\x6e\x80\xbf\xff\xa2\xca\x72\x0a\xf1\x09\x77\x40\x8e\x69\x44\x64\x9e\x18\x61\x8a\xc7\xc4\x95\xbf\x26\x34\x8a\x44\xce\x35\xe1\x00\xb1\xb5\x6c\xac\xc3\xd5\x2d\x88\xed\x16\xf2\xd3\xb6\xd2\xd3\xc0\xae\xf3\xd1\xbb\xdc\x37\x9c\xd8\x4f\x58\x5b\x50\xbd\x3a\xb6\x97\xb6\xf0\xf5\x8f\x73\xad\x5d\x58\xe1\xd6\x8c\xb0\xb6\xbf\x23\x91\xb0\x68\x71\x95\x27\x40\x66\x22\x89\x15\x96\xf5\x37\xdc\xbd\x70\x38\x54\x45\xe4\x0c\xef\xc6\xd5\xf7\xc9\x38\xd7\x24\x16\xa0\x08\x17\xda\x17\x06\xa8\x3d\x6e\x5d\x4c\x77\x33\xdb\xda\xc1\x3c\x44\x68\x96\x25\x98\x4a\x21\x8c\xd0\x72\x37\x63\xd1\xcc\xf6\xab\xc9\x68\x04\xeb\x6e\xdb\x5e\x7a\xd9\x4a\xbc\x26\x3b\x89\xd8\xc4\xdb\xac\xc6\x8f\xa1\x0a\xd9\x51\xd6\x26\xb6\x44\xfc\xb7\x52\xe4\xd9\x96\xb7\xaf\x5a\x16\xed\xd3\x86\xca\xeb\xa5\x06\x36\xfe\xa2\x73\x19\xd9\xbd\xb1\xb7\x15\x26\xd1\x21\x21\x17\x13\x92\xe6\x89\x66\x59\x82\x8f\xd8\x6a\x03\x8a\x50\x09\x25\xdf\xe8\x13\xca\x17\xde\x03\xe5\xda\x44\x40\x4c\xe8\xd4\xcc\xa8\xb1\x3f\x8c\x2f\x49\xcf\xf3\x14\xcc\x69\x8e\xcb\x97\xa0\x3a\xc5\x17\xe5\xec\xe4\x8e\x25\x89\x91\x67\x69\x92\x88\xbb\xf5\x6c\x69\xdd\xd8\x4d\x28\x24\xbb\x09\x86\x64\x77\x11\x98\x10\x2e\xb8\x37\xed\xfe\x70\xf5\xb6\xd9\x26\x5e\xd6\xe7\x70\xbd\x40\x40\x1b\x90\x66\x54\x6a\x46\x13\x92\xcb\x44\xd9\x7d\xa4\x46\x09\x90\xbe\x99\xca\x8c\xa2\x67\x30\x02\x65\xbb\x76\x90\xdf\xdb\x9d\x73\x80\xb5\xe7\x53\xf0\x64\x41\xa8\xdd\xf9\x49\x9e\x24\x7d\x32\x61\x9c\x1a\xb2\x0b\x99\xcf\x84\x31\xfa\x13\xb9\x66\x3c\x02\xf3\x4d\x83\x42\xb0\xc0\x15\x99\x19\xcd\xf9\x2e\x0e\x69\xdc\x77\x6d\x45\xac\xb6\xac\xdc\x2b\xcc\x81\x8d\xe8\x38\x01\xec\x6b\xe1\x44\x96\x2b\x91\xa0\x79\xdb\x19\xbe\x63\xdb\x8b\x84\x56\x2f\xff\x37\xe3\xa8\xa4\x90\x2b\x64\x1c\x46\xd9\x01\xa6\x67\x46\xf7\xc9\xb2\x64\x61\x08\x85\xc1\x9d\x12\xa1\x0e\x55\x1e\xcd\xcc\x27\x1d\x64\x22\x56\x07\x86\x8c\x1c\x28\x88\x24\x68\x75\x70\x64\xfe\x5a\xfe\x06\xfc\xbe\xea\x73\xc7\x34\x63\x07\x47\x7d\x82\x00\xc2\x46\x27\x42\xcf\x9e\x2f\x1e\xfa\x6f\xad\xf5\xd7\x7a\x6c\xd4\xb5\xd6\xea\x0c\xae\x6b\x87\xc8\x6c\x13\x0c\x43\xa3\x35\x60\x9e\x94\x41\x4a\x44\x03\xdf\x1e\x6a\x95\x58\x13\x72\xc2\x09\xa4\x99\x5e\x20\x16\xa7\x40\xb9\xbb\x1b\xe6\x20\x17\x7a\x66\xb4\x55\xa6\x9e\xff\xe1\xdf\xd2\xb1\x54\x8e\xb5\x00\x77\x07\xde\x03\xb7\x44\x72\xdb\x59\x69\x19\xb8\xbd\xdf\xf7\xaa\x52\xaf\x11\x9f\x4a\x6a\xfe\x6c\x41\x89\xec\xb5\x11\x18\x3f\x98\x27\xeb\x20\xb4\x3f\x59\x6a\x59\xd0\x8f\xb7\x6f\x6d\x17\x25\x07\xab\xef\x19\x8f\x55\x51\xc9\x28\xb6\x64\xd0\xc1\x7b\x2d\x90\x71\x85\xcf\x11\xc0\xab\xe2\xeb\xb6\x22\xe7\x23\xd3\x57\xf4\x9b\x7d\x50\x49\xb0\x2b\x53\x4d\xca\x31\x74\xaa\x6f\x5d\x4e\x46\x17\x49\xe8\x18\x12\xdb\x72\xc9\x5c\x2d\x97\x4f\x4e\xde\xbe\x2b\xba\x93\x49\xa0\x8f\xd8\xb3\x3e\x82\x22\xb2\x85\xe3\x74\xa5\xc7\xdb\xea\xd8\x5e\xf6\x44\x50\xec\x66\x0c\x26\xd7\xa0\xed\x31\x4b\x69\x66\x4e\x99\x9d\x63\xad\x2d\xf3\x2d\x42\xfa\xf1\xc3\xb2\x93\xcc\xbe\x7d\x4f\xa6\x75\x2f\xd9\xea\xa8\x6c\xe7\xf1\xdd\xe5\xec\x3d\x60\xe1\x28\x47\x0d\xcc\x4b\x08\xed\xe4\x7a\x27\x89\x47\x45\x7f\x3d\x8b\xc1\xca\x26\x46\xdb\x34\x74\xe9\x7f\x2f\xa7\xe8\x78\x0b\x76\x51\x9a\x8c\xde\x9c\x40\xa4\xc5\xc3\x65\xdf\xfc\xcd\x1a\xd2\x2c\x79\xec\xe4\x91\x9d\x15\xac\x94\xf1\x2b\xa0\xf1\xe2\x1a\x22\xc1\xe3\x2d\x09\x6c\x6d\x3f\xde\x31\xce\xd2\x3c\x25\x3c\x4f\xc7\x80\x20\x56\x76\x2e\x24\x24\x56\x79\xa5\x84\xc3\x5d\xb2\x70\xc4\x23\x26\x99\x88\x3d\x3d\x19\x1b\x65\x8b\xc6\x0b\xec\x6f\x86\x05\x52\xf9\xc2\x4c\xc2\x74\xc9\x7d\x24\x89\x24\x55\x46\x2c\xea\xe3\xa4\x4c\x1b\x8e\x35\x06\xf4\x2d\xb1\x18\xcc\x1e\xd3\x39\x65\x89\x11\xad\x87\xe4\x0c\x26\x34\x4f\xb0\x4d\x1f\x79\x45\x0e\xcd\xcb\xbc\x3e\xb5\xee\x01\x23\xee\x2a\x61\x34\x71\xe5\x72\xdc\x71\x41\x47\x3b\x58\xcb\xb7\xa9\xdf\xe7\xc7\xb6\x75\xfc\xfc\xc8\x68\xae\xb6\x55\xc3\x6b\x1b\x73\xc1\x63\x73\x1e\xaa\x92\x68\x85\xa4\x33\xe5\x66\xde\x8e\x65\x3f\x5c\xfb\x60\xcd\xaa\xa5\x98\x4a\x50\xea\x0c\x68\x9c\x30\x0e\xcd\xf1\xeb\x66\x06\x24\xa5\xf7\x88\x63\x9a\xa5\x60\x24\x91\x2a\x86\xd1\xea\x57\x69\x41\x52\x7a\x0b\xc5\xeb\xc9\x18\x26\xd8\x86\x11\x3f\xb8\xb2\xfb\x16\x7f\x26\x94\x25\x10\x0f\xf1\x1d\x95\x59\xca\xee\xc5\x16\x71\xcc\xdf\x8c\xe7\x60\x9e\xca\xa4\x40\x65\xd2\x3e\x5a\xe5\xf1\xc8\x43\xa9\xb9\xd9\xd2\x61\xdf\xb1\x6f\xb4\x04\x8a\xf3\xfb\xc8\x1a\xf9\x24\x50\x85\xb7\x59\xdc\x54\xb9\x9c\x18\xd5\xd1\x6b\x9c\x95\x05\xb9\x56\xaf\xe4\x52\x68\xd7\xf8\xaf\xf8\x40\x7c\xda\x35\xa2\x04\xa5\x59\x8a\x07\x2c\xce\xa5\x6f\x8b\x89\x30\xa3\xeb\xb7\xbe\x76\x54\xfe\xfc\xea\xd5\x96\xf2\xdb\xc7\x47\x7a\x09\xa8\x29\x37\xc1\x97\xcb\x82\x0e\x79\xf2\x6f\x54\x60\xb3\xc7\xcc\x89\xc1\xd8\xdf\x13\x24\xfa\x09\x99\xd2\x8c\x4f\x73\xa6\x66\x64\x0c\xfa\x0e\x80\x13\xb8\xb7\x15\x2e\xc8\xbf\x41\x0a\xdc\x54\x03\xde\xd2\x45\x50\x03\xda\xeb\xfd\x81\xd8\x9c\x29\x26\xf8\x77\x4c\x69\x21\x17\x6f\x59\xca\x1e\x29\x3d\xea\xc7\x6a\x97\xe3\x02\x82\x22\x89\xb1\x37\x31\x8b\xe8\x35\xd8\x0f\x96\x80\x16\x4c\x2d\xac\x7a\x4a\xcc\x39\x19\xd3\xe8\xf6\xa3\x01\xf8\xd5\xbe\x40\xd8\xb3\xeb\x06\x50\x45\x79\xaf\x98\x00\xc9\x96\x45\xca\xf3\x7b\x0b\x9f\x1a\x94\xef\x66\x42\x01\xde\x60\x8d\x8c\xf8\x98\x77\x0a\x30\x55\x10\x0c\x73\xba\x05\x07\x45\xe8\x64\x52\xbf\xa3\x3c\xec\x28\x79\xa6\xb9\xd2\x24\xa5\x3a\x9a\x59\x53\x96\x88\x0b\x71\xa2\xa7\x9c\xd8\xbf\x0b\x94\xb7\x36\x22\xef\x6e\xee\x25\x76\x9d\xe7\xf7\x46\xb7\x7c\xd4\x9b\x53\x1f\x35\x90\x2f\x4f\x53\xd7\x80\x93\xfa\x86\x38\xb9\x2d\xb5\x2d\x82\x6f\xd0\x00\x5c\xfe\x82\xbb\x70\x72\x79\xb6\xbd\x29\xa6\x89\x82\xbb\xb3\x8a\xbb\x6c\xea\x7e\xe0\xa3\xbc\xc9\xd4\x5d\xa9\xdb\xbb\x6d\x6b\xe8\x3e\xa1\xe4\x16\x16\xb6\x8b\xf4\x4a\x5b\x5e\x09\x89\x93\x24\x00\xbb\xd3\x9a\x9b\x5c\x4b\xe9\x1d\xd6\xbb\x33\xf6\xd8\xb1\x9b\x2b\xc2\x8f\x81\x59\xe8\x8e\x4f\xf8\x8f\xde\xe1\xb1\xdd\x11\xdc\x8e\x5b\x58\xec\xf6\xc0\xd2\x76\x9b\x5d\x70\xba\x8f\xdd\x77\xf3\x43\x21\xe8\x15\x5b\xbd\x9b\x8f\xa8\x3a\x76\x36\x51\xf9\xe1\x81\xd8\xea\xf3\x0a\xf4\xab\x5a\x99\xcc\x37\xf6\x94\x45\x46\x73\xa6\x67\x2c\x43\x46\xe4\x9d\x01\xbe\xc9\xf9\x07\x9a\xb0\xb8\x98\xc2\x9e\xdf\x0b\xde\x37\xe2\x93\xf9\x0f\x12\x5d\x2b\xae\x9d\x09\x50\x97\x42\xe3\x2f\x9f\x0c\x40\x76\x99\xad\xc0\x63\xa7\x70\x56\x68\xa4\x32\xa8\x78\x55\xfa\xa3\xab\xa1\xaf\xec\x55\x80\x92\x29\x72\xc1\x89\x90\x1e\x0e\xd8\xb1\xde\x4e\x64\xa7\x40\x3e\x31\xb6\x0e\x0e\xb4\x4f\xaf\x9d\xc3\x81\x4f\xc8\x1a\xf4\x1e\x98\xce\x4d\x85\xf2\x81\xbd\x62\x3b\xe2\x27\x28\xed\x3a\x51\x95\x7a\x27\x37\x8b\x48\x0a\x72\x8a\x1e\x97\x68\x6b\x8f\x43\x7d\x53\x76\xa3\xbb\x76\xec\x4c\x7d\xab\x2f\xdc\x09\x0b\x90\x35\x59\x13\x50\x1b\xe6\x66\x67\xa8\x99\x9c\xfe\x8f\xa1\xe0\xb8\x07\xff\x97\x64\x94\x49\x35\x24\x27\x44\x31\x3e\x4d\xa0\x76\xcd\x69\x18\xd5\x69\xcc\x0c\x4c\x11\x43\x6a\xe7\x34\x71\xba\x14\xe5\x04\xac\xcd\xca\xcc\xbe\xcc\x52\xfb\x4e\x52\x31\x94\xa7\x70\x74\x1d\xdc\xc2\xe2\xa0\xbf\x82\x34\x07\x17\xfc\xc0\xf2\x96\x15\x34\x29\x18\x11\xfa\xc8\x0e\xf0\xda\x41\x97\x5c\x78\x47\x86\xd3\xd4\x8e\x56\x7f\xe9\xd6\x18\xe1\x63\x3b\x1a\x0a\xeb\x35\x2d\xd1\x45\x34\x69\x41\x72\x05\x56\x5a\xc7\x53\x46\xc0\xcb\x99\x28\x55\xa2\x62\xca\xe1\x0e\xa5\xc7\xbd\x11\xfc\x8c\x26\xc1\xf8\xf4\x87\x2c\xa6\x7a\xab\xa0\x52\x3b\x6a\x10\xe9\x5d\xd9\x49\x48\x8e\xb3\x18\xdc\x9a\xb0\x29\xc9\xa8\xa4\xa9\x1a\x92\x91\xab\x6e\x88\x98\xc6\x26\x55\x5b\xa2\x83\xdd\xcd\x22\x03\xf2\xff\x90\xab\xea\x5a\x86\x64\x30\x18\x90\x9b\xf7\x67\xef\xdf\x10\xfb\x8b\x95\xb2\xb5\x20\x13\x81\x4a\x90\xc8\xa5\x79\xd5\x1c\x38\x2a\xfe\x46\xbe\x17\x1c\xde\x4f\xcc\x09\xa1\x1a\xe6\x20\xc9\x9d\xd9\xaa\x88\xc5\x50\x58\xaf\x86\xbd\x8f\x8b\xc7\xcd\x24\x93\x94\xde\x5f\xe7\x72\xba\xc3\x06\x90\x95\x4d\xa8\x9a\x6c\x4a\x65\x12\x51\xaf\x9a\x9d\xab\xa2\x19\xc4\x79\x02\x31\xa1\x63\x31\x87\x9a\xc9\xb6\xfe\x18\xb2\xf4\x1c\xfc\x83\x86\xe7\x8d\x95\x48\x72\x5d\x28\xab\x87\x70\xff\x86\xfc\x27\xba\xb6\x29\xc9\x40\x46\xc0\x35\x9d\xc2\xb2\x19\xc0\xde\xf7\xfa\xd5\x7f\x1c\x39\x7e\x64\x66\x74\xd6\x93\x57\x06\x23\xde\xd1\xfb\x1f\x78\x69\x1a\x64\x8a\xbc\x1a\x92\x93\xa5\x97\xe1\x73\x49\x94\x27\x68\x6b\x41\x77\x7d\xe5\x95\xe3\x05\x91\x22\x47\x87\x3d\xc9\xb3\xba\x36\xfb\x87\xff\xfc\x0f\xa3\xf4\xd1\x34\x4b\xe0\x8d\x2f\x8a\x6a\xd5\x66\x23\xc3\x68\x41\xfe\xf8\xea\x3f\x2c\xf5\x34\xe7\xb3\xd4\x0a\x4b\x98\x51\x03\xb0\x3c\x23\x2c\xb5\xa1\x98\x90\x2c\xca\xea\xaa\xb2\x8e\xfe\x4a\x53\xa9\x55\x9f\xa0\x57\xbf\x10\x0e\xb5\xd0\x34\x59\xd2\xf2\x51\x0b\x87\x3b\x0b\xa4\x58\x20\x4c\x00\x0d\x55\xe4\xf5\x1f\x5f\xfd\xc7\xaa\x39\xe5\x3d\x8f\x00\x9f\xc4\x27\x30\xcc\x62\x6c\x94\xfb\x5b\x96\x24\x10\xf7\x1f\x5d\xfe\x24\x97\x7a\x06\xb2\x4f\x80\x2b\x6f\xac\x32\xeb\x5b\x5a\x1b\xce\x2e\x73\xce\x51\x46\xb0\xd6\x61\xb4\x68\x55\x2c\x5c\xee\x63\x0d\x23\xd4\x24\x15\x4a\xaf\x5f\xf2\xf6\xc7\xcd\x0c\xca\x17\xef\x27\xbb\x8a\x03\x83\x06\x66\x88\xd5\xa7\x1b\x88\x94\xf7\x83\xdb\x22\x53\x72\xc0\xb8\x1e\x08\x39\xb0\xd3\xbc\x21\x5a\xe6\x8f\x7b\x0d\xca\x91\xd6\x4e\xc0\x27\x20\x03\x79\xe5\xbc\xad\xec\xea\x47\x39\xf9\xcd\xcf\x73\x2c\xee\xf8\x66\xca\x81\x84\xd3\xd1\x8c\x86\xa7\xbe\x6e\x71\x5b\x3a\x36\xe6\xed\xe6\xee\xff\xdf\x2a\x76\xef\x40\x0e\xdc\xd9\x2d\x4e\xbb\x91\xab\xd0\xe3\xd1\xdf\xe2\xed\xc5\xb1\xb5\x9c\xcf\xda\x9c\xcc\x0d\xf6\x35\x6b\x28\xd7\xca\x09\x5f\x43\x81\xec\x3a\x4a\x87\x8c\xc6\x88\x02\x73\xce\xd5\xc6\x83\x9e\x00\x55\x7a\x1d\x28\xc2\x41\x7f\x7c\x3c\x1c\xc0\xbf\x3c\xea\x42\xa7\x91\x90\x10\xe4\xa5\x8d\xf1\xd4\x22\xca\xc1\x15\x58\x0f\x9f\x0d\x38\xab\x09\x51\x07\xc5\x91\x30\xfb\x57\x97\xaf\x3e\x56\xd8\x8c\x37\x72\x36\x11\xad\xdd\xa3\x95\xc0\x5e\x67\x3a\x75\xc4\xab\xf0\x28\x5a\x97\xe6\xde\x48\xd1\x29\x68\xfa\x70\x92\xc7\xf2\xa8\x13\xed\x6b\x4d\x79\x4c\x65\xec\x56\xd9\xeb\xa9\x62\xca\x21\x79\x87\xbe\x34\x3e\x11\x6f\xc8\x4c\xeb\x4c\xbd\x39\x3e\x9e\x32\x3d\xbc\xfd\x8b\x1a\x32\x71\x1c\x89\x34\xcd\x39\xd3\x8b\x63\x74\xa0\xb1\x71\xae\x85\x54\xc7\x31\xcc\x21\x39\x56\x6c\x3a\xa0\x32\x9a\x31\x0d\x91\xce\x25\x1c\xd3\x8c\x0d\x4a\x99\x59\x0d\xd3\xf8\x0b\xff\xa2\x8f\x2c\x18\xd7\xce\x10\x5a\x97\xe4\x1c\x06\x39\xbf\xe5\xe2\x8e\x0f\x50\x93\x55\x3b\x9d\xa6\xed\xa2\x18\xfc\x58\x82\xf7\x2e\x81\x0b\x99\x88\x3f\xfa\x26\x98\x8f\x19\x50\x1e\x0f\xac\xd3\xf1\x23\xef\x45\x13\xdb\xee\xa0\x0c\x0c\xd8\x26\xe2\xdc\x8e\x66\xda\x10\x8d\x34\x9b\x43\x23\x27\xb6\x1f\xb5\xed\x7e\xef\x03\x46\xe3\x5c\xda\x1d\xaf\x78\xb3\xbd\x6f\x26\xa5\x0b\x94\x75\xf0\xdd\x44\x58\x56\xce\x45\x0c\xce\xf2\x39\x47\xd5\xfe\xda\x30\xf3\x1b\x23\x0a\x3b\x1f\x37\xda\x7d\x17\x4a\x43\x6a\x89\x93\x7d\x3e\x59\x10\x2d\x17\xd6\x31\x2e\x6f\x8d\xf2\xe9\x3c\xd7\x46\xe2\xbf\xc5\xfb\x94\x12\x11\x43\xd1\xa7\x84\xab\x97\xbb\xbc\x0d\x8f\x92\x4c\x28\x86\xef\x76\x3c\x6f\x37\xcb\x5c\x73\x76\x59\x71\xd3\xfd\xf9\x4f\xbb\x6c\xdd\x04\xdb\x28\xec\x68\x65\xaf\x47\x50\x4c\xaa\x11\xfe\x6e\x7b\x7a\xca\x2b\xae\x46\x2c\x89\x04\x57\x5a\x52\xb6\x39\x87\x69\xfd\x68\xe8\x0a\x69\xee\x6f\x20\x88\x41\x27\x8d\x80\x42\x56\x63\xb0\x3c\x53\x44\xb4\xf4\xa0\xae\x02\xc6\xa6\x38\xf9\x58\x42\x43\xb8\x1a\x9a\x56\x1b\xc0\x88\xb4\x82\x93\x7d\x1a\x26\x20\x25\xc4\x67\x28\x7d\x5e\x17\xdf\x75\x31\xe5\xa2\xf8\xf9\xfc\x1e\xa2\x7c\xdb\x4c\xf0\xd5\xb1\x62\xcb\xf3\x06\x11\x17\x76\x62\x17\x61\x8e\xae\xbf\xe0\xe4\x0f\x81\x60\x77\x82\x88\xa2\x9a\xa9\x89\xcd\x17\x2b\x36\x02\x2a\x8e\xcf\x02\x85\x0b\xf7\x30\xb2\x38\x9b\xfa\xc0\x34\x92\x9b\x68\x26\x84\x32\xa7\x1c\xf7\x13\xe7\x9d\x33\x61\x7d\x7e\x98\xbc\x22\x49\x6a\x68\x8c\x4f\x62\x29\xa7\xb7\x86\xda\xf2\x31\xa6\xac\x0a\x5e\x40\xd0\x7b\xa9\xcc\x34\x68\x78\x34\x7f\x4c\x51\x6a\x52\x9a\xa8\x3c\x35\x93\xde\x01\x9b\xce\xb4\xea\x13\x36\x84\x21\x62\x0d\xd0\x68\x56\x99\x36\x05\xd0\xb5\x2e\x28\x55\x54\xab\x5a\x89\x0f\x8b\xac\x06\x97\x86\xd3\x2f\x78\xcc\xf2\x5e\xae\x05\x57\x9f\x80\x8e\x86\x47\x7d\x52\x26\x8a\x9b\x35\x8e\x17\x84\x69\x30\x34\x1b\x75\x11\x29\xf2\xa9\xfd\x12\xf0\x31\x9d\xb8\xae\x22\xe5\x03\xbd\xa8\x31\xea\x8c\x07\xf6\xe3\x0e\xcc\xbe\xe1\xca\xf3\xd4\xe8\x8b\x05\x51\x47\xb3\xba\x6f\x9c\x23\xa4\x04\x95\x09\xab\x6d\x2e\x1b\xdc\xff\xff\xc5\x43\x87\xea\xa8\x04\xe6\x8c\x4d\x67\x1e\x96\xd4\x31\x82\xfa\x1e\xec\x7e\xf6\x48\x2b\x5f\x8a\x1d\x0d\x3d\x2a\x76\xd4\x7d\xdb\x3e\x5f\xa2\xc4\xaa\xca\xfe\x6b\x90\x69\x01\x45\x44\x11\x24\x19\xce\xce\xed\x1b\xd6\x38\x1c\x23\xaf\xc8\x21\x22\x19\xd3\x3d\x85\x08\x3f\x10\xd9\xd1\x90\x9c\x10\x9e\x17\x67\xee\xa1\x17\x70\x51\xcc\xef\x26\x32\x2f\x55\xa2\x9c\xab\xe1\x17\xb7\x22\x77\x76\x34\xf3\x94\x57\xc7\xc0\x41\x00\x1e\x2f\x8b\xf8\xd0\x24\x16\xd6\x0d\x27\x68\x47\xba\xfd\x1c\xfe\x2b\x9a\xcf\xb1\x12\x60\x81\xc7\xb5\x8c\xa2\x00\x99\xf6\xab\xd2\x53\x71\x20\xeb\xa7\xd8\xc2\xa2\x29\x56\x90\x6e\x30\x83\x74\x04\x57\xd2\x2a\x42\x67\xfd\x58\x0e\x63\xf1\x59\x54\x35\x68\xd7\x88\xfc\x78\x81\x57\x77\x0c\x5e\xda\x3c\xda\x52\xba\x72\xb4\xa2\x79\xe5\x78\x10\xf1\xf6\x2f\xb0\x67\xfd\xe8\x08\x6d\xed\x68\x4f\xda\xca\xb1\x7b\x68\xd0\xa6\x79\x1a\x04\x0c\xad\x1f\x5d\x9d\x4d\x3b\x1a\x04\x17\xad\x1f\x2b\x22\xea\xc7\x89\x35\x5a\x3f\x1a\x1b\x49\xd7\x8f\xa6\x71\x49\xeb\xc7\x52\xaa\xe2\x47\x0a\x52\xea\xd7\x23\x94\xc8\xb7\xda\x9e\xe3\xb7\xad\xf8\x49\x39\x3a\x06\x71\xb3\xc8\xa6\xf5\x63\x59\x00\x7c\x26\x51\x4e\x6b\xa6\xfa\x56\x9b\x69\xde\x6e\x7c\xd8\xe6\xa8\xfb\x38\x1d\xa7\x50\xf4\x5d\xea\x8c\xb7\x33\x63\x44\x75\x26\x01\xcb\x0a\x60\xd8\x97\xb7\xc3\x7c\x9a\xc0\xaa\xf5\xa3\x3b\xc6\x69\x47\x47\xec\xd3\x8e\xce\x90\x1b\x05\x9e\x6f\xac\x5d\xf8\x09\x65\x1d\x6b\x99\x0e\xb2\x4e\x90\x75\x76\x18\x41\xd6\xd9\x76\x04\x59\x67\xd3\x08\xb2\xce\x9a\x11\x64\x9d\x20\xeb\xb4\x1a\xfb\x27\xeb\x58\x4b\x55\x67\x06\xb3\x1f\xad\xc1\x75\xd9\x42\x86\xd2\x94\x0f\xe9\xa9\x9b\xca\x0c\xef\xbf\x76\x24\xf6\x06\xcd\x6b\x2e\x52\x5d\x52\x3e\x05\xf2\x7a\xf0\xfa\xd5\x96\xe9\x80\xeb\x47\x9b\xa0\x9d\xea\xd8\x35\x75\x70\x79\x6c\xf2\x48\x7c\x34\xef\x92\x3b\xa9\x85\xc3\xa3\x26\x61\x6e\x70\x10\x15\x55\xad\x52\xd0\x84\xea\x9a\x41\x9c\xa5\x50\x38\x44\x6b\x29\xc8\x65\x4c\xaf\xe0\xce\xdf\x61\x36\x75\xd8\x6c\x05\x11\x50\x1b\xc7\x3e\x86\x62\x15\x22\x05\x9b\x60\xea\x0f\xbd\x59\x02\x78\x58\x91\x43\x18\x4e\x87\x24\xb6\xc9\xda\x94\xbb\x98\xb1\xa3\x7e\xd5\x3d\x9e\x1a\xe2\x2a\xf1\x3f\x66\xd9\xce\x3f\x0e\x73\xe0\x3a\xa7\x49\xb2\x20\x30\x67\x91\x2e\xbe\x0f\x03\x02\x99\xb6\xce\xce\x36\xae\x94\x16\xe2\x61\x5b\x91\x70\xb0\x72\xb6\x76\xf3\x57\xfb\xd1\x5e\x76\x5b\x59\x47\x73\x7a\xb3\x24\x97\x58\x08\x0d\x37\xaa\x55\xda\xbc\xcd\xfa\x2b\xf1\x9f\x88\xe0\xef\xaf\x9a\xba\xc7\x48\x47\x3c\xa1\x35\x1f\x58\x56\xa0\xf2\x24\x31\xe8\x6d\x3d\x66\xab\x20\x58\xe3\xc9\x5a\x93\x6d\x63\xdd\xac\x69\x25\xeb\x06\xef\xb9\x11\x99\x48\xc4\x74\x51\xdd\x41\xdb\x91\xa5\x52\xde\x86\x12\x95\x8f\x9d\x08\x68\x0e\xd1\xe5\xd2\x96\x07\x5f\xc8\xc6\x11\x7c\x21\x2b\x23\xd8\x07\x96\x47\xb0\x0f\xec\x30\x82\x7d\x60\xcd\x08\xf6\x81\xd5\x11\xec\x03\xc1\x3e\xd0\x66\xbc\x7c\xfb\x00\x09\xbe\x90\x4d\x23\xc8\x3a\xe5\x08\xb2\xce\xf6\x23\xc8\x3a\xab\x23\xc8\x3a\x41\xd6\x09\xb2\x4e\x90\x75\x9a\x8e\x16\xc8\x9d\x89\xb8\xf3\x14\x99\x4c\xc4\x0f\x64\xc8\x58\x7b\x75\x24\x06\x89\x88\x8a\xca\x22\xe6\x11\xe7\xf9\x50\x34\xb5\x26\xf4\x3e\xf9\xb7\xe0\x60\xd3\x13\x6c\xc9\xda\x14\x88\xc0\x26\x10\x99\x88\x0f\xd5\x51\x83\xc0\xf3\x90\x61\x13\x32\x6c\x3e\x83\x0c\x9b\x19\x55\xae\xf0\x11\x92\xd6\xcd\x09\x37\x95\xe3\x7f\x03\x32\xfd\x6c\xf3\x6d\x0c\xc2\x39\x84\xc1\x1e\x71\x25\x52\x58\xd8\xc5\xce\xb7\x0b\xf1\xa8\x0e\x31\xa7\x97\xd9\x16\x3b\x71\x0c\x31\xc9\x40\x0e\x2c\x92\x09\x32\x61\xae\xfe\xd7\x12\xfe\x3a\x08\x3f\xf3\xbc\x99\x3a\x24\x9e\x75\xf2\x4c\xfd\x53\x3a\xf3\x4d\x55\x5d\x74\x35\xae\xf8\xec\x52\x69\xba\xd1\x4a\x07\x44\x3b\x77\xda\xf7\xad\xf4\xd2\xae\x94\x48\x54\xf2\xae\x77\x2a\x73\xbc\x79\xac\x2d\x4e\xfb\xaf\x1c\xe4\x82\x88\x39\xc8\x52\x31\x2a\xba\xf3\xf4\x8b\x26\x33\x11\x75\x05\x90\xbb\x31\xf0\x74\x62\x8a\xe8\x52\x53\xef\xda\x6b\x48\xf6\xac\xfa\xf1\xe6\xd1\xad\xe2\xd0\xa1\xda\xf0\xdc\x6a\x29\x6f\x1e\x9d\x9a\xdf\x48\xc7\x26\x38\xd2\xa1\x19\x8e\x74\x6b\x8a\x23\x9d\x9b\xe3\x48\x97\x26\x39\xf2\xc9\x2b\x40\x6f\x1e\x1d\x9b\x8f\x48\xe7\x56\x3a\xf2\x0c\xeb\x49\x6f\x1e\x1f\x01\xdc\x5d\x5a\xec\x48\xa8\x4e\xdd\x7a\x74\x6d\x50\x23\x5d\x1b\xd5\x48\xd7\x78\xd8\xa8\x0a\xf6\xe6\x11\xea\x63\x7f\x04\x39\xad\x33\x21\xa2\x6d\x4d\xed\xc7\x16\xda\x01\x4e\x16\xbd\x7b\x3f\x95\x02\x64\xb9\x74\xd9\x30\xd6\xbc\xbb\xd2\xab\x0b\x43\x35\xab\x8d\x4d\x7d\xdc\x2a\x62\x34\xfe\x1e\x7b\x83\x57\xce\x2b\xc5\xe3\x2a\x93\xad\xb4\x8e\x29\x4d\x67\x45\xf3\x18\xa3\x14\x94\x4d\xa7\x2a\x0f\xe3\xbd\x43\x1b\x4e\x5a\x4a\x13\x3c\x5e\x0e\x30\x2d\x9f\x40\xfd\xc2\xb6\xb3\x3d\xf0\x76\xec\x9e\x2a\xef\x38\x18\x56\x3b\xdf\xba\x19\x0f\xff\xcf\xff\x3d\xaa\x55\x6f\x29\x27\x0c\xda\xdf\xd6\x23\x68\x7f\xad\x46\xd0\xfe\x36\x8e\xa0\xfd\xb5\x18\x41\xfb\xdb\x6e\x04\xed\x6f\xf3\x08\xda\x5f\xd0\xfe\x1a\x8c\xa0\xfd\x05\xed\xaf\xe9\xf8\x8c\xb5\xbf\x6e\xa3\x9a\xab\xba\x98\x0b\x12\x41\xf9\x51\x53\xcd\xa2\x32\xe2\xd9\xdf\x65\xff\xd5\xad\x0e\x58\xd5\xef\xd6\x6b\x80\x55\x2d\x71\x45\x0b\x1e\x3e\xa2\xee\x15\x0a\xe1\xca\x93\x0f\x6b\x82\x2f\x2d\x72\xbb\x33\x4c\xac\xb8\x84\x3b\x45\xc5\x1b\x1f\x58\x56\x36\x5e\x2f\xa2\xce\x62\x72\xe8\x7d\xf1\xd8\x48\x85\x0b\x5d\xbf\xc8\x35\x1b\x94\x77\x14\xde\x79\x0c\xaa\xa9\xe5\xf3\xd7\x5c\xc8\x45\x0c\x5b\x11\x1f\x55\x62\x8f\x21\x8f\x20\x6b\x6b\xc0\xc6\xb5\x13\xc6\x6d\xa4\xa3\x6f\xfa\x23\xb8\x0f\x9a\xb2\xf4\x14\x29\xa0\xc7\x73\x2b\xfa\xe2\x7a\x50\xfe\x2d\x61\x57\x89\xf2\xa1\x78\xc8\x28\x77\xc9\xb0\x82\xfb\xae\xf4\xb6\xd3\x7c\x29\x2f\x17\xbd\x54\x8a\xb7\x0f\xc9\x39\x62\x7d\x75\x62\xa6\x10\x3e\xd4\xf6\x3f\xe9\x06\x91\xf7\xab\x70\xc3\xdd\xce\x85\x1b\x96\x22\x46\x42\xdd\x86\x50\xb7\xa1\x55\xdd\x06\xbc\x68\x0f\x77\xe7\x05\x1c\xc8\x8f\xae\x3d\x92\x04\x04\x55\x9a\x27\x9a\x65\x65\x04\xb6\xb2\xaf\x4a\xac\x26\x31\x71\x91\xa0\x75\x7c\x37\x6f\xa3\xd1\x6c\x19\xef\x71\x3e\x8c\xd8\x56\x48\x4e\x5c\xb4\x25\x36\x33\xc2\x8a\x03\x5e\xed\xb0\x21\xa5\xec\xf9\x47\x0a\x9e\x21\xc1\x56\xa5\xd6\x6c\x7b\x6d\x19\x3a\x9f\x18\x94\x30\x14\xfb\x01\x06\x51\x6d\x68\x81\x51\xab\x6c\x0e\xbc\xe4\x12\x87\xea\xe8\xc8\x4b\x43\x9d\x72\xaf\x8f\xc2\x7d\xfe\x56\xe1\x12\xff\xb5\x0d\xff\xc1\x0f\x2a\x38\x50\x09\xbe\x92\xff\x3c\xef\x90\xc8\xf6\xd1\x6d\x5d\x58\xe4\x3a\x8b\x6a\x7b\xf2\x88\xb6\xcf\xa9\xf6\xc5\x5e\xfa\x30\xf6\x4e\xeb\x78\x19\x7e\x8b\x90\x30\xba\xfd\x78\x0e\x09\xa3\x4f\xe4\x9b\x78\x3e\x79\xa3\xcf\xd6\x1f\xf1\x5c\xf2\x46\x83\x0f\x62\xa7\xf1\x52\xd3\x39\xeb\xa3\x43\x9f\x43\xf0\x37\x74\x2c\x53\x75\xc2\xfc\x3f\x8e\x9f\xa1\x13\xfc\xeb\x34\xba\x2c\x44\x96\x3d\x65\x64\x59\xd0\xc2\x82\x16\x56\x1f\x41\x0b\x5b\x19\x41\x0b\xdb\x61\x04\x2d\x6c\xf3\x08\x5a\xd8\xea\x08\x5a\x58\xd0\xc2\xb6\x18\x41\x0b\x0b\x5a\xd8\xb6\xe3\x33\xd3\xc2\xba\xab\xb7\x1e\x22\xbc\x3e\x42\x84\x57\x37\x94\xb0\x03\xfa\xd7\x09\xd6\x75\x14\xd1\x15\xa2\xb9\xf6\x3b\x9a\xab\x65\xd9\x39\xae\xd9\xc7\x29\x3d\x57\xdd\xed\x4d\xf5\xe7\xe8\x5c\xb0\x98\x64\xb9\x76\xd5\xb7\x42\x0d\xba\x7d\xae\x41\x57\xdb\xd1\x50\x88\x6e\xab\x42\x74\x9b\x60\x16\xaa\xd1\x6d\x18\xfb\x13\x63\x16\xaa\xd1\xed\x3a\x42\x35\xba\xf5\x23\x54\xa3\x7b\x60\x84\x6a\x74\xa1\x1a\x5d\xa8\x47\xd0\x62\x84\x7a\x04\x6b\x46\xa8\x47\xd0\x7c\x84\x7a\x04\x5b\x8d\x50\x8f\x20\xd4\x23\xa8\x8f\xe0\x85\x6a\x37\x42\x3d\x82\x96\x23\x78\xa6\x42\x3d\x82\x56\x13\x86\x6a\x74\x2f\x2a\x66\x90\x04\xed\x2f\x68\x7f\x5b\x8f\xa0\xfd\x6d\x1c\x41\xfb\x6b\x31\x82\xf6\xb7\xdd\x08\xda\xdf\xe6\x11\xb4\xbf\xa0\xfd\x35\x18\x41\xfb\x0b\xda\x5f\xd3\xf1\x19\x6b\x7f\xa1\x1a\xdd\xde\xc7\x2a\x92\x7d\xcc\x48\x0a\xd5\xe8\x42\xfc\x62\xa3\xed\x0e\xd5\xe8\x1e\x1f\x9f\x7d\x35\xba\x5a\x2c\xdd\xd3\x95\xa4\xdb\x7d\x19\xa1\x2e\x5d\xa8\x4b\x17\xea\xd2\x85\xba\x74\xa1\x2e\x5d\xa8\x4b\xb7\xfd\xd8\x7f\x6f\xc6\xde\xe9\x1f\x2f\xc3\x83\x11\x2a\x22\x6c\x3f\x42\x45\x84\x8d\x23\x54\x44\x08\x15\x11\x82\x37\xa2\xc9\x08\x15\x11\x76\x1c\xc1\xf3\x10\x2a\x22\xec\x34\x42\x5d\xba\x17\x13\x63\x16\xb4\xb0\xa0\x85\xd5\x47\xd0\xc2\x56\x46\xd0\xc2\x76\x18\x41\x0b\xdb\x3c\x82\x16\xb6\x3a\x82\x16\x16\xb4\xb0\x2d\x46\xd0\xc2\x82\x16\xb6\xed\xf8\xcc\xb4\xb0\x50\x97\x6e\xaf\x63\xbd\x42\x5d\xba\x35\x23\xc4\x75\xed\x77\x5c\x57\x43\x5c\xa1\xb9\x16\xa9\xc8\xb9\xbe\x06\x39\x67\x11\x9c\x44\x91\xf9\xeb\x46\xdc\xc2\x8e\xb1\x44\x75\x35\xf4\x81\x69\x09\xe3\x31\x8b\x50\x91\xbc\x9b\x01\x96\x95\x33\xf2\x2d\xde\x47\xa8\xbd\x91\x68\xbc\xb3\x44\x2f\x5c\xa7\x21\x6a\x18\x60\x83\x53\xef\x0a\x2f\x0b\xa1\xb1\x10\x09\x50\xbe\xc3\x93\x8e\x1b\x82\xdc\xf1\x34\xd7\x00\xf2\xd6\x91\xe2\x72\x32\x32\x86\x44\xf0\xa9\x8b\xe7\x71\x27\x60\x48\x4e\xcb\x1b\x22\xca\xf1\xf0\xe4\x52\x02\xd7\xc9\x02\xe1\x80\x05\xae\x50\x6b\x48\xc5\x1c\x62\x24\xd9\x18\x46\x64\xe5\x48\xaa\x49\x02\xd4\xbc\x8b\x43\xf9\x32\x73\x78\x28\x19\xe1\xfc\x76\xd2\x31\xb8\xd0\xa6\x46\x40\xdc\x9d\x36\x36\xa2\x86\x4b\x96\x0d\x27\x36\x21\x5f\x8a\x50\x3f\xaa\x7c\x21\x1e\xcd\x85\xc8\xc9\x1d\xb5\x92\x92\xcc\x39\x1e\x66\xfc\x74\x03\xda\x1d\x5f\xde\x42\x26\x69\x6e\x7e\x18\x20\x55\xdb\xf1\xb1\x36\xe6\x00\x2a\xa7\x8d\x98\x54\x6d\x6b\x7a\x27\x72\x9a\x5b\x91\xd0\xa1\x32\x70\x2d\x17\x18\x6f\x67\x65\x8a\x0a\x26\xa6\x74\x0a\xbd\x9e\x22\xa7\xef\xce\x0c\xf9\xcb\x95\xa1\xd6\xae\xca\x9e\x23\x87\x99\x14\x73\x16\x1b\xe4\xfe\x40\x25\xa3\xe3\xc4\xc8\x9d\x13\x90\xc0\x8d\x58\xf0\xe5\xe1\x87\x93\xab\x5f\x2f\x4f\xde\x9d\x1f\xa1\x04\x0a\xf7\x19\xe5\xe6\x54\xe4\xaa\x0c\x14\x75\xaf\x33\x2f\x02\x3e\x67\x52\x70\xb3\x3e\xd4\xd5\x28\x99\xfb\x59\xa3\xe2\x30\x48\x50\x22\x99\x43\x6c\xe5\xe4\xe2\x6d\x9e\xeb\x30\x9e\xe5\xda\xeb\x8e\x18\xbe\x68\x0e\x10\x8f\x66\x94\x4f\xcd\x3a\xcf\x44\x6e\xe6\xfb\xf2\x4b\x5c\x91\x84\x38\x8f\xac\xe4\x44\x3d\xd6\x7e\xd9\xf7\x9c\xc2\xd0\x7a\x65\x4b\x22\xaa\x88\x66\x7e\xcd\xd5\xcf\x52\x0b\xae\xe9\xfd\x1b\x1b\xbf\x77\xf0\x65\xe5\xd2\x81\x2f\x27\x29\xcc\x2b\x2c\xbf\xb1\xab\x4a\xb0\x92\x61\x42\x0e\xaa\x77\x0f\xc9\xb9\x79\x07\xc4\x55\x00\xda\xf0\x4b\x98\x83\x44\xcd\xd3\x81\xaf\x4f\x24\x4c\xa9\x8c\x13\x50\x18\x78\xe8\x69\xb3\xd5\x0e\x1c\xc0\xa0\xd0\x6b\xb9\xd0\xeb\x88\x09\x79\x27\x30\x08\x71\x22\xde\x90\x99\xd6\x99\x7a\x73\x7c\x7c\x9b\x8f\x41\x72\xd0\xa0\x86\x4c\x1c\xc7\x22\x52\xc7\x9a\xaa\x5b\x75\xcc\xb8\x39\x5c\x83\x98\x6a\x3a\xa8\x9c\xea\x63\xcb\xb9\x07\x91\x48\x53\xca\xe3\x01\x75\xd8\x35\x28\xb6\xf5\xf8\x0b\xc7\x53\x07\xb4\xb8\x8b\xf1\x01\x1d\xa8\x19\x24\x49\xaf\x01\x3e\xb7\x93\xf9\x5a\xc8\x7a\xad\x64\x3c\xf7\xed\xed\x0f\xf0\x79\x71\x5e\x2d\x0c\x86\xe4\x52\x68\x17\x1f\xeb\x42\xb1\x91\x8e\x22\x7c\x37\x1e\xe9\xf3\xcb\x9b\xab\xbf\x8f\xde\x5f\x5c\xde\x84\x93\x1d\x4e\x76\x38\xd9\x2d\x4e\x36\xf0\x79\xeb\x53\xed\x65\xce\xca\x31\x29\xf6\x1b\x39\xb5\x02\xed\x8f\x41\xb1\x01\xad\x25\x44\x3b\x9e\x0c\xea\x35\x08\x9c\xf3\xf9\x07\x5a\xb7\xb0\xf3\xb5\xe0\x20\xee\x06\x2b\x28\x17\x32\x78\x9b\xf8\xf8\x16\xd6\xac\xb6\xee\xab\x46\x52\xa4\x1d\xed\x5d\x4b\xe6\xd5\xcd\x0d\x0d\xb5\xed\xbb\xa4\x69\x59\xa1\x7a\xcd\xae\x0d\xc9\x3b\xaf\xf6\x90\xd3\x5f\x2f\xce\xce\x2f\x6f\x2e\xbe\xb9\x38\xbf\x6a\xae\x47\x77\x60\x71\x41\x9b\x42\x47\x00\xe8\x35\xe4\x92\x99\x84\x39\x13\xb9\x4a\x16\x85\x15\x64\x3d\x11\x58\x3e\xfd\xce\xef\xbb\x28\xf4\xf1\xb5\x8f\x05\x66\xdb\x2d\xb3\x3d\x83\x09\xcd\x13\xab\x3d\x1d\x1c\x0c\x9b\x70\x39\x3b\xba\x42\xdf\x6f\xa4\x68\x51\x81\xb9\x86\xc2\xd7\xb6\x76\xfb\x44\xc8\x8d\xc7\xb8\xe7\xa2\x0f\x6a\xac\xc7\x09\x8f\xd6\x42\xe7\xa4\x47\xeb\x24\x6b\x09\x9d\x96\x5e\x86\x6e\x7c\xef\x91\xe0\x13\x36\x7d\x47\xb3\xef\x61\x71\x05\x93\x76\x66\xe2\x3a\xbc\xd1\xfa\xe8\x5c\xc9\x68\xab\x34\xec\xcc\xbe\xac\x9d\x9b\xa6\x33\x27\x4d\x57\xd1\x19\xed\x23\x33\xba\x0b\xa4\xe8\x24\x88\x62\xa5\x1e\xbe\xb5\x43\x3b\x8b\x72\x57\x31\x36\x9d\x78\xee\xdb\x71\x79\x3f\xea\xcc\xae\xca\xee\x1d\x9d\xd5\xdb\xaa\x1d\x91\xe0\x11\x64\x5a\x1d\x8b\xb9\xe1\x5c\x70\x77\x7c\x27\xe4\xad\xd1\x23\x8c\xee\x3a\xb0\x58\xab\x8e\xd1\x67\x70\xfc\x85\x75\x83\xdd\xbc\x3f\x7b\xff\x86\x9c\xc4\xb1\x6b\x6e\x92\x2b\x98\xe4\x89\x6b\x27\x30\x24\x34\x63\x1f\x40\x2a\x26\x78\x9f\xdc\x32\x1e\xf7\x49\xce\xe2\xaf\x9b\x13\x67\x3f\x3a\xdc\x05\x91\x59\x57\x67\xc7\x3b\x71\x8d\x3e\x96\x45\x8d\x77\x15\x44\xc4\x70\x2d\xa6\x15\xe2\xa6\xb7\x3a\x3b\x21\xa3\x23\xd0\xec\x6e\xa2\x5f\x1e\xb8\x85\xdd\xd2\xd5\x5e\x49\x58\xad\x8b\xd3\x21\x6a\x26\xe2\x37\x44\xe5\x59\x26\xa4\x56\x24\x05\x4d\x8d\xd2\x3b\x34\x18\xd6\xaf\xff\x89\xbe\xaa\x3e\xf9\x47\xf1\x23\x3a\x9c\xd4\x4f\xbd\xde\xdf\xbe\x3f\xff\xfb\x7f\xf5\x7a\xbf\xfc\xa3\x7a\x15\x59\xa1\x8d\x02\xaa\xdf\xa2\x32\x88\x86\x5c\xc4\x70\x89\xef\xc0\x3f\x55\xcd\xcd\xe2\x2e\x68\xaa\x73\x35\x9c\x09\xa5\x2f\x46\xc5\x9f\x99\x88\x97\xff\x52\x2d\x24\x0e\xb2\x9f\x8c\x01\xb7\x68\x44\xf5\x6c\x4f\xd8\x43\x49\x4b\x3a\x3e\xaa\x6e\xd6\x6a\x13\x9d\x94\xe2\x3f\xbf\xf1\x20\x30\xd2\xd3\x9d\x64\x5a\xa3\xeb\xcd\xa5\x82\x8b\x49\xdf\x9c\xda\x52\xec\x9c\xbf\x6e\x5d\x1f\xa5\x53\xd2\x56\xec\x60\xc7\x00\x43\x88\x38\x68\xd9\x83\x5c\x30\xd8\x55\x17\xf3\xc9\xe8\x82\xcc\x2d\x84\xf7\x06\x38\x3e\xbd\xf7\x9b\x8f\x4a\xe3\x8a\xa6\x4b\x0e\x54\x85\x86\xf8\xc6\x06\x05\x15\x49\xc6\x24\x61\x29\x73\xb1\x86\xae\x41\x93\x22\x87\xf6\xc7\x61\x94\xe5\x7d\x77\xc3\x30\x85\x54\xc8\x45\xf1\x27\x64\x33\x48\x8d\xa6\x35\x50\x5a\x48\x3a\x85\x7e\xf1\xb8\x7d\xac\xf8\xcb\x3e\x58\x7b\xc1\xea\xd3\x56\x15\x2e\x5d\xa5\x8e\x22\x43\xfc\xf2\x68\x9b\x07\xfd\x9e\x90\xb6\x02\x33\x2e\x3f\x82\x48\x58\x58\xe2\xac\xc0\x59\x40\x11\xf5\xc9\xb9\x48\xf2\x14\x54\xbf\x10\x83\xac\x35\x80\xcf\x8d\x66\xa9\xf6\x4a\x50\x8b\xd9\x9c\xa9\x2e\xc2\x88\xd7\xc8\x69\xcc\x45\xe4\x8b\x5c\x67\xb9\x76\xf5\x66\x2a\x8d\xdd\x84\x42\xbb\x45\x51\x14\xa0\x46\xf6\x5f\x1f\xb4\x8f\x46\xa7\x5a\x83\xe4\x6f\xc8\xff\x1c\xfe\xfc\xd5\x6f\x83\xa3\xaf\x0f\x0f\x7f\x7a\x35\xf8\xeb\x2f\x5f\x1d\xfe\x3c\xc4\x7f\xfc\xfe\xe8\xeb\xa3\xdf\xfc\x1f\x5f\x1d\x1d\x1d\x1e\xfe\xf4\xfd\xbb\x6f\x6f\x46\xe7\xbf\xb0\xa3\xdf\x7e\xe2\x79\x7a\x6b\xff\xfa\xed\xf0\x27\x38\xff\x65\xcb\x49\x8e\x8e\xbe\xfe\xb2\xf5\xd2\x29\x5f\xbc\x6f\x49\x40\xed\x18\x74\x56\x2e\x68\x79\xc6\x8e\xe2\xac\xef\x07\xa5\xd2\x34\x60\x5c\x0f\x84\x1c\xd8\xa9\xdf\x10\x2d\xf3\x76\xc4\xa4\x64\x4a\x5d\x9f\x7f\xdf\xbd\xeb\x4d\xc9\x90\x0a\x76\xbd\x37\x07\x5c\x41\x24\x41\x7f\x0a\x4b\x8e\x7d\x93\x97\x53\x96\x62\x1e\x5f\x1a\x9f\xfb\x1c\x8c\x3b\x45\xc8\x20\xee\x6b\x29\x89\x4e\xa4\x48\x87\xa4\xe2\xde\x98\x63\xc2\x87\xbb\xef\x16\x5a\x58\x41\xfd\x08\xc6\xa0\x60\x0c\xda\x30\x1e\x35\x06\x5d\x5b\x3c\xdc\x5b\x4b\x10\xf0\x79\x53\x17\xc6\x5a\x0f\xba\xd7\x75\xb4\x20\x99\xc8\xf2\x84\xea\x0d\x9e\xb1\x35\xee\x74\x77\xd4\xcb\x78\xe4\x32\x98\xc6\x32\xb4\x74\xbd\x0f\x93\x9c\x24\x09\x61\xdc\x1e\x7c\x9c\xc0\x3b\xcc\x24\x58\xd5\x86\x50\xeb\xcf\x9e\x9b\x25\xdc\xb9\xb2\x72\xd5\xb8\x1c\x45\x94\xa6\x52\x63\xec\x31\x96\x9d\xb3\xac\xc4\x79\x9f\x18\x2f\x8b\xcf\x15\xc2\x61\x91\x0b\xb2\xb6\x33\x66\x42\x95\xf6\xcb\xc6\xd5\x68\x7a\x8b\xde\xc6\x08\x62\xe0\x11\x60\x62\x5a\x0e\xe5\xb7\x8e\x8d\xde\x46\xce\xf9\xdc\xce\x41\x49\x9c\xdb\x60\x10\x4b\xfe\xd6\xcf\xf1\xb2\x02\x10\x0c\x22\x5e\xfb\x06\xc6\x45\x1c\x02\x52\xfd\x42\xc3\x2e\xf2\xfb\x0a\x2b\xab\x7a\x9a\xc8\x83\xf6\x3c\xb3\xf0\x6c\xb5\x12\x86\x56\x98\x65\x69\x7e\xae\x33\xc9\x97\xe0\x0c\x6c\xcf\x3e\x3f\x3b\xd6\xd9\x11\xdb\xec\x86\x65\xee\xe0\x3b\xe9\x92\x4d\x76\xe1\x2c\xc9\x24\x4c\xd8\x7d\x47\xe7\xf4\x84\x97\x96\x18\x16\x03\xd7\x6c\xc2\x6c\xcf\xfb\x4c\x42\x06\x3c\x2e\x0a\x97\x62\x72\x38\xaf\xc3\x66\x2f\x83\x79\xac\xc0\xdd\x2d\x29\xbb\x5e\x27\xec\x07\x3a\x46\x02\x1d\x6b\x3c\x3e\x11\x1d\x73\x98\xbb\x3f\x44\x0c\x23\xcf\xdb\x47\xbf\x9f\xd6\x43\xd9\x11\x91\x77\x46\xb4\x32\xb3\xeb\x18\x67\x51\x36\x4b\xb2\x48\xc3\x2e\x48\xa3\x16\x36\x78\x8d\xcc\xd8\xd4\x40\x36\x81\x39\x24\x4e\x6e\x22\x29\xe5\x74\x6a\xf3\xbb\xb5\xf0\xa6\x5a\xa3\x68\x19\x3c\x96\x2c\x5e\x89\xbb\x47\x39\xde\xe0\x76\x22\x68\x8c\x17\xa5\x48\x12\x90\x8a\x24\xec\x16\xc8\x19\x64\x89\x58\xb8\x74\x6d\x1e\x93\x6b\x4d\xb5\xc1\xea\x6b\xd0\xcd\xdc\xbe\xad\x30\x16\x57\x3c\xca\x93\x64\x24\x12\x16\x35\x32\xaa\xd4\x77\xee\x02\xf7\x2b\xcb\x93\x84\x64\x38\xe5\x90\xbc\xe7\x48\x34\x4e\x92\x3b\xba\x50\x7d\x72\x09\x73\x90\x7d\x72\x31\xb9\x14\x7a\x64\xa5\xef\x7a\xc0\x9d\xbd\x91\xb0\x09\x79\x83\xd5\x6d\x34\xd1\x74\x8a\xba\x93\x77\x03\xf6\x0d\xfc\xab\x13\x58\xfa\x70\xc7\xd4\x5a\x65\xa5\x35\xe2\x7c\x81\x33\x19\x5a\x65\xff\xfe\xe4\xdb\x94\xb0\x09\x44\x8b\x28\x69\x7f\xb4\x4e\x22\x0c\x60\x28\x33\xce\x2b\xf8\xed\xaa\xa9\xbb\x1c\x4f\xd4\x02\x19\x27\xb6\xcc\xb9\xad\xdf\x5e\xa2\x7a\xb1\x22\xab\xed\xaa\x4e\x95\xc4\xc6\xcc\xb3\x2d\xdb\xcc\x84\xd2\xd7\x46\x43\xef\xa4\x18\x7a\x6f\xe4\xa7\x23\x58\xf2\x39\x49\x20\x26\x2c\x4d\x21\x36\x5a\x7c\xb2\x20\x74\xa2\x31\xd7\xb6\x66\x21\x88\x24\x58\xac\x75\x55\x4c\x66\x94\xc7\x09\x48\x32\xa1\x2c\x71\xf6\x80\xda\xfd\x1a\x64\xca\x38\x9a\x05\xac\x47\x16\x4d\x0c\xe6\xaf\x28\x12\xd2\x97\xa7\x67\x5a\xf9\x4b\xe5\xc1\x44\x3e\x52\x41\x80\x65\xd7\x32\x19\x27\x22\xba\x55\x24\xe7\x9a\x25\x76\x31\x42\xdc\x92\x48\xa4\x59\x82\x47\xa7\xc5\xc9\x2a\xfe\x39\x28\x50\x69\x60\x66\x57\xc7\x5f\x94\x97\xf0\x87\xa6\x0c\xbd\x03\x41\xac\x0b\x31\x0c\xee\x21\xea\x2c\xcf\xff\xfc\x1e\xa2\x4a\x61\x09\xec\xc7\x80\x27\x1a\xf3\x3c\xe9\x2d\xbc\xa0\x4a\x76\x2d\x72\xe9\xaa\xa3\x06\xbf\x53\x3b\xa7\x2f\x84\xe5\x5e\x41\x12\xc6\x91\xbe\xb9\xfc\x3a\xc2\xb8\x32\x9c\xbd\x76\x18\xec\xd1\x73\x42\x2b\x89\x99\xc4\x2a\x08\x8b\x22\x90\xda\xcf\x85\x05\x06\x84\xd0\xe4\xb0\x77\xdc\x3b\x5a\xb1\x3f\xf6\x8c\x04\x92\x80\xa5\xb5\x3e\x71\xaf\x58\x94\x62\x69\x96\x2c\x70\x1d\xbd\xb8\x4f\x98\xf6\x91\xd6\x32\xe7\x7e\x55\x2e\xe9\xaf\x4f\x94\x20\x5a\x52\x5f\x5d\xc5\xfe\x6a\x6e\xd2\x32\x77\x54\xfe\xb0\xf7\x5b\xaf\x4f\x40\x47\x47\xe4\x4e\xf0\x9e\xc6\xe5\x0f\xc9\x8d\x30\xa2\x74\x39\xd1\x42\xe4\x84\x83\x0d\xec\x87\xfb\x2c\x61\x11\xd3\xc9\x02\x29\x16\x11\xb9\xb6\x39\xc4\x54\xfb\x64\xc3\xf3\x7b\xa6\x5d\xbc\x9a\x21\x19\xaf\x10\x9a\x96\x6a\x11\x6a\xc4\x9c\x39\x1c\xcf\x80\x26\x7a\x66\x83\x44\xb8\xe0\x83\x7f\x83\x14\x98\x83\xc8\xdd\x95\x17\x57\xf5\xaf\x13\xcd\xc1\x10\xd1\x6f\xa1\xbb\x26\x3e\xdf\xdd\xdc\x8c\xbe\x05\xbd\x44\x32\xcc\x5b\x7c\xe8\x0e\x5a\x03\x40\x4e\x84\x4c\xf7\x80\x76\x74\xe3\xac\x1c\x90\x4c\xc8\x7d\x20\x61\x33\xa1\x5a\xed\x25\x59\xd9\x4f\xa1\x34\x6a\x43\x4e\x1a\xe3\x10\x99\x1d\xac\xc7\x90\xf8\x3e\x37\x17\xa3\x21\xf9\xbb\xc8\xcd\xd7\x8c\xe9\x38\x59\x14\x95\x18\x14\x68\x72\x60\xa6\x3a\x30\xe4\xc9\x60\xc3\x77\x40\x63\xa3\xa2\x18\xea\x01\x74\x3f\xfa\x59\x11\x77\x1e\xdc\xda\xba\xe5\x03\xb9\xd2\x22\x25\x33\xf7\xd9\xf5\xd4\x4b\x77\x32\x86\x78\x7a\x7c\x5e\x93\x84\xcc\x52\x38\xf7\xcc\x8b\xa3\x5f\x2b\x74\xc3\xc2\xdd\xfd\x3e\xc6\x32\x56\x51\x15\x6c\xae\xa1\x93\x4d\x0c\xe2\x16\x58\x06\xd5\xa0\x99\xab\xa4\x3a\xf6\xb8\xf6\x68\xe3\x44\xce\xe5\x89\xd0\xa9\xd7\x3e\xd6\xab\xd3\xca\xa3\xdd\xc4\x0d\x90\x75\x46\x56\x87\x33\xd6\xfa\xd2\x11\x10\x3f\x4e\xe9\xcb\x4f\x01\x80\x6e\x36\x9f\x74\x09\x81\xac\x83\xd0\xee\xd5\xc0\x6e\x2d\x8c\x1e\x8a\xa9\x97\x96\xb8\x22\x99\x50\x20\xe7\x4d\x93\xb9\xcb\xd1\xdd\xa7\x8b\xe6\x1a\xbf\x1f\x6b\xf2\xa4\x25\xe1\x79\x3a\x06\x59\x66\xa6\x48\xbd\x0a\x90\x4a\x64\xc2\xa5\xbd\xdd\x9b\x73\xeb\xed\x13\xcd\x93\x7f\xfe\xcf\xff\xfc\xe3\x7f\x0e\xed\xf4\x45\x94\x02\x27\x17\x27\x97\x27\xbf\x5e\x7f\x38\xc5\xe4\xd8\xb6\x50\xed\x28\x04\xb3\xeb\x00\xcc\x4e\xc3\x2f\x3f\x6a\xf0\x25\xa6\x7c\xb4\xa6\x22\x75\xdb\x3f\x4e\x69\x30\xc0\xe8\x6d\x46\xe3\x74\xb2\x5f\xa5\x58\x99\x91\x35\xeb\x86\x54\x73\xd4\xf6\xe2\x8c\xe9\x28\xbb\x16\xd1\x6d\x87\x7a\xcd\x19\x64\x12\x22\x6b\x27\xbb\x39\x1d\xd9\xd9\x8d\x7e\x79\xf9\xfe\xa6\x4c\x35\xc0\x78\x1c\xf2\xd6\xdb\x97\xbe\x73\x96\x34\xa3\x93\xde\x42\xa6\x0b\xd5\x7d\x4c\xa3\xdb\x3b\x2a\x63\xb4\x6c\x51\xcd\xc6\x2c\x61\xb6\xf8\xaf\x6f\x0a\xc9\x85\x0d\xf8\xb3\x45\xce\xc4\x64\xb9\xb4\x66\x69\x0e\x45\x93\x95\x8d\xa3\x99\x50\x96\xa0\x05\x35\xe7\x9a\xa5\xe0\x22\x82\xa2\xac\x30\xe9\x55\x6d\xda\x41\xf9\xf2\x63\x6f\x95\xaf\xde\x7b\xef\xd5\xdb\x59\x0f\x6b\x1b\x97\xb8\xc7\xac\xce\xb1\x38\x9b\x10\x12\x58\xdd\x67\xc1\xea\x32\x09\xd7\x5a\x64\x1d\x79\x49\xec\x64\x1b\x7c\x24\x63\x98\x08\x43\x84\x37\x3a\x3d\x7c\x8f\x60\x8e\xc9\x81\xde\xaa\x25\x6a\x8e\x0d\x1b\x91\xa9\xf2\x68\xe6\x0d\x94\x1c\x94\x3a\x46\x77\x48\x9e\x59\xad\x15\xc9\x75\x2e\xa1\x6f\xbe\x0e\x52\x5c\x5d\xbf\xcc\x72\x30\xaf\x07\x6e\x7f\x04\x1d\x59\xcb\x6d\x85\x90\x63\x61\x50\xb7\xfc\x65\x37\x4a\x24\xa9\x9a\x01\x96\x17\x81\x7b\xe6\xbb\xa1\x8c\x44\xdc\xeb\x95\x9f\x62\x18\xcb\x54\xd2\x08\x48\x06\x92\x09\xc3\x8c\x72\xae\x63\x71\xc7\xc9\x18\xa6\x8c\x2b\x0f\x0a\x33\xb7\x87\x19\xfa\x63\x98\x2a\x0a\xc3\x0d\xc9\x55\xad\xd8\x89\x4b\x43\x8a\x44\x79\x34\xdd\x9a\x97\x3d\x49\xc8\xb1\x2a\x2d\x93\x0b\x08\xfb\xf0\x58\xbd\xc5\x92\x0f\x73\x8e\x6f\x8e\x21\xa1\x0b\x1b\x6d\x3a\x61\x9c\x26\xec\xdf\x20\xd5\x51\x07\x1e\x27\x03\xc2\xf2\xda\xc6\x75\x60\xa9\x7e\x1a\xcd\xda\x39\x7f\x83\x8b\x6a\xcb\x11\x5c\x54\x6d\x26\x09\x2e\xaa\xe0\xa2\x7a\x64\x04\x17\x55\x70\x51\x2d\x8d\xbd\xd5\x92\x82\x8b\xaa\xf1\x08\x2e\xaa\x87\x47\x70\x51\x6d\x31\x82\x8b\x6a\xcb\x11\x5c\x54\xc1\x45\x15\x5c\x54\xc1\x45\xf5\x19\xd9\xed\xfc\x08\x2e\xaa\x95\x49\x82\x8b\x2a\xb8\xa8\xb6\x1e\x7b\xab\x7c\x05\x17\x95\x1d\xc1\x45\x55\x1f\x9f\x17\xab\xf3\x0e\x9e\x91\x51\xf5\xda\xe7\xb4\x8d\xd0\xa9\xc0\x22\xe7\x27\xaa\x36\x8d\x2b\x5e\x55\xe9\x13\x57\x29\x0b\xe2\x53\x71\x9c\x47\xa8\xf4\x33\xad\xcd\x97\xda\xd5\x55\xe1\x93\x0c\xd5\x71\x26\xec\xff\x95\x8e\x8a\x8a\x87\xc2\x2a\xbc\xcd\x73\xd6\x9e\x2c\x1b\xab\x8d\x5b\xe2\xd3\xb8\x24\xf6\xc4\x7f\xd3\x81\x1b\x22\xb8\x20\x5e\x9c\x0b\xe2\xe5\x74\xcd\x75\x9e\xf9\x9b\x99\x04\x35\x13\x49\x63\x44\xaf\x21\xf9\x3b\xc6\x59\x9a\xa7\x06\xe7\x94\xc1\x67\x36\x2f\x42\x00\x54\x81\xae\x96\x62\x5b\x2b\xa2\xb9\x91\xc5\x80\xc5\x4e\x29\x4b\xcc\x36\x62\xfe\xe6\x8c\xce\x0d\xae\xab\x3c\x8a\x00\xb0\x95\x5a\x55\xc3\xf9\xe3\xb0\x78\x53\xd1\x3a\xe3\x75\x3b\x7a\xd3\x8e\x89\xdb\x72\xa4\x38\xcb\x1f\xff\xd0\x68\x8e\xa9\xcc\xba\xa1\xcb\xdf\x5e\x8d\x4e\xab\x6d\xb2\xb9\x27\xcb\x8c\xcf\x45\x32\xb7\x1d\xf6\xf1\x26\x23\xac\xb9\x66\xfc\xd8\xcc\x7d\x0c\x9a\x56\x74\x1b\xa7\x16\x28\x02\x9c\x8e\x13\xf3\x9c\x79\xaa\xe0\xc8\x23\xcb\x77\x81\xea\x5c\x02\x99\x52\xfd\x94\x04\xbf\xbd\x0a\xd3\x4a\x7d\xe9\x82\xdf\xb4\x95\xd0\xeb\x36\x38\x23\x87\xd7\xad\x50\x53\xc4\x0b\x5b\x41\x7f\x6b\x39\xbc\x35\xa5\x6c\x2f\x1b\xb7\x3f\x5a\x04\x4b\xdc\xe0\x87\x77\x06\xe0\x03\xd7\xf2\xd9\xb3\xf3\xaa\x12\xe4\xbb\x4a\x69\x41\xb2\x84\x96\x7d\xa1\x70\x07\xbe\x43\x1e\x74\x3a\x83\xe8\xf6\xca\x79\x62\x0f\x15\x40\x21\x9b\x4e\x99\x9e\xe5\xe3\x61\x24\xd2\x63\x43\x12\xec\xff\x8d\x13\x31\x3e\x4e\xa9\xd2\x20\x8d\xb8\xea\x58\xdc\x20\x32\xb3\x30\x3e\x1d\xa6\xf1\xd1\x90\xfc\xcc\x6d\x76\x7b\xd9\x87\xb2\x52\xdb\xc1\xbc\xdf\xd7\xd9\x18\x83\xa1\xae\x42\x56\xdb\x87\x8f\x17\xb8\xbc\x61\x9b\x42\xc9\xad\x59\x52\x4b\x2f\xf8\xa7\xf7\x80\x07\xca\x45\x3a\x30\xb8\x3c\x37\x4f\x77\x67\x11\x1f\x1d\x78\xb8\xf7\xc8\xbb\xbd\x37\xa2\xf1\xbe\x78\xb4\xf7\xb0\xda\x74\x07\x0e\xd8\x2e\x3c\xd8\xdd\x79\xaf\x3f\x42\x51\xe6\x8f\xe3\xb5\xee\xd0\xb4\xd7\x91\xb7\xfa\x53\x78\xaa\x3b\xf9\xea\xb6\x1e\xea\x4f\xe7\x9d\xee\xe6\x73\xbb\x54\x04\x9e\xab\x47\xba\x03\x13\x7d\x97\xe6\xf9\xce\x4c\xf3\x1f\xcd\x03\xdd\xde\xfb\xbc\x07\x9e\xe7\xd6\x40\x66\x9c\x69\x46\x93\x33\x48\xe8\xe2\x1a\x22\xc1\xe3\xc6\x1c\x66\xa9\x4a\x67\x71\x7e\x94\x9d\xd6\xd9\xa9\xea\x89\x16\x33\xea\x8a\x91\x1b\x8d\xca\x26\x96\x78\x5f\x86\x13\x28\xd0\xab\x6c\x57\xb9\x97\xde\x09\xb2\x37\x06\x31\x9b\x75\xd2\xe5\x26\x7e\x27\xee\x88\x98\x68\xe0\xe4\x90\x71\xbf\x8f\x47\x15\x35\xb0\xb4\x4e\x16\x68\x6d\xae\xbe\x7e\xe5\x6f\x7e\x79\x66\x47\x34\xb0\x2a\xf5\xf1\xad\xc0\xee\x45\x8f\x9b\x81\xdd\x8d\x93\x3c\xa9\x9b\x82\xad\x79\xb8\x4e\x6f\x5e\x97\xe5\x94\x5f\xe3\xbc\xc5\x69\xa3\x3c\x26\x2e\x13\xed\xe5\x6d\x5a\xeb\xb8\x9a\xba\xe8\x57\xc4\xd1\x3c\x66\x35\xbe\x39\x1d\x59\xa3\x71\x30\x97\xec\x8b\xb9\xe4\x89\x62\x53\xf6\x50\xd0\x7d\xa6\xf1\x28\x41\xd0\xdd\x61\x54\x72\x53\xbf\x95\x34\x82\x51\xe7\x32\x82\x3f\x4e\x24\xce\x25\x75\x04\xb0\x10\xf9\xfc\xe1\xe1\x00\xb1\x3d\x4d\x45\x3e\x2f\x66\xca\x4e\xf2\x24\x59\x90\x3c\x13\xbc\x9e\xfd\x6c\x7d\xed\xcb\xc9\xb4\x68\x92\x5f\xf3\x96\x52\xb0\xcc\xa4\x70\x3c\x53\xe6\x9c\x1b\x1a\x5c\xf6\x44\x43\x41\x12\xcb\x34\xd3\x5a\xca\xae\x62\x53\xb3\x7c\xc3\xff\x30\x9b\xb7\x0c\x40\xac\x4d\x68\x9e\x9e\x08\x19\xb1\x71\xb2\x20\x33\x9a\x14\x0d\x70\x28\xb9\x65\x49\xe2\xa6\x19\x92\x6b\xd0\xd6\xa5\x60\x79\x67\x22\xf8\x14\x17\x47\xb9\x6f\xbc\x08\x91\x79\x36\x4a\x80\xf2\x3c\xb3\xef\x33\x9c\x78\x21\x72\xe9\xdf\x37\x2c\x1c\x13\x05\x07\xe6\x2c\xe9\x57\xda\xbb\x3d\xb8\xb1\x45\xec\x4f\xae\x8c\x00\xf0\xde\x97\xa5\xee\x57\xe7\xf4\x95\xc3\x55\xa5\xb9\x4f\x26\xc5\x9c\xc5\xd6\xbb\xe1\xc1\x86\x8d\xa4\x6d\x03\x9f\xe2\x3c\x73\xc1\x07\x1c\xa6\x14\x05\x15\x77\x8a\xec\x9e\xd9\x79\x6c\x04\x01\x8f\xb1\xa5\x8f\x91\xf0\x45\x56\x4b\xa7\x9f\x33\xdb\x8c\xb8\x02\x39\x72\xc8\x05\x11\x18\x8f\x9a\x73\xa6\x6d\x83\xfb\x59\xae\x49\x2c\xee\xf8\xd1\x4e\x5e\x57\x74\xb4\xde\xac\x05\x50\xdd\xfd\xba\x4e\xce\xb1\xdf\xfb\x30\x78\x99\x72\xa6\xcf\x09\xc9\xb9\x82\x96\xec\xbd\x33\xe1\xe8\xcf\x7f\x6a\x46\x23\x58\x0a\x22\xd7\x9f\x44\xfb\xbb\x9b\xb1\x68\x56\x15\x66\x59\x0a\x8a\x88\x7c\x49\x2d\x7e\xed\x1e\x5b\xbf\x43\x41\x05\x5c\x37\x9a\x1a\x76\xd7\x58\xbf\x96\xcb\x21\x94\x9d\xaf\x31\x4e\xfc\xec\xf2\xfa\xd7\xb7\x27\xff\x7d\xfe\x76\x48\xce\x69\x34\xab\xd6\xc4\xe0\x84\x22\xd1\x40\x42\x31\xa3\x73\x20\x94\xe4\x9c\xfd\x2b\x77\x0e\xdf\xc3\xe2\xd9\xa3\x4e\x6b\xb5\x37\xe4\xbe\xd8\x9d\xbf\xb3\x76\x70\xb6\xd7\xbf\x8d\xcb\x12\x0a\xb0\x81\xcb\xb2\xf8\x74\x6e\x2e\x59\xe5\x00\x45\x2d\x0c\x9c\x9f\xb2\xb9\x23\xc3\xae\xf8\x3d\x8d\x8b\x48\x31\x83\xe7\x06\x2d\x0c\xab\xa2\x63\x8c\xf0\x9a\x01\xe1\xa0\x0d\x5a\x17\x36\x26\xc1\x55\xad\x38\x49\xae\x40\xf5\xc9\x38\xc7\x98\xb4\x4c\xb2\x94\x4a\x96\x2c\xaa\x93\x19\x5e\x75\x59\xb8\xbc\x17\xcb\x4b\x3a\x7b\x7f\x7e\x8d\x39\x02\x99\xb4\x65\x4b\x30\xa8\x0c\xaf\xe3\x67\x8d\xc1\x3c\xe1\xda\x08\x0f\xc9\x09\x5f\xd8\x8b\xf6\x80\x33\x45\x12\xa6\x34\x20\x0b\x76\x32\xa4\x77\xa6\x1f\xbc\x1a\xe2\xff\x0e\xcc\x57\x4a\x23\x64\x16\xb1\x72\xd1\x4a\xf0\xaa\x15\x43\xd9\x38\xa9\x40\xd3\x7d\xfb\x8b\x6a\x08\x57\x06\x09\x19\x20\x56\x1a\xc2\xd1\x62\xab\x11\xbc\xb6\x41\x20\xe3\xd3\xa4\x8a\x55\xcd\xc8\x7e\x5b\xdd\xb2\xad\x66\x39\x28\xbf\x60\xd4\x54\xc1\xec\xa4\x31\x5d\xb9\x86\x8e\xda\x39\x95\xdc\xcf\xab\x53\x8e\x22\x88\x6a\x87\xde\x8b\x91\x3f\x01\x4e\xba\x49\x97\xda\xba\x66\x65\x4c\x52\x9f\xbc\x22\x7f\x23\xf7\xe4\x6f\xa8\x5e\xfd\xb9\x6d\xf3\xab\xb6\x8a\x4f\x17\x21\x46\x46\xab\xbf\x18\x75\x04\xf1\x1f\x0d\x75\x32\x33\x1a\xa8\x6a\x41\xc6\xcc\x89\xf3\x70\xaf\x41\x1a\x3a\xea\x76\xe2\x49\xdb\x86\x99\x05\x7e\x42\x34\xb3\xee\x86\x8b\x49\x3d\xac\x69\x37\x44\x33\x8f\x7f\x27\x94\xbe\x74\x54\xa8\xde\x00\xa7\x9c\x2d\xa5\x3a\x9a\xd5\xc9\x98\x11\xd4\x94\x2e\x0f\x98\x22\xb1\xc0\x28\x2b\x1b\xbe\x3c\x63\x2d\x82\x27\xf6\x07\x8d\xdb\xf9\xd3\x6b\xfb\xf9\xd0\x4e\x2d\x19\x50\x50\xf3\x71\x82\x55\xa5\x32\x56\x26\x62\x27\x93\x99\x65\xc5\x15\x9e\xf1\x80\x50\xe6\x6c\x35\x85\x95\x19\x71\xc9\x9c\xa7\x88\x72\x9b\x40\x32\x01\x29\x6d\xc4\xf9\x78\xe1\x83\xf5\x5a\x6f\x5e\xab\x93\x94\x49\xa1\x45\x24\x5a\x74\x36\xab\xfb\xb8\xdd\x74\x08\x04\x1b\xe5\xeb\xcd\xe4\x3f\x9c\x8d\xfa\xe4\xe6\x74\x84\xdd\x9e\xae\x4f\x6f\x46\x75\x4d\xe5\xe0\xe6\x74\x74\xf0\xa4\xa0\x20\x5e\xb2\x42\xc3\x74\x83\x49\x6a\x86\x27\x23\xb6\x0d\x52\x9a\x0d\x6e\x61\xd1\x90\xa7\x76\xc1\xd7\x07\xc5\x0e\x77\xf2\x41\x16\xcc\x29\xcd\x76\x9e\x4d\x02\x8d\xd9\x27\xca\xe2\xf2\x61\xb0\xc5\x3b\xd7\xa7\x73\xa5\x62\x0e\xb1\x15\x87\xfd\x13\xc0\xe3\x4c\x30\x23\x2f\x86\x1c\xaf\xdd\x9f\x0e\x39\x5e\x5b\x8f\x90\xe3\x15\x72\xbc\x56\xc7\xde\x04\xb2\x86\x1c\xaf\x97\xe5\xb7\x0f\x39\x5e\x9f\xb9\xeb\x3f\xe4\x78\xad\x1f\x21\xc7\x2b\xe4\x78\x6d\x37\x42\x8e\xd7\xee\x63\xef\x82\x96\x42\x8e\xd7\x4e\x23\xe4\x78\xad\x8e\x90\xe3\xb5\x61\x84\x1c\xaf\x0d\x23\xe4\x78\x85\x1c\xaf\x90\xe3\x15\x42\x5f\x1f\x9d\x6b\x3f\x43\x5f\x49\xc8\xf1\x72\x23\xe4\x78\xbd\x88\x00\x3f\x12\x72\xbc\xb6\x1a\x21\xc7\x2b\xe4\x78\x35\x19\x21\xc7\xeb\xa5\x98\x4b\x42\x8e\x57\xc8\xf1\xfa\x7c\x04\xdd\x90\xe3\x15\x72\xbc\x42\x8e\x57\xc8\xf1\x7a\x70\x15\x21\xc7\xeb\x25\xa8\x80\xbe\x0f\x70\xfb\x9c\xa5\xde\xa9\x48\xb3\x5c\x03\xb9\xf2\x53\x16\x52\xa4\x25\x0c\x4c\x55\x25\x82\xf6\x21\x84\x91\xe0\x13\x36\x75\x94\xfd\xd8\x36\xdf\x1d\x14\xdf\x33\xa8\x34\xbc\x7d\x86\xf1\x83\x09\x4b\x59\xb3\x44\x32\xb2\xb2\x31\x6f\x71\xae\x8a\x5f\xc6\x9c\xa4\x94\xde\xe3\x11\xa1\xa9\xc8\x6d\xc3\xe2\xc8\xed\x5f\x01\x42\xeb\xbd\xda\xbb\x9d\x21\xdd\xa8\x38\x65\x46\xdc\xa8\x8b\xb0\x12\xaa\x35\x48\xfe\x86\xfc\xcf\xe1\xcf\x5f\xfd\x36\x38\xfa\xfa\xf0\xf0\xa7\x57\x83\xbf\xfe\xf2\xd5\xe1\xcf\x43\xfc\xc7\xef\x8f\xbe\x3e\xfa\xcd\xff\xf1\xd5\xd1\xd1\xe1\xe1\x4f\xdf\xbf\xfb\xf6\x66\x74\xfe\x0b\x3b\xfa\xed\x27\x9e\xa7\xb7\xf6\xaf\xdf\x0e\x7f\x82\xf3\x5f\xb6\x9c\xe4\xe8\xe8\xeb\x2f\x1b\x2f\xb9\xb5\x48\xdc\x9d\x40\xdc\x91\x38\xfc\x51\x84\x61\xe7\xd0\xed\xe8\x2c\xba\x60\x94\x95\xd3\xe8\x18\xd6\x43\xa7\xd1\x53\x53\x14\xf3\x8a\x79\x98\x22\x22\x65\xda\x08\x87\x46\x1e\xa4\xd5\x70\x56\xa6\x6b\x4a\xa9\xa3\x03\x18\xd0\x4d\xb5\x6d\xaf\x5e\x84\x82\x56\x82\x58\x84\x97\xfc\x5c\xff\x79\x96\x66\x09\xb6\x35\xc7\xf3\x3c\xf0\xb1\x2c\xc8\x5c\x03\x6d\x78\x7c\x04\xda\xf0\x12\x69\x83\x82\x28\x97\x4c\x2f\x4e\x05\xd7\x70\xdf\xc8\xc2\x52\x27\x0d\xd7\xf5\x09\x5d\xcc\x98\xcb\xe2\x76\xd7\x88\xc8\x6c\xdc\xf7\x52\x3a\xfd\x4c\xe4\x49\x8c\xc9\x1c\x39\x47\x05\xd3\x66\xe9\x81\xb6\xda\x1f\xea\x3d\x18\xca\xbd\xfc\x12\xaf\xcf\x59\x35\xf3\x5f\x39\x9b\xd3\xc4\x68\xbb\xe5\x13\x23\xd4\x60\xaa\x0f\x6d\x7b\xe6\x35\x55\xb7\xe5\x81\x87\x81\x91\xa1\x8b\x35\x1f\xfb\x4f\xc2\x9f\xe0\x5e\x3f\x47\x29\x0d\x05\xa4\x91\x64\x73\x96\xc0\x14\xce\x55\x44\x13\xa4\x6b\xdd\xf0\x8a\x93\x0d\xb3\xe3\xc6\x4b\x91\x28\x72\x37\x03\x43\xab\x09\xf5\x26\x00\xcc\xb0\x9b\x52\xc6\x49\x6a\xb6\x28\xf3\x0f\x2b\x6b\x4b\x30\xe4\x3f\xa3\xd2\x6c\x70\x61\x33\x40\x15\x79\x2c\x44\xe2\x32\x1e\x92\x45\x39\xbf\xcb\xfd\xe1\xe2\x57\x0e\x77\xbf\x9a\xd9\x14\x99\x24\x74\x5a\x98\x0a\x14\xe8\x15\x6b\x5f\x39\xf5\xc6\x0f\xc0\x74\x82\x1c\x08\x4d\xee\xe8\x42\x95\x86\x93\x4a\xdd\x07\xf5\x86\xbc\x3e\x42\x74\xa6\x8a\x14\x73\xc4\xe4\x0f\x47\xe8\xfe\x3b\x3d\x19\xfd\x7a\xfd\xf7\xeb\x5f\x4f\xce\xde\x5d\x5c\x92\x4b\xa1\xc1\x32\xb5\x4a\x73\xc0\xa8\xd0\x30\xcc\x2a\xf1\x1d\xa8\xa5\x0b\x35\x44\xdb\x25\x53\xe4\x8e\xf1\x58\xdc\xa9\xc6\x36\x5a\x8b\x7e\x06\x78\x40\x79\xa3\x39\x22\x9a\x51\xec\x79\xd8\x82\xc3\xac\x44\x98\x54\x27\x45\x1e\x1e\xc7\xc7\xb1\x14\x99\x05\x82\x37\x72\x95\xac\xb6\xae\x46\x57\x63\x58\x71\x7f\x27\xf5\x09\xa7\x92\x72\x5d\x5a\x7b\xca\x3d\x73\xcd\x16\x87\xad\xb7\xe3\x79\x67\x34\xd1\xb8\xbb\x6c\xa6\x93\x38\x86\xb8\x06\xfe\x17\x17\x39\x78\xea\x3f\x6e\x51\x56\xa9\x20\xa3\xf7\xd7\x17\xff\x7b\x09\x8f\x17\x59\xbb\x40\xa9\x6e\x32\x63\xa5\xc8\x3a\xdb\xdd\x2b\x97\x79\x19\xf6\x77\x2f\xf6\xb7\xe0\x96\xdd\xb8\xe7\xaf\x72\x5e\x2f\x64\x54\xce\x4f\x52\x11\xc3\x90\x8c\x0a\x3f\x41\xfd\x6a\xa5\xc0\x01\x95\x40\xcc\x2d\x5c\x33\x9a\x24\x8b\xaa\x88\xa6\x85\xcd\x42\xac\xd5\x66\xa8\x12\xf2\x09\x4d\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x3e\xdc\xc9\x76\x14\xb3\x91\x18\xb8\xd0\x4e\xb0\x36\xab\xc4\x7a\x17\x52\x44\xc4\x2a\xdf\x95\x60\xac\x1a\x7f\x53\xd6\x57\xe1\x59\x23\x53\x1e\xd8\xa3\x62\x66\x6b\xa8\xce\x15\x2c\x0b\xe8\xbe\x0f\x71\xa1\x8e\x9b\xd9\x25\xd0\x58\xf0\x64\x81\x91\x97\x36\x96\x22\xa5\xea\x16\x62\xfb\x83\x13\xcd\x0a\x4f\x85\x99\xb1\x78\xd5\x8d\x59\xb7\x77\x4b\xa0\x48\x66\x23\x3c\xd0\x9d\x01\xf1\x13\xef\x7a\x8b\x43\x68\x80\xf2\x9e\x27\x8b\x2b\x21\xf4\x37\x45\x1a\x6d\x27\x18\xf0\xa3\x93\x96\xeb\xa6\x68\x14\x27\x29\xbe\x77\x80\xbb\x81\x87\xaa\x9a\xc1\x7b\x56\xee\xf8\x73\x3f\x52\x32\xe7\x27\xea\x5b\x29\xf2\xc6\x4c\x6c\x45\xd8\xfc\xf6\xe2\x0c\x49\x51\xee\x5c\x95\x5c\xcb\x05\x96\x0e\x58\xad\xfa\x56\x28\x06\x3f\x38\x67\x6b\xf5\x4c\x94\x7e\x31\xf2\x8e\x2e\x08\x4d\x94\xf0\xb0\x64\x7c\xad\x16\xea\x54\x5c\x73\x79\x2c\xf4\x6c\x45\xb7\x35\x07\x6a\xf5\xb9\x7e\xc5\x73\x59\x96\xa1\x63\x7c\xe5\x71\x4d\x6f\x41\x91\x4c\x42\x04\x31\xf0\xe8\xa9\xb7\xfd\xa9\x1d\x7e\x88\x3a\x97\x82\x9b\x83\xd9\x09\xf2\x5c\x14\x9e\x5e\x07\xd2\x2a\xaa\xa0\xcf\xd8\x69\x7f\x14\x3d\xc7\x78\x2c\x73\x05\xd2\xba\xb9\x65\x0e\x76\x27\xbf\xcf\xc7\x90\x18\xc8\x1b\x95\xd4\x75\x8a\xb7\xe6\x0c\x96\xd2\x29\x10\xaa\x0b\x4c\xd3\x82\x00\x57\x86\x62\x5a\x03\xa8\x26\xb1\x80\x32\xfb\x9e\x2a\xf2\xc3\xc5\x19\x79\x45\x0e\xcd\xbb\x8e\x10\x7f\xb0\x91\xbc\x16\x36\xc8\x6d\x59\x47\x9d\xf8\x29\x70\x49\x88\xbc\x44\x48\x4b\x24\xfa\x84\x0b\xa2\xf2\x68\x56\xed\x5e\xef\xd5\x66\x17\x08\x89\xae\x95\xfd\xc4\xf5\xa7\xa5\x50\x3f\x28\x90\x9d\x11\xa8\x1f\x1a\x10\xa8\xaa\x18\x65\x70\xae\x0e\x3d\x8b\x58\x29\x68\x1a\x53\x4d\x1d\xe1\xf2\x37\xec\xed\x96\x7e\xde\xe4\x4b\xc1\x5b\xc6\xf3\x7b\x1b\x78\xd4\x9d\xa9\xe5\xfa\x1c\xa7\x25\x91\x87\x3a\xee\x3a\xcd\xb2\x84\xd9\x6a\x1b\x4b\x81\x70\x17\x35\x5c\xe9\x6f\x10\x13\x91\x4e\xd0\x24\x11\x86\x3e\x1a\xe1\x84\xf2\x58\xa4\x2b\x2f\x33\x42\x24\xd4\xea\xa5\x0e\x49\xc0\xbe\xfa\xd8\x13\xa3\x50\x02\x73\x68\x51\x5b\x6c\xb9\x3e\xac\x99\xcd\x00\xc7\x63\x04\x4e\x4f\x12\x3a\x86\xc4\xc2\xd8\x62\xa0\x5a\xc5\xc0\xa7\x8e\x46\x95\x22\xe9\x2e\x7d\xe6\x4a\x24\x60\xc3\xbb\x3c\x20\xcc\xf4\xcf\x02\x0e\x38\x49\x57\x70\x40\x6d\xb0\x06\x07\xd4\x6b\x9f\x03\x1c\xf2\x16\xac\x9e\x2c\xc3\xc1\xc8\x0d\x75\x38\x20\xf3\xde\x77\x38\x28\x88\x22\x91\x66\x23\x29\x8c\xda\xd9\x19\x6f\x72\xd3\x96\x3e\x43\x6b\xd8\x58\x13\x8c\x85\xbc\xa0\x7e\x33\x95\x95\xc0\x4e\xaa\x2d\x93\xf0\xd1\x9d\xff\xab\xc2\xb3\x90\xf4\x2c\x33\x32\x3f\x4b\xcd\xbd\x68\x9e\x74\x17\x9e\x33\x3b\xe8\x22\x37\xa2\x85\xb1\xb3\x13\x6e\x24\x22\x9a\x60\xed\xd8\x76\x28\x47\x96\xd1\x6e\x79\xe2\x4a\x38\x2f\xfa\x28\xf1\x37\x1f\x40\x82\x65\x44\xf1\x17\x67\xc2\xe4\x22\x86\x8a\x2f\xdb\xc6\x21\xdf\xd8\xb0\x4f\xbc\xcf\x47\x12\x1b\xb9\xc2\xbb\x95\xe3\xda\xd3\x5a\xb8\x0a\x68\xef\x8a\x8a\xb4\x66\x81\xc0\x63\xc6\xa7\x68\x57\xeb\x13\x09\x89\x8d\x41\x76\x44\xe0\xd6\x6a\x90\x3d\x3c\x12\x7e\x52\x7f\x1e\xfc\xab\x51\x16\x63\x82\xbb\x99\xd1\x52\xe4\x25\xac\x89\x25\xb7\x4c\x91\x83\xb7\x1e\x00\x2d\x4a\x78\xee\x23\x87\x39\xb0\x5f\x58\xec\xa6\xb5\x74\xde\x32\x1e\xbb\x70\xdd\x1a\xb0\x8a\x62\xeb\x56\x0e\xc6\x40\x70\x16\x57\x69\xcb\x1b\xf2\x33\x27\x05\xb0\xc8\xa0\x31\x7a\x5c\x59\x91\xd9\xdb\xe8\x06\x0f\x1b\x5e\x8b\x97\x2c\x4f\xf3\x03\xc7\xbd\x37\xef\x1d\x18\xcd\x7d\xf5\x3e\xff\x2d\x4f\x5a\xba\xc7\x51\xbf\xae\xb5\x98\x1f\xed\xb4\x5e\xa4\x8f\x0c\x5a\x6b\xc6\xa7\xaa\xaa\xc9\xd0\x24\xa9\x19\xc3\xd7\xa9\x32\x7e\x87\x8b\xd2\xfa\xab\x2a\xc4\x52\x9a\xc1\x73\x51\x43\x12\x23\x4e\x3c\x73\x25\x64\x9a\x2a\x7a\x2a\x0d\x24\x34\xa3\xc9\x75\xd6\xbc\x44\x29\x59\x29\x87\xf7\xee\xfa\xa4\x3e\x35\x32\x6b\xec\xfc\x60\xf6\xca\x5c\x27\x34\x4e\x99\x52\x68\x08\x83\xf1\x4c\x88\x5b\x72\xb8\xa6\x1e\x57\x25\x4e\x4b\xb1\xa9\x3a\x76\x38\x3f\x30\xab\x3f\x22\x8c\x27\x45\x54\x14\xea\xc1\x5c\x2b\x6f\xc8\xc1\x97\x44\xc5\x2a\x70\x0f\x5d\xdd\x6a\x17\xac\xb0\xba\x4c\x5b\xa9\xda\x60\xc1\x93\x13\xec\xd5\xed\xb9\x6c\x59\x76\xe5\x91\x2d\xba\x74\xb8\xbd\x5c\x59\x6d\x2d\x1c\xad\xf4\xf8\xe4\x40\x72\xc2\x45\x04\xaa\xbb\x82\x4e\xdf\x95\x73\x92\x18\x6c\x16\x0f\x60\xf4\x13\xdd\x18\x64\x87\x76\xe9\x1e\x26\x83\xba\x47\x7b\x55\x89\xfa\xa6\x24\x2e\x46\x1f\x49\xb2\x19\x1d\x58\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x09\x2e\x5c\x92\x84\x61\xa2\x82\x23\x4a\x23\x89\xb2\xde\x3c\xdc\x13\x47\xa2\x2b\x4b\x3d\x2d\xbd\xc4\x55\x47\x20\x26\x93\xd9\xfa\x11\xe5\x1a\xee\x98\x9e\xf9\x4e\x2f\x35\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\xbf\x7a\xaa\xea\xa8\x2e\x4b\xc1\x63\xbc\xa2\xc1\x26\x98\x4c\x20\x42\x41\xab\x0a\x60\x4b\xb5\x0f\xcb\xc2\xb7\x2e\xcb\xc0\x20\x98\x2b\x25\x9f\xb2\x7b\xf3\x96\xea\x53\x55\x97\xb8\x2b\x38\xbb\xfe\xf2\xd1\x90\x90\x0b\x5e\x44\xf0\xf6\xcd\x2e\x56\xef\xf4\xa1\x67\xda\x7c\x62\xb5\x0f\x01\x7e\x40\xd5\x70\x66\xa4\x43\x99\x77\x80\xf1\x6d\xcc\xe1\xa4\x6a\x12\xef\x94\x1c\xa0\x69\xdc\x4d\x6a\xb6\xde\xcb\x00\x6d\x4c\xe5\xe6\x96\x8f\x65\x2e\x7f\x1e\x0e\x10\xd2\x96\xce\xb9\x6a\x0a\x1d\x15\x87\xbf\xae\xcc\x56\x91\xde\x0b\x87\xdb\x48\xc4\xb6\x9a\x4a\x51\x0d\x02\x7b\x3a\x61\x75\x17\xf6\x6f\x2f\x9f\x95\x32\x1e\x17\x36\x3b\xa0\x5a\x66\xc5\x95\xd4\x8e\x89\x11\xb5\x13\x6f\x5b\x48\xb3\x04\x30\x8b\xb3\x32\x73\x99\xa0\x5a\xa9\x26\xdf\x2f\x16\x52\x16\xa4\x77\xc5\x5d\xfa\xe4\x9f\x78\x28\x8b\x40\x54\x5f\x77\x62\x54\x3c\x6e\x35\x44\xa6\x7c\x6b\x09\xcc\xb0\xd4\xc2\x9b\x2e\x48\xcc\x26\x13\xf0\x01\xaf\x46\x73\xa4\x92\xa6\x86\xc4\x2b\xe2\x40\x30\x86\x29\xb3\x01\x91\x05\x61\xeb\x19\x71\xcf\xe5\xfa\xf5\x2d\x31\x64\x9a\xa4\x6c\x3a\xb3\x88\x42\x28\x66\xe8\x12\xef\x54\x4c\x04\x8d\x09\xe2\xb6\x90\xe4\x8e\xca\xd4\xf0\x0d\x1a\xcd\xd0\x43\x49\x39\x89\x73\x89\x55\x96\x35\xd0\x78\x31\x50\x9a\x6a\x23\x29\x83\x74\x0a\xa5\x5f\x7f\x28\xa9\xff\xe0\x08\x25\xf5\xb7\x1c\xa1\xa4\x7e\x28\xa9\xbf\x3a\xf6\x26\x3a\x34\x94\xd4\x7f\x59\x65\x92\x42\x49\xfd\xa7\xf6\x26\x84\x92\xfa\xa1\xa4\xfe\x43\x23\x94\xd4\x7f\x64\x84\x92\xfa\x0d\xc6\x0b\xa0\x5c\xa1\xa4\x7e\x83\x11\x4a\xea\xaf\x1f\xa1\xa4\xfe\xea\x08\x25\xf5\x37\x8e\x50\x52\xbf\xf1\x08\x25\xf5\x43\x49\xfd\x50\x69\x74\xb7\xb9\xf6\xb3\xd2\x28\x09\x25\xf5\xdd\x08\x25\xf5\x5f\x44\x3d\x45\x12\x4a\xea\x6f\x35\x42\x49\xfd\x50\x52\xbf\xc9\x08\x25\xf5\x5f\x8a\xb9\x24\x94\xd4\x0f\x25\xf5\x3f\x1f\x41\x37\x94\xd4\x0f\x25\xf5\x43\x49\xfd\x50\x52\xff\xc1\x55\x84\x92\xfa\x2f\x41\x05\x54\x3a\x66\x8d\x2a\x80\x6e\x53\xac\xc8\x05\xa1\x57\x6a\x03\x8c\xf3\xc9\x04\x24\x52\x2e\x7c\xf3\x4a\xf0\x54\x59\x97\x71\xd9\xc9\x0a\xba\x8f\x75\x8f\x5c\xbe\xce\x86\xc7\x5d\x31\x02\xac\xd4\x59\x46\x8a\x9f\xbf\xff\x66\x4d\x65\xa4\xc6\x51\x85\x4d\x63\xa4\x71\xcd\xef\x79\x33\xff\xf8\x06\x80\xaf\xcb\x1f\x73\x70\x8f\x12\xa1\x5c\x84\x3b\x02\x2b\x9a\x51\xce\xc1\xeb\x7b\x4c\xa3\x1d\x65\x0c\xc0\x89\xc8\xc0\x79\xa7\x29\x51\x8c\x4f\x13\x20\x54\x6b\x1a\xcd\x86\xe6\x4d\xdc\x03\xbb\x8c\x46\x77\xbf\x28\x2d\x81\xa6\x3e\x2e\x3f\xa5\xcc\x4e\x45\x68\x24\x85\x52\x24\xcd\x13\xcd\xb2\x62\x32\xa2\x00\x13\x6a\x2c\xa3\x2a\x80\x81\x51\x71\x65\x08\x7b\xbf\x7c\x9b\x5b\x96\xa8\x96\xa6\x43\x6d\xb3\x8f\xf5\xc0\xd3\x4c\x2f\x8a\x38\x5e\x20\x13\x26\x95\x26\x51\xc2\x90\x5b\xe3\x1b\x6d\xee\x34\xce\xd7\xf7\xbc\x9a\xbb\x95\x2a\xb7\x54\x1e\xa3\xd8\x9a\x69\x65\xa3\x62\xcb\x09\xdd\x54\x31\x53\x4e\xcc\x57\x7d\x42\x7d\xdd\x34\x0b\x68\xbf\x52\x04\xb5\xe7\x2c\x76\x76\xf7\x53\x65\xba\x4a\xbd\xd8\x32\x6c\xb8\x44\x74\x4c\x71\xf0\xc8\xd9\xaf\x65\x73\x94\x02\x05\x46\xe9\xad\x1c\x03\xdc\x00\x0e\x73\x83\x03\x10\x81\xe1\xaf\x74\x03\xd6\x7f\x72\xa4\xaf\x30\xc5\x77\xa0\x14\x9d\xc2\xa8\xa1\xa3\x61\x93\x46\x86\xbe\x86\x72\x63\x10\x15\x12\x9b\x5d\x5b\xfc\x52\x46\x67\xd6\xc5\x20\x92\xda\x35\x15\xc2\xcf\x9d\x64\x5a\x03\x6e\x2a\x56\xd8\x43\x5f\xe5\x72\x02\x7e\x6f\x29\xc6\xf3\x9d\x9f\xa4\x7c\xd8\x10\x75\x1e\xdb\x88\xcb\x31\x90\xb1\x64\x30\x21\x13\x86\x61\x9c\x18\x58\xd9\xb7\x05\x97\xa8\xb5\x02\x28\x65\xf4\x5d\xc1\xbd\x2c\xeb\xd7\x35\x24\x3f\xba\x85\x69\x99\xf3\x88\x56\x6a\xd9\x62\x86\x29\x9b\x90\x29\x06\x66\x3a\x69\xf1\x4f\xaf\xfe\xfa\x67\x32\x5e\x18\x96\x86\x92\x95\x16\x9a\x26\xc5\x47\x26\xc0\xa7\x06\x56\xf6\x78\xd6\x73\x24\x0b\x08\x60\x37\x0f\xbb\xf0\xd7\x7f\xb8\x1d\xd7\x79\xec\x71\x0c\xf3\xe3\x0a\xfc\x06\x89\x98\xae\xeb\x8f\xd2\x3c\x64\xbb\xa1\x4a\xb4\x06\xcd\x44\xc2\xa2\x45\x6b\x44\xf3\x95\xbf\xc8\x4c\xdc\x59\x59\x7f\x0d\xf6\x94\xe9\x56\x99\xc8\xf2\xc4\x1a\x9d\xbf\x29\xb2\x8b\x73\x05\xab\x39\x80\x6b\xcf\x05\x9a\x49\xdd\x14\xcb\x75\xd3\x6d\x3c\xae\x7f\xa5\x70\xb9\x25\xce\x90\x57\x14\x00\x43\x45\xe8\x1b\x9a\x24\x63\x1a\xdd\xde\x88\xb7\x62\xaa\xde\xf3\x73\x29\x85\xac\xaf\x25\xa1\x86\x5a\xce\x72\x7e\x6b\x3b\x38\x14\x25\x12\xc4\xd4\x88\x56\x59\xae\x7d\x22\xc3\xba\x0f\xb6\xf9\xf2\x9e\x08\x7b\x35\xa8\x9c\x05\xee\x59\xa9\xeb\xb8\x54\x2d\x8b\x91\xd5\xf9\x55\x15\xd9\xfe\xf0\xea\x4f\x7f\xb1\xa8\x4b\x84\x24\x7f\x79\x85\x31\xdb\xaa\x6f\x0f\x31\xd2\x36\xc3\x28\x52\x9a\x24\x46\x6d\xa8\x22\xa5\x01\xf4\x3a\x24\xfc\xe4\x38\xa8\xdb\xa3\xdb\xd6\xa2\xd4\xcd\xcd\xdf\x51\x8e\x62\x5a\x41\x32\xe9\xdb\xac\xa4\x42\xad\xe9\x21\x63\xe8\x39\xea\x83\xa9\x61\x7b\x20\x00\xcd\x45\x92\xa7\x70\x06\x73\xd6\x45\x13\xa7\xda\x6c\x5e\xd5\x4f\x98\xc2\x04\xb0\x71\x22\xa2\x5b\x12\xbb\x8b\x95\xc8\x93\xe5\x4a\xe0\xcd\xa1\xd0\x34\x06\xa7\x45\xec\xcd\xc6\xef\xaf\x45\xdd\xa4\x34\xcb\x8a\x1c\x21\x49\xef\x6a\xc0\xc0\x33\x89\xe5\x0a\x5a\xd6\x93\x69\x6d\x66\x6e\x6b\x64\x1e\xb8\x2f\x32\x74\xb3\xf1\x14\x8d\xa3\x4e\xda\xdb\xa8\xcb\xd5\x37\x37\x4c\xd6\x10\xa2\x9c\xd0\x9f\x86\x0c\xff\x6d\xb3\x4a\x56\xb2\x22\x8b\xc4\xba\x02\x31\xac\x00\x60\xd0\x07\x49\x72\x73\x83\x6b\x07\xd6\xcd\x76\x21\x47\x35\xb8\xf0\xc2\xaa\x9c\x52\xed\x04\x42\x6f\xbe\xa6\x24\x03\xa9\x98\x32\x7c\xf9\x03\x1e\xa8\xd3\x84\xb2\xb4\x62\x02\x7c\x1a\x20\xd8\xc3\x8d\xe5\x93\xdb\x53\xca\x91\x88\xdd\x84\x48\x0a\x6d\xe9\xe8\x35\x62\x6d\x5d\xaa\xed\x90\xa1\x3e\x35\xa9\xfc\x50\x42\xb3\x4e\x29\xcd\x2f\x05\xa9\xb4\x77\xbd\x24\x02\x89\xdf\xf7\x5c\xe9\x63\xb1\xf8\x8e\xc8\x00\x12\x46\xb7\xb9\x75\x4a\x58\x53\x1e\xed\x41\xa9\x88\xf4\x4e\x0f\x1c\x12\xeb\x05\x37\x67\xc2\x3d\x4a\x7a\x6f\x7a\x4f\x4a\x24\x2d\x88\xa4\xc8\xe8\xb4\x55\x2f\x9f\x25\x48\x2d\x4f\x5b\x2d\x34\x61\xd4\x20\xbc\x5e\x94\x5d\xc3\xbb\x20\x2e\xeb\xe8\x60\x95\x24\xeb\x1d\xf5\x00\x76\x0a\x82\xcd\xc7\xbe\xa3\x0b\x42\xa5\xc8\x79\xec\xec\x4b\x85\x81\xef\xdd\xd2\x8b\x2f\x05\x07\x6f\x38\x5f\xae\x53\x81\x16\x7d\xc6\xc9\xeb\xe1\xeb\x57\x2f\x85\x53\xe1\x17\x2e\x71\xaa\xcb\x82\x53\x59\xfa\xf4\xa4\xdf\xea\x2b\xde\x77\xf4\xbd\xef\x9c\x89\xa5\x2c\x68\xcf\x7c\xb9\x6c\xfc\xe9\x4e\x32\x0d\x95\x1e\x7f\x87\xa8\xb8\x18\xfd\xb0\x52\x95\xe1\x68\x5d\x27\x89\x96\x40\x6a\x57\x06\x43\xe5\xe3\x8f\x48\xb7\x1c\x81\xc2\xe3\xb6\xce\xc2\xa5\x1e\x20\x61\x55\x40\x1d\x1c\x90\x43\x7b\x67\xcf\x26\x34\x1f\x3d\x29\x6a\x39\xa0\x9d\xdf\x67\x2d\x6a\x6c\x2e\xe5\xce\x67\x14\x6d\x70\x59\x87\x10\xfc\x6f\x98\xd1\x39\x60\x22\x37\x4b\xa8\x4c\xd0\xe7\x78\x6d\xd7\x4e\xc6\xb9\x26\xc0\xe7\x4c\x0a\x9e\x02\xd7\x64\x4e\x25\xc3\xaa\x38\x12\xb0\xb2\x83\xd1\x45\xbf\x3c\xfc\x70\x72\x85\x01\x0d\x47\xae\x24\x85\x5b\x65\xae\x7c\xf9\x9a\xea\x4a\x2a\xd3\x3d\xba\x7d\x7e\x1d\x06\x86\x48\x73\xfd\xba\xcc\x7b\xd2\x5c\xe7\xb6\x2d\xcb\x7d\x94\xe4\x8a\xcd\x9f\x8a\x92\xb8\x0c\xfb\x33\xd6\x68\x9f\x97\xb2\xfd\x4b\x40\xad\x24\xee\xa3\x69\x7d\x4d\x82\xde\x8a\xc3\xa4\xa7\x8a\xa4\xbd\xaa\x0f\xdc\x99\x9e\x5c\x2d\x0d\x1b\x3e\xe7\x2b\x2e\xae\x88\x10\x58\x37\xe6\x69\x8d\x50\x31\x57\xa7\xb8\xc2\xdd\xc0\x5a\x0f\x48\xae\xe5\xf1\x9d\x5d\x5e\x57\x8b\x90\x58\x75\x49\xc4\x43\x32\x2a\x7f\x2c\x2b\xd5\x60\xfd\xb4\x42\x89\x04\x39\x2d\x8b\x8a\x4f\x81\x83\x44\x21\xc1\x4c\x59\x6b\xab\x4a\xc6\x54\x59\x27\xcf\xd9\xe5\xb5\xb5\xd9\xee\x06\xb3\xc6\x62\x76\x73\x09\xd5\x70\x7c\x9b\xc6\xd0\x40\xb8\xad\xf7\x4c\x2b\x0c\x56\x06\x30\xa8\x94\xda\x89\xc9\xc5\x88\xd0\x38\x96\xe8\xf6\x71\xa2\x4f\xa5\x52\x65\xe1\x5b\xc0\xaa\x30\x54\x41\x75\x4d\x15\x70\x23\x89\x2b\x01\x4b\xce\xf2\x2c\x61\xd6\x8d\x50\x7d\xa0\xac\x66\x83\x4d\xbe\x76\x47\xda\x36\x6a\x5e\x63\x25\xaf\x05\x15\x12\x4d\x8b\x52\x3e\xb0\x7b\x12\x94\x48\xe6\x65\x41\xe1\xa5\x5d\x73\x27\x02\x4d\xe2\xc5\xae\xf9\x1a\x94\x5b\xed\x18\x70\x2d\xcd\xd1\x5c\xde\x2d\xec\x62\x9f\xe4\x78\x9a\x8a\x09\xd9\x1c\xd0\x3f\xee\xca\x6f\xba\x32\x6e\x65\x89\x63\xeb\x1b\xb6\x55\xa6\x81\x4a\x4f\xd1\x70\x55\x0d\x4f\x22\x79\x2a\x44\x58\x36\x76\x9c\x5d\x5e\x5b\x4a\x68\x3f\xbe\xe8\x4e\xbb\x6e\x97\x4a\xaa\xd6\x18\x03\x9f\xac\xca\x50\x1b\xcd\x63\xa9\xb9\x9f\x6b\xd7\xdd\x2a\x90\xa5\x85\xf8\xd7\x2a\xd9\xae\xc5\xdb\x15\x50\x19\xcd\x9a\xc0\xff\x01\x42\x60\x27\x25\xb1\xb0\x91\x00\x13\x21\x51\x25\x1e\x20\x79\x4f\x84\xb8\xcd\xb3\x6d\x28\xba\x9b\xc6\x36\x5c\xdb\x8a\x40\xd4\x9e\xf8\xac\x68\x7a\xcc\x55\x13\x7f\x6f\x5d\xf6\x01\x6d\x25\x1e\x9c\xa8\x4c\xa0\x10\xcb\x7a\xd3\x69\x92\x2b\x0d\xf2\x1b\x26\x95\x3e\xf0\xf5\xa2\x11\x83\xad\x4d\xa4\x57\xbd\xe1\x47\xa6\x67\xae\x74\x63\xaf\x5f\xbf\x64\xfe\x76\x13\xf7\x8c\x4e\xdb\xbb\x14\x1c\x7a\xc3\x65\xb1\xab\x20\xe5\x05\x59\xdb\xc8\x53\xdc\xd2\x15\x24\x36\x5e\x14\x2f\x54\x70\xe5\xc6\x95\xad\x34\x6f\xf0\xf4\x4f\x81\x26\x14\x4b\xc4\xe1\xdd\xb3\xb2\xcc\xa4\xad\x1b\x65\xeb\x64\x0a\x27\xe8\x2d\xaa\x20\xaa\x94\x92\xd2\x62\xf3\x67\x37\x91\xe7\x76\xc6\x00\x5b\x7e\xd4\xd5\x0b\x79\xcb\xf8\xed\x8e\xe8\x57\x8f\x2e\x39\x5f\x99\xad\x56\x4f\xdc\xfa\x68\x19\xb7\xc1\x77\x86\xc5\xd0\xb1\xc8\xb5\xaf\x49\xa2\x2a\x8a\x23\xe3\xff\xb4\x7b\x81\xf6\xf6\xcc\x56\xec\x5b\xa7\x23\xaa\xbe\x35\xfa\x78\x25\x50\x2d\xb8\xa6\x58\x5b\xf4\x4c\x44\xb7\x20\x49\x62\x96\x31\x24\x65\xe0\x4b\xad\x9a\xa5\xcc\x61\xc7\xa8\x8b\xa6\x96\x0e\xc8\x66\x90\x82\xa4\x49\x59\xd4\xb5\x05\xa8\xdf\x3a\xc2\x59\xcc\x5a\x8d\x49\xb1\x45\xd1\x5c\x19\x46\x73\x0e\xcf\xd7\xdd\x95\xd2\x85\xaf\x74\xcb\x38\x86\x1b\xdc\x33\x85\x66\xfd\x4c\xc4\xd5\xc4\xb3\x5c\x81\x1c\x14\x69\x81\x2e\xf7\x46\x15\x81\x38\x31\x8c\xf3\xe9\x94\xf1\xa9\xa3\xce\x48\xd3\x2b\xe5\xb6\x0b\x4d\x07\x23\xbd\x23\x09\xb6\xe0\x2c\x4a\x0f\x36\xbe\x8c\x55\xef\x4f\x45\x6c\x6f\x1f\x2f\xac\x36\xe8\x77\xb6\x0c\x90\xbe\xe0\x44\x48\x57\x1a\x81\xc6\x31\xae\x7d\xf5\x0b\xf1\x6a\xfd\xab\xfa\x45\x1c\x87\x8d\xec\x2e\x9e\xaa\x80\x45\xe5\x63\x23\xec\xe4\x32\x82\x75\xb6\xd3\x4a\x89\x5f\x3a\xa7\x2c\x41\x3b\x85\xe0\x24\xb2\xa7\xd8\xc5\x9a\x99\xd3\xcf\x7b\x18\x05\x87\xcd\x3a\xf1\x9d\xe7\xab\x18\xd0\xa2\x44\x55\x53\x3e\xd3\x88\xc7\xd4\xcb\x0b\x9d\xf0\x35\xdf\x62\x03\xc6\x35\xa4\x99\x90\x54\x2e\x96\x3d\xa6\x86\x26\x1a\x8c\x33\xfb\xb5\xb4\x31\x23\x11\x23\xdb\x58\x83\x67\x73\xdb\x38\x78\x0d\xaa\xad\x45\x69\x24\xba\x5c\x10\xbf\x81\x86\x3d\xa8\x68\x06\x71\x8e\xc1\xea\xd3\x9c\x62\x63\x73\x43\x34\x9c\x6d\x7d\xe1\xa2\x00\x2d\xee\x15\xf1\x85\x45\x56\xc2\x02\x63\x72\xb0\xe8\xa7\xf9\x05\x8b\x87\xda\x48\x44\xdb\xd7\x19\x7b\xbc\x16\x41\x89\x37\x65\xab\x09\xfc\x58\x98\xb3\x48\xfb\x87\x26\x9b\xf0\x34\xa2\x45\x3b\xd9\x91\x70\xc5\x06\x23\x30\xb4\x4f\xab\xf2\x53\x5c\x10\x0b\x96\x13\xfd\x99\x1b\x9e\xb4\x19\xf5\x4b\x3c\x7f\x04\xc3\x51\x8c\xaf\x6f\xc5\x03\xd4\xa2\x80\xd2\xba\x6f\x37\x6b\x5a\xca\x1b\x70\xb8\xdd\xf9\x39\xd9\xb5\x0e\x54\x0b\x7d\xa3\xb9\x33\xb1\x91\x13\xb0\x8d\x6a\x43\xe5\xb4\xbd\x1a\xd8\x3b\x91\xd3\x3c\xb5\xe5\xc9\xc5\x52\x85\x68\x8b\xdf\x68\xb2\x33\xdc\xf8\xf4\xdd\x59\x35\x3b\xa3\x1a\x76\xee\x73\x5b\x8c\x94\xd7\xd2\x94\xbb\x6c\xcb\xbd\x30\x7a\x67\x61\x20\x2e\xd9\x86\x53\x50\x9d\xb1\xb2\x78\x9b\x57\xd0\x19\xcf\x8c\xa0\x81\xe2\x51\x69\xae\xe4\xd1\x8c\xf2\x29\x5a\xf8\x45\x6e\xe6\xfb\xf2\x4b\x5c\x91\x84\x38\x8f\x5c\x4b\x0c\x1f\xda\xfd\xa5\x37\x6c\xba\xea\x44\xd8\x99\x4f\x45\x34\xf3\x6b\xae\x7e\x96\x95\x42\xde\x10\x36\x84\x21\x39\xf8\xb2\x72\xe9\xc0\xbe\x3d\x93\xc2\xbc\xc2\x45\x85\xe3\xaa\x12\xa6\xf1\xd0\x1d\x54\xef\x1e\x92\x73\xf3\x0e\x74\xf6\x14\x00\xac\x04\x2e\x8f\x4b\xf0\xf5\x89\x84\x29\x95\x71\x82\xc9\x84\x93\x42\xde\xb2\x29\x47\x0e\x60\x78\xd2\x31\x54\x90\x0b\xbd\xce\xf0\xba\x65\xc6\x87\xa6\xea\x56\x1d\x5b\x29\x6d\x10\x53\x4d\x07\xd8\x46\xc4\x12\xa8\x63\x6b\x39\x18\xb8\x02\xae\x03\xea\x70\x6a\x50\x6c\xeb\xf1\x17\x2e\x69\x6c\x40\x8b\xbb\x18\x1f\xd0\x01\x96\x52\x6d\x1e\x06\xfb\x04\x11\x13\xad\x94\xf8\x16\x75\x7c\x97\x25\xef\xa2\x8e\x3b\xc2\x00\xbb\xa0\x94\x75\xbb\x8b\xe0\x0c\x57\xaa\xb6\x76\x90\xcf\x2f\x6f\xae\xfe\x3e\x7a\x7f\x71\x79\x13\xce\x73\x38\xcf\xe1\x3c\xb7\x38\xcf\xc0\xe7\xad\xcf\x72\xa1\xda\xad\xd3\x76\x97\xea\xe6\x55\x92\xc5\x5f\x50\xdc\xd9\x39\x9f\x7f\xa0\x46\xb8\xcc\x24\x28\x94\x45\x8c\x8c\xba\xce\x41\xec\x6e\xb0\x8d\xc4\x4e\x9f\x7d\xe0\xd9\x13\x86\x8d\x75\x18\x8e\x73\x59\xa9\x71\xb0\x6e\xd7\xaa\x9d\xfb\x4e\x7f\xbd\x38\x3b\xbf\xbc\xb9\xf8\xe6\xe2\xfc\xea\x49\xe3\x28\x5a\xd6\xad\xab\x73\xe3\x86\x5c\x32\x93\x30\x67\x22\x57\xc9\xa2\x28\x7d\xbb\x9e\x08\xac\x86\xe2\x71\xa3\x0a\x2e\x8a\xea\xbe\x6b\x1f\x0b\xcc\xb6\x5b\x66\x5b\x0f\x2b\x69\x51\xb2\xa4\x2b\xf4\xfd\x46\x8a\xb4\x23\x14\xbe\xb6\xe6\x01\x6f\xcd\x5f\x87\x4f\x3d\x57\xdd\xa0\xc6\x7a\x9c\xf0\x58\x96\x52\x30\x52\x68\x9a\xe9\x16\x7d\x0d\x3a\xa9\x54\xda\x4d\x51\x4f\x1b\x82\xf1\x8e\x66\xdf\xc3\xe2\x0a\x5a\x56\x46\x59\xf2\xa2\x24\x10\x19\x46\x47\x6e\x61\x61\x9d\xab\xa7\xfe\x65\x6d\x2a\xb8\xec\x65\xa1\xd7\x5b\x68\x53\x84\xb7\xcb\x0a\xad\xb7\xd0\x22\x26\xd3\x8f\x95\x5a\xa5\x66\x0b\x51\x4e\x33\x7b\xda\x6e\xf7\x48\xb7\xd5\x59\x3f\x42\x45\xda\x5e\x95\xdd\x3b\x3a\xab\x77\x2e\x1c\x21\xe6\x86\x73\xc1\xdd\xb1\x8b\x47\x1b\x18\x8d\x75\x60\xb1\x56\x1d\x63\xd0\xcd\xf1\x17\xf8\x1f\x72\xf3\xfe\xec\xfd\x1b\x72\x12\xc7\x2e\x2e\x3a\x57\x30\xc9\x13\x6b\xa5\x57\x43\x42\x33\xf6\x01\xa4\xc2\xc6\x70\xb7\x8c\xc7\x7d\x92\xb3\xf8\xeb\x36\xf5\xa4\xec\xe8\x70\x17\x84\xf7\x45\x75\xbb\x13\xd7\xce\xd5\x58\xe5\x5d\x05\x11\x21\x36\xe9\x11\x71\xd3\x97\x96\x71\x42\x46\x47\xa0\x69\xdb\x03\x8f\xd8\x2d\xec\x96\xae\xf6\x4a\xc2\x6a\xdd\x38\x45\xed\xad\xf8\x0d\x51\x39\xd6\xc0\x51\x45\xe3\x3a\x6c\x05\xdb\xaf\xff\xa9\x32\x1a\x41\x9f\xfc\xa3\xf8\x11\x5b\xcd\xab\x9f\x7a\xbd\xbf\x7d\x7f\xfe\xf7\xff\xea\xf5\x7e\xf9\x47\xf5\x2a\xb2\x42\xd4\x9a\x97\x6e\x41\xd7\x15\x17\x31\x5c\xe2\x3b\xf0\x4f\x27\xae\x9d\x44\x91\xc8\xb9\x76\x17\x30\x61\x79\x38\x13\x4a\x5f\x8c\x8a\x3f\x33\x11\x2f\xff\xa5\x5a\x15\x49\xdb\x4b\xc6\x80\x5b\xd4\x22\xf1\xc6\x8e\xee\xd8\x43\x49\x4b\x3a\x3e\xaa\x6e\xd6\xa2\x29\x47\x34\x83\xd4\x96\x69\xfa\xc6\x83\x00\x9b\xeb\xfa\xca\x08\x1c\xd3\xc9\x8d\x64\x5a\xaf\x98\x77\x30\x7f\xdd\xaa\x0b\xb9\x1d\x1d\x92\xb6\x62\x07\x3b\x06\x18\x42\xc4\x41\xcb\x1e\xe4\x82\xc1\x7a\x2d\xa5\x74\x34\x9f\x8c\x2e\xc8\xdc\x42\x78\x6f\x80\xe3\x3d\x6e\xdf\x7c\x54\x1a\x57\xf5\xeb\xd5\x34\xc4\x37\xb6\x17\xad\xbf\xee\x4a\x08\xa8\xa2\xaa\x17\x18\xc5\xe6\xd0\xfe\x38\x8c\xb2\xbc\xef\x6e\x18\xa6\x90\x0a\xb9\x28\xfe\x2c\xfc\x89\x03\xa5\x85\xa4\x53\x4c\x39\xb1\x8f\xdb\xc7\x8a\xbf\xec\x83\xb5\x17\xac\x3e\x6d\x55\xe1\x28\x97\x46\x68\x48\x16\x9e\x22\x37\x2c\x85\x51\x8e\x3d\xa4\x6d\x1e\xf4\x7b\x42\xda\x0a\xcc\x68\xdb\x71\xd6\x8e\x3a\x42\x96\x41\x01\x28\x70\x16\x50\x44\x7d\xd2\xa5\xd4\xf6\x0b\x31\xc8\x5a\x03\xf8\xdc\x68\x96\x8d\x8b\x82\x95\xa3\x43\x6a\x16\xb3\x39\x53\xa2\x45\x62\x4d\x31\xd1\xe6\x6c\x01\x57\xd5\xc3\xc6\x44\x15\x66\xb3\xfb\x0c\xeb\x20\x15\xe7\x75\x89\xec\xbf\x6e\xd3\x0a\xc9\x8e\x8c\x6a\x0d\x92\xbf\x21\xff\x73\xf8\xf3\x57\xbf\x0d\x8e\xbe\x3e\x3c\xfc\xe9\xd5\xe0\xaf\xbf\x7c\x75\xf8\xf3\x10\xff\xf1\xfb\xa3\xaf\x8f\x7e\xf3\x7f\x7c\x75\x74\x74\x78\xf8\xd3\xf7\xef\xbe\xbd\x19\x9d\xff\xc2\x8e\x7e\xfb\x89\xe7\xe9\xad\xfd\xeb\xb7\xc3\x9f\xe0\xfc\x97\x2d\x27\x39\x3a\xfa\xfa\xcb\xd6\x4b\xef\xa0\x2c\xa9\x1d\x5d\x16\x27\xad\xcf\xd8\x09\xfa\x7d\xc4\x8a\xfc\x76\x78\xf4\xea\xfa\xfc\xfb\xc0\xe8\x37\x25\x43\x2a\xd8\xf5\xde\x1c\x70\x05\x91\x04\xfd\x29\x2c\x39\xf6\x4d\x95\xe2\x08\x3d\x45\x0a\xd5\xe2\xa5\xf1\xb9\xcf\xc1\xb8\x53\xf4\xd2\xc3\x7d\x2d\x25\xd1\x89\x14\xa9\x4f\x78\x47\xf7\x06\x36\xd8\xf7\xf7\xdd\x42\xab\xee\xae\x76\x04\x63\x50\x30\x06\x6d\x18\x8f\x1a\x83\xae\x2d\x1e\xee\xad\x25\x08\xf8\xbc\xa9\x0b\x63\xad\x07\xdd\xeb\x3a\xd5\xea\x70\xdb\x39\xd4\x86\xfe\xa8\x97\x4d\x28\xcb\x10\x1a\xcb\xd0\xd2\xf5\x3e\x4c\x72\x82\xcd\xa6\xed\xc1\xc7\x09\xca\x8c\x12\xab\xda\xb8\xe2\x85\x30\x37\x4b\x28\xaa\x5f\xd7\xea\x5c\x62\x50\x25\x86\xb9\xfe\x68\xa3\x4e\x6f\x6d\x20\xaa\x51\xd2\x18\x2f\x2b\x84\x16\xc2\x61\x59\x56\x9a\x2a\x25\x22\x1b\x40\x5b\xe4\x37\x60\xd1\x3a\xb7\x6c\x5c\x0d\x76\xb8\xcf\x24\x44\x10\x03\x8f\xc0\x95\x9c\xae\x35\xdc\xa4\x9c\x9c\xf3\xb9\x2f\xbb\x1d\xfb\x6c\x19\x5c\xc9\xfa\x39\x5e\x56\x00\x82\x41\x44\xe7\x04\xab\xc4\x21\x20\xd5\x2f\x23\x67\x31\x14\x43\x4c\x4a\x2b\x6b\xb3\x9e\x7c\xad\xb9\x78\x7b\x9e\x59\x78\xb6\x5a\x09\x43\x2b\xcc\xb2\x34\x3f\xd7\x99\xe4\x4b\x70\x06\xb6\x67\x9f\x9f\x1d\xeb\xec\x88\x6d\x76\xc3\x32\x77\xf0\x9d\x74\xc9\x26\xbb\x70\x96\x64\x12\x26\xec\xbe\xa3\x73\x7a\xc2\x4b\x4b\x0c\x8b\x81\x6b\x36\x61\x36\x7b\x26\x93\x90\x01\xb7\x19\x09\x34\x9a\x21\xed\x77\x9c\xb2\x74\x4e\xef\x63\x30\x8f\x15\xb8\xbb\x25\x65\xd7\xeb\x84\xfd\x40\xc7\x48\xa0\x63\x8d\xc7\x27\xa2\x63\x0e\x73\xf7\x87\x88\x61\xe4\x79\xfb\x98\xf7\xd3\x7a\x19\x19\x44\xe4\x9d\x11\xad\x4c\x71\x3a\xc6\x59\x1a\x19\xa0\x5b\xe1\x03\xbe\x76\x94\x27\x49\x47\xa5\xb7\x7b\x17\x08\x8d\x2c\x4f\x12\x97\x71\x3c\x24\xef\x39\x1e\xc9\x13\x6c\xf1\xd0\x27\x97\x30\x07\xd9\x27\x17\x93\x4b\xa1\x47\x56\xb6\xad\x87\xb3\xd9\x1b\x09\x9b\x90\x37\x46\x6b\x52\x9a\x68\x5b\x66\xbf\x52\x14\x48\xc8\xda\x04\x65\xbd\xb1\x16\x61\xe8\x9b\xb7\xe5\x0b\x9f\x0b\x3a\x78\xa2\x6d\x2a\xfa\x98\x74\xa0\x9e\xba\x99\x7c\x80\x1c\x06\x45\x3a\xef\xc8\xba\x84\xde\x67\x58\x63\x23\x13\x4a\x5f\x1b\x2d\xb6\x9b\x1e\x37\x23\x3f\x1d\xb6\x8d\xa0\x49\x02\x71\xad\xc9\x91\x6d\xce\x41\xeb\x5a\x34\xa6\x1a\x17\xbd\x22\x80\xcc\x28\x8f\x13\x90\x58\xef\x5d\x2d\x17\xb5\x62\x65\x83\x83\xa2\x25\x85\x4f\x06\xa5\x51\x24\x64\xec\x9a\xcb\xba\xa4\x4c\x5c\x4c\x71\xbc\x90\xd6\xa6\x94\xd3\x29\xa0\x65\x61\xa5\x6a\x30\xd6\x92\x56\x95\xbe\x16\x33\x21\x6e\x49\x24\xd2\x2c\xc1\x03\xd0\xe2\x7c\x94\x6d\x75\x0a\x14\x1d\x98\xd9\xd5\x71\xa5\xe3\x0e\xfe\xd0\xae\xe1\x4e\x2b\x61\xa5\x0b\x51\x05\xee\x21\xea\xac\x25\xdf\xf9\x3d\x44\x95\x9e\x92\x66\x4b\x5c\x53\x49\x2d\xd0\xb6\xd1\xbe\x55\x70\x6b\xb3\x7c\x57\xa6\xf0\x16\x59\x66\xd5\xb1\x54\x43\x0e\xe7\xf4\x25\xb3\xdd\x2b\xb0\xfb\x80\xcd\x60\xc6\xcc\x33\x5f\x45\xbb\x76\x18\xec\xd1\x5b\x29\x3c\x57\x04\x1b\xfb\xb9\x30\xcf\x5a\x08\x4d\x0e\x7b\xc7\xbd\xa3\x15\x1b\xdd\x52\xdd\xe5\x9b\xca\x93\x0c\x0b\x0d\x66\x58\xb5\x0f\xa2\x5e\xdc\x27\x4c\x7b\x62\x6b\xeb\x1d\xe0\xaa\x5c\x3a\x5c\x9f\x28\x41\xb4\xa4\x31\x73\x5a\x10\xfe\x6a\x6e\xd2\x32\x77\xc5\x0e\x0e\x7b\xbf\xf5\xfa\x04\x74\x74\x44\xee\x04\xef\x69\x5c\x3e\x56\x06\xc9\x55\x65\xa2\x85\xc8\xb1\x01\x9f\x05\x41\x51\xe6\xc3\x50\x2c\x22\x72\xdb\xad\x67\x46\xb5\x4f\xc3\x3b\xbf\x67\xda\x77\xa8\x10\x13\xf2\xca\x36\x0b\x02\xea\xac\x84\x09\x9b\xc3\xf1\x0c\x68\xa2\x67\x36\x90\x82\x0b\x3e\xb0\xfd\xde\x0c\x29\x71\x57\xda\xfa\x14\xda\x99\xdc\xaa\xa3\x85\xf9\x6d\x75\x41\x2d\xa5\x6b\x43\x44\xbf\x6d\xde\x84\x96\xac\xf4\x67\xbe\xb9\x19\x7d\x5b\x6b\x43\x8b\x54\x5c\xeb\xcc\x87\xb7\x54\x4a\x66\xec\x01\xed\xe8\xc6\xa1\xd7\xaa\x1f\x2d\xe9\x90\x84\xb5\xed\x4b\x4b\x56\xfb\x6d\xef\xd6\x90\x96\xfc\x5d\xe4\xd8\x48\x8f\x8e\x93\x05\xb9\xa3\x5c\xfb\x54\xbc\x03\x33\xd5\x81\x21\x4f\x06\x1b\xbe\x03\x1a\x83\x54\x48\x3d\x80\x36\x2e\x0d\xe6\x47\x67\x8e\xa6\xca\xda\xba\xe5\x03\xb9\xd2\x22\x25\x33\xf7\xd9\xf5\xf4\x44\x77\x32\x86\x78\x7a\x7c\xee\x8f\x84\xcc\x52\x38\xf7\xcc\x8b\xa3\x5f\x2b\x74\xc3\xc2\xbd\x56\x42\x3f\xaa\x82\xad\xda\x68\x85\x71\x0b\x2c\xdb\x22\xb1\x23\x5a\xda\x41\x80\x00\xe9\x30\x48\x80\xb4\x4b\x76\x5c\x9e\x08\x1d\x5f\xed\xe3\xa1\x3a\x8b\x3b\x20\x9d\xf9\xd6\xc9\x3a\x43\xa4\xc3\x19\x1b\x05\xdb\x11\x10\x3b\xf5\x68\x93\xf6\xe9\x94\xd5\xf1\x30\x00\xba\xd9\x7c\xd2\x25\x04\xb2\x0e\xc2\x9f\x57\x83\x9f\x57\x1a\x85\x23\x99\xb0\xa5\x68\xf7\x86\xcb\xb4\xed\x9a\x4e\xd6\xe7\x12\x4b\xc2\x8b\x26\xb7\xfa\x59\x74\x4e\x27\xdd\x85\x29\x76\x1d\xa4\xd8\x69\x88\xe2\x47\x0d\x50\xc4\xb4\x88\xd6\x54\xa4\x6e\x1f\xc7\x29\x0d\x06\x18\xbd\xcd\x68\x9c\x4e\xf6\x73\xd6\x1d\xdf\x88\xa3\x6e\x0e\x35\x47\x6d\x2f\xce\x98\x8e\xb2\x6b\x11\xdd\x76\xa8\xd7\x9c\x41\x26\x21\xb2\x76\xb2\x9b\xd3\x91\x9d\xdd\xe8\x97\x97\xef\x6f\xca\x70\x7c\x8c\x59\x29\x0d\x97\xdf\x39\x4b\x9a\xd1\x49\x6f\x21\xd3\x85\xea\x3e\xa6\xd1\xed\x1d\x95\x31\x5a\xb6\xa8\x66\x63\x96\x30\xbd\x40\xe5\x5c\x02\xc6\xfa\x73\x61\x83\xe2\x6c\xfd\x47\xe1\xbb\xb8\x16\x2d\xc6\x0b\x1b\x16\x5a\xc8\x5c\xf4\xcc\x84\x32\xa3\x8f\x17\xad\x7a\x6d\xd4\x4c\x94\x15\x26\xbd\xaa\x65\x3a\x28\x5f\x7e\xec\xad\xf2\x55\x69\x43\xbb\xab\x1e\xd6\x36\x76\x6f\x8f\x59\x9d\x63\x71\xb2\xe8\xb2\x16\x58\x5d\x47\xf3\xed\x2f\xab\xcb\x24\x5c\x6b\x91\x75\xe4\x25\xb1\x93\x6d\xf0\x91\x8c\x61\x22\x0c\x11\xde\xe8\xf4\x88\x73\x70\xa5\x39\x4f\x46\x17\x85\x55\x4b\xd4\x1c\x1b\x36\x6a\xd1\xd7\xe3\x4c\xd8\x1c\x38\x28\x75\x8c\xee\x90\x3c\xb3\x5a\xab\x6f\xa8\xdb\x37\x5f\x07\x29\xae\xae\x5f\x66\x02\xb8\x76\xbe\xf8\x23\xe8\xc8\x5a\x6e\x2b\x84\x1c\x3b\x85\xb9\xe5\x2f\xbb\x51\x22\x49\xd5\xcc\xb6\xba\x85\x7b\xa6\x5d\xbb\xe6\x91\x2d\x0f\x5c\xed\xb8\x3b\x95\x34\x02\x92\x81\x64\xc2\x30\xa3\x9c\xeb\x58\xdc\x71\x32\x86\x29\xe3\xca\x83\x02\x2b\x6e\x3a\x98\xa1\x3f\x86\xa9\xa2\x64\xda\x90\x5c\xd5\x0a\x82\xb8\x54\x9d\x48\x94\x47\xd3\xad\x79\xd9\x93\x84\x1c\x0b\xe1\x64\x1b\xc7\x14\x10\xae\xf6\xd2\x79\x6c\xc9\x87\x39\xc7\x37\xc7\x90\xd0\x85\x8d\xc8\xc4\x36\xd8\xec\xdf\x20\xd5\x51\x07\x1e\x27\xdb\x0d\xca\x5f\xdb\xb8\x0e\x2c\x75\x4a\xa3\x59\x3b\x17\x6e\x70\x51\x6d\x39\x82\x8b\xaa\xcd\x24\xc1\x45\x15\x5c\x54\x8f\x8c\xe0\xa2\x0a\x2e\xaa\xa5\xb1\xb7\x5a\x52\x70\x51\x35\x1e\xc1\x45\xf5\xf0\x08\x2e\xaa\x2d\x46\x70\x51\x6d\x39\x82\x8b\x2a\xb8\xa8\x82\x8b\x2a\xb8\xa8\x3e\x23\xbb\x9d\x1f\xc1\x45\xb5\x32\x49\x70\x51\x05\x17\xd5\xd6\x63\x6f\x95\xaf\xe0\xa2\xb2\x23\xb8\xa8\xea\xe3\xf3\x62\x75\xde\xc1\x33\x32\xaa\x5e\xfb\x1e\xc3\xa8\x30\x3a\x1a\xfb\x22\xd3\x9e\xda\xd8\xff\x3f\x8d\xed\x7f\x4f\x1c\x25\x1d\xd8\xfb\x83\xad\xff\xc5\xd9\xfa\xbb\xb1\x93\x75\x60\x23\x6b\x4d\x93\x9d\x0b\xfc\x66\x26\x41\xcd\x44\xd2\x18\xd1\x6b\x48\xfe\x8e\x71\x96\xe6\xa9\xc1\x39\x65\xf0\x99\xcd\x0b\x5f\xbb\x2a\x1b\x2f\xa3\x0b\xde\x9a\xeb\xcc\x8d\x2c\x06\xac\xbc\x49\x59\x62\xb6\x11\x13\x25\x67\x74\x6e\x70\x5d\xe5\x51\x04\x80\x7d\xbd\xaa\xaa\xc4\x1f\x87\xc5\x9b\x8a\x3e\x0e\xaf\xdb\xd1\x9b\x76\xdc\xd2\xd6\xc6\xc4\x59\xfe\xf8\x87\x46\x73\x4c\x65\xd6\x0d\x5d\xfe\xf6\x6a\x74\x5a\xa1\xcb\x94\x7b\xb2\xcc\xf8\x5c\x24\x73\xdb\xd8\x16\x6f\x32\x52\xd1\x70\xa5\x25\x66\xa1\x44\x38\xf9\x5b\xd9\x0e\xcc\xe6\x39\xf3\x54\x91\xd2\x3e\xb2\x81\x14\x8d\xbb\xc3\x96\xa3\x03\x82\xdf\x5e\x57\x68\xa5\x27\x74\xc1\x6f\xda\x8a\xc2\x75\x39\xc6\x08\xbc\x75\x73\xcf\x14\xf1\xc2\x96\x73\xdf\x5a\xe0\x6d\x4d\x29\xdb\x0b\xa1\xed\x8f\x16\xc1\x7a\x2b\xf8\xe1\x9d\x01\xf8\xc0\xb5\x10\xf7\xec\xbc\xaa\x6d\xf8\x16\x47\x5a\x90\x2c\xa1\x65\x93\x22\xdc\x81\xef\x90\x07\x9d\xce\x20\xba\xbd\x72\x2e\xcf\x43\x05\x50\xc4\xab\x4c\x99\x9e\xe5\xe3\x61\x24\xd2\x63\x43\x12\xec\xff\x8d\x13\x31\x3e\x4e\xa9\xd2\x20\x8f\x63\x11\x39\x16\x37\x88\xcc\x2c\x8c\x4f\x87\x69\x7c\x84\xed\x6d\x2f\xea\x4d\x11\x2b\xa5\x10\xcc\xfb\x9d\x32\x48\xc6\x60\xa8\xab\x40\x85\xbf\x52\x4f\xcd\x2c\x6f\xe7\xc6\xb5\xd5\xd1\x9a\x25\xb5\x74\x37\x7f\x7a\x57\x73\xa0\x5c\xa4\x03\xcb\xc6\x73\x73\x29\x77\x16\x5a\xd1\x81\x2b\x79\x8f\xdc\xc8\x7b\x23\x1a\xef\x8b\xeb\x78\x0f\x4b\x1f\x77\xe0\xe9\xec\xc2\x55\xdc\x9d\x9b\xf8\x23\x54\x08\xfe\x38\xee\xe1\x0e\x6d\x68\x1d\xb9\x85\x3f\x85\x4b\xb8\x93\xaf\x6e\xeb\x0a\xfe\x74\x6e\xe0\x6e\x3e\xb7\x4b\x45\xe0\xb9\xba\x7e\x3b\xb0\x85\x77\x69\x07\xef\xcc\x06\xfe\xd1\x5c\xbd\xed\xdd\xbc\x7b\xe0\xe2\x6d\x0d\x64\xc6\x99\x66\x34\x39\x83\x84\x2e\xae\x21\x12\x3c\x6e\xcc\x61\x96\x4a\x46\x16\xe7\x47\xd9\x69\x9d\x9d\xaa\x9e\xd1\x30\xa3\xae\x32\xb6\xd1\xa8\x6c\x06\x87\xf7\x4f\x38\x81\x02\x5d\x0b\x76\x95\x4d\x8a\xce\xdd\x09\x79\x9b\x08\x1a\xab\xe3\x4c\xd8\xff\x2b\xf3\x15\x2a\x89\x0a\xf6\x5d\xed\x32\x15\x9e\xda\x20\x66\xd3\x3b\xba\xdc\xc4\xef\xc4\x1d\x11\x13\x0d\x9c\x1c\x32\xee\xf7\xf1\xa8\xa2\x06\x96\xd6\xc9\x02\xad\xcd\xd5\xd7\xaf\xfc\xcd\x2f\xcf\xec\x88\x06\x56\xa5\x3e\xbe\x15\xd8\xbd\xe8\x71\x33\xb0\xbb\x71\x92\x27\x75\x53\xb0\x35\x0f\xd7\xe9\xcd\xeb\xb2\xb6\xef\x6b\x9c\xb7\x38\x6d\x94\xc7\xc4\xa5\x7c\xbd\xbc\x4d\x6b\x1d\xc0\x52\x17\xfd\x8a\x80\x95\xc7\xac\xc6\x37\xa7\x23\x6b\x34\x0e\xe6\x92\x7d\x31\x97\x3c\x51\x10\xc8\x1e\x0a\xba\xcf\x34\xf0\x23\x08\xba\x3b\x8c\x4a\x12\xe8\xb7\x92\x46\x30\xea\x5c\x46\xf0\xc7\x89\xc4\xb9\xa4\x8e\x00\x16\x22\x9f\x3f\x3c\x1c\x20\xb6\xa7\xa9\x48\x9c\xc5\x94\xd4\x49\x9e\x24\x0b\x92\x67\x82\xd7\xd3\x8c\xad\xaf\x7d\x39\x6b\x15\x4d\xf2\x6b\xde\x52\x0a\x96\x99\x14\x8e\x67\xca\x9c\x73\x43\x83\xcb\x06\x5d\x28\x48\x62\x55\x63\x5a\xcb\x8d\x55\x6c\x6a\x96\x6f\xf8\x1f\xa6\xcd\x96\x91\x7e\xb5\x09\xcd\xd3\x13\x21\x23\x36\x4e\x16\x64\x46\x93\xa2\x1b\x0b\x25\xb7\x2c\x49\xdc\x34\x43\x72\x0d\xda\xba\x14\x2c\xef\x4c\x04\x9f\xe2\xe2\x28\xf7\x5d\x00\x21\x32\xcf\x46\x09\x50\x9e\x67\xf6\x7d\x86\x13\x2f\x44\x2e\xfd\xfb\x86\x85\x63\xa2\xec\xba\xcf\x92\x7e\xa5\xd7\xd8\x83\x1b\x5b\xf4\xa7\xc9\x95\x11\x00\xde\xfb\x2a\xce\xfd\xea\x9c\x62\x0e\x52\xb2\xd8\xd9\xf9\xed\x6f\x99\x14\x73\x16\x5b\xef\x86\x07\x1b\x76\x35\xb6\xdd\x64\x8a\xf3\xcc\x05\x1f\x70\x98\x52\x14\x54\xdc\x29\xb2\x7b\x66\xe7\xb1\x11\x04\x3c\xc6\xfe\x32\x46\xc2\x17\x59\x2d\x6f\x7d\xce\x6c\x67\xdc\x0a\xe4\xc8\x21\x17\x44\x60\xe0\x67\xce\x99\xb6\xdd\xd6\x67\xb9\x26\xb1\xb8\xe3\x47\x3b\x79\x5d\xd1\xd1\x7a\xb3\x16\x40\x75\xf7\xeb\x3a\x39\xc7\x7e\xef\xc3\xe0\x65\xca\x99\x3e\x27\x24\xe7\x0a\x5a\xb2\xf7\xce\x84\xa3\x3f\xff\xa9\x19\x8d\x60\x29\x88\x5c\x7f\x12\xed\xef\x6e\xc6\xa2\x59\x55\x98\x65\x29\x28\x22\xf2\x25\xb5\xf8\xb5\x7b\x6c\xfd\x0e\x05\x15\x70\xdd\x68\x6a\xd8\x5d\x63\xfd\x72\x0d\x4b\x57\xe3\xf7\x2a\x0d\x99\x31\x34\xfb\xec\xf2\xfa\xd7\xb7\x27\xff\x7d\xfe\xd6\x9d\x4f\x5e\x65\xfa\x39\x67\xff\xca\x81\xd0\x54\x18\x59\x38\xa9\x86\x01\xf6\x51\xa3\xaf\xfc\x80\x27\xb9\xdb\x80\xc1\x86\x0c\x19\xbb\xc7\xb7\x0f\x8b\xc4\x1e\xf4\x1f\x3f\x2a\xf2\xa9\xbb\x6a\x95\xc1\x2d\x46\x6e\xac\x74\xd5\xa2\x84\x83\x36\x27\xcf\x4a\x94\xb6\xcb\x1a\xe3\xd3\xa4\x2a\x4c\x36\x23\x57\x6d\x75\xa2\xb6\x1a\xd1\xa0\xfc\x82\x51\x53\xc5\xa8\x93\xee\x5e\xe5\x1a\x3a\xea\x89\x53\x52\x6d\xaf\x06\xd8\xa6\xc5\x5e\x0d\xb0\xa2\xc7\xc5\x88\xd0\x38\x96\x28\xa6\xe0\xa9\x4f\x97\x7a\x63\x66\x65\x2c\x4d\x9f\xbc\x22\x7f\x23\xf7\xe4\x6f\xa8\x16\xfc\xb9\x6d\x07\xa1\xb6\x02\x7b\x17\xa1\x31\x46\x1b\xbd\x18\x75\x04\xf1\x1f\x67\x54\xe3\x8c\x06\xaa\x5a\x90\x31\x73\x62\x28\xdc\x6b\x90\x46\x2c\x72\x3b\xf1\xa4\xbd\x97\xcc\x02\x3f\x21\x9a\x59\x33\xf9\xc5\xa4\x1e\x8e\xb3\x1b\xa2\x99\xc7\x8d\x7e\x7f\xe9\xa8\x50\xbd\xcf\x49\x39\x5b\x4a\x75\x34\xab\x93\x31\x23\x60\xa8\x1a\x73\x8a\x05\x92\x71\x1b\x76\x3b\x63\x2d\x9c\xfe\xfb\x83\xc6\xed\xfc\xc0\xb5\xfd\x7c\x68\xa7\x96\x14\x7f\xe4\xf3\x4e\x30\xa8\x94\x4e\xca\x44\x3c\x24\xe7\x34\x9a\xe1\xb2\xe2\x0a\xcf\x30\x1a\x08\x4e\x36\xa3\x73\xb3\xf1\xee\x59\xdb\x17\x08\xa5\x95\xc2\x3a\x8a\xb8\x64\xce\x53\x44\xb9\x6d\xce\x39\x01\x29\x6d\xa4\xf4\x78\xe1\x83\xcc\x5a\x6f\x5e\xab\x93\x94\x49\xa1\x45\x24\x5a\xb4\x87\x5a\xce\xbe\xc0\xe9\x10\x08\x36\x3a\xd5\x9b\x77\x7f\x38\x1b\xf5\xc9\xcd\xe9\x08\x9b\xfa\x5c\x9f\xde\x8c\xea\x12\xf6\xc1\xcd\xe9\xe8\xe0\x49\x41\x41\xbc\x99\x0d\x0d\xaa\x0d\x26\xa9\x19\x4c\x12\xa6\xf4\x20\xa5\xd9\xe0\x16\x16\x0d\x79\x6a\x17\x7c\x7d\x50\xec\x70\x27\x1f\x64\xc1\x9c\xd2\x6c\xe7\xd9\x24\xd0\x98\x85\x34\x9f\xed\x47\x48\xf3\xd9\x72\x84\x34\x9f\x90\xe6\xb3\x3a\xf6\x26\x96\x31\xa4\xf9\xbc\x2c\xd7\x6d\x48\xf3\xf9\xcc\xbd\xbf\x21\xcd\x67\xfd\x08\x69\x3e\x21\xcd\x67\xbb\x11\xd2\x7c\x76\x1f\x7b\x17\xb7\x12\xd2\x7c\x76\x1a\x21\xcd\x67\x75\x84\x34\x9f\x0d\x23\xa4\xf9\x6c\x18\x21\xcd\x27\xa4\xf9\x84\x34\x9f\x10\xfd\xf8\xe8\x5c\xfb\x19\xfd\x48\x42\x9a\x8f\x1b\x21\xcd\xe7\x45\xc4\x78\x91\x90\xe6\xb3\xd5\x08\x69\x3e\x21\xcd\xa7\xc9\x08\x69\x3e\x2f\xc5\x5c\x12\xd2\x7c\x42\x9a\xcf\xe7\x23\xe8\x86\x34\x9f\x90\xe6\x13\xd2\x7c\x42\x9a\xcf\x83\xab\x08\x69\x3e\x2f\x41\x05\xf4\x3d\x57\xdb\xe7\xa8\x5c\xf9\x99\xb6\x0f\xeb\x23\xe7\x6b\x7e\x45\x4b\x88\xca\xcc\x24\xb2\x9c\x32\x91\x40\xe3\x05\x4e\x89\x7d\x1e\x2a\x42\xd6\x33\x8c\x0e\x4c\x58\xca\x9a\xa5\x05\x91\x95\x43\xf3\x16\xe7\xaa\x78\x5d\x0c\x58\x52\x7a\x8f\x07\x80\xa6\x22\xb7\xad\x5f\x23\x91\x66\xb9\xae\xc3\x14\xb7\xa7\x49\xd7\xd6\x09\x9b\x3a\x8e\x7a\x6c\x1b\xcc\x0e\x8a\x69\x07\x95\xa6\xae\x4f\xd8\xaa\x95\xc6\x3e\x6a\x6e\xd4\x45\xd0\x08\xd5\x1a\x24\x7f\x43\xfe\xe7\xf0\xe7\xaf\x7e\x1b\x1c\x7d\x7d\x78\xf8\xd3\xab\xc1\x5f\x7f\xf9\xea\xf0\xe7\x21\xfe\xe3\xf7\x47\x5f\x1f\xfd\xe6\xff\xf8\xea\xe8\xe8\xf0\xf0\xa7\xef\xdf\x7d\x7b\x33\x3a\xff\x85\x1d\xfd\xf6\x13\xcf\xd3\x5b\xfb\xd7\x6f\x87\x3f\xc1\xf9\x2f\x5b\x4e\x72\x74\xf4\xf5\x97\x8d\x97\xdc\x5a\xe0\xed\x4e\xdc\xed\x48\xd8\xfd\x28\xa2\xae\x73\xd7\x76\x74\x16\x5d\xa8\xc9\xca\x69\x74\xec\xe8\xa1\xd3\xe8\x35\x6e\x14\xe2\x8a\x79\x98\x22\x22\x65\x5a\x3b\x2a\x4a\xab\xc1\xaa\x4c\xd7\x54\x4e\x47\x07\xb0\x21\x36\xd5\xb6\x51\x75\x11\xe8\x59\x09\x51\x11\x5e\xae\x73\x9d\xbc\x59\x9a\x25\xd8\x20\x1a\xcf\xf3\xc0\x47\xaa\x20\xeb\x0c\xb4\xe1\xf1\x11\x68\xc3\x4b\xa4\x0d\x0a\xa2\x5c\x32\xbd\x38\x15\x5c\xc3\x7d\x23\xfb\xc9\x26\x03\xd2\x75\x7d\x6a\x17\x1b\xa6\x5c\x4c\x9b\xbd\x46\x44\x66\xe3\xbb\x37\x66\x4e\xcf\x44\x9e\xc4\x98\x97\x94\x73\x54\x29\x6d\x8a\x1b\x68\xab\xef\xa1\xa6\x83\xc1\xdb\xcb\xaf\xf3\x1a\x9c\x9d\xfa\x5f\x39\x9b\xd3\xc4\xe8\xb7\xe5\x13\x23\xd4\x59\xaa\x0f\x35\x32\x62\x3d\xb1\x8c\x85\xe2\xcd\x48\xb2\x39\x4b\x60\x0a\xe7\x2a\xa2\x09\x52\xa5\x6e\x28\xfd\xc9\x86\xd9\x71\x8b\xa4\x48\x14\xb9\x9b\x01\x76\xe0\xa7\x5e\x3d\xc7\x44\xb2\x29\x65\x9c\xa4\x86\xa8\x66\xfe\x61\x65\xf5\x7c\x43\xbc\x8d\xd4\xcb\x75\xa9\xcf\xa3\xfa\x3a\x16\x22\x71\xd9\x08\xc9\xa2\x9c\x9f\x59\xd3\x1b\x17\xbf\x72\xb8\xfb\xd5\xcc\xa6\xc8\x24\xa1\xd3\x42\x8d\x57\xa0\x57\x2c\x71\xe5\xd4\x1b\x3f\x00\x43\xfd\x73\x20\x34\xb9\xa3\x0b\x55\x1a\x35\xca\x39\x98\x7a\x43\x5e\x1f\x21\xe2\x51\x45\x8a\x39\x62\xf2\x87\x23\x74\xcd\x9d\x9e\x8c\x7e\xbd\xfe\xfb\xf5\xaf\x27\x67\xef\x2e\x2e\xc9\xa5\xd0\x60\x59\x52\xa5\x49\x5a\x44\xb9\xd1\x10\xdc\x2a\xf1\x1d\xa8\x41\x0b\x35\x44\xbb\x22\x53\xe4\x8e\xf1\x58\xdc\xa9\xc6\xf6\x53\x8b\x7e\x06\x78\x40\x79\xa3\x39\x22\x9a\x51\xec\xfd\xd6\x82\x3f\xac\x44\x7f\x54\x27\x45\x0e\x1c\xc7\xc7\xb1\x14\x99\x05\x82\x37\x40\x55\x95\xa4\xb3\x25\xbb\xb2\x8f\x2f\xc5\xfd\x9d\xd4\x27\x9c\x4a\xca\x75\x69\x89\x29\xf7\xcc\x35\x9d\x1b\xb6\xde\x8e\xe7\x9d\x6d\x44\xe3\xee\x32\x8d\x4e\xe2\x18\xe2\x1a\xf8\x5f\x5c\x54\xdf\xa9\xff\xb8\x45\x59\x8c\x81\x8c\xde\x5f\x5f\xfc\xef\x25\x3c\x5e\x64\xed\x82\x98\xba\x49\x00\x95\x22\xeb\x6c\x77\xaf\x20\x15\xf3\xb0\xbf\xfb\xb2\xbf\x05\xb7\xec\xc6\x75\x7e\x95\xf3\x2a\x43\xe3\x95\xf9\x49\x2a\x62\x18\x92\x51\x61\xc3\xaf\x5f\xad\x16\x99\x91\x40\xcc\x2d\x5c\x33\x9a\x24\x8b\xaa\x30\xa5\x85\xcd\x10\xac\x95\x20\xa8\x12\xf2\x09\x4d\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x36\xdb\xc9\x76\x14\xb3\x91\x18\xb8\xd0\x4e\x18\x36\xab\xc4\xb2\x0e\x52\x44\xc4\xaa\xce\x95\x40\xa9\x1a\x7f\x53\xd6\x8f\xe0\x59\x23\x53\x1e\xd8\xa3\x62\x66\x6b\x44\xce\x15\xa8\xf5\xac\xb1\x54\xa6\xcd\xec\x12\x68\x2c\x78\xb2\xc0\xa8\x48\x1b\xe7\x90\x52\x75\x0b\xb1\xfd\xc1\x89\x66\x85\x17\xc1\xcc\x58\xbc\xea\xc6\xac\xdb\xbb\x0c\x50\x24\xb3\xd1\x17\xe8\x6a\x30\x1a\xfe\x93\xee\x7a\x8b\x43\x68\x80\xf2\x9e\x27\x8b\x2b\x21\xf4\x37\x45\x8a\x6b\x27\x18\xf0\xa3\x93\x96\x11\x20\xf5\x48\x2f\x8a\xef\x1d\xe0\x6e\xe0\xa1\xaa\x66\xd7\x9e\x95\x3b\xfe\xdc\x8f\x94\xcc\xf9\x89\xfa\x56\x8a\xbc\x31\x13\x5b\x11\x36\xbf\xbd\x38\x43\x52\x94\x3b\x37\x22\xd7\x72\x91\x09\x66\x6d\x50\x1b\x14\x83\x1f\x9c\x23\xb4\x7a\x26\x4a\x9f\x15\x79\x47\x17\x84\x26\x4a\x78\x58\x32\xbe\x4e\x5f\x24\x4e\x19\x35\x97\xc7\x42\xcf\x56\xb4\x50\x73\xa0\x56\x9f\xeb\x57\xbc\x8a\x65\x6d\x30\xc6\x57\x1e\xd7\xf4\x16\x14\xc9\x24\x44\x10\x03\x8f\x9e\x7a\xdb\x9f\xda\x19\x87\xa8\x73\x29\xb8\x39\x98\x9d\x20\xcf\x45\xe1\x85\x75\x20\xad\xa2\x0a\xfa\x73\x9d\xf6\x47\xd1\xab\x8b\xc7\x32\x57\x20\xad\x0b\x5a\xe6\x60\x77\xf2\xfb\x7c\x0c\x89\x81\xbc\x51\x49\x5d\xc7\x6c\x6b\x78\x60\x29\x9d\x02\xa1\xba\xc0\x34\x2d\x08\x70\x65\x28\xa6\x35\x5f\x6a\x12\x0b\x28\x33\xe3\xa9\x22\x3f\x5c\x9c\x91\x57\xe4\xd0\xbc\xeb\x08\xf1\x07\x1b\x6a\x6b\x61\x03\xd0\x96\x75\xd4\x89\x9f\x02\x97\x84\xc8\x4b\x84\xb4\x44\xa2\x4f\xb8\x20\x2a\x8f\x66\xd5\x2e\xde\x5e\x6d\x76\x41\x8a\xe8\x18\xd9\x4f\x5c\x7f\x5a\x0a\xf5\x83\x02\xd9\x19\x81\xfa\xa1\x01\x81\xaa\x8a\x51\x06\xe7\xea\xd0\xb3\x88\x95\x82\xa6\x31\xd5\xd4\x11\xae\xa2\xab\xfa\xbe\x6e\xe9\xe7\x4d\xbe\x14\xbc\x65\x3c\xbf\xb7\x26\xd2\xee\x4c\x2d\xd7\xe7\x38\x2d\xe2\x10\x42\x1d\x77\x9d\x66\x59\xc2\x4a\x07\x72\x25\x48\xed\xa2\x86\x2b\xfd\x0d\x62\x22\xd2\x09\xef\x87\x36\xc2\x09\xe5\xb1\x48\x57\x5e\x86\x4e\x6f\x1a\xcd\xaa\x2f\x08\xd8\x57\x1f\x7b\x62\x14\x4a\x60\x0e\x2d\x4a\x68\x2d\x61\xde\x5b\x33\x9b\x01\x8e\xc7\x08\x9c\x9e\x24\x74\x0c\x89\x85\xb1\xc5\x40\xb5\x8a\x81\x4f\x1d\x29\x2a\x45\xd2\x5d\x6a\xcb\x95\x48\xc0\x86\x5e\x79\x40\x98\xe9\x9f\x05\x1c\x70\x92\xae\xe0\x80\xda\x60\x0d\x0e\xa8\xd7\x3e\x07\x38\xe4\x2d\x58\x3d\x59\x86\x83\x91\x1b\xea\x70\x40\xe6\xbd\xef\x70\x50\x10\x45\x22\xcd\x46\x52\x18\xb5\xb3\x33\xde\xe4\xa6\x2d\xfd\x7c\xd6\xb0\x81\x76\xfb\xaa\x06\xec\xbc\x7a\xf5\x9b\xa9\xac\x04\x5d\x52\x6d\x99\x84\x8f\xbc\xfc\x5f\x15\x9e\x85\xa4\x67\x99\x91\xf9\x59\x6a\x8e\x40\xf3\xa4\xbb\xf0\x9c\xd9\x41\x17\x79\x0b\x2d\x8c\x9d\x9d\x70\x23\x11\xd1\x04\x4b\xa4\xb6\x43\x39\xb2\x8c\x76\xcb\x13\x57\x42\x6d\xd1\x47\x89\xbf\xf9\xf0\x0f\xac\x96\x89\xbf\x38\x13\x26\x17\x31\x54\xbc\xce\x36\x46\xf8\xc6\x86\x64\xe2\x7d\x3e\xca\xd7\xc8\x15\x2e\x0a\x04\xe2\xda\xd3\x5a\xb8\xea\x64\xef\x8a\xc2\xab\x66\x81\xc0\x63\xc6\xa7\x68\x57\xeb\x13\x09\x89\x8d\x0f\x76\x44\xe0\xd6\x6a\x90\x3d\x3c\x12\x7e\x52\x7f\x1e\xfc\xab\x51\x16\x63\x82\xbb\x99\xd1\x52\xe4\x25\xac\x89\x25\xb7\x4c\x91\x83\xb7\x1e\x00\x2d\x2a\x55\xee\x23\x87\x39\xb0\x5f\x58\xec\xa6\xb5\x74\xde\x32\x1e\xbb\x50\xda\x1a\xb0\xbc\x9e\xeb\xe4\x60\x0c\xd2\x66\x71\x95\xb6\xbc\x21\x3f\x73\x52\x00\x8b\x0c\x1a\xa3\xc7\x95\x15\x99\xbd\x8d\x6e\xf0\xb0\xe1\xb5\x78\xc9\xf2\x34\x3f\x70\xdc\x7b\xf3\xde\x81\xd1\xdc\x57\xef\xf3\xdf\xf2\xa4\x65\x75\x1c\xf5\xeb\x5a\x8b\xf9\xd1\x4e\xeb\x45\xfa\xc8\xa0\xb5\x66\x7c\xaa\xaa\x9a\x4c\xbd\x1e\xfe\x7a\x55\xc6\xef\xf0\x44\x0a\x9b\x82\xb9\xaa\x42\x2c\xa5\x00\x3c\x17\x35\x24\x31\xe2\xc4\x33\x57\x42\xa6\xa9\xa2\xa7\xd2\x40\x42\x33\x9a\x5c\x67\xcd\xcb\x87\x92\x95\x52\x75\xef\xae\x4f\xea\x53\x23\xb3\x9e\x81\xb4\xbc\xdf\x5c\x27\x34\x4e\x99\x52\x68\x08\x83\xf1\x4c\x88\x5b\x72\xb8\xa6\x56\x56\x25\xca\x4a\xb1\xa9\x3a\x76\x38\x3f\x30\xab\x3f\x22\x8c\x27\x45\x24\x13\xea\xc1\x5c\x2b\x6f\xc8\xc1\x97\x44\xc5\x2a\x70\x0f\x5d\x79\x66\x17\xac\xb0\xba\x4c\x5b\x90\xd9\x60\xc1\x93\x13\xec\xd5\xed\xb9\x6c\x59\x12\xe5\x91\x2d\xba\x74\xb8\xbd\x5c\xf5\x6c\x2d\x1c\xad\xf4\xf8\xe4\x40\x72\xc2\x45\x04\xaa\xbb\x62\x4b\xdf\x95\x73\x92\x18\x6c\x86\x0d\x60\xf4\x13\xdd\x18\x0e\x87\x76\xe9\x1e\x26\x6a\xba\x47\x7b\x55\x89\xfa\xa6\x24\x2e\x46\x1f\x49\xb2\x19\x1d\x58\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x09\x2e\xa4\x45\x51\xc3\x44\x05\x47\x94\x46\x12\x65\xbd\x79\xb8\x27\x8e\x44\x57\x96\x7a\x5a\x7a\x89\xab\x8e\x40\x4c\xf4\xb2\xb5\x1d\xca\x35\xdc\x31\x3d\xc3\x1a\xac\xb3\x25\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\xbf\x7a\xaa\xea\xa8\x2e\x2b\x9e\x63\x8c\xa1\xc1\x26\x98\x4c\x20\x42\x41\xab\x0a\x60\x4b\xb5\x0f\xcb\xa2\xb4\x3e\x85\x43\x0b\x5f\x31\x3d\x65\xf7\xe6\x2d\xd5\xa7\x96\xfa\xae\x70\xc1\x07\xeb\x2f\x1f\x0d\x09\xb9\xe0\x45\xfc\x6d\xdf\xec\x62\xf5\x4e\x1f\x7a\xa6\xcd\x27\x56\xcb\xed\xe3\x07\x54\x0d\x67\x46\x3a\x94\x79\x07\x18\xdf\xc6\x1c\x4e\xaa\x26\xf1\x4e\xc9\x01\x9a\xc6\xdd\xa4\x66\xeb\xbd\x0c\xd0\xc6\x54\x6e\x6e\xf9\x58\xe6\xf2\xe7\xe1\x00\x21\x6d\xe9\x9c\xab\x74\x10\x6a\xa0\x6f\x37\x42\x0d\xf4\x2d\x47\xa8\x81\x1e\x6a\xa0\xaf\x8e\xbd\x09\x19\x0c\x35\xd0\x5f\x56\x5d\x9b\x50\x03\xfd\xa9\x4d\xcc\xa1\x06\x7a\xa8\x81\xfe\xd0\x08\x35\xd0\x1f\x19\xa1\x06\x7a\x83\xf1\x02\x28\x57\xa8\x81\xde\x60\x84\x1a\xe8\xeb\x47\xa8\x81\xbe\x3a\x42\x0d\xf4\x8d\x23\xd4\x40\x6f\x3c\x42\x0d\xf4\x50\x03\x3d\x94\x86\xdc\x6d\xae\xfd\x2c\x0d\x49\x42\x0d\x74\x37\x42\x0d\xf4\x17\x51\x00\x8f\x84\x1a\xe8\x5b\x8d\x50\x03\x3d\xd4\x40\x6f\x32\x42\x0d\xf4\x97\x62\x2e\x09\x35\xd0\x43\x0d\xf4\xcf\x47\xd0\x0d\x35\xd0\x43\x0d\xf4\x50\x03\x3d\xd4\x40\x7f\x70\x15\xa1\x06\xfa\x4b\x50\x01\x95\x8e\x59\xa3\xb2\x90\xdb\x54\xb0\x71\x91\xc9\x95\x84\xf1\x71\x3e\x99\x80\x44\xca\x85\x6f\x5e\x09\x9e\x2a\x8b\xf5\x2d\x3b\x59\x41\xf7\xb1\x18\x8e\x4b\xe2\xd8\xf0\xb8\xcb\x50\xc7\xf2\x8d\x65\xf8\xf0\xf9\xfb\x6f\xd6\x94\xcb\x69\x1c\x55\xd8\x34\x70\x16\xd7\xfc\x9e\x37\xf3\x8f\x6f\x00\xf8\xba\xa4\x22\x07\xf7\x28\x11\xca\x85\x3d\x23\xb0\xa2\x19\xe5\x1c\xbc\xbe\xc7\x34\xda\x51\xc6\x00\x9c\x88\x0c\x9c\x77\x9a\x12\xc5\xf8\x34\x01\x42\xb5\xa6\xd1\x6c\x68\xde\xc4\x3d\xb0\xcb\x10\x65\xf7\x8b\xd2\x12\x68\xea\x83\xb5\x53\xca\xec\x54\x84\x46\x52\x28\x45\xd2\x3c\xd1\x2c\x2b\x26\x23\x0a\x30\xcb\xc2\x32\xaa\x02\x18\x18\x15\x57\xc6\x35\xf7\xcb\xb7\xb9\x65\x89\x6a\xbd\x32\xd4\x36\xfb\x58\xe2\x39\xcd\xf4\x82\x98\x4f\x4e\x5c\xd9\x57\xa9\x34\x89\x12\x86\xdc\x1a\xdf\x68\x13\x6a\x71\xbe\xbe\xe7\xd5\xdc\xad\x54\xb9\xa5\xf2\x18\xc5\xd6\x4c\x2b\x82\x61\xc0\xe5\x84\x6e\xaa\x98\x29\x27\xe6\xab\x3e\xa1\xbe\x98\x96\x05\xb4\x5f\x29\x82\xda\x73\x16\x3b\xbb\xfb\xa9\x32\x5d\xa5\x88\xa8\xc1\x4d\x6b\xc0\x2a\x11\x1d\xe3\xde\x3d\x72\xf6\x6b\x21\xfe\xa5\x40\x81\x51\x7a\x2b\xc7\x00\x37\x80\xc3\xdc\xe0\x00\x44\x60\xf8\x2b\xdd\x80\xf5\x9f\x1c\xe9\x35\x95\x53\xd0\x45\x3c\x53\xd3\x58\xf1\x7a\x58\x48\xb5\xdc\x6f\x55\x11\x29\x41\x86\xd0\x19\x89\x18\x53\x7e\xca\xbc\xaa\x75\xf5\x84\xed\x0a\x5d\x19\xb5\x75\x37\x78\xc1\xc8\x86\x68\x16\x2f\x55\x19\x8d\x40\x91\xc3\x8b\xd1\x69\x9f\x8c\x2e\xce\x5c\x1c\xa6\x98\xac\xcb\x63\x76\x34\xcc\x62\xe0\xa6\xca\xc6\x45\x85\xb6\xca\xf4\x95\xdc\x4f\xf7\xee\x51\x21\x5f\xfd\xcc\x5d\x78\xe9\x32\x05\x40\x91\xab\xa8\x6e\x4e\x54\x8e\x22\x92\xb3\x09\xb1\x22\x31\xc3\x21\x1f\x94\xe9\x88\xbe\xee\x90\x7f\xa2\x58\x88\x83\x92\xcb\xba\xf0\xbe\x6e\x24\xb0\xc8\xaf\x57\x52\x3b\x30\x14\xd4\xc5\xbd\x34\x8a\x77\x69\xa5\x21\x55\x44\xb1\x77\xa0\x14\x9d\xc2\xa8\xa1\x7b\x6b\x93\x1d\x00\x3d\x5c\x25\x39\x40\x02\x94\xd8\x44\xdf\xe2\x97\x32\x26\xb8\x2e\x7c\x93\xd4\xae\xa9\xc0\xac\x3b\xc9\xb4\x06\x24\x25\x58\xec\x0f\x37\x7b\xb9\x16\x40\x6f\x29\xb2\xf8\x9d\x9f\xa4\x7c\xd8\x88\x12\x3c\xb6\x71\xbe\x63\x20\x63\xc9\x60\x42\x26\x0c\x83\x87\x31\x9c\xb7\x6f\x6b\x3f\x51\x6b\x7b\x52\x0a\x24\xae\xc7\x69\x50\x7e\x5d\x43\xf2\xa3\x5b\x98\x96\x39\xb7\x4d\x47\x9c\x70\x8f\xc9\xae\x6c\x42\xa6\x18\x0e\xec\x74\x94\x3f\xbd\xfa\xeb\x9f\xc9\x78\x61\x04\x29\x44\x48\x2d\x34\x4d\x8a\x8f\x4c\x80\x4f\x0d\xac\x2c\x53\xa8\xa7\x6b\x16\x10\xc0\xb6\x20\x76\xe1\xaf\xff\x70\x3b\xae\x4b\x76\xc7\x31\xcc\x8f\x2b\xf0\x1b\x24\x62\x3a\x24\xa7\x45\x76\x64\x9e\xc5\x68\xe7\x6f\x5e\xaa\xbb\x3b\x34\x13\x09\x8b\x16\xad\x11\xcd\x17\x21\x23\x33\x71\x67\x35\xcc\x35\xd8\x53\x66\x7e\x65\x22\xcb\x13\xeb\xea\xf8\xa6\x48\x74\xce\x15\xac\xa6\x23\xae\x3d\x17\x68\x9c\x77\x53\x2c\xd1\x51\x17\x05\xee\x5f\x29\x5c\x9a\x8b\x33\x1f\x17\xb5\xc8\x90\x98\x7c\x43\x93\x64\x4c\xa3\xdb\x1b\xf1\x56\x4c\xd5\x7b\x7e\x2e\xa5\x90\xf5\xb5\x24\xd4\xf0\xe8\x59\xce\x6f\x6d\x2b\x88\xa2\x5a\x83\x98\x1a\x81\x3e\xcb\xb5\x2f\xee\xbd\xee\x83\x6d\xea\xbe\x67\xfd\x5e\xf9\x2e\x67\x81\x7b\x56\x6a\xd8\x2e\x6b\xcc\x62\x64\x75\x7e\x55\x45\xb6\x3f\xbc\xfa\xd3\x5f\x2c\xea\x12\x21\xc9\x5f\x5e\x61\xa6\x80\xea\xdb\x43\x8c\x1c\xd5\x88\x27\x29\x4d\x12\x43\xc8\xab\x48\x69\x00\xbd\x0e\x09\x3f\x39\x0e\xea\xf6\xe8\xb6\xb5\x00\x7f\x73\xf3\x77\xe4\x22\x4c\x2b\x48\x26\x7d\x9b\x20\x55\x28\xd3\x3d\x14\x47\x7a\x8e\xfa\x60\x96\xda\x1e\x88\xdd\x73\x91\xe4\x29\x9c\xc1\x9c\x75\xd1\xeb\xa9\x36\x9b\x37\x30\x25\x4c\x21\x1f\x1c\x27\x22\xba\x25\xb1\xbb\x58\x89\x77\x5a\x2e\x4a\xde\x1c\x0a\x4d\x23\xbf\x5a\x44\x7c\x6d\xfc\xfe\x5a\xac\x57\x4a\xb3\xcc\xc8\x00\x98\x87\x29\xe9\x5d\x0d\x18\x78\x26\xb1\x72\x42\xcb\xd2\x36\xad\x9d\x1b\x6d\x5d\x1b\x03\xf7\x45\x86\x6e\x36\x9e\xa2\x71\xac\x53\x7b\xcf\x48\xb9\xfa\xe6\xe6\xf0\x1a\x42\x94\x13\xfa\xd3\x90\xe1\xbf\x6d\x2e\xd3\x8a\x60\x5e\x14\xd5\x2c\x10\xc3\x0a\x00\x06\x7d\x90\x24\x37\x37\xf3\x77\x60\x53\x6f\x17\xe8\x56\x83\x0b\x2f\x7c\x19\x29\xd5\x4e\x20\xf4\xba\x0a\x25\x19\x48\xc5\x94\xe1\xcb\x1f\xf0\x40\x9d\x26\x94\xa5\x15\xc3\xf3\xd3\x00\xc1\x1e\x6e\xac\xe4\xdc\x9e\x52\x1a\x3d\xc5\x4e\x88\xa4\xd0\x56\xb1\x5e\x23\xd6\xd6\xa5\xda\xeb\x7c\x8c\xf8\x83\xb7\xef\xd2\x50\xaf\x43\x4e\xfc\xd4\x34\xf6\x43\xb9\x0d\x75\x12\x6b\x7e\x29\x68\xac\xbd\xeb\x25\x51\x56\xfc\xbe\xe7\x4a\x58\x8b\xc5\x77\x44\x3f\x90\xa2\xba\xcd\xad\x93\xd0\x9a\xd6\x69\x4f\x58\x45\x17\x70\x0a\xe4\x90\xd8\xa0\x0d\x73\x26\xdc\xa3\xa4\xf7\xa6\xf7\xa4\xd4\xd5\x82\x48\x8a\x8c\x4e\x5b\xf5\x23\x5a\x82\xd4\xf2\xb4\xd5\x62\x19\x46\x7f\xaa\x90\x92\xcc\xdd\x65\x28\x89\xaf\x05\x84\x95\x9e\xac\x33\xdf\x03\xd8\x69\x16\xd8\x2f\x8e\xdc\xd1\x05\xa1\x52\xe4\x3c\x76\xe6\xd0\xc2\x1e\xfd\x6e\xe9\xc5\x97\x82\x83\xf7\xf3\x2c\xd7\xda\x40\x07\x14\xe3\xe4\xf5\xf0\xf5\xab\x97\xc2\xe2\xf0\x0b\x97\x58\xdc\x65\xc1\xe2\x2c\x7d\x7a\xd2\x6f\xf5\x55\xfb\x3b\xfa\xde\x77\xce\x36\x53\x16\xe5\x67\xbe\xe4\x37\xfe\x74\x27\x99\x86\x4a\x97\xc1\x43\xd4\x78\x8c\x62\x59\xa9\x2c\x71\xb4\xae\x1b\x46\x4b\x20\xb5\x2b\xe5\xa1\xf2\xf1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x67\x1a\x53\x0f\x90\xb0\x2a\xa0\x0e\x0e\xc8\xa1\xbd\xb3\x67\xf3\xef\x8f\x9e\x14\xb5\x1c\xd0\xce\xef\xb3\x16\x75\x42\x97\x4a\x3d\x64\x14\x8d\x77\x59\x87\x10\xfc\x6f\x98\xd1\x39\x60\xdd\x01\x96\x50\x99\xa0\x8b\xfc\xda\xae\x9d\x8c\x73\x4d\x80\xcf\x99\x14\x1c\xed\xc4\x73\x2a\x19\x56\xf6\x91\x30\x01\x09\xdc\x28\xb1\x5f\x1e\x7e\x38\xb9\xc2\xf8\x9b\x23\xdb\xf5\xc5\xaf\x32\x57\xbe\x04\x4f\x75\x25\x95\xe9\x1e\xdd\x3e\xbf\x0e\x03\x43\xa4\xb9\x7e\x5d\xe6\x3d\x69\xae\x73\xdb\x5a\xe6\x3e\x4a\x72\xc5\xe6\x4f\x45\x49\x5c\x41\x88\x33\xd6\x68\x9f\x97\x8a\x53\x94\x80\x5a\xa9\x33\x51\xba\x09\x1e\x29\xc3\xdd\x53\x45\x8e\x69\x35\x64\xc3\xd9\xac\x48\xca\xa6\x33\xed\xa2\x3d\x97\x3c\x07\x15\x17\x54\x8a\x66\xde\xa7\xb4\x5e\x19\xb6\x7b\x92\x30\xaa\x76\x15\xb9\x56\x12\x19\xdd\x2c\x18\xe8\xc1\x5d\xad\x3f\x9a\x14\x46\x19\xf3\x22\x6b\xa9\xbc\x18\x39\x0f\x9a\x87\x1b\xe3\xff\xb4\x81\x35\x85\x5a\x62\x03\x65\xec\x23\xd6\xdc\x38\x21\x95\xa2\x40\x3e\xa0\x04\x89\x3f\x56\xa2\x42\x8d\x84\x0b\x3e\x98\x55\x8a\x36\x65\x22\xde\x31\xc9\xaf\xa9\xe2\xd1\x48\xe5\x58\x0f\x41\x32\x13\x49\xec\x7b\x68\x5b\x5b\xce\x18\xf4\x1d\x00\x27\x17\x23\x84\x9f\xf9\x44\xf4\x08\x6d\x80\xa2\x75\x2b\x60\x79\xa6\x8a\x2a\x5b\x83\xe7\xae\x08\xd6\x42\x2b\x69\x23\xd2\x17\x5f\xda\xfa\xcc\x7f\x57\xc0\xcc\x47\x64\xd3\xb1\x98\x03\x82\x34\x8e\x25\xa8\x16\xe5\x8d\x9e\x40\x4f\x6d\x45\x4a\x59\xa3\xf6\x3e\x75\xc7\x48\x01\x36\x6f\x5a\x42\xf1\x1d\x8f\x2a\x22\xde\x27\xa6\x60\x17\xa3\xd3\x16\xd4\xab\xf7\x83\xf3\x8b\x98\xa9\x7a\x3d\x45\x58\x16\x95\x3e\xd7\x21\x29\xdd\x8d\x95\x44\x09\x2b\x31\xee\xe6\xeb\x6a\x2a\x26\x56\x88\x5a\x4b\x22\x4d\xb8\x9d\xc6\x90\x15\x97\x24\xed\xcc\x39\xe8\x74\xc8\x44\x8c\xfd\x97\x4a\x68\x28\xff\x44\x15\x20\x3e\x58\xc2\x12\x79\x17\x3a\xd2\x2f\x82\x90\x97\x08\x13\x9a\xde\x7d\xf8\x61\x85\x8a\xaf\x00\xf3\x93\xc1\x72\x74\x71\xd6\x25\xba\x64\x2c\xde\x3b\x74\xd9\x5d\xbf\xac\xa7\xc4\xd5\x2b\x49\xb8\x09\xfd\x61\x1f\x89\x78\x83\x98\x54\x32\x1a\xbc\xbf\xda\x09\x58\x0b\x42\x89\xb5\x2f\x2e\xf5\x78\x6f\x00\x94\x9d\xa9\x04\x8a\x5a\xa3\x3c\x49\xae\x21\x92\xb0\xab\x5d\xb5\xbe\xff\x17\x4b\x73\x6d\x12\x79\x2a\xf2\x3b\x96\x27\x70\x37\xf3\xb2\x08\x66\x25\xb0\xa3\x4c\x3e\xcc\xf2\x04\x63\x61\x29\x5f\x78\x80\xe3\xea\x55\xc5\x89\xc5\x94\x0f\xab\xb1\x61\x5c\xb5\x5d\x50\x50\xbc\xac\xe8\x29\x45\x95\xb2\xae\x56\xc6\x63\x36\x67\x71\x4e\x13\x7c\x11\x4a\xa1\xd5\xfe\xfb\x05\x87\x4c\x7d\x51\xd7\x06\x2d\xf8\x7d\x8f\x7d\xbb\xee\x2f\xec\xf2\x16\x8c\x4f\x07\xf8\x8b\x79\xb1\x5b\xe1\x40\xf0\x01\x1d\x18\xb4\x79\x26\x82\x1a\x96\x25\x7f\x8f\x92\xd0\x95\xdf\x5f\x2f\xd2\x1b\xc5\x4b\xe4\xd3\x19\x02\x4b\xa6\xd4\x57\x08\x4c\x40\x63\xf1\x37\xe7\xc0\xb5\x51\x3b\xee\xd9\xd8\x89\x55\xd5\x62\x78\x75\xdc\x78\x26\xc2\x5a\x53\x8b\xd6\x52\xf4\x71\x85\xcc\x38\x18\xe9\x9d\x31\x50\xcc\x41\xce\x19\xdc\x1d\x3b\x56\x37\x30\x6a\xfc\xc0\x42\x44\x1d\x23\x60\x8f\xbf\xb0\xe2\xe0\xcd\xfb\xb3\xf7\xd8\x49\xd9\x99\x19\x73\x05\x93\x3c\x71\xbd\xe8\x87\x84\x66\xec\x03\x48\x85\xb5\x62\x6f\x19\x8f\xfb\x24\x67\xf1\xd7\x9f\x30\xc2\x85\x71\x56\x86\xed\xb5\xa2\x5a\x6f\x1d\x55\x72\x69\xc3\xec\xdf\x65\xbb\x78\x17\x05\x34\x86\x44\xf0\x69\x25\xe9\x19\xc5\x81\x0b\xce\xf4\x4a\xd3\x59\x5b\xc0\x11\x55\x5a\x21\x63\x0c\x8e\x64\x42\xd6\xec\xb7\x66\x3e\x2c\x6b\x57\x09\xb1\x34\x24\x8d\xd5\xe6\xc3\xb8\x15\x55\x30\x0f\x62\x23\x1f\x7c\x7e\xa4\xaf\xfa\xeb\xcb\xe5\xd9\xea\x8d\x33\xca\x63\xfc\x33\x8a\x84\x8c\xdd\x7a\x99\x2e\xe2\x39\x6d\xf4\x8f\x0d\x39\x41\x36\x64\x28\x1a\xe5\xcb\x6f\x46\x8d\x51\xa6\xb5\xd8\x3f\x2f\xa6\xe4\x9c\xfd\x2b\x07\x42\x53\x61\x08\xf1\x72\x6d\xfb\x25\x88\xa4\x74\x81\xbc\x10\x97\xfa\xd6\xc7\xa7\xbb\xa4\x42\xd5\x27\x57\x40\x63\x56\xc9\x8b\xee\x93\xb7\xf5\x44\xe9\xbe\x59\xcb\xb5\xcd\xe0\x74\x3f\xd9\xd5\x4b\x50\x22\x97\x11\x5c\x59\xa7\x4e\xea\x03\x88\x56\x3f\xc6\xec\x8a\xa6\xb7\xc0\xad\x12\x6d\x40\x83\x7e\xab\x5c\xe2\x1e\x44\x33\x88\x73\xe4\x2a\xe3\x05\x99\x30\xdb\xf0\x02\x59\x3b\x9b\xce\x40\x69\x2f\x0c\x1e\x63\x50\x4e\xd9\x3b\xcc\x2f\x00\xd1\xb7\x12\xbd\x5b\x9a\x9d\x52\x8a\xe5\x98\xf1\xc8\x52\xed\x13\x54\xac\x8e\xa5\xf2\xd4\x9f\xe5\x65\x48\xab\x21\x79\x6b\x5e\x65\xf1\xa9\xd2\x48\x80\x2d\x01\x17\x9d\x6a\xce\x6e\x46\x26\x54\xcd\xb0\xcd\xc6\xf2\x16\xb8\x1a\xfd\x51\x2e\x0d\xc1\xb0\xa5\xb3\x29\xb6\x47\xc7\x56\xba\xd8\x49\x7b\x9d\xa1\xa5\x65\x42\x82\x59\xec\xa0\xc2\xef\x9e\x0b\x13\x3b\x29\x02\xcc\x0d\xe0\xa3\x25\x4a\x60\x77\xd2\x30\x2c\x5f\x62\x4a\xe6\xbc\xf4\x70\x1a\xaa\xf0\xe9\x58\x52\x73\x7f\x66\x23\x3f\x64\x1b\x0e\x48\xe5\xb4\xbd\xa5\xa2\x77\x22\xa7\xb9\x3d\xe8\x8e\x0a\x97\x85\xb6\x87\x4b\x81\xc6\x28\x4c\x19\x0d\xe4\xf4\xdd\x59\x35\xb3\xa9\x9a\xb2\xe1\xf3\xc2\x86\xe4\x43\x5b\xbb\xf2\xb2\x61\xd9\x10\xf4\xd2\x5a\x5d\xb6\xc9\x30\x44\x23\x99\x7b\x95\xa0\x78\x9b\x97\x7c\x19\xcf\x72\xed\x38\x61\xa9\x24\xf2\x68\x46\xf9\x14\xf5\x42\x91\x9b\xf9\xbe\xfc\x12\x57\x24\x21\xce\x23\xd7\x63\xc4\x63\xed\x97\xde\xca\xea\x2a\x7b\x21\xb9\x52\x11\xcd\xfc\x9a\xab\x9f\xf5\xff\xb1\xf7\x3f\xde\x71\xdb\x46\xbf\x30\xfe\xaf\xe0\xa8\x3d\x5f\x69\x93\xdd\xb5\x9d\xb4\x7d\x52\xdf\x7c\x9b\xa3\x48\x72\xaa\x1b\x5b\xd6\x23\xc9\xc9\xdb\x37\xce\xd3\x62\x49\xec\x2e\x2a\x12\x60\x08\x50\xf2\xf6\xfa\xfe\xef\xef\xc1\x0c\x00\x02\xdc\x95\x2c\x91\x94\x77\xa5\x2c\x7b\x4e\x63\x71\x49\x90\x1c\x0c\x06\xf3\xf3\x33\x6a\x21\x34\xfd\xf0\x92\xf0\x31\x1b\x93\x9d\x3f\x06\x3f\xed\xe0\xd3\x8b\x52\x9a\x47\xd8\x8a\x0a\x78\xab\x8c\x6b\xc8\x6c\xd8\x09\xaf\x1e\x93\x23\xf3\x0c\x88\x3c\x79\x02\x06\x49\xff\x93\x9a\x7c\x43\x52\xb2\x19\x2d\xd3\xcc\x7a\x48\xae\x83\x4a\x11\x4f\x30\xf6\x81\x2b\xad\x70\x1b\xd2\x1d\x84\x93\xa6\xea\xd2\x88\x22\xb3\xb8\x46\x29\xd5\x74\x14\xac\xea\x67\x68\x6a\x8d\x2c\xf8\xf1\x88\x5a\xee\xaa\xa5\xd6\xb3\x3f\xd8\x82\xcb\x11\xf5\x57\x71\xa3\x94\x03\x0c\x71\x7b\x55\xe7\xb1\xb9\xc5\x3a\x60\x60\xc7\x0b\xf8\xa8\x06\xc6\x07\x1a\x40\x5b\x99\x5a\x65\xf2\x72\xd4\xc2\x3c\xdf\xb0\xa4\x8f\x4e\x2e\xce\xfe\x71\xfa\xf6\xf8\xe4\x62\xbb\xb2\xb7\x2b\x7b\xbb\xb2\x3b\xac\x6c\x26\xae\x3a\xaf\x6a\x67\x3d\xad\x0a\xd4\x36\xd1\x27\x83\x9a\xa3\x27\x94\x0e\x77\x24\xae\x7e\xa2\x46\x99\x2e\x4a\xa6\x40\x3f\x81\x28\xd3\x8a\xb8\xb5\xbd\x00\x55\xf7\x83\x47\x9f\x0f\xb7\xc6\x6c\xb6\x1e\xb3\x84\x42\xc7\xca\xaa\x59\x0b\x9b\x22\x1e\xfc\xf3\xf8\xf0\xe8\xe4\xe2\xf8\xd5\xf1\xd1\xd9\x5a\xd3\x3b\x3a\xa2\x3f\xc6\xfb\x72\xcb\x5d\xb2\x28\xd9\x15\x97\x95\xca\x16\x1e\x40\x7a\xb5\x10\x58\xce\x10\x14\x29\x78\x3c\x1c\x46\xf6\xca\xdb\xb6\x9b\x6d\xbf\x9b\x6d\x9c\xed\xd2\x01\xf8\xa7\x2f\xf6\x7d\x55\xca\xbc\x27\x16\x3e\x47\x5f\x8c\x0b\x61\xaf\xe2\xa7\x5d\x8b\x11\x12\x6d\x3d\x56\x79\xac\x01\x49\x8c\x3e\x9a\x17\xba\x43\x77\x90\x5e\xf0\x7e\xfb\x81\xc6\xc5\x0c\x9b\x37\xb4\xf8\x91\x2d\xce\x58\x47\x7c\xa1\x98\xde\x2c\x63\x89\xd9\xe8\xc8\x25\x5b\x60\x3a\xe5\x81\x7b\x58\x17\x1c\xa4\x8d\x84\x4b\xbe\x64\x5d\xa0\xac\xfb\xc4\x39\xbe\x64\x1d\x52\x45\xdd\xb1\x84\xf8\x6b\xa6\x10\xf4\x34\x33\xa7\xdd\x66\x8f\xf4\x8b\x71\xfc\x00\xb8\xce\x4f\x37\x8e\x12\x1f\x3d\xce\x82\x0b\xdf\xf6\x3c\x13\x18\x49\x5f\x44\x7b\x97\x17\x22\x04\x8b\x38\x81\x37\x5d\xe8\xc1\x2a\x19\x3d\x91\xa6\x6b\x7b\x41\x82\x53\xd8\xaf\x5c\xdd\xad\x05\x2b\x66\xe6\x7b\x04\xbb\xf4\xa5\x03\x3d\x50\xbe\x27\x20\x74\xd9\x1d\xc6\x7f\x42\x60\x74\x48\xfe\xe5\x4f\x42\x17\x7f\xf5\xcb\xee\xee\xb7\x3f\x1e\xfd\xe3\x6f\xbb\xbb\xbf\xfe\x2b\xfc\x15\xb6\x42\x0c\x6f\xc7\x97\x00\x82\x83\x90\x29\x3b\x81\x67\xc0\x9f\x56\x5d\xdb\xc7\x10\x8a\xfd\x01\x0a\xb0\xc7\x98\x6b\xe4\xff\x2c\x64\xda\xfc\x4b\x75\x82\x1a\xdc\xc8\x8d\x01\xa6\xa8\x43\x3d\x10\x1e\xfd\x6d\x0f\xb5\x2c\xe9\x79\xa9\xda\x51\x7d\x6b\x9b\x64\xce\x72\x04\x3b\x7b\xe5\x48\x00\x7d\x8b\x1d\xd2\x83\x80\xf2\x78\xa3\x99\xc6\xb8\x93\x3b\x57\x2f\x3a\x35\x78\xc7\xa3\x47\xd1\xe6\x67\xb0\x67\x82\x01\x45\x2c\xb5\x70\x21\xfb\x0d\xd6\xa7\xb9\xf8\xbe\x9a\xfb\xa7\xc7\xe4\x0a\x29\xbc\x31\xc4\x71\xe1\xcd\x57\x0f\x2a\xe3\x7c\x10\xb5\x59\x86\xfb\x12\x33\x98\xdd\xef\x16\x12\x41\x79\x6c\x3c\x66\x0c\x9b\x3d\x3c\x39\x4e\x8a\x6a\x68\x2f\x18\xe7\x2c\x97\xe5\xc2\xff\xe9\x4b\x31\x47\x4a\xcb\x92\xce\xa0\x12\x06\x6f\xc7\xdb\xfc\x5f\x78\x63\xf4\x80\xe5\xbb\xd1\x14\xae\x63\xa9\x56\x22\xb7\x84\xf6\xa8\x8f\x0d\x94\x6d\x8e\xf4\x1b\x22\xda\x92\xae\x00\x4d\xf1\x11\x33\xa4\xf7\xc4\xa1\xc2\xe9\xa9\x08\xf6\xa4\x2d\x11\x1e\xd6\x59\x6c\xe0\x0d\x10\x57\xc6\xb2\x6c\x0d\xad\x57\x1f\x3d\x4a\xb3\x94\x5f\x71\x25\x3b\xd4\xfb\xf8\x81\x6e\xce\x78\xb4\x28\x25\x98\xc5\xe5\xdd\x66\x1f\x0a\x40\x13\xf3\xeb\xb5\x21\xf6\x5f\x74\x69\x28\x86\x47\x41\xb5\x66\xa5\x78\x49\xfe\x67\xef\xfd\x97\x1f\x47\x83\xef\xf6\xf6\x7e\x79\x3e\xfa\xeb\xaf\x5f\xee\xbd\x1f\xc3\x3f\xbe\x18\x7c\x37\xf8\xe8\xfe\xf8\x72\x30\xd8\xdb\xfb\xe5\xc7\x37\x3f\x5c\x9c\x1e\xfd\xca\x07\x1f\x7f\x11\x55\x7e\x89\x7f\x7d\xdc\xfb\x85\x1d\xfd\x7a\xc7\x41\x06\x83\xef\xfe\xd8\xf9\xd5\x7b\x00\xf7\xc5\xa3\x4f\x88\xdf\x78\xc4\x5e\xd8\xef\x01\xfb\x5a\xe0\xe1\xd8\xab\xef\xf5\x7f\xe6\xa4\x66\x90\xd5\xe3\xb6\xeb\x8d\x59\xe0\x98\x16\xfa\x39\x3c\x39\xf8\xa4\xb8\x42\xc6\x9b\x16\x4f\x6d\x9f\xfb\x3d\x38\x77\x7c\x47\x4a\x98\xd7\x5a\x13\x9d\x96\x32\x77\x75\xf8\x10\xde\xc0\x8a\x31\x7b\xdd\x25\xeb\xd4\x23\x19\x8f\xad\x33\x68\xeb\x0c\xba\xe1\xf8\xa4\x33\x08\x8b\x08\x36\xd7\x13\xc4\xc4\x55\xdb\x10\xc6\xca\x08\xba\xb3\x75\x42\xb4\xbb\xbb\x05\xd4\xc6\x6e\xa9\xd7\xad\x5c\xeb\x64\x1a\xdc\xd0\xf2\xd5\x31\x4c\xb2\x0f\x2d\xdb\x71\xe1\xc3\x00\x1e\x4d\x94\xa1\x69\xe3\xaa\x26\xaf\xcc\x2b\x78\x0c\xf9\x08\x2d\x16\x72\x8b\xb9\x98\x59\xfc\x09\xdc\x4a\x6c\xf4\x89\x8b\x1a\x67\xd7\x2b\x87\x35\x38\x3b\x55\x4a\x26\xd0\x05\x09\x61\xf1\x3c\x08\x9f\x7d\x6d\x78\x1b\x4d\x2f\x21\xda\x98\xb0\x94\x89\x84\x59\xe0\xf6\xa8\x6d\x2d\x15\xe4\x48\x5c\x39\xf0\xfa\xb4\xc2\x64\x10\x14\x7f\xab\xc7\x78\x5a\x09\x08\x86\x11\x6d\x10\x2c\xc8\x43\x00\xa9\xef\x2d\x6c\x0a\xa9\x18\x72\x5a\x7b\x59\xdb\x75\xb6\xec\xbc\x8b\x77\xdf\x33\x7d\x64\xab\x93\x32\xb4\xb4\x59\xd6\xee\xe7\x78\x93\x7c\x0a\xc1\xc0\xee\xdb\xe7\xef\x6e\xeb\xec\x69\xdb\xec\x67\xcb\xbc\x47\xec\xa4\xcf\x6d\xb2\x8f\x60\x49\x51\xb2\x29\xff\xd0\xd3\x3a\xdd\x0f\xea\x09\x79\xca\x84\xe6\x53\x8e\xcd\x7b\x8b\x92\x15\x4c\x80\xab\x15\x4a\x34\x8c\xec\xb7\x3b\x65\x1d\x9c\xde\xc4\x64\x1e\x54\xb8\xfb\x15\x65\xe7\xab\x94\xfd\xad\x1c\x23\x5b\x39\xd6\xfa\xf8\x4c\x72\xcc\x72\xee\xe6\x08\x31\xc8\x3c\xef\x9e\xfd\x7e\x10\xa7\xb2\x03\x23\x77\x2f\x21\x6e\xc0\xb8\x79\xd1\xa8\x25\x26\xaf\x61\x1d\x5b\x49\x32\x76\xc5\x32\xab\x37\x91\x9c\x0a\x3a\x43\xec\x7d\x2d\x3d\x5a\x8f\x2c\x7d\xff\xa4\x66\xde\x3d\xe8\xf1\xae\xc4\x0b\x7e\x2c\x65\x96\xb1\x52\x91\x8c\x5f\x32\x72\xc8\x8a\x4c\x2e\x72\x9b\xfb\x9a\x92\x73\x4d\xb5\xe1\xea\x73\xa6\xdb\x85\x7d\xbb\xc1\x78\xb8\x2a\xf4\x9e\xc0\xce\xb1\xac\x1d\x8a\xc2\x49\x61\x2b\x28\xdf\x0a\x10\x1a\xfb\xd0\xca\x65\x48\x4e\xd8\x15\x2b\x87\xe4\x78\x7a\x22\xf5\x29\x6a\xdf\x71\xc2\x1d\x5e\x48\xf8\x94\xbc\x34\x76\x9d\xd2\x44\x63\x3b\x8d\xa0\x40\x5d\x96\xd1\x00\x35\x50\x5b\x1f\xf5\x79\xcb\xb5\xe7\x30\x92\xaf\x3c\x6f\x15\xc9\xe8\x34\x4d\xbe\x5f\x51\xe7\x09\xda\xc7\x7a\xd2\x1a\xbb\x37\xe0\x6f\xc4\x55\x70\xd0\x63\x60\x05\x72\x41\x4a\xa6\x0a\x29\x14\x8b\x71\x15\xfd\x1b\xa1\xb5\xdb\x2f\x68\x6b\xeb\xcd\xb3\xeb\xb6\x59\x48\xa5\xa1\x84\xb6\x9f\x2e\x58\xa7\x6e\x38\xa8\x48\xa6\x59\xc6\xd2\xa8\x0d\x1a\xb6\xef\xa1\xb1\x87\x20\x81\x76\x0c\xa9\x6f\xe8\x81\x85\xca\x51\x8d\x73\x74\xbd\x6f\xa9\xe7\x9a\xd6\xb8\x7e\xca\x37\x55\x36\xd7\x0b\x13\xf6\x91\x80\x01\x96\x10\x9e\x01\xf7\x5b\x05\x9d\x6f\xe6\x52\x5e\x92\x44\xe6\x45\x06\x4b\xa7\xc3\xca\xaa\x1b\x6f\x79\x56\x1a\x99\xd1\xd5\xb3\xa0\x27\x17\x9c\xe8\xd6\x92\xab\x93\x22\xd6\x87\x1a\xc6\x3e\xb0\xa4\xb7\xa6\x9d\x47\x1f\x58\x12\x74\x9d\x05\x0c\xaa\xc4\x21\x44\x98\x15\xdb\xbd\x99\x78\xe7\x90\x43\x5f\x6e\xfe\x0e\xb5\x74\xe1\xd1\x80\xed\x83\x31\x1d\xbc\xb9\x7d\x04\x74\x8a\x00\x5b\x08\xeb\xeb\x42\x18\x0d\xcf\x8c\xb8\xf4\x96\xb0\xfe\x7c\x22\xb5\x1b\x0b\x7a\x42\x49\xa9\xc9\xde\xee\xb3\xdd\xc1\x92\xff\xb1\x81\x91\x7d\x11\xdc\xc9\x01\xdb\xb1\x00\xa0\x44\x96\xec\xa6\x43\xc2\xb5\xcb\xb4\xc6\x86\x45\xf0\x56\xb6\xe8\x6f\x48\x94\x24\xba\xa4\x29\xb7\x6a\x0c\x9c\x35\x17\xe9\xb2\xb2\x52\x7e\x6f\xf7\xe3\xae\xed\x65\x74\x2d\xc5\xae\x86\xd7\x1f\x93\x0b\xc4\x89\xf1\x03\x2d\x64\x05\x2d\x3a\x91\x04\x45\xc6\x13\xae\xb3\x05\x48\x2c\x22\x2b\xec\xe7\x65\xf6\x0b\x5b\x6c\x78\xf4\x81\x6b\xd7\x4d\x44\x4e\xc9\x73\x6c\x27\xc6\xa8\xf5\x80\x66\xfc\x8a\x3d\x9b\x33\x9a\xe9\x39\x26\x89\x08\x29\x46\xd8\x11\xd2\x88\x12\xfb\x4b\xd7\x78\x49\x37\x77\x62\x78\x74\x70\x2d\x2e\xbf\x50\x47\xcb\xc1\x08\xd1\x1f\xda\xb7\xa9\x26\x4b\x70\x5d\x17\x17\xa7\x3f\x44\x8d\xaa\x41\x8a\x6b\x5d\xb8\xd4\x9d\xa0\x9b\xfb\x06\xc8\x8e\x7e\x82\x95\x9d\x3a\x56\x93\x1e\x45\x58\xd7\xce\xd5\x64\x35\xfc\xda\xdd\x5b\x56\x93\x7f\xc8\x0a\xc0\x40\xe8\x24\x5b\x78\x24\x06\xc5\x34\xd9\x31\x43\xed\x18\xf1\x64\xb8\xe1\xef\x8c\xa6\x08\x94\xa1\x34\xa3\xad\x54\xb7\xf0\xe8\x2d\x88\x16\xbc\x5b\xbf\xfb\x40\xa5\xb4\xcc\xc9\xdc\x7e\x76\x5c\x7a\x69\x57\xc6\x18\x56\x8f\xab\x6b\x2a\x59\x81\x12\xce\xde\xf3\xe4\xe4\xd7\x92\xdc\x40\xba\x47\x5d\x0b\x92\x90\x6c\x61\x53\x1c\x2e\x90\x58\x88\x3b\xd3\x93\x2c\xed\x21\xf9\x81\xf4\x98\x00\x41\xba\x15\x72\x36\x07\x82\xa0\x5e\xf7\x5c\xaf\xde\x72\x2a\x48\x6f\x79\x03\x64\x95\x93\xd5\xf2\x0c\x7a\x5f\x7a\x22\x62\xaf\xd1\x7a\xd2\xbd\x54\x34\x3c\x6e\x27\x40\x3f\x93\x4f\xfa\xa4\x40\xd1\x43\x6a\xf7\x72\x62\x37\xc2\x48\x41\xe9\x25\x0a\x57\x10\x13\x8a\x95\x57\x6d\x8b\xb9\xeb\xa3\xbf\x4f\x97\xed\x2d\x7e\x77\xac\xa8\x93\x2e\x89\xf0\x6d\xb0\x1d\xac\xe9\x32\x41\x82\xcc\x04\xdb\x35\xdb\xb9\x73\xdd\x76\x44\xc5\x8c\x91\x17\xe6\xce\xbf\xfc\xf9\xcf\x5f\xff\x79\x8c\xc3\xfb\x2c\x05\x41\x8e\xf7\x4f\xf6\xff\x79\xfe\xd3\x01\x14\xc7\x76\xa5\x6a\x4f\x29\x98\x7d\x27\x60\xf6\x9a\x7e\xf9\xa0\xc9\x97\x50\xf2\xd1\x59\x8a\xc4\xbe\x7f\x18\x32\xc4\xf7\xb4\xba\x5f\x80\xb3\x67\x74\xcd\xd8\x91\x6a\x96\xda\x46\xac\x31\x9d\x14\xe7\x32\xb9\xec\xd1\xae\x39\x64\x45\xc9\x12\xf4\x93\x5d\x1c\x9c\xe2\xe8\xc6\xbe\x3c\x79\x7b\x51\x97\x1a\x40\x3e\x4e\x0d\xa6\xf7\x77\xeb\x49\x33\x36\xe9\x25\x2b\xb4\x37\xdd\x27\x34\xb9\xbc\xa6\x65\x0a\x9e\x2d\xaa\xf9\x84\x67\x5c\x23\xf6\x5f\xc9\x6c\xdf\x2a\x4c\xf8\x43\x90\x33\xd7\x17\x18\x65\x39\x3a\x10\x9c\x3b\x14\x5c\x56\x98\x47\x33\xa5\x3c\x03\x0f\xaa\x6d\xc9\x8b\x19\x41\x49\xe1\x5d\x7a\xa1\x4f\x7b\x6b\x7c\xb9\x63\x63\x8d\xaf\xa0\x65\xf0\x7d\xed\xb0\xae\x79\x89\x1b\xbc\xd5\xd9\x2d\xae\x8c\xba\x77\x6f\xb7\xba\x1e\xc6\xdb\xdc\xad\xae\x28\xd9\xb9\x96\xad\x5a\x00\x90\xe5\x28\x09\x0e\x76\x43\x8c\x64\xc2\xa6\xd2\x08\xe1\x1b\x83\x1e\x69\x05\x8b\x90\x0a\x28\x0e\x74\x5e\x2d\x19\x05\x36\x30\x23\xd3\xf5\xcb\xce\x2c\x70\xea\x33\x15\xa2\xa5\xba\xe6\xc7\x43\xf3\x75\x2c\x87\xb7\x1b\xd6\x55\x0e\xb6\xf5\x32\x9c\x64\x3a\x41\xcf\x6d\x20\xc8\x01\x39\xd4\xbe\x7e\x33\x8c\x92\x94\x54\xcd\xb1\x2d\x31\xfb\xc0\x5d\x7f\xfa\x53\x99\x36\x9b\x89\xcf\x4a\x9a\x30\x52\xb0\x92\x4b\xb3\x19\x55\x42\xa7\xf2\x5a\x90\x09\x9b\x71\xa1\x1c\x29\x00\x3c\xdd\xd2\x0c\xe2\x31\x5c\x79\x60\xb8\x31\x39\x8b\xc0\x4e\x6c\x19\x52\x22\xeb\xa5\x69\xdf\xb9\x19\x49\x82\x1d\x0b\xe8\x84\xbd\x7a\x3c\x85\xc3\xf6\x45\x9f\x7a\xe5\xbd\x4a\xc0\x93\x53\x96\xd1\x05\x66\x9b\x42\xcb\x72\xfe\x1f\x56\xaa\x41\x0f\x11\x27\x6c\xc0\xe5\x7e\xbb\xf1\x3d\xb8\x22\x25\xa3\xc9\xbc\x5b\xf0\x77\x1b\xa2\xba\xe3\xb1\x0d\x51\x75\x19\x64\x1b\xa2\xda\x86\xa8\x3e\x71\x6c\x43\x54\xdb\x10\x55\xe3\xd8\x58\x2b\x69\x1b\xa2\x6a\x7d\x6c\x43\x54\xb7\x1f\xdb\x10\xd5\x1d\x8e\x6d\x88\xea\x8e\xc7\x36\x44\xb5\x0d\x51\x6d\x43\x54\xdb\x10\xd5\xef\xc8\x6f\xe7\x8e\x6d\x88\x6a\x69\x90\x6d\x88\x6a\x1b\xa2\xba\xf3\xb1\xb1\xc6\xd7\x36\x44\x85\xc7\x36\x44\x15\x1f\xbf\xaf\xad\xce\x05\x78\x4e\x8d\xa9\xd7\xbd\xa6\xed\x14\x82\x0a\x3c\xb1\x71\x22\x39\x8d\xea\xa0\xf0\x51\xe3\xba\x47\x45\x00\x0b\xe2\x4a\x71\x6c\x44\xa8\x8e\x33\xad\xac\x97\xea\xd8\x47\xae\x90\x69\x1d\xa8\x08\x22\x14\x68\xf0\xb6\xaf\x59\x5b\x5b\x35\x56\x97\xb0\xc4\xe7\x09\x49\x6c\x48\xfc\xa6\x87\x30\xc4\x36\x04\xf1\xe4\x42\x10\xfd\xb8\xef\x7a\x70\xdd\x75\xde\x2a\x6c\x64\xfe\x62\x5e\x32\x35\x97\x59\x6b\x46\x8f\x98\xfc\x0d\x17\x3c\xaf\x72\xe8\x14\x6b\xf8\x99\x5f\xf9\x14\x00\xdf\xbe\xda\x4a\x6c\xf4\x22\x06\x2d\x65\x5d\x2b\x59\xa8\xdf\x9c\xd3\x2b\x68\x8f\x5a\x25\x09\x63\x69\xd0\x94\x1e\x34\xac\xaf\xc7\xfe\x49\xbe\x75\xc6\x8b\x6e\xf2\xa6\xdb\x26\x8e\x70\xa4\x30\xca\xd7\x5f\xb5\x1a\x63\x56\x16\xfd\xc8\xe5\x1f\xce\x4e\x0f\x02\xb9\x4c\x85\x13\xcb\x5c\x5c\xc9\x0c\xa8\x4a\xf1\x22\xa3\xac\x8d\xb1\x7e\x9f\x1b\x83\x69\xc2\x34\x0d\x6c\x1b\x6b\x16\x28\xc2\x04\x9d\x40\x87\x5a\x73\x97\xdf\x91\x4f\x71\xdf\x65\x54\x57\x25\x23\x33\xaa\xd7\x29\xf0\xbb\x9b\x30\x9d\xcc\x97\x3e\xf6\x9b\xae\x1a\x7a\xec\x83\x33\x7a\x78\xec\x85\x9a\x01\x5f\x20\x82\xfe\x9d\xf5\xf0\xce\x92\xb2\xbb\x6e\xdc\x7d\x69\x11\x80\xb8\x81\x0f\xef\x8d\xc0\x3b\xe7\xb6\x75\x94\xdd\xce\x43\x23\xc8\x75\x95\xd2\x92\x14\x19\xad\xfb\x42\xc1\x0c\xfc\x1d\xf6\xa0\x83\x39\x4b\x2e\xcf\x6c\x24\x76\x4f\x31\xe6\x75\xd3\x19\xd7\xf3\x6a\x32\x4e\x64\xfe\xcc\x88\x04\xfc\xbf\x49\x26\x27\xcf\x72\xaa\x34\x2b\x8d\xba\x6a\xb7\xb8\x51\x62\x46\xe1\x62\x36\xce\xd3\xc1\x98\xbc\x17\x58\xdd\x5e\xf7\xa1\x0c\xb0\x1d\xcc\xf3\x1d\xce\xc6\x84\x19\xe9\x2a\xc1\x0f\x11\x40\xd8\x99\xd7\x1b\x77\x01\x4a\xee\xbc\x25\x75\x8c\x82\x7f\xfe\x08\xf8\x56\x72\x91\x1e\x1c\x2e\x8f\x2d\xd2\xdd\x5b\xc6\x47\x0f\x11\xee\x0d\x8a\x6e\x6f\x8c\x6a\xbc\x29\x11\xed\x0d\x44\x9b\xee\x21\x00\xdb\x47\x04\xbb\xbf\xe8\xf5\x03\x80\x32\x3f\x4c\xd4\xba\x47\xd7\x5e\x4f\xd1\xea\xcf\x11\xa9\xee\xe5\xab\xbb\x46\xa8\x3f\x5f\x74\xba\x9f\xcf\xed\xd3\x10\x78\xac\x11\xe9\x1e\x5c\xf4\x7d\xba\xe7\x7b\x73\xcd\x3f\x58\x04\xba\x7b\xf4\x79\x03\x22\xcf\x9d\x89\xcc\x05\xd7\x9c\x66\x87\x2c\xa3\x8b\x73\x96\x48\x91\xb6\xde\x61\x1a\x28\x9d\x7e\xfd\x28\x1c\xd6\xfa\xa9\xe2\x42\x8b\x39\xb5\x60\xe4\xc6\xa2\xc2\xc2\x12\x17\xcb\xb0\x0a\x05\x44\x95\xf1\x2d\x37\x32\x3a\x41\x36\xc6\x21\x86\x55\x27\x7d\x4e\xe2\xdf\xe5\x35\x91\x53\xcd\x04\xd9\xe3\xc2\xcd\xe3\x20\x30\x03\x6b\xef\xa4\x67\x6b\xf3\xeb\x8b\xe7\xee\xe2\xa7\xe7\x76\x04\x07\xab\x52\x0f\xef\x05\xb6\x0f\xfa\xb4\x1b\xd8\x5e\x38\xad\xb2\xd8\x15\x8c\xee\xe1\x58\xde\xbc\xa8\xe1\x94\x5f\xc0\xb8\x7e\xb5\x51\x91\x12\x5b\x89\xf6\xf4\x26\xad\x73\x5e\x4d\xac\xfa\xf9\x3c\x9a\x4f\x79\x8d\x2f\x0e\x4e\xd1\x69\xbc\x75\x97\x6c\x8a\xbb\x64\x4d\xb9\x29\x1b\xa8\xe8\x3e\xd2\x7c\x94\xad\xa2\x7b\x8f\x23\xa8\x4d\xfd\xa1\xa4\x09\x3b\xed\x5d\x47\x70\xcb\x89\xa4\x55\x49\xad\x00\xf4\x2a\x9f\x5b\x3c\x82\xb1\x14\x57\x93\xaf\xe7\x85\x4a\xd9\x69\x95\x65\x0b\x52\x15\x52\xc4\xd5\xcf\x18\x6b\x6f\x16\xd3\x82\x4b\x7e\xc5\x53\x6a\xc5\xb2\x28\xa5\xdd\x33\xcb\x4a\x08\x23\x83\xeb\x9e\x68\xa0\x48\x02\x4c\x33\x8d\x4a\x76\x15\x9f\x99\xd7\x37\xfb\x1f\x54\xf3\xd6\x09\x88\xd1\x80\xe6\xee\xa9\x2c\x13\x3e\xc9\x16\x64\x4e\x33\xdf\x00\x87\x92\x4b\x9e\x65\x76\x98\x31\x39\x67\x1a\x43\x0a\xb8\x77\x66\x52\xcc\xe0\xe5\xa8\x70\x8d\x17\x59\x62\xee\x4d\x32\x46\x45\x55\xe0\xf3\xcc\x4e\xbc\x90\x55\xe9\x9e\x37\xf6\x81\x09\xbf\x03\x0b\x9e\x0d\x83\xf6\x6e\xb7\x4e\xac\xcf\xfd\xa9\x94\x51\x00\xde\x3a\x58\xea\x61\x38\xa6\x43\x0e\x57\x41\x73\x9f\xa2\x94\x57\x3c\xc5\xe8\x86\x23\x1b\x34\x92\xc6\x06\x3e\x7e\x3d\x0b\x29\x46\x82\xcd\x28\x28\x2a\x76\x15\xe1\x9c\xe1\x38\x98\x41\x20\x52\x68\xe9\x63\x34\x7c\x59\x44\xe5\xf4\x57\x1c\x9b\x11\x07\x94\x23\x7b\x42\x12\x09\xf9\xa8\x95\xe0\x1a\x1b\xdc\xcf\x2b\x4d\x52\x79\x2d\x06\xf7\x8a\xba\x42\xa0\xf5\x62\x25\x81\xe2\xf0\xeb\x2a\x3d\x07\xbf\xf7\x76\xf2\x72\x65\x5d\x9f\x53\x52\x09\xc5\x3a\x6e\xef\xbd\x29\x47\x7f\xf9\x53\x3b\x19\xc1\x73\x26\x2b\xfd\x59\xac\xbf\xeb\x39\x4f\xe6\xa1\x32\xcb\x73\xa6\x88\xac\x1a\x66\xf1\x0b\x7b\xdb\xea\x19\xda\x9a\x80\xab\x8e\xb6\x8e\xdd\x15\xde\xaf\x26\x1c\x42\xdd\xf9\x1a\xf2\xc4\x0f\x4f\xce\xff\xf9\x7a\xff\xfb\xa3\xd7\x63\x72\x44\x93\x79\x88\x89\x21\x08\x05\xa1\x01\x82\x62\x4e\xaf\x18\xa1\xa4\x12\xfc\xb7\xca\x06\x7c\xf7\xfc\xbd\x83\x5e\xb1\xda\x5b\xee\xbe\xd0\x9d\xbf\xb7\x76\x70\xd8\xeb\x1f\xf3\xb2\xa4\x62\xd0\xc0\xa5\xa9\x3e\x1d\x99\x9f\xd0\x38\x00\x55\x0b\x12\xe7\x67\xfc\xca\x8a\x61\x0b\x7e\x4f\x53\x9f\x29\x66\xf8\xdc\xb0\x85\xd9\xaa\xe8\x04\x32\xbc\xe6\x8c\x08\xa6\x0d\x5b\x7b\x1f\x93\x14\x2a\x02\x27\xa9\x14\x53\x43\x32\xa9\x20\x27\xad\x28\x79\x4e\x4b\x9e\x2d\xc2\xc1\xcc\x5e\x75\xe2\x43\xde\x8b\xe6\x2b\x1d\xbe\x3d\x3a\x87\x1a\x81\xa2\x44\xd8\x12\x48\x2a\x83\xdf\xe1\xb3\x26\xcc\xdc\x61\xdb\x08\x8f\xc9\xbe\x58\xe0\x8f\xb8\xc0\xb9\x22\x19\x57\x9a\xc1\x16\x6c\x75\x48\x17\x4c\xdf\x79\x3e\x86\xff\xed\x98\xaf\x2c\x8d\x92\xe9\x73\xe5\x92\xa5\xe4\x55\x54\x43\xf9\x24\x0b\xa8\x69\xbf\xfd\x49\x35\x84\xab\x93\x84\x0c\x11\x83\x86\x70\xd4\x4f\x35\x90\x17\x1b\x04\x72\x31\xcb\x42\xae\x6a\x27\xf6\xbb\xda\x96\x5d\x2d\xcb\x51\xfd\x05\xa7\x6d\x0d\xcc\x5e\x1a\xd3\xd5\xef\xd0\x53\x3b\xa7\x7a\xf7\x73\xe6\x94\x95\x08\x32\xec\xd0\x7b\x7c\xea\x56\x80\xd5\x6e\xf2\x46\x5b\xd7\xa2\xce\x49\x1a\x92\xe7\xe4\x5b\xf2\x81\x7c\x0b\xe6\xd5\x5f\xba\x36\xbf\xea\x6a\xf8\xf4\x91\x62\x64\xac\xfa\xe3\xd3\x9e\x28\xfe\xb3\x91\x4e\x66\x44\x43\x55\x2d\xc9\x84\x5b\x75\x9e\x7d\xd0\xac\x34\x72\xd4\xce\xc4\x5a\xdb\x86\x99\x17\xfc\x8c\x6c\x86\xe1\x86\xe3\x69\x9c\xd6\x74\x3f\x46\x33\xb7\xff\x5d\x2a\x7d\x62\xa5\x50\xdc\x00\xa7\x1e\x2d\xa7\x3a\x99\xc7\x62\xcc\x28\x6a\x4a\xd7\x0b\x4c\x91\x54\x42\x96\x15\xa6\x2f\xcf\x79\x87\xe4\x89\xcd\x61\xe3\x6e\xf1\xf4\x68\x3e\x6f\x9b\xa9\x86\x03\x05\x2c\x1f\xab\x58\x05\xc8\x58\x85\x4c\xad\x4e\x66\x5e\x2b\x0d\xf6\x8c\x5b\x94\x32\xeb\xab\xf1\x5e\x66\xe0\x25\xb3\x9e\x12\x2a\xb0\x80\x64\xca\xca\x12\x33\xce\x27\x0b\x97\xac\xd7\x79\xf2\x3a\xad\xa4\xa2\x94\x5a\x26\xb2\x43\x67\xb3\x38\xc6\x6d\x87\x03\x22\x60\x96\xaf\x73\x93\xbf\x3b\x3c\x1d\x92\x8b\x83\x53\xe8\xf6\x74\x7e\x70\x71\x1a\x5b\x2a\x3b\x17\x07\xa7\x3b\x6b\x25\x05\x71\x9a\x15\x38\xa6\x5b\x0c\x12\x39\x9e\x8c\xda\x36\xca\x69\x31\xba\x64\x8b\x96\x7b\x6a\x1f\xfb\xfa\xc8\xcf\x70\x2f\x1f\x84\x64\xce\x69\x71\xef\xd1\x4a\x46\x53\xfe\x99\xaa\xb8\x5c\x1a\xac\x7f\xe6\xea\x72\xae\x5c\x5e\xb1\x14\xd5\x61\x77\x07\x13\x69\x21\xb9\xd1\x17\xb7\x35\x5e\xf7\xbf\x7b\x5b\xe3\x75\xe7\x63\x5b\xe3\xb5\xad\xf1\x5a\x3e\x36\x26\x91\x75\x5b\xe3\xf5\xb4\xe2\xf6\xdb\x1a\xaf\xdf\x79\xe8\x7f\x5b\xe3\xb5\xfa\xd8\xd6\x78\x6d\x6b\xbc\xee\x76\x6c\x6b\xbc\xee\x7f\x6c\x5c\xd2\xd2\xb6\xc6\xeb\x5e\xc7\xb6\xc6\x6b\xf9\xd8\xd6\x78\xdd\x70\x6c\x6b\xbc\x6e\x38\xb6\x35\x5e\xdb\x1a\xaf\x6d\x8d\xd7\x36\xf5\xf5\x93\x63\x6d\x66\xea\x2b\xd9\xd6\x78\xd9\x63\x5b\xe3\xf5\x24\x12\xfc\xc8\xb6\xc6\xeb\x4e\xc7\xb6\xc6\x6b\x5b\xe3\xd5\xe6\xd8\xd6\x78\x3d\x15\x77\xc9\xb6\xc6\x6b\x5b\xe3\xf5\xfb\x51\x74\xb7\x35\x5e\xdb\x1a\xaf\x6d\x8d\xd7\xb6\xc6\xeb\xd6\xb7\xd8\xd6\x78\x3d\x05\x13\xd0\xf5\x01\xee\x5e\xb3\xb4\x7b\x20\xf3\xa2\xd2\x8c\x9c\xb9\x21\xbd\x16\x89\x82\x81\xab\x50\x23\xe8\x9e\x42\x98\x48\x31\xe5\x33\x2b\xd9\x9f\x61\xf3\xdd\x91\xff\x9e\x51\xd0\xf0\xf6\x11\xe6\x0f\x66\x3c\xe7\xed\x0a\xc9\xc8\xd2\xc4\xbc\x86\xb1\x82\xb8\x8c\x59\x49\x39\xfd\x00\x4b\x84\xe6\xb2\xc2\x86\xc5\x89\x9d\x3f\x4f\x42\x8c\x5e\x6d\xdc\xcc\x90\x7e\x4c\x9c\xba\x22\xee\xb4\x8f\xb4\x12\xaa\x35\x2b\xc5\x4b\xf2\x3f\x7b\xef\xbf\xfc\x38\x1a\x7c\xb7\xb7\xf7\xcb\xf3\xd1\x5f\x7f\xfd\x72\xef\xfd\x18\xfe\xf1\xc5\xe0\xbb\xc1\x47\xf7\xc7\x97\x83\xc1\xde\xde\x2f\x3f\xbe\xf9\xe1\xe2\xf4\xe8\x57\x3e\xf8\xf8\x8b\xa8\xf2\x4b\xfc\xeb\xe3\xde\x2f\xec\xe8\xd7\x3b\x0e\x32\x18\x7c\xf7\xc7\xd6\xaf\xdc\x59\x25\xee\x4f\x21\xee\x49\x1d\x7e\x10\x65\xd8\x06\x74\x7b\x5a\x8b\x36\x19\x65\x69\x35\xda\x0d\xeb\xb6\xd5\xe8\xa4\x29\xa8\x79\x7e\x1c\xae\x88\xcc\xb9\x36\xca\xa1\xd1\x07\x69\x98\xce\xca\x75\x64\x94\x5a\x39\x00\x09\xdd\x54\x63\x7b\x75\x9f\x0a\x1a\x24\xb1\x48\xa7\xf9\xd9\xfe\xf3\x3c\x2f\x32\x68\x6b\x0e\xeb\x79\xe4\x72\x59\x60\x73\xdd\xca\x86\x4f\x1f\x5b\xd9\xf0\x14\x65\x83\x62\x49\x55\x72\xbd\x38\x90\x42\xb3\x0f\xad\x3c\x2c\xb1\x68\x38\x8f\x07\xb4\x39\x63\xb6\x8a\xdb\xfe\x46\x64\x81\x79\xdf\x8d\x72\xfa\xb9\xac\xb2\x14\x8a\x39\x2a\x01\x06\x26\x56\xe9\x31\x8d\xd6\x1f\xd8\x3d\x90\xca\xdd\x7c\x88\xb3\xe7\xd0\xcc\xfc\xad\xe2\x57\x34\x33\xd6\x6e\x7d\xc7\x29\x58\x30\xe1\x4d\x77\x5d\xf3\x9a\xaa\xcb\x7a\xc1\xb3\x91\xd1\xa1\xfd\x3b\x3f\x73\x9f\x04\xa7\xd8\x07\xfd\x18\xb5\x34\x50\x90\x4e\x4b\x7e\xc5\x33\x36\x63\x47\x2a\xa1\x19\xc8\xb5\x7e\xf6\x8a\xfd\x1b\x46\x87\x89\x2f\x65\xa6\xc8\xf5\x9c\x19\x59\x4d\xa8\x73\x01\x40\x85\xdd\x8c\x72\x41\x72\x33\x45\x85\xbb\x59\xa1\x2f\xc1\x88\xff\x82\x96\x66\x82\xbd\xcf\x00\x4c\xe4\x89\x94\x99\xad\x78\xc8\x16\xf5\xf8\xb6\xf6\x47\xc8\x7f\x0a\x76\xfd\x4f\x33\x9a\x22\xd3\x8c\xce\xbc\xab\x40\x31\xbd\xe4\xed\xab\x87\xbe\xf1\x03\xa0\x9c\xa0\x62\x84\x66\xd7\x74\xa1\x6a\xc7\x49\x80\xfb\xa0\x5e\x92\x17\x03\x60\x67\xaa\x88\x1f\x23\x25\x5f\x0d\x20\xfc\x77\xb0\x7f\xfa\xcf\xf3\x7f\x9c\xff\x73\xff\xf0\xcd\xf1\x09\x39\x91\x9a\xe1\xa6\x16\x34\x07\x4c\xbc\x85\x61\xde\x12\x9e\x01\x56\xba\x54\x63\xf0\x5d\x72\x45\xae\xb9\x48\xe5\xb5\x6a\xed\xa3\x45\xf6\x33\xc4\x63\x54\xb4\x1a\x23\xa1\x05\x85\x9e\x87\x1d\x76\x98\xa5\x0c\x93\x70\x50\xd8\xc3\xd3\xf4\x59\x5a\xca\x02\x89\xe0\x9c\x5c\xf5\x56\x1b\x9b\xd1\x61\x0e\x2b\xcc\xef\x34\x1e\x70\x56\x52\xa1\x6b\x6f\x4f\x3d\x67\xb6\xd9\xe2\xb8\xf3\x74\x3c\xee\x8a\x26\x9a\xf6\x57\xcd\xb4\x9f\xa6\x2c\x8d\xc8\xff\xe4\x32\x07\x0f\xdc\xc7\x2d\x6a\x94\x0a\x72\xfa\xf6\xfc\xf8\xff\x69\xf0\xf1\xa2\xe8\x96\x28\xd5\x4f\x65\x6c\x29\x8b\xde\x66\xf7\xcc\x56\x5e\x6e\xe7\x77\x23\xe6\xd7\xef\x96\xfd\x84\xe7\xcf\x2a\x11\x03\x19\xd5\xe3\x93\x5c\xa6\x6c\x4c\x4e\x7d\x9c\x20\xfe\x35\x00\x38\xa0\x25\x23\xe6\x12\xa1\x39\xcd\xb2\x45\xa8\xa2\x69\x89\x55\x88\x11\x36\x43\x28\xc8\xa7\x34\x53\xeb\x96\xc6\x5d\xf6\x46\xa3\x47\xbc\x31\xf6\x70\x2f\xd3\xe1\x47\x23\x29\x13\x52\x5b\xc5\xda\xbc\x25\xe0\x5d\x94\x32\x21\x68\x7c\x07\xc9\x58\xd1\xfe\xa6\x30\x56\xe1\xb6\x46\xae\x1c\xb1\x4f\xfd\xc8\xe8\xa8\xae\x14\x6b\x2a\xe8\xae\x0f\xb1\x37\xc7\xcd\xe8\x25\xa3\xa9\x14\xd9\x02\x32\x2f\x31\x97\x22\xa7\xea\x92\xa5\x78\xc2\xaa\x66\x3e\x52\x61\x46\xf4\x8f\xba\x30\xef\xed\xc2\x12\xa0\x92\x61\x86\x07\x84\x33\x58\xba\xe6\x59\xef\xb0\x08\x0d\x51\xde\x8a\x6c\x71\x26\xa5\x7e\xe5\xcb\x68\x7b\xe1\x80\x9f\xad\xb6\x1c\xbb\xa2\x41\x9d\xa4\xf0\xdc\x11\xcc\x06\x2c\xaa\xb0\x82\xf7\xb0\x9e\xf1\xc7\xbe\xa4\xca\x4a\xec\xab\x1f\x4a\x59\xb5\xde\xc4\x96\x94\xcd\x1f\x8e\x0f\x41\x14\x55\x36\x54\x29\x74\xb9\x00\xe8\x80\x65\xd4\x37\x6f\x18\xbc\xb3\xc1\xd6\x70\x4d\xd4\x71\x31\xf2\x86\x2e\x08\xcd\x94\x74\xb4\xe4\x62\xa5\x15\x6a\x4d\x5c\xf3\xf3\x44\xea\xf9\x92\x6d\x6b\x16\xd4\xf2\x7d\xc3\x20\x72\x59\xc3\xd0\x71\xb1\x74\xbb\xa6\x97\x4c\x91\xa2\x64\x09\x4b\x99\x48\xd6\x3d\xed\xeb\x0e\xf8\x01\xeb\x9c\x48\x61\x16\x66\x2f\xcc\x73\xec\x23\xbd\x96\xa4\x21\xab\x40\xcc\xd8\x5a\x7f\x14\x22\xc7\xb0\x2c\x2b\xc5\x4a\x0c\x73\x97\x15\xc3\x99\xfc\xb1\x9a\xb0\xcc\x50\xde\x98\xa4\xb6\x53\x3c\xba\x33\x78\x4e\x67\x8c\x50\xed\x39\x4d\x4b\xc2\x84\x32\x12\x13\x1d\xa0\x9a\xa4\x92\xd5\xd5\xf7\x54\x91\x77\xc7\x87\xe4\x39\xd9\x33\xcf\x1a\x00\xff\x40\x23\x79\x2d\x31\xc9\xad\x69\xa3\x4e\xdd\x10\xf0\x4a\xc0\xbc\x44\x96\x28\x24\x86\x44\x48\xa2\xaa\x64\x1e\x76\xaf\x77\x66\xb3\x4d\x84\x84\xd0\xca\x66\xf2\xfa\x7a\x25\xd4\x3b\xc5\xca\xde\x04\xd4\xbb\x16\x02\x2a\x54\xa3\x0c\xcf\xc5\xd4\x43\xc6\xca\x99\xa6\x29\xd5\xd4\x0a\x2e\x77\xc1\xc6\x4e\xe9\xef\x5b\x7c\x29\xf6\x9a\x8b\xea\x03\x26\x1e\xf5\xe7\x6a\x39\x3f\x82\x61\x49\xe2\xa8\x0e\xb3\x4e\x8b\x22\xe3\x88\xb6\xd1\x48\x84\x3b\x8e\x78\x65\x78\x83\x9a\x08\x72\x82\x66\x99\x34\xf2\xd1\x28\x27\x54\xa4\x32\x5f\x7a\x98\x51\x22\x59\x84\x97\x3a\x26\x5b\xee\x8b\x8f\x0d\x71\x0a\x65\xec\x8a\x75\xc0\x16\x6b\xe2\xc3\x9a\xd1\x0c\x71\x1c\x47\xc0\xf0\x24\xa3\x13\x96\x21\x8d\x91\x03\xd5\x32\x07\xae\x3b\x1b\xb5\x94\x59\x7f\xe5\x33\x67\x32\x63\x98\xde\xe5\x08\x61\x86\x7f\x14\x74\x80\x41\xfa\xa2\x03\x58\x83\x11\x1d\xc0\xae\x7d\x0c\x74\xa8\x3a\x6c\xf5\xa4\x49\x07\xa3\x37\xc4\x74\x80\xcd\x7b\xd3\xe9\xa0\x58\x92\xc8\xbc\x38\x2d\xa5\x31\x3b\x7b\xdb\x9b\xec\xb0\x75\xcc\x10\x1d\x1b\x2b\x92\xb1\x60\x2f\x88\x2f\xa6\x65\x90\xd8\x49\x35\x6e\x12\x2e\xbb\xf3\xff\x17\xec\x59\x20\x7a\x9a\x1b\x99\x1b\x25\x0a\x2f\x9a\x3b\xed\x0f\x8f\x79\x3b\xe8\xa3\x36\xa2\x83\xb3\xb3\x97\xdd\x48\x26\x34\x03\xec\xd8\x6e\x2c\x47\x9a\x6c\xd7\x1c\x38\x48\xe7\x85\x18\x25\x9c\x73\x09\x24\x00\x23\x0a\x67\xac\x0b\x53\xc8\x94\x05\xb1\x6c\xcc\x43\xbe\xc0\xb4\x4f\xb8\xce\x65\x12\x1b\xbd\xc2\x85\x95\xd3\xe8\x6e\x2d\x2d\x02\xda\x1b\x8f\x48\x6b\x5e\x90\x89\x94\x8b\x19\xf8\xd5\x86\xa4\x64\x19\xe6\x20\x5b\x21\x70\x89\x16\xe4\x2e\x2c\x09\x37\xa8\x5b\x0f\xee\xd1\xa0\x8b\x71\x29\xec\xc8\xe0\x29\x72\x1a\xd6\x14\xc5\x2d\x57\x64\xe7\xb5\x23\x40\x07\x08\xcf\x4d\xdc\x61\x76\xf0\x0b\xfd\x6c\xa2\xa7\xf3\x92\x8b\xd4\xa6\xeb\x46\xc4\xf2\x60\xeb\xa8\x07\x43\x22\x38\x4f\x43\xd9\xf2\x92\xbc\x17\xc4\x13\x8b\x8c\x5a\xb3\xc7\x19\xaa\xcc\xce\x47\x37\xba\xdd\xf1\xea\x1f\xd2\x1c\xe6\x9d\x80\xb9\x37\xcf\x1d\x19\xcb\x7d\xf9\x3a\xf7\x2d\x6b\x85\xee\xb1\xd2\xaf\x6f\x2b\xe6\x67\x1c\xd6\xa9\xf4\x89\x61\x6b\xcd\xc5\x4c\x85\x96\x0c\xcd\xb2\xc8\x19\xbe\xca\x94\x71\x33\xec\xa1\xf5\x97\x4d\x88\x46\x99\xc1\x63\x31\x43\x32\xa3\x4e\x3c\x72\x23\x64\x96\x2b\x7a\x50\x1a\x4a\x68\x4e\xb3\xf3\xa2\x3d\x44\x29\x59\x82\xc3\x7b\x73\xbe\x1f\x0f\x0d\x9b\x35\x74\x7e\x30\x73\x65\x7e\x27\x34\xcd\xb9\x52\xe0\x08\x63\x93\xb9\x94\x97\x64\x6f\x05\x1e\x57\x90\xa7\xa5\xf8\x4c\x3d\xb3\x3c\x3f\x32\x6f\x3f\x20\x5c\x64\x3e\x2b\x0a\xec\x60\xa1\x95\x73\xe4\xc0\x43\x12\xff\x16\x30\x87\x16\xb7\xda\x26\x2b\x2c\xbf\x26\x22\x55\x1b\x2e\x58\xbb\xc0\x5e\x9e\x9e\x93\x8e\xb0\x2b\x9f\x98\xa2\x13\xcb\xdb\x4d\x64\xb5\x95\x74\x44\xed\x71\xed\x44\xb2\xca\x45\xc2\x54\x7f\x80\x4e\x7f\xaf\xc7\x24\x29\xc3\x2a\x1e\x06\xd9\x4f\xf4\xc6\x24\x3b\xf0\x4b\xef\x42\x31\xa8\xbd\x75\x37\xd4\xa8\x2f\x6a\xe1\x62\xec\x91\xac\x98\xd3\x11\x1a\xe9\x46\xa2\x81\x08\x74\x2a\xc4\x5c\x0a\x69\x8b\x24\xcc\x26\x2a\x05\xb0\x34\x88\x28\x8c\xe6\xc1\x9c\x58\x11\x1d\xbc\xea\x41\x1d\x25\x0e\x03\x81\x50\x4c\x86\xf8\x11\xf5\x3b\x5c\x73\x3d\x77\x9d\x5e\xa2\xa8\x21\xbc\x49\xc9\x14\x04\x60\x04\x61\x65\x29\x4b\x9b\x90\xe5\xfc\xd6\x30\x12\x48\x72\xc8\xe8\x32\x4c\x42\xcd\x5f\xbb\x2a\x0c\x54\xd7\x50\xf0\x90\xaf\x68\xb8\x89\x4d\xa7\x2c\x01\x45\x2b\x24\x30\x4a\xed\xbd\x1a\xf8\xd6\x56\x19\x18\x06\xb3\x50\xf2\x39\xff\x60\x9e\x12\xde\x15\x86\xc4\x2d\xe0\xec\xea\x9f\x07\x63\x42\x8e\x85\xcf\xe0\x1d\x9a\x59\x0c\xaf\x74\xa9\x67\xda\x7c\x62\xd8\x87\x00\x3e\x20\x74\x9c\x19\xed\xb0\xac\x7a\xe0\xf8\x2e\xee\x70\x12\xba\xc4\x7b\x15\x07\xe0\x1a\xb7\x83\x9a\xa9\x77\x3a\x40\x17\x57\xb9\xb9\xe4\xa1\xdc\xe5\x8f\x23\x00\x42\xba\xca\x39\x8b\xa6\xd0\x13\x38\xfc\x79\x30\x5a\xa0\xbd\xfb\x80\xdb\xa9\x4c\x11\x4d\xc5\xa3\x41\x40\x4f\x27\x40\x77\xe1\xff\x71\xfa\x59\xad\xe3\x09\x89\xd5\x01\x21\xcc\x8a\x85\xd4\x4e\x89\x51\xb5\x33\xe7\x5b\xc8\x8b\x8c\x41\x15\x67\x30\x72\x5d\xa0\x1a\xa0\xc9\x0f\xfd\x8b\xd4\x80\xf4\x16\xdc\x65\x48\xfe\x0d\x8b\xd2\x27\xa2\x3a\xdc\x89\x53\x7f\x3b\x5a\x88\x5c\xb9\xd6\x12\x50\x61\xa9\xa5\x73\x5d\x90\x94\x4f\xa7\xcc\x25\xbc\x1a\xcb\x91\x96\x34\x37\x22\x5e\x11\x4b\x82\x09\x9b\x71\x4c\x88\xf4\x82\x6d\xd7\xa8\x7b\xb6\xd6\x6f\x88\xc2\x90\x6b\x92\xf3\xd9\x1c\x19\x85\x50\xa8\xd0\x25\x2e\xa8\x98\x49\x9a\x12\xe0\x6d\x59\x92\x6b\x5a\xe6\x66\xdf\xa0\xc9\x1c\x22\x94\x54\x90\xb4\x2a\x01\x65\x59\x33\x9a\x2e\x46\x4a\x53\x6d\x34\x65\x56\x5a\x83\xd2\xbd\xff\x16\x52\xff\xd6\x63\x0b\xa9\x7f\xc7\x63\x0b\xa9\xbf\x85\xd4\x5f\x3e\x36\x26\x3b\x74\x0b\xa9\xff\xb4\x60\x92\xb6\x90\xfa\xeb\x8e\x26\x6c\x21\xf5\xb7\x90\xfa\xb7\x1d\x5b\x48\xfd\x4f\x1c\x5b\x48\xfd\x16\xc7\x13\x90\x5c\x5b\x48\xfd\x16\xc7\x16\x52\x7f\xf5\xb1\x85\xd4\x5f\x3e\xb6\x90\xfa\x37\x1e\x5b\x48\xfd\xd6\xc7\x16\x52\x7f\x0b\xa9\xbf\x45\x1a\xbd\xdf\x58\x9b\x89\x34\x4a\xb6\x90\xfa\xf6\xd8\x42\xea\x3f\x09\x3c\x45\xb2\x85\xd4\xbf\xd3\xb1\x85\xd4\xdf\x42\xea\xb7\x39\xb6\x90\xfa\x4f\xc5\x5d\xb2\x85\xd4\xdf\x42\xea\xff\x7e\x14\xdd\x2d\xa4\xfe\x16\x52\x7f\x0b\xa9\xbf\x85\xd4\xbf\xf5\x2d\xb6\x90\xfa\x4f\xc1\x04\x54\x3a\xe5\xad\x10\x40\xef\x02\x56\x64\x93\xd0\x03\x6c\x80\x49\x35\x9d\xb2\x12\x24\x17\x3c\x79\x29\x79\xaa\xc6\x65\x6c\x06\x59\x99\x1e\x02\xee\x91\xad\xd7\xb9\xe1\x76\x0b\x46\x00\x48\x9d\x75\xa6\xf8\xd1\xdb\x57\x2b\x90\x91\x5a\x67\x15\xb6\xcd\x91\x86\x77\x7e\x2b\xda\xc5\xc7\x6f\x20\xf8\xaa\xfa\x31\x4b\xf7\x24\x93\xca\x66\xb8\x03\xb1\x92\x39\x15\x82\x39\x7b\x8f\x6b\xf0\xa3\x4c\x18\x13\x44\x16\xcc\x46\xa7\x29\x51\x5c\xcc\x32\x46\xa8\xd6\x34\x99\x8f\xcd\x93\x84\x23\x76\x9d\x8d\x6e\xcf\x28\x5d\x32\x9a\xbb\xbc\xfc\x9c\x72\x1c\x8a\xd0\xa4\x94\x4a\x91\xbc\xca\x34\x2f\xfc\x60\x44\x31\x28\xa8\xc1\x8d\xca\x13\x03\xb2\xe2\xea\x14\xf6\x61\xfd\x34\xfb\x5a\x32\x84\xa6\x03\x6b\x73\x08\x78\xe0\x79\xa1\x17\x3e\x8f\x97\x91\x29\x2f\x95\x26\x49\xc6\x61\xb7\x86\x27\x62\xed\x34\x8c\x37\x74\x7b\xb5\xb0\x6f\xaa\xec\xab\x8a\x14\xd4\xd6\x42\x2b\xcc\x8a\xad\x07\xb4\x43\xa5\x5c\x59\x35\x5f\x0d\x09\x75\xb8\x69\x48\x68\xf7\xa6\x40\x6a\xb7\xb3\xe0\xe8\xf6\x54\x30\x5c\x80\x17\x5b\xa7\x0d\xd7\x8c\x0e\x25\x0e\x8e\x39\x87\x51\x35\x47\xad\x50\x40\x96\xde\xd2\x32\x80\x09\x10\xec\xca\xf0\x00\x4b\x98\xd9\x5f\xe9\x0d\x5c\xff\xd9\x99\x3e\xd8\x14\xdf\x30\xa5\xe8\x8c\x9d\xb6\x0c\x34\xdc\x64\x91\x41\xac\xa1\x9e\x18\x60\x85\x0c\xab\x6b\xfd\x99\x3a\x3b\x33\x56\x83\x48\x8e\xef\xe4\x95\x9f\xeb\x92\x6b\xcd\x60\x52\x01\x61\x0f\x62\x95\xcd\x02\xfc\xdd\x46\x8e\xe7\x1b\x37\x48\x7d\xb3\x11\xea\x22\xc5\x8c\xcb\x09\x23\x93\x92\xb3\x29\x99\x72\x48\xe3\x84\xc4\xca\x21\x02\x2e\x51\xf4\x02\x28\x65\xec\x5d\x29\x9c\x2e\xeb\xde\x6b\x4c\x7e\xb6\x2f\xa6\xcb\x4a\x24\x34\xc0\xb2\x85\x0a\x53\x3e\x25\x33\x48\xcc\xb4\xda\xe2\x9f\x9e\xff\xf5\x2f\x64\xb2\x30\x5b\x1a\x68\x56\x5a\x6a\x9a\xf9\x8f\xcc\x98\x98\x19\x5a\xe1\xf2\x8c\x6b\x24\x3d\x05\xa0\x9b\x07\xbe\xf8\x8b\xaf\x2e\x27\xf1\x1e\xfb\x2c\x65\x57\xcf\x02\xfa\x8d\x32\x39\x5b\xd5\x1f\xa5\x7d\xca\x76\x4b\x93\x68\x05\x9b\xc9\x8c\x27\x8b\xce\x8c\xe6\x90\xbf\xc8\x5c\x5e\xa3\xae\xbf\x82\x7b\xea\x72\xab\x42\x16\x55\x86\x4e\xe7\x57\xbe\xba\xb8\x52\x6c\xb9\x06\x70\xe5\xba\x00\x37\xa9\x1d\xa2\x89\x9b\x8e\xf9\xb8\xee\x91\xd2\xd6\x96\x58\x47\x9e\x07\x00\x03\x43\xe8\x15\xcd\xb2\x09\x4d\x2e\x2f\xe4\x6b\x39\x53\x6f\xc5\x51\x59\xca\x32\x7e\x97\x8c\x1a\x69\x39\xaf\xc4\x25\x76\x70\xf0\x10\x09\x72\x66\x54\xab\xa2\xd2\xae\x90\x61\xd5\x07\x63\xbd\xbc\x13\xc2\xce\x0c\xaa\x47\x61\x1f\x78\x6d\xeb\xd8\x52\x2d\xe4\xc8\x70\x7c\x15\x32\xdb\x57\xcf\xff\xf4\x0d\xb2\x2e\x91\x25\xf9\xe6\x39\xe4\x6c\xab\x21\x2e\x62\x90\x6d\x66\xa3\xc8\x69\x96\x19\xb3\x21\x64\x4a\x43\xe8\x55\x4c\xf8\xd9\x79\x50\x77\x67\xb7\x3b\xab\x52\x17\x17\xff\x00\x3d\x8a\x6b\xc5\xb2\xe9\x10\xab\x92\xbc\x59\xb3\x0b\x1b\xc3\xae\x95\x3e\x50\x1a\xb6\x01\x0a\xd0\x95\xcc\xaa\x9c\x1d\xb2\x2b\xde\x47\x13\xa7\x68\x34\x67\xea\x67\x5c\x41\x01\xd8\x24\x93\xc9\x25\x49\xed\x8f\x41\xe6\x49\x13\x09\xbc\x3d\x15\xda\xe6\xe0\x74\xc8\xbd\xb9\xf1\xfb\xa3\xac\x9b\x9c\x16\x85\xaf\x11\x2a\xe9\x75\x44\x0c\x58\x93\x00\x57\xd0\x11\x4f\xa6\xb3\x9b\xb9\xab\x93\x79\x64\xbf\xc8\xc8\xcd\xd6\x43\xb4\xce\x3a\xe9\xee\xa3\xae\xdf\xbe\xbd\x63\x32\x62\x88\x7a\x40\xb7\x1a\x0a\xf8\x37\x56\x95\x2c\x55\x45\xfa\xc2\x3a\xcf\x18\xa8\x00\x18\xf6\x01\x91\xdc\xde\xe1\xda\x83\x77\xb3\x5b\xca\x51\x44\x17\xe1\xbd\xca\x39\xd5\x56\x21\x74\xee\x6b\x4a\x0a\x56\x2a\xae\xcc\xbe\xfc\x13\x2c\xa8\x83\x8c\xf2\x3c\x70\x01\xae\x87\x08\xb8\xb8\x01\x3e\xb9\xbb\xa4\x3c\x95\xa9\x1d\x10\x44\x21\x42\x47\xaf\x50\x6b\x63\xad\xb6\xc7\x0d\x75\xdd\xa2\xf2\xa7\x9a\x9a\xb1\xa4\x34\x67\xbc\xa8\xc4\xab\x9e\x92\x80\x84\xef\x7b\xac\xf2\xd1\xbf\x7c\x4f\x62\x00\x04\xa3\x9d\xdc\x58\x12\x46\xc6\x23\x2e\x94\x40\xa5\xb7\x76\xe0\x98\x60\x14\xdc\xac\x09\x7b\x2b\xd9\x7d\xb9\xbb\x56\x21\x89\x24\x2a\x65\x41\x67\x9d\x7a\xf9\x34\x28\xd5\x1c\x36\x04\x9a\x30\x66\x10\xfc\xee\x61\xd7\xe0\x2a\x96\xd6\x38\x3a\x80\x92\x84\xd1\x51\x47\x60\x6b\x20\x60\x3d\xf6\x35\x5d\x10\x5a\xca\x4a\xa4\xd6\xbf\xe4\x1d\x7c\x6f\x1a\x0f\x3e\x91\x82\x39\xc7\x79\x13\xa7\x02\x3c\xfa\x5c\x90\x17\xe3\x17\xcf\x9f\xca\x4e\x05\x5f\xd8\xd8\xa9\x4e\xfc\x4e\x85\xf2\x69\xad\xdf\xea\x10\xef\x7b\xfa\xde\x37\xd6\xc5\x52\x03\xda\x73\x07\x97\x0d\xa7\xae\x4b\xae\x59\xd0\xe3\x6f\x0f\x0c\x17\x63\x1f\x06\xa8\x0c\x83\x55\x9d\x24\x3a\x12\xa9\x1b\x0c\x86\xaa\x26\x0f\x28\xb7\xac\x80\x82\xe5\xb6\xca\xc3\xa5\x6e\x11\x61\x21\xa1\x76\x76\xc8\x1e\x5e\xb9\x8b\x05\xcd\x83\xb5\xb2\x96\x25\xda\xd1\x87\xa2\x03\xc6\x66\xa3\x76\xbe\xa0\xe0\x83\x2b\x7a\xa4\xe0\xf7\x6c\x4e\xaf\x18\x14\x72\xf3\x8c\x96\x19\xc4\x1c\xcf\xf1\xdd\xc9\xa4\xd2\x84\x89\x2b\x5e\x4a\x91\x33\xa1\xc9\x15\x2d\x39\xa0\xe2\x94\x0c\x90\x1d\x8c\x2d\xfa\xc7\xbd\x9f\xf6\xcf\x20\xa1\x61\x60\x21\x29\xec\x5b\x56\xca\xc1\xd7\x84\x6f\x12\x0c\xf7\xc9\xe9\x73\xef\x61\x68\x08\x32\xd7\xbd\x97\x79\x4e\x5e\xe9\x0a\xdb\xb2\x7c\x48\xb2\x4a\xf1\xab\x75\x49\x12\x5b\x61\x7f\xc8\x5b\xcd\x73\xa3\xda\xbf\x26\xd4\x52\xe1\x3e\xb8\xd6\x57\x14\xe8\x2d\x05\x4c\x76\x95\x2f\xda\x0b\x63\xe0\xd6\xf5\x64\xb1\x34\x30\x7d\xce\x21\x2e\x2e\xa9\x10\x80\x1b\xb3\x5e\x27\x94\x90\x29\xbb\x3f\xea\x4e\x9c\xde\x63\x87\xc0\x98\x79\x50\xc1\xa7\x92\x39\x4b\x2b\x80\x77\xe2\x0a\xc1\x51\x8d\xf9\x40\x6b\x14\x3e\x01\x5d\x82\x8e\xa7\x1e\xd2\x40\x8c\xc0\x39\x88\x34\x77\xf7\x97\x0e\x00\xc1\x9d\x50\x8d\x11\xc1\x28\x35\x63\x0d\x09\x55\xaa\xca\x71\x49\x60\x03\x84\x29\xd7\xca\xf7\x98\x75\xda\xb1\x59\x18\xf7\x2c\xa8\xea\x40\xdf\x73\x96\x01\x73\x75\xa0\xf1\xee\x49\x30\x0e\x12\x5a\xb9\xbf\x2c\xc3\xd9\x84\x09\x88\xb6\xf9\x3c\x4e\x09\x5e\xd2\x29\x87\x26\x4a\xd4\xd2\xfb\x7c\xc5\x9d\xa8\x3a\xe0\x15\x00\x0f\x43\x27\x2c\x53\xcd\x81\x26\xf5\xa4\x58\x54\x52\x4b\xf8\x8e\x5d\x72\xa9\x52\x7c\x26\xa0\x7f\xa6\x19\xed\x9e\x9d\x32\x5b\xdb\x4c\x7d\x74\xc1\x6d\x2d\xd5\xa2\x2c\xac\x9c\x16\x23\x6b\xf5\x6a\x99\xf3\xe4\x1e\x23\xc9\x7b\xbe\x72\xa3\x56\x3a\xaa\xc1\x7d\x7b\xbe\xe4\xf1\x51\x81\x57\x63\x4c\xce\x65\x6e\x53\x9c\x44\xd0\xc5\xcb\x35\x53\x35\x3b\x46\xc9\x0c\x2d\x20\xf1\x88\xd7\xd1\x78\xe8\x7a\xe3\xaa\xa0\xe1\x39\x5e\x25\xb7\x61\x5c\x80\x9f\xb4\xcd\x5c\x65\x96\xc9\x6b\x48\x2c\xc6\x71\x1d\x6f\x43\x0a\xcc\x4b\x32\x6a\x74\xa6\x1d\xc7\xa0\xa1\xb7\x3f\xc7\x5e\x3b\xfc\xf4\x53\x30\x3f\x07\xe0\xf8\x8e\x0f\xc3\x3f\x8f\x4f\x0f\xdc\x9f\xcd\x37\x89\x9b\x30\xdc\x7c\x55\x08\x87\x7d\xd3\x55\x53\xec\x63\xf4\x89\x9f\x0f\xe6\x54\xb8\xb8\xd5\x8d\xcf\x5b\xa8\x44\x67\xf5\xeb\xcc\x69\xc9\x2c\x5c\x9c\x11\xdc\xaa\xa0\xc9\x8d\x6f\xe1\xb1\xd9\x6e\xbd\xe0\xd6\x37\x55\x55\xe1\xfa\x6b\x67\x70\xa1\x7f\x93\x9a\xcb\x7e\xf9\xe2\xd7\x3b\x12\xf3\x53\xf7\xac\x22\xed\xed\xf7\x44\x5d\xfa\xee\x74\xc7\xea\x1e\x5e\x77\xbb\x37\x68\x83\x77\xa7\xeb\x6f\x6a\xc1\x7b\xd7\xa7\xb9\xd6\x6d\x77\xfb\xb0\xe6\x6c\xdf\xe1\x72\x9c\xfb\x4f\x67\xcd\x99\x05\x79\x0c\x88\x9b\xd3\xc5\xa9\x4c\xcd\xda\xc4\x14\xb9\xfb\x01\x1b\xb4\x96\xf6\x6d\x3d\x63\x2d\xfc\x59\xed\xfd\x58\xed\xfc\x02\x0d\x5d\xe1\x06\xd4\x53\x8b\xc8\x26\x66\x24\xc2\x99\xaa\xca\x92\x09\xe8\x90\x5f\x41\x52\xa4\xeb\x7c\x8f\xf2\x1c\xe4\xb2\xc5\xf4\x44\x60\x7a\xb2\xef\xb7\x4d\x9b\x2c\x97\x53\xc0\xf9\x0c\x70\xad\xa7\x15\xe4\x3e\xc2\x2e\x81\xb8\x75\x52\x98\xf7\x78\xb9\x0a\x4c\x43\x16\x4c\x04\x6d\xf1\xad\x82\x3d\x32\xfc\x17\xc1\x6b\xa0\xce\x30\xce\xd3\x3f\x14\x19\xd5\x53\x59\xe6\x23\xa7\x49\x8e\x22\x7d\x82\x1c\x40\x16\x8e\x72\xa6\x18\xa6\xc2\x22\xfe\xa6\x48\x33\x16\x6c\xfc\xfe\x53\x45\x8a\x68\x55\xa4\x12\x25\x4b\xe4\x4c\xf0\xff\xd4\x84\x80\x2d\xd0\xfb\x91\xa8\x32\x9b\x2e\x11\x55\x96\xdd\x3f\x65\xa1\xa5\xbe\x20\xaf\x58\x39\x67\xf4\x9e\xcc\xdb\xc8\x7e\xb1\x63\xd4\x6d\x4a\x95\x85\x1f\xb0\xda\xb1\x7b\x88\xd1\xa2\x65\x02\x65\x70\x18\x8d\x77\x39\xce\x14\xf6\x7e\xa3\x14\x52\x32\xe3\x57\x4c\x38\x74\xf2\x83\x8c\xfa\x56\xdb\x0e\x90\xd5\x22\xa4\x57\x5a\xfa\xfc\x06\x42\x75\x80\x91\x0c\xe9\x50\x36\xb4\x1a\x8e\x13\x5c\x62\x1b\x75\x67\xae\x29\xda\x5d\xae\x84\x14\x03\xec\x12\x39\xac\x3f\x29\x77\x6e\xd8\x08\x84\x93\x24\x90\x08\xe3\xac\x16\x9b\x00\xf3\xe9\x47\xd8\xec\x35\x23\x83\x56\x0d\x63\x35\x6b\x8f\x16\x5b\x13\x36\x33\x5b\xc7\x02\xf5\xa1\xe3\x69\xfc\x24\x1e\xe1\xf3\x43\x99\x14\x68\xea\xb5\xe9\x78\x2a\x53\xa3\xb0\x0d\x89\x9f\xca\xb0\x4f\xb9\x0d\xcd\xe0\x9a\x0c\x16\x23\xea\x73\x65\xc9\x54\x21\xb1\x4d\x40\xf8\xd8\x61\xe0\x2a\xe3\x3a\xca\xcb\xc3\x86\x6f\x7e\x69\x20\x90\xdb\x7f\x58\x29\x57\xaa\xfb\x33\xae\xc7\x97\xdf\x80\xae\xcf\xc4\x9c\x8a\x04\xcd\xac\x67\x97\xac\x50\xcf\x14\x9f\xa1\x6a\xff\x97\x6f\xbe\x01\x3d\xdf\x91\xe4\xd9\xd9\xd1\xfe\xe1\x9b\xa3\x71\x9e\x3e\x22\xa5\xbf\xa0\x5a\xb3\x52\xbc\x24\xff\xb3\xf7\xfe\xcb\x8f\xa3\xc1\x77\x7b\x7b\xbf\x3c\x1f\xfd\xf5\xd7\x2f\xf7\xde\x8f\xe1\x1f\x5f\x0c\xbe\x1b\x7c\x74\x7f\x7c\x39\x18\xec\xed\xfd\xf2\xe3\x9b\x1f\x2e\x4e\x8f\x7e\xe5\x83\x8f\xbf\x88\x2a\xbf\xc4\xbf\x3e\xee\xfd\xc2\x8e\x7e\xbd\xe3\x20\x83\xc1\x77\x7f\xbc\xe7\x8b\xb6\x2c\x61\xe9\x5a\xb6\xd2\xa9\x54\xa5\xc7\xf2\x94\xa2\x64\x2c\x07\xf1\xd7\x26\xb1\x2b\x76\xa8\x36\x86\x72\x1b\xac\xfd\xcb\xc8\x44\xf7\x34\x31\x33\x62\x52\xa1\xe8\xcc\xe4\x35\x24\x63\x72\x69\x14\xa7\x31\x79\x0b\xfb\x20\x39\x61\x57\xac\x1c\xba\x51\x5f\x9b\x8b\x4e\xfd\x35\xa1\xc7\x6e\xd5\x15\x2d\xcb\x01\x5a\xce\x89\x7b\xf7\x0e\xc4\xc3\x16\x27\xf6\xe5\x41\x3e\x8d\xc9\x4f\xb4\xe4\xb2\x52\x56\x17\x09\x91\xc1\x31\xdb\xcc\xef\x24\xe0\xc0\xb0\xb1\x20\x3f\x88\x2f\x22\x73\xe1\x20\x4f\x9b\x7d\x2f\xaf\x0f\x56\x6f\x09\x5c\x9b\x99\xba\x72\x8f\x2a\x5d\x56\xec\x12\xa8\x38\x6e\x06\x2b\xe5\xbf\xdb\xd1\x54\xf8\xa2\x30\x8c\x7b\x0f\x90\xad\x46\x13\xc3\x51\xe6\x7c\xe6\x72\xaf\xe1\xfb\xd1\xd2\x0d\xce\x7a\x0e\x69\x31\xa5\x6d\x96\x69\xdb\x12\x80\xa2\xf9\x7d\x1d\xd8\x22\x86\x5e\x0e\xd1\x9b\x5d\xf1\x51\xbd\x6e\x76\x90\x4f\x60\x13\x19\x25\x25\xd7\x3c\xa1\xd9\x0e\x6c\x4e\xee\xa7\x24\xab\x8c\x9e\x18\xfe\x5a\x32\xa2\xaf\x25\x3e\x85\x66\xe4\x92\x2d\xae\x65\x99\xba\xfd\xd9\x3d\xb1\x9e\x0b\xa5\xdd\x23\x8d\x2d\x08\x0b\x18\x3d\x12\x65\xce\x4a\x32\x61\xce\xd9\xde\xb8\x78\x31\x26\xfb\x62\x61\x23\x95\x22\xac\x47\x0c\x40\xdc\x40\x47\x40\x2d\x2a\x62\x12\xbb\x89\xb9\xa7\x51\xac\x14\xbd\xc9\x11\x6d\x14\x30\xbf\x0a\xdc\xee\xef\x3c\xd1\xb2\xb4\x05\x51\xb0\x3a\x4a\x2c\xe7\x92\xee\xe7\xcf\x22\x2d\x8c\x7e\xc3\x05\x53\xea\x07\x33\x95\x5d\xd4\xd5\x98\x3b\x28\xa8\x25\x76\x6c\x28\xaa\xaa\xb3\x8f\x99\x59\x52\x18\x4e\x36\x62\x58\xa6\xf5\x95\x63\xb2\x0f\x27\x20\x7d\xde\x68\x5e\x50\x70\x67\x06\xe3\x5a\x35\xfb\xd0\xe3\x15\xfb\x27\x87\x2e\xcd\x19\x35\x05\x15\x23\xab\xa3\xca\x1c\xbf\x09\x68\x7a\x36\xd9\x96\xfd\x56\x51\x68\xa9\xbb\x73\x51\x56\x6c\xa7\x9d\xaa\x84\x98\xfd\xcf\xfe\xfc\xcd\x73\xd0\x96\xfc\xf3\x46\xf0\xbc\x36\xaa\xd2\xfd\xd3\x69\x5a\x25\xd2\x34\x73\x88\xce\x42\x7e\x70\x04\x77\x76\x87\x8d\x6f\x41\x19\x30\x4c\x93\xa7\x79\x2b\x2f\x6c\xab\xb4\x99\xf6\x09\x33\xa3\xfa\x75\x2f\xee\xdf\xee\xac\x4b\xae\x4b\xf4\xdc\x3e\x02\x62\xf5\x68\x38\x2b\x0a\xa7\xc4\x3f\x27\x70\x02\x63\x57\x0c\x7b\x1a\x32\x67\x41\x70\x41\x00\x01\xc4\xe3\xa2\xe8\x90\x25\xdc\x42\xde\x40\x51\x4c\x67\xfd\x6e\xf7\x0c\x07\x22\x45\xad\xd0\x2d\x15\x3b\xf8\x60\x30\xe8\x1d\x56\x95\xdb\x87\xca\xb1\x21\x79\x2b\x5e\x61\x2a\xfd\x10\xb5\xbb\x08\xa8\x04\x2f\xea\xb5\xa2\xf0\xd9\x1f\xec\xb7\x8f\xf0\x95\xdb\x08\x85\xfb\x93\x3b\xb0\x1c\x3b\xee\xfe\xbb\x67\x8d\xb1\x22\xd6\x8b\x2c\x63\xbb\x43\xf2\xba\x4d\x9a\x15\x9f\x64\x56\xca\xaa\x70\x41\xd7\xb8\xe7\x59\xdd\xe8\x03\x63\x85\xd8\x12\x58\xc8\x78\x68\xef\xfc\x00\x06\x66\xb5\xd7\x2c\x25\x09\x9a\xc7\x6e\xd7\xc5\x82\x29\xf4\x20\x94\x95\x88\x5b\xa2\x07\x61\xcb\x9d\x8c\xcd\x68\xb2\xd8\x89\x9f\xb3\x2a\x48\xcc\xa1\x8e\x87\xe7\x88\xad\x8e\xcf\xab\xcb\x1f\xa0\x4a\x02\xf4\x07\x5c\x6b\xa0\x1a\x54\xca\xbe\xa2\xdb\xf2\x5d\xfd\x1e\x7a\xb6\xca\x0e\x96\xf9\x9f\xbf\xf9\xf3\xc8\xf9\xde\xe0\x55\x3e\x0b\x43\xf9\x20\x6f\xaf\xba\x64\x34\x67\x46\x41\xe2\xaa\x80\xf9\x05\x4d\xac\xde\xce\xfd\xd3\x6f\x53\xb7\x56\x0f\xe2\x26\xa0\x1e\xe2\xb3\x90\x2b\xf6\xc0\x77\x59\x7e\xcd\x0e\x31\x73\x99\xa5\xb0\x50\x6c\x1f\x27\xf7\x28\x42\xb5\x2e\xf9\xa4\xd2\xd6\x4d\x9a\xc8\x3c\x8f\xcb\x2b\x6d\x2f\xbd\x31\xa9\xeb\xeb\x42\x13\x16\x38\x79\x4c\xc8\x39\x63\xd8\x47\x32\x78\x0f\x90\xb3\x8e\x94\xd6\xdb\x2a\xa7\xd8\xf4\x1b\x8d\xb0\xcf\xe4\x16\x6a\xbf\x1d\xdb\x40\x5c\x47\xaf\xfd\xce\xbe\xb7\x52\xc2\x78\x19\x0a\xb8\xa5\xd6\xbe\x8d\x9d\x09\x32\x8f\xeb\x00\xad\x4d\x44\x32\xb4\x50\x08\x27\x0b\xbc\xfc\x23\xb6\x01\x85\x2c\x4b\x88\x1a\xa2\x6f\xf2\xda\x0c\x31\xe7\x05\xda\xd4\x54\xfb\xdb\x21\xde\x6f\x7e\x0e\x51\x1a\xa0\xaf\xe5\x0b\x34\x6a\xe5\x35\x78\x85\x7f\x38\x3e\xf4\x6b\xc4\x5c\xf5\xea\x1c\x43\x42\x5f\x8d\x6d\x97\x5e\x3d\xe3\x29\x99\x60\x8e\x87\x91\x97\x7b\x82\x5d\x63\xd6\xb8\x75\x9c\x7a\xbd\xfa\xca\x65\x53\xe3\x68\xfe\xe1\x76\xc8\x01\xf9\xda\xf6\x4b\x65\xa5\xb3\xca\x27\xdc\x66\x95\xbe\x3d\xdb\x75\xee\xea\xeb\x51\x79\x3d\x1a\x8d\x46\x36\x14\x0c\x52\x7a\x18\xd1\xc0\x0b\xf3\x5c\xa6\x7c\xba\x68\x50\xc2\xb0\x79\xfd\x08\xe0\x48\x2a\x16\xf6\xed\xba\xb7\xf6\xbd\x3f\x92\x77\x37\x77\x5c\x17\xe4\x86\x15\x61\xe6\xae\xf1\xa9\x55\x91\x6b\xb4\x93\x55\x0d\x80\x2e\xa7\xc8\xa4\x90\x68\x7f\xc3\xc4\x38\x2f\x90\xe5\x1a\x0b\xeb\x87\x56\x3a\xfb\x50\x48\x04\x0d\x86\x42\x16\x68\xee\xd6\x0c\x4f\x40\xf2\xa8\x59\x55\x90\x8f\x17\xad\x1a\xab\x50\x60\x44\xcc\x11\x81\x4c\xa8\x19\xd2\xbf\xce\x5e\x83\x4f\x06\x63\x72\x6c\x59\x0b\x0c\x42\x21\x6d\x8b\x38\x22\x05\x61\xc5\x9c\xe5\xac\xa4\x59\xfc\x20\x5b\xd0\xfb\xd2\x88\xdb\xd2\x70\x29\x86\x00\x72\x5a\xa0\xb4\x05\xe1\x99\xf2\xd2\xb5\x98\x0d\x42\x73\x3b\x6f\xc5\x99\x94\xfa\x0d\x57\xa0\xbb\x58\x67\x08\x6a\x9a\x3b\xab\x36\x34\xf7\x5b\x9d\x1d\xdd\x95\x93\x3f\x5b\xfc\x8b\xb8\x36\x71\x7d\xc8\x5a\x23\x41\x8c\xd0\xba\x6f\x27\xb8\x77\x16\xef\x27\x6a\xb8\xeb\x7d\xb1\xab\xfa\xbc\x2d\x35\x79\xfb\xcc\x5d\xde\x6c\x02\x17\xd5\x11\xb0\xd6\xe7\xee\x4c\xbe\x3e\xe9\x05\x2c\x73\x22\x61\x9d\x74\x64\x9a\xe3\xe5\xe6\x72\x35\x8b\x80\xbb\xcf\x77\xcd\x14\x52\x8c\xa0\xd9\x53\xa5\x5c\xe0\xb2\x74\x2e\xdf\x68\x03\xb2\x1d\x28\x71\xdb\xc4\x2e\x82\xb4\x56\xe9\x8d\xea\x24\x54\x55\x32\x9f\xcc\x98\x4a\x56\x37\x7e\xa2\x8a\xbc\x3b\x3e\x24\xcf\xc9\x1e\x24\xf2\xfa\x62\x6e\x84\xaf\x30\xa6\x6c\x23\xdb\x74\xea\x86\x88\x4d\x17\x8b\x1d\x21\x24\xca\x22\xd7\x15\x53\x0a\xbf\x0d\x5b\x0c\xce\x1b\x7a\x19\xae\x9b\xc7\xdb\xf2\x63\xbb\x74\x7d\x9f\x21\xd3\x83\x0c\x7a\xd7\x42\x06\x85\x8a\x75\x1f\x9d\x28\xd7\x3d\x7b\xbf\x77\x09\x15\x27\xb9\xf5\xc0\x54\xe7\x47\x30\x20\xe2\x46\x7c\xd0\x56\x8d\xbf\x67\x9b\xf3\x65\x7c\x20\x0b\x92\xe4\xa1\x04\x4a\x2a\x52\x99\x2f\x3d\xcd\xcc\x26\x18\x6f\xc1\x6c\x6e\xd9\xee\xa6\xa3\x53\xb5\x67\xb7\x62\x49\xb0\xf1\x7b\xa8\x92\x7d\x0d\xbe\x02\xae\x3c\x27\xa0\xf3\x00\xf2\xc7\x97\xcc\xd6\xce\x20\x0a\x9d\x8b\x86\x4a\x99\xb5\xac\xbb\x8b\xbe\xfa\x4c\x66\xb6\xde\xc1\x7d\xb6\x19\x78\x63\xbf\x5a\xb7\x0c\x13\x34\xc5\xcb\xa2\x68\x7c\x35\xb8\x73\x36\xf5\xab\xab\x56\xbb\x34\x69\x7e\x35\xa4\xc3\x46\x5f\x0d\xfb\xee\x26\x7e\x75\x9c\xfd\xdc\xc3\x66\x62\x07\x24\xd2\xe6\x60\xdb\xa6\x03\x4d\x3c\x94\x3a\x43\x12\x9c\x50\x8f\x4b\x8e\x76\xa9\x98\xc7\x44\xa7\xcf\x2d\xba\x65\x42\xb3\x39\xb6\x7c\x6f\x37\xcf\xa4\x39\xd7\xcd\x21\x83\x64\x0c\x6a\xde\x16\xce\x05\x29\x85\x14\xc1\x9c\x64\x1d\x90\x69\x04\x5f\xac\x9b\xce\xde\xe9\xb2\x21\xcc\xfe\x5b\x67\x38\x86\x77\x6b\x69\xbb\xd0\x3a\xd0\x78\x0a\x2f\xc8\x30\x5f\xb1\xa0\x7a\x3e\x24\x25\xcb\x10\x07\xd6\xae\xb3\x4b\x34\xa5\x76\xa3\xb4\x49\xc7\xb1\xee\xd1\xa0\xb0\x40\x17\x6a\x18\x19\x5c\x3e\x4e\x0d\x99\xa2\xfc\xe2\x8a\xec\xbc\x76\x04\xd8\x79\xcc\x02\x7a\x07\xbf\xc7\xcf\x1d\x7a\xb1\x2e\xb9\x48\x2d\x40\x6a\x44\x1a\x9f\xa2\x8b\xba\xa1\xf3\x30\xb9\xb5\x4e\x4b\x06\xce\x5e\x4f\x1a\x32\x6a\xcd\x0c\x36\x14\xe6\x02\xa2\xa3\x1b\x94\x4c\xe7\x53\x71\x0f\x69\x0e\xf3\x4e\xc0\x4c\x0b\xa8\x9d\x10\x72\xc5\x75\xee\x5b\xda\x35\x4b\xec\x22\x7a\x97\x8a\x5c\x3a\x8a\xdf\x7d\x0f\x4b\x35\xc3\x9a\x99\x40\x85\xaf\xa1\x2b\xad\x5d\x68\x3b\x41\x37\x54\xef\x21\xcc\x8e\xcd\x77\x5d\xda\x9d\x30\xbd\x2a\xa7\xe5\x82\xfc\x70\x7c\x88\x1a\x78\x64\x08\x08\xe9\x1e\xed\x39\x25\xb5\xe8\x84\x54\x2c\x36\x40\x71\x6e\x87\x10\xd3\x1a\x1f\xa6\x2b\xf2\x6e\x27\x33\x11\x4b\xb8\x3a\xf2\xd4\xb9\x2d\x04\x9b\xcb\x2c\x25\xd4\x33\x98\x70\x45\x60\xa9\x7b\x0e\x06\xd0\x83\xea\xcf\xb1\x31\xbe\x6c\x70\xba\x12\x75\xa5\x88\xbb\x7e\xaf\xa9\x12\xb8\x35\x3d\xb0\xa5\xd0\xce\x33\x95\xd1\x4a\x24\xf3\xdf\x0b\xcb\xac\xa0\xbe\x0f\x75\x50\x72\xc9\x4a\xc1\x32\x52\xd0\x92\xe6\x4c\xfb\x66\x87\x8a\xb5\x81\xfe\xe9\x88\x1c\xd4\x0d\x37\xa8\x03\xe6\x4f\xfb\xa6\x85\x5d\xd1\x82\xba\x60\xb0\xac\xe8\xe4\x36\xc5\xdd\xd1\xbc\xd2\xc2\x36\xf8\x6c\x39\x78\x67\x60\x8c\x4e\x6d\x08\x63\x10\x2c\x44\xf0\xdf\x88\x6f\x8b\xcb\x7c\x7b\xb0\x6e\x7e\xc6\x01\x6b\x3c\x02\x97\xc9\x70\x5f\x77\x99\x53\x99\x96\x51\xc0\x76\xd5\x92\x2b\x2a\x6e\x99\xf0\x99\x7d\xe5\xad\xe5\x2e\xd4\x01\x3e\x2a\x0f\xd7\x2c\x57\xf4\xa0\x64\x50\x71\x4a\xb3\xf3\x82\xb5\x6c\xe2\x1f\xb7\xf0\x7f\x73\xbe\x1f\x0f\x0a\x9b\x12\x24\x5b\x9b\x39\x31\xbf\x07\x25\x03\xd7\x6c\x32\x97\xf2\x92\xec\xad\x28\x7b\x0c\xaa\x5c\x14\x9f\xa9\x67\x96\xbd\x47\xe6\xbd\x07\x84\x0b\x80\xb2\x5d\x86\x00\x76\x0f\x49\xfc\x5b\xc0\x5c\xd9\x9c\x35\xbb\x0d\x2f\xbf\x26\xc8\x28\xcc\xa8\x59\x87\x81\xb3\x3c\x19\xf7\xcf\xf7\x72\xc7\x27\x26\xe4\xa6\xf2\xd7\x95\x54\x43\x87\xc6\x5a\x48\x62\xcd\x6d\xa3\xbe\xf7\x40\x87\xbf\xd7\xa3\x85\xc8\x6b\x7c\x1a\x81\xc2\xd7\x86\x92\x0f\x56\xee\x42\x73\x2a\x7b\xeb\x6e\xa8\xd5\xc7\xd0\x69\x34\x2b\xe6\xd4\xa6\x86\x61\x39\xb0\xcb\xa0\x98\x30\x32\x97\x42\x96\xb6\xcc\xa1\x2e\xe4\x01\x31\x83\x75\x37\x30\x03\x56\xde\x06\xaf\x7a\x50\x7b\x90\x5c\xbf\x94\x69\x46\x67\xd0\xdc\xa6\x51\x8d\x03\xc2\x55\x56\x18\xd5\x0c\x2f\x76\x25\x8b\xae\x71\x03\xe0\x46\x2b\x94\x62\x2e\x98\x69\xcb\x36\x20\x0b\x64\xdf\xbc\xb7\x21\xcb\xa9\x4b\x66\x76\xaf\x00\x6e\x0a\x5f\xb4\xa9\x0c\xef\x60\xfe\x06\xbf\x62\x11\x81\x51\xf2\xee\x39\xd4\x1a\x8d\x49\x56\xb8\x5f\xc0\xfd\x94\xe4\xfc\x83\x79\x4a\x78\x57\x58\x6d\x20\x52\x88\x12\xaf\xfe\x79\x60\x8c\xb1\xda\x72\x1b\x9a\x59\x0c\xaf\x0c\x9a\x2a\x08\xf8\xe1\x04\xcb\x05\xf0\x03\xc2\x48\x8b\xed\x8f\xd0\x85\xbf\xdb\xa3\x9a\xf9\x50\x69\x4f\x4b\x1d\x42\xa6\x76\x38\x33\xd1\x6e\xfb\xee\x12\x42\x35\x97\xf4\x11\x46\x5d\xde\xa3\x3f\xfb\xd6\xfe\x39\x65\x98\x62\xe5\x15\x4f\xd8\x7e\x92\xc8\x4a\x74\xca\x42\x3d\x64\xe6\x13\xa8\x66\xe9\x79\x34\x26\x7a\xdc\x53\xf8\x15\x2b\xd1\x69\xc6\x29\x22\x12\xc5\x57\x62\x91\x5d\x3d\x0e\x78\xec\x1b\x6f\x68\x59\x46\x69\x46\xdb\x65\x94\x76\xa4\x50\xd7\x54\xf9\xe5\x2f\x5e\xb5\xc3\x35\x28\x68\x9d\xf5\x4b\x69\xf0\x77\xab\x41\xd0\x54\x5d\xd6\x38\x4d\x0c\xca\x90\xfc\x62\x0a\xce\xdb\x0f\x1d\x51\x7c\x6a\x2b\xec\xa6\x16\xd4\xd5\x46\xee\x99\x8f\xdf\x57\xaf\xfe\xfb\xf0\xa4\x5b\xe6\xb8\x6f\x51\x83\xf5\x2d\x73\x3b\xb4\x57\xd5\xc3\xb2\xfc\xb0\x3c\xd1\x3c\x79\x48\x4a\x6a\xd1\xf7\x6d\xe7\xb5\x8c\x51\xf4\xa9\x90\xbd\x20\x53\x7f\x30\x36\x32\xbd\x8e\x96\xa3\xa8\xb7\x8d\xd2\x72\x46\x85\x0a\x4a\x50\x19\x0c\xed\xb2\x62\xfd\xfb\xe0\x46\x68\x67\xdb\x7a\x0f\xf6\x9c\xd3\x35\xbe\x42\xe9\xb2\x4a\x34\xa9\xb4\x32\xe7\xf1\xe1\x4e\x60\xde\xe1\xf1\x25\x9b\x71\xa5\xcb\x85\x6b\xe1\x36\x0d\x5e\xc2\x7a\x85\xfc\x25\x97\x6c\x41\xfe\xfe\xe3\xd1\x3f\xfe\xf9\xfa\xed\xc1\xfe\xeb\x7f\xbe\xd9\x3f\xf8\xfb\xf1\xc9\xd1\xfb\xf7\xe7\xff\x38\xbf\x38\x7a\xf3\xfe\xfd\x01\x22\x8c\xd8\x72\xdc\x73\xa6\xdf\xbf\xb7\x9c\xaa\xde\xbf\xbf\x48\x0a\x5e\xbc\x7f\x7f\xea\x7c\x20\xd8\x9c\xe1\xbf\x0f\x4f\x40\x7e\x62\x55\x98\x4f\x7b\x82\xbd\x15\x89\x0e\xef\x3d\xa7\xaa\x4e\xb2\x8c\xea\x6d\x5a\x00\x7a\xb6\xdd\xee\x56\xc2\x29\x75\x5a\xec\x66\xc0\xba\xab\x92\x73\xf1\x7a\x2f\x1d\x99\x30\x7d\xcd\x6c\x19\xe3\x4a\xbc\x2e\x1a\x14\x46\x07\x10\x5c\xab\x3a\xb7\xa0\x72\x26\xc9\x15\x67\xd7\x88\x39\x81\x4d\xf2\xea\xf6\x41\x50\xd6\x8c\xa5\xad\xcb\xa8\x60\xa0\x24\x15\x32\xf5\xad\x92\x1a\x7e\xe9\x25\x9f\x74\x54\x46\x83\xb8\x6f\x2c\x25\xa7\xc7\x87\xe4\xc5\x18\x95\x9c\xe3\x43\x84\xa1\x5c\x89\x52\xe5\x2c\x55\xb3\xa1\xe2\xee\xbb\xa2\xea\xa0\x66\x80\x36\xc2\xa8\x05\x07\x54\x93\x54\xe6\xf4\xbe\x4d\xd1\x3e\x51\xbf\x82\x2d\x2b\x7f\xab\x68\x86\x3a\xc0\xa9\x4c\x97\x25\xd3\xce\xb7\xee\xd4\xdf\xc6\xdf\xfa\xf7\xf8\xdb\xf8\x5b\x68\x86\xe9\xc8\xf6\xb7\xb1\xba\x4a\xc6\xdf\xda\x02\x69\x62\x2f\x5a\x99\x23\xbc\x54\xed\x64\xf5\x59\xbc\x07\x9e\x4d\x41\xdf\xfd\x2c\xe5\x2e\x3d\x76\x15\xed\xb9\x97\x28\x6a\x81\x50\x7b\x9d\x94\x8c\x62\xaa\x39\x49\x59\xc6\x6a\x1c\x98\x0d\x68\x66\x79\x73\x77\x4f\x17\x6b\x8b\x7a\x9f\x86\xbe\x29\xaf\x2f\xfd\xee\x5b\xa4\x86\x06\xc3\xd7\x75\xc7\xf9\x16\x0b\xa0\x23\x52\xc3\xbd\xc2\x46\x5a\x66\x0c\xe7\xa7\xcb\x4a\x59\x59\x57\xb7\xab\xc2\xd1\xdb\x10\x62\x1d\xd5\xe8\x17\x0e\xc8\xd4\x70\xc4\x85\x7f\x7f\xb0\x34\xb0\xf5\x1f\x06\x57\xf1\x17\xa8\x76\x5b\x10\xb3\x6b\x69\xf4\x64\x84\x15\xa2\xba\x84\x26\x85\xdf\x5e\xb2\xc5\x10\x01\x3d\x50\x09\xf9\x5b\x80\xc8\xec\x4b\xa2\x11\x78\x4d\x96\xe4\x5b\xf7\xaf\xbf\xdd\xd7\x5a\xeb\xe0\x47\xed\xe2\x45\xc5\x8f\xea\x1c\xf9\x3a\xc2\x2a\x98\x18\xe1\x03\x29\x6b\x0b\x64\xb4\x44\x72\x8d\xc9\x11\xd4\xbd\xa2\x46\x6a\x51\x69\xb3\x2c\xba\x58\xb9\x0e\x93\x11\x3a\x04\xf8\x5f\x82\xea\x98\x13\x79\x6e\x2b\x33\x01\x66\x67\xca\xca\xfa\x0c\x08\x98\x13\x79\xf4\x81\x25\x95\xfe\x9c\xd5\xea\x78\x5c\xb2\xee\x3d\xbf\x7e\x64\x1e\x82\x08\x69\x63\xb4\x70\x5f\x99\x50\xaf\xce\x20\x39\xed\x76\xda\x5e\xb2\x85\xf2\x20\x6b\x97\x38\xba\xad\x6a\xf6\xfc\xeb\x36\xb2\xa3\x0f\x5c\x69\xf5\xbf\x5c\xc3\xb1\x7c\x52\xb7\x7a\xa3\x98\x25\x56\x8f\x1e\x00\xec\x99\x3f\xe1\x31\x9f\x9b\xe0\xee\x03\x3a\x53\xfd\xad\xa3\x44\x00\xa1\x47\xcd\x37\xed\x2a\x9b\x9e\x24\x05\x14\xaa\x85\x58\x6c\x75\x62\x0d\xde\x8c\xfc\x89\x34\x04\xba\x1c\x19\x25\x2f\xde\x66\xec\x29\x7b\x11\x07\x54\x11\x7e\x45\x33\x26\x2c\x8a\x6d\x96\x26\xb4\xc4\x10\xbd\x05\x14\x52\x16\x08\xdb\x22\x69\x98\x3d\xce\x4a\xb2\x7a\x96\x95\x0d\xe5\xd1\x52\xf3\xa4\xca\x68\x49\xcc\x7a\x9c\xc9\xf2\x9e\xb8\x43\x78\x74\x6b\x7c\xe7\x59\xb4\x43\x3f\xe8\x58\xbe\x37\x47\x6c\x02\x1d\x5a\xed\xc5\x98\x4c\x50\x5f\x13\x2f\x94\xbd\x18\x48\x5b\x4e\x9d\x6c\xf2\x82\x22\x84\xca\xd3\x91\x73\x9c\xcf\xc0\xff\x3d\x08\x36\x0f\xbf\x32\xc7\xe4\x7b\x5f\x2d\x3e\x24\xb5\xcf\x18\x6a\x52\xed\x33\xed\xb2\xb1\xd3\x55\x2f\xea\xa9\x2c\xa1\x8b\xe1\x5e\x2a\xe1\x1e\x76\xc5\x13\x3d\x18\x93\xff\xd7\x68\x8a\xe0\x44\x76\xea\xa4\x5d\x66\xbe\x0e\xb7\x06\xec\x7b\x4e\xf6\xe0\xb6\x50\x95\x1c\xb8\x40\x91\x45\x02\x7d\x64\xd9\x30\x1d\x22\xdc\x2b\xa2\xdb\x91\x18\x45\x4d\xb1\xc1\x1a\x7e\xe7\x97\x5e\x42\x7a\x99\xc8\x95\x5d\xa5\x91\xe7\xd6\xc7\x59\x9c\x08\xf5\x8c\xf3\x6f\xf0\xd1\x93\x92\xcd\x60\xfd\xe1\xea\xf9\x8c\xab\x4f\xcb\x42\x66\x72\xb6\x38\x2f\x4a\x46\xd3\x03\x29\x94\x2e\x41\x34\x74\xc1\x77\xbb\x69\xcc\xa0\x71\xd6\x5c\x5e\x13\x6a\xcb\xd9\xe5\x14\x11\xf2\x64\x35\x9b\x63\xab\x00\xb8\xd1\x35\x99\x75\xaf\x68\x8d\x4e\x35\x26\xe7\xbe\x15\x00\x30\xb8\xef\x2c\x00\xa3\x80\xc3\xe3\x9a\x2e\xec\x62\xa2\x13\x9e\x32\x15\xe4\x28\xbb\x97\xc1\xd0\xcf\x8d\xdf\x0f\x52\x79\xff\xe4\xf0\xbe\xfd\x17\xd6\xa8\xd0\xde\xf0\x29\x5e\x33\x42\xaa\xd7\xf4\xf5\x1a\x29\xd0\x8d\xe6\xd2\x6a\xaa\x88\xe5\xea\x28\xf3\x19\x75\xd3\x2e\xe0\x4b\x39\xfd\x70\x7e\xc9\xae\x5b\xdc\xe9\x3e\xf4\x47\x76\xff\x54\xb0\x11\xd8\xa3\xef\x84\xa2\x9a\xab\x29\x34\x6a\xf9\x8c\xfa\x38\x14\x1d\xb4\xeb\x27\x81\x47\x5c\xbb\x13\x8e\xe6\x8a\xc2\x3d\xde\x62\xc4\x2c\x36\xff\xaf\xb6\x83\x70\x03\xc4\x22\x08\xdf\x8a\xc2\xac\xa0\xc4\xb6\x67\xd2\xb2\x8e\x43\x63\xa4\xa2\xca\x27\xac\xf4\x6b\x1f\x9d\x01\xbc\x6c\x40\xd3\x36\xd6\x7e\x7b\xc1\xd8\x3a\x13\xae\x6b\x5a\x19\x90\xe7\xe8\x83\xd1\x3c\x54\xbb\x44\x25\x3c\xe2\xee\x6a\x8d\x41\x31\x3c\xe6\x12\x38\x1b\xd3\x10\x75\x39\x01\xb3\x37\x3c\xd3\x56\xce\xd5\x47\xb7\xfe\x8c\xa4\x5b\x8f\x46\xb2\x22\x51\xfa\xc6\xcf\x6f\xb4\x4a\x09\x0b\xfe\xac\x53\x48\x0d\x51\x81\x47\x07\x36\x15\xf5\xc6\x6e\xdb\xe6\x67\x5e\x9b\x33\x46\x91\xb9\x08\xef\xeb\xda\x08\xa9\x43\x8f\x47\xd2\x43\x9f\x47\x02\xb2\xec\xb2\x85\x04\x0c\xef\x77\xc4\x6a\x3d\x48\xf7\x8e\x8f\xa4\xbd\x41\x5d\x1f\x11\x43\x5d\xd6\xa6\x35\x72\x56\x64\x5a\xd7\xc2\xae\x36\xac\x3b\x3d\xbb\x87\x36\x68\xa4\xa3\x8d\x5b\x1f\x11\x21\xe4\x3d\xac\x5d\x0a\x01\x26\x39\x75\xab\x63\xa5\xcd\x7b\x2c\x86\xe4\x44\x6a\xf3\x9f\xc0\xfc\x3d\x94\x4c\x9d\x48\x0d\x67\x36\x82\x94\xf8\x09\x3d\x12\xd2\xb5\x11\x00\xbc\x37\x90\x9b\x36\x44\x6b\x76\x3c\x47\xb0\x15\x86\xc5\xb1\x20\xb2\x74\x14\xf3\xd6\x85\xb2\x43\x84\x61\x05\x8b\xb1\x75\xa3\x71\x62\xc6\x09\xe9\x7c\xcb\x70\x76\x28\xc8\xfe\xc2\x5f\x00\x3c\xb5\xc8\xa0\x40\x20\xad\x4a\xc4\xb0\x35\xba\xa6\x66\x33\x9e\x90\x9c\x95\x33\x68\x1b\x9d\xcc\xfb\x98\xbe\x2e\xfb\x0a\x1e\x1d\x77\x97\xf0\x65\x3a\xf0\x12\x6c\xd9\xa0\x62\xf5\xa8\x02\xe0\x78\xb8\xad\xe5\x14\x2c\xa9\xff\xe3\x7d\xd0\xff\x97\x14\x94\x97\x80\x79\x6b\x63\xc7\xe1\x6f\x36\xfa\x12\x0e\x63\x46\x58\xf2\x2d\x51\x41\x18\x56\x32\x99\xd1\x9b\x8a\xc7\x90\x5c\xcf\xa5\xc2\xcd\xd0\xbb\x3f\x76\x2e\xd9\x62\x67\xb8\xc4\x7a\x3b\xc7\x62\xa7\x0e\x0c\x47\xcc\xe6\x37\x61\xc8\x20\xdc\x81\xdf\x76\x1e\x4e\x57\xe9\xb4\xd9\xf6\xd1\x31\xa0\xf9\x42\x2d\xf9\xca\xda\x3c\x9d\x35\xff\xdd\x37\x38\x50\x60\x9f\x63\x4c\x70\x56\x32\x2c\xc6\x04\x53\x1a\x14\x75\xdb\xdd\xa5\x12\xec\x8a\x99\xc9\x4a\xb9\xb2\x78\x80\x2e\xc5\xe0\x5f\x4b\x26\xd1\xff\xff\x50\x9e\x48\xed\xac\xf6\x7f\x39\xb7\x17\xf2\xdf\x07\x9e\x57\x39\xe2\x66\x69\x63\x29\xa4\x7c\xea\x80\x80\x5d\x66\x43\x6c\x2f\xc4\x66\xab\xe5\x63\x4d\xcb\x19\x64\x38\x5a\x7b\xc1\xb1\xd9\x2c\x93\x13\x9a\x91\x9c\x0b\xf3\x18\x1b\xbc\x8c\xce\xf9\x37\xb1\x7f\xde\xf2\x20\x58\x0b\x7c\xc6\x27\x19\xb3\x06\x49\x03\x63\x3b\xb8\xb9\x71\x21\x2c\xd2\x8c\x29\x85\xf1\xc6\x37\x5c\x1c\x3a\x6f\xc6\x2b\x59\x12\xf6\x81\xe6\x45\xc6\xb0\x44\x8f\x7c\x3d\xfa\x8f\x14\x8c\xd8\x00\xfd\x90\xb8\xe9\xa9\xfb\x96\xbd\xc0\x85\x54\x37\x16\xf0\xd9\x17\x91\x4d\xe8\x3d\x29\x8a\x7c\xf5\xec\xab\x67\x2f\x5e\x9a\x3d\x04\xdd\xf4\x54\x59\x08\xa2\x65\x6a\xbc\x18\x93\x8f\xc4\xbc\xc1\x0b\xfb\xdf\xaf\xec\x7f\xbf\x26\x1f\xc9\x47\x42\x4e\xc9\x29\x09\xff\x6b\xfe\x43\x3e\x92\x91\x21\x42\xf0\xaa\x2f\xcc\xd7\x24\x32\xb7\x14\x04\x1f\xb4\x2f\xb8\xf5\x7d\x03\xb5\xb4\x43\x43\xb5\x53\x22\x73\x06\xaf\xfa\xd5\xff\x72\xd7\x40\xa8\x58\x63\x6b\x47\x78\xa9\x3d\x78\xa5\x01\xb9\x06\xa7\x5a\x4e\x2f\xd1\xa0\xdc\x4f\x74\x45\x33\xf3\xf0\xbd\xaf\x47\x2f\x06\x44\x8a\xf8\xf2\x2b\x2e\x8d\xf2\xee\xde\x70\xef\xc5\x60\xbc\xf4\xca\x5f\xad\x78\xe5\x46\x97\x43\x5b\xee\x68\x06\xbd\x99\xdf\x1d\xab\xef\x8b\xc5\x35\x5d\x78\x86\x77\x06\xf5\x8c\x5f\x79\xb4\xff\x00\x84\x04\xa2\x8d\xc0\xbf\xdc\xe1\x4a\xe1\xa0\x0b\xc2\xf5\x98\x1c\xeb\xdd\x5d\xd7\x53\xd3\xe8\xfa\xae\x2d\xc1\x61\x88\x97\x09\x84\x07\xde\x78\xde\xc8\x46\x6e\x81\xce\xd6\xab\x5b\xf7\x5e\x7d\x05\xf0\xc8\xfd\x2a\xe9\x2c\xe2\x76\xea\x15\x17\x55\xb3\x2f\xaf\xfa\xe6\xc2\xf5\x89\x53\xb7\xae\xee\x06\xea\xb5\x13\x43\x97\x6c\xd1\x58\xf9\xf5\x37\x0d\x21\x87\xc7\x79\xed\x08\xba\xed\xd0\x55\xaf\xc8\xfb\x9d\x78\x5d\xbe\xdf\x01\xe7\xbd\xdf\x3f\x6d\x1f\x1f\x9a\x25\x95\x6d\x00\x27\xa7\xc4\xb1\x71\x80\xd0\xb5\x2f\xd2\x3a\x65\xa2\xe5\xfb\x03\x84\x3d\xe8\x8c\x33\x88\x23\x94\xcb\x5f\x12\xa4\x55\x44\x59\x78\x66\x15\xd6\xeb\x78\x4c\xf6\x91\x81\x15\x04\x3f\xee\xf2\x5e\x37\xd2\xae\x6e\x07\x7b\x2d\xc5\x6e\x0d\xbc\x4b\x72\x89\x10\x69\xc2\x6d\x8f\xd6\x57\x25\x89\x06\x55\xc5\x4f\xeb\xf1\x74\x45\x1e\x4c\xed\x20\x46\xf0\x49\xc3\x24\x50\x37\x11\xf2\x4f\x80\xea\xff\x62\x05\x12\xa3\x5d\x2e\x2a\x26\xd7\x73\xcb\x48\xf5\x33\xa5\xc6\xe7\xfe\xdc\x94\x1f\x5e\xf9\x8e\xf6\x4d\x68\x99\xd9\x66\xb3\xf8\x6a\xd8\x78\x7b\x7b\xfe\xcf\x6d\xf6\x90\xaf\x5e\xde\x6f\x73\xb0\xff\xbd\x88\xa6\x79\xe5\xec\xfe\x79\xaf\x7e\xcb\x01\x04\x30\x57\x2c\x02\x28\x76\xa8\x83\x59\x63\xbf\xa1\x29\xae\x2b\x8a\xf5\x11\x82\x5d\xdb\xa4\xb5\x9b\x3f\x2a\xa8\x71\x73\xc2\x7d\x68\xf6\x1f\x5a\x29\x06\x45\x2b\x15\xd4\x33\x1b\x42\xba\x20\xda\xd7\x7b\x5f\x93\x11\x79\x3e\x30\xdc\x20\x90\xad\x80\x98\xe1\x56\x66\xb6\x06\x9b\x83\xa9\xe7\x46\x79\x32\x94\x51\x43\xdf\x4a\xab\xb1\x09\xc1\x94\xfa\x5e\x89\x02\xab\x6a\x56\x75\x4b\x84\xb2\x19\xb3\x32\x6b\x12\x1d\x8b\x53\x99\xc6\x3e\x7f\x5f\x08\x33\xa3\x9a\xb5\x02\x3d\x58\xaf\xbc\x0f\x3c\xf1\x3d\x84\x7f\xfd\x58\x4e\xc3\x33\x46\x8a\x9c\x22\x24\x05\x76\x34\x1e\x43\xbb\x6a\xbb\xd7\xda\xd4\x46\x74\xf2\x58\xde\xe1\xca\xfb\xf9\x38\x54\x8a\x25\x41\x93\xc0\x12\xc5\x05\x4f\x59\xc9\x5c\x43\xe4\x30\x11\xd6\x47\x50\xc8\xcf\xf5\x95\x98\x00\x0b\x99\x42\x38\xd0\xdf\xb0\xf0\x6a\x67\x52\x25\x97\x4c\x3b\x0b\xa9\x84\xdc\xbd\xa2\xd2\x64\x42\x33\x2a\x8c\xad\xbd\xe4\x31\xd7\x12\x07\xc3\x3b\xe1\x29\x58\x4d\xee\x13\x34\x71\xe8\x20\xbe\xcf\x85\xd2\x66\x34\x0c\xfc\xd7\x2f\xb8\x9f\x29\x39\x24\xd7\xf5\x00\xcb\x9a\x2e\x0c\x65\xff\x8d\x46\x9f\x00\xda\x39\xff\xbf\xc3\xfa\xb0\x2b\x6c\x4c\xd8\x78\x06\x42\xb6\x31\x13\x3b\x71\x75\x81\x4b\x58\xdd\x19\xe2\xc7\x98\x09\xb1\xd5\x1e\x56\xc3\xb6\x38\xd4\xc1\xcb\x8a\x14\x8a\xa0\x9a\x03\xfb\x2b\xe2\x27\x98\x25\xe8\x46\x07\x51\x79\xfb\xe8\xc7\x7a\x95\x96\xf5\xb9\xf3\x21\x96\x74\xca\xee\x46\xde\xf2\x36\x53\x2b\x42\x36\x30\x98\x32\x9a\xb9\xd4\x49\xe8\x93\xe3\x41\x42\xc5\xee\x6e\xad\x8d\x02\x87\xa3\xc4\xa9\xf7\x4b\xa3\x4d\x47\xfb\x15\xd9\x73\xb5\x0e\x44\xb3\x2c\xc3\x35\x58\x6f\xdb\x46\xfc\x86\x6d\xe1\x39\x8c\x10\x6b\xce\x2b\x6f\x8c\x7b\xc9\x63\x12\x1f\x18\x67\x0b\x0f\xef\x33\x24\x93\x4a\x1b\x35\xdb\x88\xcc\x3b\x29\xda\x68\x4c\xcc\x59\x56\x90\x92\xa5\x55\x62\x8b\xfe\x40\x46\xef\x87\x5a\x01\xb6\x65\x74\x8b\x7e\x27\x22\xe8\x0e\xf6\x09\x11\xb1\x11\xc1\xa7\xb0\xa4\xc1\xf4\xe1\x53\xc2\xae\x58\xb9\x20\x85\x54\x0a\x56\x17\x2c\x1a\xcc\x7c\x07\x27\x8b\x47\x22\x84\x1d\x0c\xde\xca\x6d\x1a\x3b\x76\xd7\xd8\x01\xad\x4a\x46\x12\xe6\xf3\x18\x91\x5f\x3f\x7b\x61\x8c\xc8\xdb\x14\x80\x53\xf8\x5f\x6d\x15\xba\xff\x1e\x4f\x57\xe8\x39\xf5\xbb\x44\x9c\x73\x1f\xc3\xf1\x2b\xb0\xef\xbe\x1e\x04\xf6\xe3\xd7\xc6\xd4\xdd\x33\xef\xfa\xd5\xc0\xbc\x75\x60\x19\x7e\x15\x58\x86\xfe\x4e\xfb\x46\x4c\x45\xb6\xe1\xb1\xb0\x65\x0e\xd0\x23\xcc\x6a\x87\x36\x65\xde\xbc\x91\xd2\x56\x2f\xe0\xb9\x13\xd1\xc8\x76\xb1\x66\xba\xab\xd1\x44\xe5\x9a\x7c\x61\x54\xd3\x2f\x82\xeb\x6f\xb4\xe9\xda\x9b\x6a\x5d\x5b\xcf\x67\x5c\x69\xe8\x3f\x6f\x34\xff\xfb\xf7\x46\x6e\x1f\x4b\xef\x1a\x49\x5f\xfe\x0a\x24\x48\x4e\x8b\x7b\x8c\x83\x60\xec\x9d\x1a\x95\xbd\xb6\x51\x58\x3b\x94\x8d\x32\xa2\x23\x21\xb7\xd1\xf0\xc9\x22\x2c\x9e\x99\xb0\x4c\x22\xb4\xbd\xcd\x13\xbc\x47\x5d\x9e\xef\x0d\xa4\xb4\x2c\xe9\x8c\x3d\xb3\x8f\x7d\x2c\x3d\xc1\x7e\x42\xf4\xfb\x28\xa4\x84\xd8\x05\x16\x17\xdf\xd5\x2f\xb9\x64\x03\x90\x02\x34\x81\xd4\x7f\x20\x64\x04\x3e\x15\x14\x15\x3c\x92\xbc\x95\x16\x48\x39\x5d\xa2\xa4\xf4\x5a\x1d\x65\x54\x69\x9e\x7c\x9f\xc9\xe4\xf2\x5c\xcb\xb2\x07\xd5\x62\xd5\xa8\xd1\x9c\x0a\xb2\xff\xf3\x39\x39\xe4\xea\xb2\x6e\xb1\x84\x30\xe6\x71\xb6\x3d\xf5\x30\x7e\xb6\xf0\x92\xe4\x34\x99\xa3\x46\x6a\xfd\x1e\xae\x95\x43\x7f\x6b\xe5\x0f\xf4\x5a\x31\x7c\xfd\x89\x79\x7d\xf3\x33\x6b\x2f\x82\xd7\x06\xba\x84\x9f\x73\x7c\xb8\x86\x2c\x97\xa9\x6a\xdb\x7b\x8e\xac\x68\x08\xe2\x90\x65\xb1\x80\x30\x63\xb6\x29\x2c\xc0\x19\xc6\x4d\x3e\x80\x87\x16\xb2\x22\xd7\x14\xc3\x55\x20\x61\xc7\xe4\x82\x17\x2f\xc9\x51\x00\x97\xbf\x6a\x28\xa3\x7d\x78\xe8\x32\x9b\x20\x08\x3c\xb7\xdc\x1a\xff\x08\x55\x2b\xf5\x92\xec\xb0\x0f\xfa\x4f\x3b\x43\xb2\xf3\x61\xaa\xcc\x7f\x84\x9e\x42\x7b\x0d\xdb\xb6\xcb\xe8\x78\x62\xca\xca\xda\x22\xc4\x1b\x96\x51\x03\xfa\x67\x59\x72\xf1\xf6\xf0\xed\x4b\xd0\xe5\x53\x69\x8c\x39\xdb\xd8\xd6\x61\x60\x58\xd9\x18\x90\x01\x8a\x39\x13\x99\x17\xa5\xcc\x79\x50\xa9\x02\x4b\xae\xcd\x0a\x20\x7d\x84\x4a\xc1\x5e\x05\x66\xe8\x85\x9f\xfc\x70\x8e\xa5\x82\x13\xe2\x2e\xcc\x74\x3c\x25\x12\x83\x53\x71\xad\x1c\x57\xfe\x22\xc3\x3e\x76\x14\x6c\xd7\x5a\x33\x8c\xd1\xcc\xed\x4f\xcf\x52\x76\xf5\x4c\xa5\xf4\xc5\x10\x1e\x83\xdc\xb0\x68\xbc\x13\x55\x64\xe7\xc5\xce\x98\x9c\xf3\x9c\x67\xb4\xcc\x6c\x1f\x39\x3b\x44\x7d\x9d\x31\x14\xdc\x80\x60\xfe\x3e\xdf\x21\x7b\x58\xac\x06\xea\x46\xc6\x1c\x74\x89\x87\xea\x82\x58\xfe\xa0\x95\x76\x49\x7a\x70\x0e\x91\xce\x0e\x22\x62\x5b\xca\xbe\x15\x59\xeb\x14\x9f\x98\x39\xdc\x68\x2e\xd3\xbb\xac\x6c\x35\xed\x54\x96\xd6\x08\xf4\x97\xb8\x8a\x78\x2e\xac\xda\xf2\xc6\x4c\xfd\xfd\xdb\x38\x3e\xd4\xf6\x43\x7a\x40\x69\x21\x7e\x17\xe9\x87\xbe\x6e\x34\x08\x7f\x09\xfe\x5b\xc5\xc8\xf1\xa1\xef\xd7\xcd\x4a\xc5\x95\x36\x22\x2a\x8d\x54\x03\x8e\xfa\xc2\xde\x7e\x4e\xff\x23\x05\x39\xfa\xfe\xdc\xbe\xd6\x60\x03\x89\xdd\x52\xd2\xd1\xff\x54\x25\x33\x1a\x51\x67\xf5\xcb\x8f\xd4\x54\xb9\xcc\x79\x72\x48\x35\x45\xcd\x0b\x25\x95\xac\x51\x24\x40\xa9\x9a\x40\x76\xaf\x83\x08\x69\xa9\x3c\x93\xf5\x6b\x3f\x86\x83\x4e\xda\xc3\x4e\x9a\xdb\xdf\x9d\x1d\xaf\x41\x77\x4a\x60\xbb\x9d\xbd\x91\x69\x4f\x0a\x54\x30\xa0\xdb\xf2\x00\xd5\xeb\x00\xcf\x93\xdc\x3c\x89\x9c\x48\xc1\x86\xe4\x8c\xd1\x94\x18\xe9\x66\xff\xf9\x73\xc9\xf5\x7d\x81\x12\xea\xa3\xf3\xd6\xef\x26\xb1\x17\x42\xb8\xc1\x1c\x11\x4e\x02\x70\x1c\x40\x72\x02\xa1\x63\x75\x80\x49\x26\x27\xc4\x0a\x8b\x75\x7e\xfd\xbb\xb3\xe3\xde\x3e\xfe\xdd\xd9\xb1\xfb\x76\xf3\x4f\x39\xdd\xcc\xcf\xee\xd1\x78\xa8\x6d\x87\x57\x0d\x65\xbf\x56\xe7\x6a\x4c\xf9\xa6\x41\x70\x77\x6b\x60\xdc\x97\x1d\xb0\x2e\x9a\x5f\x72\xd1\x3a\x59\x3c\x96\x36\x80\x27\xef\xb1\x13\x82\xd8\x18\x40\xb6\xa4\x2f\x49\x5e\x65\x1a\xca\xe3\x81\xd7\x0c\xf3\x41\x86\x82\xe3\x3a\x62\xa1\xa2\x08\x39\x64\x18\x8e\x48\x5f\xba\x84\x45\x7f\xc7\xea\x1b\xde\x50\x41\x67\xe6\x72\xd8\x01\x49\x8e\x7f\x06\x4c\xbe\x87\x4e\x77\xe1\x7f\xa2\x57\x94\x67\x74\xc2\x33\xae\x41\x9f\x1b\x8c\x9d\x36\xaf\x10\x2b\xc3\xbc\xf2\xda\xa4\x5f\xaf\xaa\xad\x57\x5b\xc3\x42\x62\xc0\xc1\x21\x7b\xe6\xb7\x67\xd7\x46\xd4\x0f\xc6\x20\xf7\xe1\x42\x80\x2d\x6d\x28\xbf\x67\x9f\x52\x7e\xd7\xa2\xa7\xc2\x7c\xbf\x6a\xd9\xec\x62\x59\x77\x32\x23\xad\xd4\x9d\xe0\x07\x8b\x4e\xf5\xc4\xd5\x27\x6c\x38\xda\x41\x81\x82\xb5\xd3\xf2\xfe\xae\x2a\xd4\xc3\x2c\x9c\xf4\xe9\x2d\x1c\x82\x6d\x81\xec\x4c\xf7\x42\xae\x7a\x38\xa7\x6b\x78\x14\x42\xfc\xa9\x51\x67\x85\x2b\xeb\xdc\xca\x72\x87\x4e\x08\xf7\x9b\xf5\xd4\xa6\x0a\x13\x8f\xce\xe2\xd7\x73\x70\x3f\x74\x71\xa3\x39\xb2\xe0\x26\x05\xa7\x49\xeb\x75\xd6\xf1\x33\x13\x56\xcc\xa7\xdd\xb3\x29\xcd\x30\xaf\xce\xe3\xa8\xcd\x01\x2b\xe6\xe4\xd5\xf9\x0a\x31\x89\x99\xac\xe6\xbb\x15\xc6\x72\x76\x15\xc9\xf8\x94\x69\xde\x8a\x08\x6b\x16\x94\xb9\x14\x5c\xcb\x52\xad\xa3\x96\xd4\x3e\xba\x1f\xc5\xcd\x8d\x66\xf8\xf3\xcc\x11\x85\xbc\x09\xce\x52\x92\xc8\x2c\x63\x89\xcb\x2f\x85\x29\xf6\xb7\xad\x70\xc4\xd8\x0c\x04\x35\xbe\xfc\x06\x5c\x31\xd6\xe9\xf2\x0c\xd9\xee\xd9\xd9\xd1\xfe\xe1\x9b\xa3\x71\x9e\xfe\x61\x2e\xaf\x47\x5a\x8e\x2a\xc5\x46\x5c\x77\xd3\xb7\xd6\x58\x78\xda\x83\xa7\x5b\xcf\xfb\x72\x72\xeb\xb9\x99\xb2\x1a\xfd\xf0\x9d\xaa\xf1\x49\x5d\xdc\xb9\x94\x52\x2f\x23\x94\x4e\xab\x2c\xc3\xb9\xd5\x25\x63\xc3\xd0\xbf\x7d\x4f\xfc\xd6\xfa\xd8\x2c\x5d\xb8\x76\xf3\x46\x24\x7a\x58\xcd\x78\x53\x16\x48\x77\x5d\xa1\xad\xa6\x4d\x96\xe6\xa1\x1e\x2f\x9e\x89\xf3\xe8\x3c\x06\x44\xf4\xdc\xcc\xcb\x25\x5b\x10\xa8\x31\x9c\xca\x12\xf0\xbe\x63\xfe\x64\x3a\x01\xe2\x3d\x83\xe6\xda\x56\xe1\xd8\x10\xc2\x77\x51\x45\xe0\x43\xce\xd8\xb4\x4f\xb2\x9f\xb1\xe9\x2a\xaa\xdb\xd3\x00\x8a\xe6\xd3\xe3\x8c\xbe\x52\xe9\x39\xa6\xbc\x22\x18\x23\xd2\x76\xe5\x34\xd8\x22\xd1\x0d\xa1\x7b\xa7\xf2\xbe\x3e\x4a\xd0\xbb\xb4\x12\x22\x4b\x93\x17\xba\x2d\xed\x24\xe9\x7b\x87\x41\xe4\x95\xb1\x62\xd9\xf5\xb3\x6b\x59\x5e\x72\x31\x1b\x5d\x73\x3d\x1f\x21\xa5\xd4\x33\x80\x86\x7d\xf6\x07\xf8\x8f\x8d\x22\xef\xa7\xa9\xcd\x7f\xab\x14\x9b\x56\x19\x66\xa6\xa9\x31\xa1\x05\xff\x89\x95\x0a\xb2\x2c\x2f\xb9\x48\x87\xa4\xe2\xe9\x77\x6d\x67\x8c\xf4\xb1\x5a\xda\xb7\x76\x6d\xd2\xba\xb2\xdd\x5d\x65\xb8\x8d\x96\x4e\x26\x95\x34\x95\x0a\x1b\x04\x18\x52\x45\x4b\x80\xa6\x39\x17\x9b\xb2\x02\xda\x5a\x07\x5c\xa4\xed\x28\xd9\x08\x40\xc0\x38\xb1\x79\x60\xcf\xd9\x30\xb6\xcf\xf9\xa1\xce\x7b\x82\x1d\x40\x6d\xf6\x4f\x9c\xfb\x73\x27\xc1\x92\x2f\xd4\x6f\xd9\x08\x9f\x32\x2a\xd2\x9a\xae\xdb\x44\x9e\xfb\x1c\x9f\x2f\x91\xa7\x5f\x87\xfc\x67\x48\xcf\x79\x50\x8e\x23\x1b\xac\x33\x3f\xac\x1f\x6c\x8d\xa4\xee\xae\x19\x3f\x8c\x86\x56\xef\x3e\xd0\xbc\x46\x39\x44\x15\x50\xc0\x50\x2a\x39\x7f\x1a\xf6\x43\xf6\xdd\x12\x5c\x85\x71\x22\x85\xb0\x40\xba\x6f\x0b\x26\xce\x35\x4d\x2e\x3b\x46\x75\xb7\x5a\xd5\xef\x4c\xab\x7a\xa0\x44\x20\xc7\xa2\x58\x4f\x67\xd3\xdf\xea\x64\x6f\x5c\xe4\x8f\x50\x00\x63\x57\x98\x37\xb4\xe8\xee\x5d\x75\x23\x35\x34\x28\x7f\xda\x3a\x54\xa1\x38\xa8\x90\x45\x95\x21\x4c\x2c\x57\x96\x8e\x9f\x5f\xe3\xe9\xba\xbe\xed\x16\xd3\x5f\x0e\x4c\x30\x60\x2c\x51\x73\x73\x66\xc2\x75\x2d\x2b\x15\xd3\x08\x3f\x62\xb1\xf4\xa4\x20\x89\x2d\x31\x06\x7d\xc4\xe8\x1e\x76\xb8\x40\x57\x11\x44\x26\xda\x15\x83\x7a\xa4\x92\xe7\xcf\x9f\x3f\x47\xf4\x85\xff\xfa\xaf\xff\x22\xb2\x84\xa6\x55\x09\xcf\x97\x2f\x84\xab\xfe\xfc\xe2\xc5\x98\xfc\x63\xff\xcd\x6b\xa8\x68\x28\xb4\xc2\x56\x26\x38\xb2\xb9\x20\xba\x59\x0d\xc9\xff\x3e\x7f\x7b\x52\x57\x05\xc7\xbf\x82\x69\xee\x3f\x2f\x06\x90\x7e\xfe\x97\x3f\xfd\x69\x4c\x0e\x79\x09\x15\x5d\x9c\xf9\xe6\xa4\xde\xd5\x42\x4b\x86\x68\x11\x50\xb7\xef\x34\x2e\xee\xfb\x00\x59\x08\x28\x6c\xdf\x8c\x85\xae\x86\x21\x33\x9e\x68\x2c\x1e\x43\xb1\xe6\x7a\x9f\x22\xf6\xb4\x45\x73\xb7\xda\x1f\xbc\xdc\x90\x64\xfc\x92\x91\xa9\x82\xb6\xe8\x35\x1e\x90\xed\xd8\x67\x0b\x65\x70\xb0\x7a\xae\x14\xd3\x8f\x3c\x6d\xb5\x93\xab\x39\xe2\x6d\x18\xa9\xa1\xb0\xda\xf2\xd6\x4b\xb6\x18\x21\x9f\x15\x94\xfb\x62\x18\xc8\x00\x8c\x9a\x45\x79\x5f\x4f\x4a\x0e\xbc\x54\x71\x75\xee\x45\x29\xff\x8d\x2c\x00\x25\xc6\x81\x78\x86\x12\x60\x98\x49\x5b\x00\x1c\x44\xb7\x5c\x99\xb4\xed\x4e\xea\x4e\x5b\xc8\xf3\xe5\xbe\x11\x19\x57\xe6\x11\x00\x30\x71\xcb\x93\xeb\xa6\x77\x86\x4b\x15\xf2\x4b\x25\x96\xee\xb6\xc5\xfc\x56\x5c\xda\x6e\x51\x16\xba\xaf\x1e\x03\x71\x8c\x2c\xf6\x82\xbd\xd6\x51\xc9\x13\x22\xca\xb7\x56\x4c\x57\x96\x34\x90\x45\x6f\x9e\x0d\x9d\x8c\xe0\x0b\x73\x5a\x5e\x1a\xc3\xd5\x4a\x97\x31\x39\x35\x2f\xe9\xe1\x1b\x10\x15\xef\x0a\x03\x9b\x39\x5d\xc0\x63\xad\xe2\x06\x0f\xd9\x1d\x8f\x77\x71\xf9\xc9\x92\x28\x4d\x4b\xbb\x96\xcc\xf9\xa7\x01\xc7\xf9\x86\x16\x0a\xe1\xe1\x8c\xa6\x0a\xd0\x89\x12\x4a\xd2\xf5\xbc\xee\x8f\x8c\xb4\xde\x42\x68\x92\x11\x10\xa6\xf5\x00\x1b\x0e\x9f\x69\x67\xdf\xae\xf2\x8d\xc0\x76\xcc\x3b\x28\x1c\x78\x34\x63\xaa\x69\x23\xb2\x71\x27\x7d\xc3\xb6\x0f\xc8\xd8\xa3\x52\x30\x56\xb7\x0b\xb3\x82\x33\x54\xc0\xe2\x1e\xe7\x8f\x55\x8f\xc0\xa3\x0f\x6d\x02\x8f\xee\x3a\x05\x1e\x5d\x82\xc8\x78\x44\x3c\xec\x22\xc9\x48\x4c\xbb\x81\xe1\x1e\x35\xad\xa7\x00\x9a\xba\x14\xc1\xb2\xc6\x0e\x68\xae\x93\x9f\x20\x74\xa2\x64\x56\x69\xbc\xb5\xfe\x31\xdc\xfd\x60\x50\x07\x2e\x09\x5b\x9e\xbf\x2c\xd8\x0b\x41\x0b\xc0\xed\xa3\xcb\xb6\x88\x47\x67\xb1\xd1\xc5\x09\xf1\x3b\x72\x40\x74\xa6\xb3\x37\xd8\xfa\xa0\xb5\x1b\xcc\x57\xdc\x5d\xcf\x99\x4d\x81\x08\xf4\x3e\x23\x4d\x8d\x8c\x00\xa5\xd2\xa9\x70\x88\x87\x93\xae\xc5\xcd\x98\x28\xde\xdd\x97\xa0\x38\xd9\xf3\x7d\xd5\x7d\xda\xdd\xb1\xd0\xac\x9c\xd2\x84\x0d\x42\x1f\x03\x2b\xe6\x2c\x67\xa5\x21\x94\xbd\xce\xd5\x68\xcf\xa9\x48\x33\x0b\x5c\xc0\x4a\x58\xc1\xec\x83\x66\xa5\x21\xea\xc1\xf9\x31\x49\x4b\x7e\xc5\x4a\x45\xf6\xbe\x67\xc6\xd6\x40\x18\xaa\xc1\x23\x4c\x83\xc5\x0f\x59\x87\x07\x04\x1e\xdc\x4f\xe9\x07\x0c\xb5\xaa\x25\x74\x3d\x55\x0e\xf2\xca\x4c\xab\x0a\x7d\x47\x63\xb3\x20\x60\x0b\x05\xe9\x0b\xad\x0f\x31\xb6\xe9\x3a\xfd\x42\x87\x86\x44\xe3\xc0\x54\xd9\xce\xbf\x00\x87\x63\x05\xbb\x85\x49\x59\x5b\x71\x43\xff\x05\x25\x75\xb0\xea\xb6\xda\x8f\xa9\xb5\x2b\xe5\x15\x4f\x9d\x3a\x04\xa9\x11\x35\xe8\x5f\x41\x55\x00\x5e\x40\x95\x92\xb6\x9f\x79\x30\x35\x68\xa5\x82\xd2\x14\xf7\xcc\x70\xe1\xe6\x30\x4c\x26\x01\x79\xbe\x55\xc3\x2e\xd2\xcb\x86\x28\x53\x76\x5a\x4d\x32\xae\xe6\xe7\xbd\x86\x44\x56\x0d\x8c\x49\x89\x4b\x99\x2a\x37\x46\x46\x14\x13\x8a\xdb\xfe\xaa\xa8\x6e\x71\xa3\x6d\x4b\x98\x06\x77\x77\xb8\x28\x24\x54\xc3\x43\xd7\x56\xf7\xd3\x49\xfd\x1e\x16\xac\x04\xdb\x05\xa6\xec\x9d\x28\xa2\xf3\x09\xcd\x32\x65\xf5\x5b\x0f\x86\xed\xf6\x1e\xd4\x50\x1d\x80\x09\x72\x05\x37\x0c\xe3\xde\x1e\x52\x70\x50\x78\x79\xe4\xf6\x95\x1f\xa6\x02\x88\x4b\x29\xdc\x45\xd0\xf5\xd0\xdd\xe0\x29\x84\x95\x38\xc8\x74\x6b\xc4\xcc\xde\x86\x7f\x1e\x5f\xf8\xe7\x61\x6a\x2a\xea\x5e\x54\x14\x4e\x8e\xa0\x42\xcb\x75\xd4\xa7\x1e\xd9\xa0\xb6\x24\xc7\x9f\x4a\xd3\x5c\x5b\x08\x18\xdf\x6f\x5f\x5b\xfc\xf3\x7e\xbc\xbb\xcd\x41\x41\x15\x33\xa6\x38\x48\xa8\x91\xa5\x5f\x12\x2c\x29\x6b\x23\xfb\x75\xbe\x2c\xd7\xea\x3d\x1d\xb6\x73\x3c\xb9\xab\x48\x2a\x93\xca\x18\x5f\x35\xd9\xeb\x84\x8b\x6e\x6d\x6d\x9e\x16\xce\x7e\x2a\xaf\xc5\x35\x2d\xd3\xfd\xd3\x56\xb5\xb9\xb1\x72\x56\x8f\x15\xaa\xde\xee\x34\x31\xe7\xe9\x44\x56\xda\x63\x1b\x6e\xa3\x7d\x2b\x87\x08\xa5\xf9\x2a\x77\x9b\x96\x46\xc8\xde\x31\x9a\x77\x5f\x87\xdd\x36\x40\xb8\x0d\x10\x46\xc7\x26\x05\x08\x8f\x31\x40\x18\xb6\x84\x8b\xc4\x8b\xf5\xd0\x1a\x8a\x3f\x89\x18\xd3\x61\x2d\x52\x51\x13\x6f\xd6\xf3\x36\x94\x7f\x5c\xbc\x35\xd7\x05\x06\x83\x93\xb9\xa0\x97\x3d\x85\x78\xd4\x06\xc4\x93\x80\x96\x1d\xac\x42\x3c\x62\x81\x5f\xd7\xab\x21\x4a\x2d\x06\xa6\x83\x08\x77\x21\xd3\x97\x08\x1a\x0b\x40\xef\xd8\x9c\x6c\x68\x61\xbf\x87\xd6\x77\x21\x52\xf8\x87\x2a\x68\xc2\x40\xbe\x79\xf5\xa7\x97\x20\x41\x47\x06\x20\x3d\x31\x01\x01\x46\x00\xea\x9c\x76\xe1\x06\xd2\x1b\x47\x98\xa3\xb6\x78\xba\x8e\xd4\x44\x14\xc5\x51\x1d\x23\xa8\x64\xce\x72\x0a\xff\x7c\xe5\x48\x60\x64\xa3\x31\x1e\x34\x43\x08\x38\x56\xe6\x8a\xc8\xe9\x30\xca\x74\xdd\xb9\x7a\xb1\xd3\x2d\xd8\x40\xfa\x8b\x53\x12\xb7\x8e\x4e\x3b\x07\x7b\x48\x93\x60\xa7\x51\x6c\xc7\xac\x21\xd0\x79\xcc\xb2\xf2\x70\xf6\x3e\x83\x02\xf6\x0f\xa4\xf0\xc6\x10\xa7\xef\x20\x6e\xdb\xe0\xed\xd0\x47\x0d\x1e\x81\xf2\xb7\x0d\xde\x3e\xc5\xe0\x6d\xb0\x31\x3a\x41\xb7\x22\x90\x1b\x86\x04\x5c\x34\x77\xc2\x9c\x51\x63\x6d\x18\x17\xca\x75\x71\x5c\x59\xc6\xa9\x4b\xbb\xe3\xf1\xee\xae\x8b\xee\x5a\xbe\xaf\xf4\x74\xf4\x0d\x61\x22\x91\x29\x32\x8b\x19\xbf\x54\x1a\xd4\xbd\xda\xdd\x16\xbe\x4b\xee\x9e\x15\xa6\x3f\xc1\xd8\x7d\x4c\x75\x67\xd9\xe2\x20\x09\x5f\x3d\x80\x12\x53\xab\x2e\x1e\xf8\xd0\x92\xc8\xe3\x59\x5b\x1d\xc6\xfd\xae\x48\xc6\x73\x6e\x1b\xa5\x9a\x85\xce\x94\x56\x64\x0f\x4f\x8e\x93\xa2\x1a\xda\x0b\xc6\x39\xcb\x65\xb9\x18\xfa\x8b\xcc\x8f\xd1\x5d\xf6\x8a\x01\xb6\x31\xa9\xca\x92\x09\x9d\x2d\x9e\xb2\x06\xe4\x88\xb8\x21\x0a\x90\x9f\xe3\x2e\x88\x23\xf5\x11\xb3\x56\x1d\xf1\x05\xb7\x79\xd0\x5f\xc0\xa3\xd1\xaa\x61\x1d\x17\x37\x67\x99\xb8\x22\x57\xb4\xbc\x27\x72\xfc\xaa\xa3\x47\x9d\x27\xe5\x57\x5c\x75\xed\x62\x4c\x9a\xe4\x39\xf7\x4e\x68\xb3\xd8\x64\xa5\x8b\x4a\x5b\x89\xee\x56\xa0\x43\x19\xf7\x2b\xaf\xa1\x1c\xbe\x68\xd3\x5d\x29\x3e\x0a\xaa\x35\x2b\xc5\x4b\xf2\x3f\x7b\xef\xbf\xfc\x38\x1a\x7c\xb7\xb7\xf7\xcb\xf3\xd1\x5f\x7f\xfd\x72\xef\xfd\x18\xfe\xf1\xc5\xe0\xbb\xc1\x47\xf7\xc7\x97\x83\xc1\xde\xde\x2f\x3f\xbe\xf9\xe1\xe2\xf4\xe8\x57\x3e\xf8\xf8\x8b\xa8\xf2\x4b\xfc\xeb\xe3\xde\x2f\xec\xe8\xd7\x3b\x0e\x32\x18\x7c\xf7\xc7\xce\xaf\x4e\xc5\xe2\x6d\x47\x51\x88\xc7\xa8\xc7\x2d\x39\x1e\xb1\x17\xf6\x6b\xb4\x95\xe0\x42\x8f\x64\x39\xc2\xa1\x5f\x02\x58\x70\xc7\x07\x38\xf6\xea\x7b\xfd\xd7\x6a\x40\x0d\xb7\xef\x94\xfa\x35\x2f\x70\x08\x7d\x1e\xf2\x1e\xca\x8c\xdd\x48\x71\x99\x8c\x66\x79\x21\x4b\x5a\x2e\x48\x6a\xbd\x99\x8b\x15\x08\x44\x01\x04\x51\x67\x48\x61\x78\x8f\x94\x97\x6b\xa8\x34\xee\x8c\x28\xc4\x52\x5e\xe5\x3d\xe1\x09\xc1\x58\xe1\x64\x5c\x03\xf2\xbe\x45\xed\x77\x29\x45\xf6\x32\x1b\xd0\x98\xd0\xe4\x12\x2d\x28\x3f\x5b\xa8\x37\x06\xa5\xf5\x3b\x3b\x36\x25\x22\x67\x54\x78\xc7\xbe\xeb\x38\x66\xa6\xd2\x5d\x8c\x63\x47\x4e\x78\x8c\xb4\xdb\x04\xc2\xba\x23\x95\x2c\xc9\x1b\x50\x80\xd6\x3a\xfb\xa4\x17\xac\x10\xfe\x1f\xf6\xda\x68\x7d\x3d\x55\xa2\xba\xe1\x5c\x02\x91\x96\x60\x6f\x5a\x5c\xaf\x29\x34\xd9\xaa\x33\xc4\x22\xcd\x02\x26\xf2\xc8\x2d\x4b\x17\xbf\x35\xd3\x69\x46\x45\xdd\x14\x1c\xd3\x99\xc2\xbc\x15\x9e\x40\x1f\x28\xb0\x4d\x61\x3a\xfc\x14\x5e\x04\xcd\xa1\x2b\x65\x9e\x24\x45\x7c\x4d\xfd\x20\x6c\x93\x35\x41\x9e\x70\x1d\x5d\x63\x8b\xda\xfc\x72\xee\xbf\xac\xf6\x67\x40\xc9\xb2\x33\x3f\x55\x05\x46\x8a\x7d\x8a\x55\xb5\xe5\x14\x32\x2b\x82\x7e\x3d\xae\x25\xcd\x12\xa3\x0a\x9e\xc5\x9c\xea\x3a\x4f\xf8\x0f\xaf\x84\x4d\x28\x5c\x62\xbb\xd5\x5c\x57\x29\x56\x8e\x66\x15\x4f\xfb\xe3\xb7\x47\xa7\x76\x74\x54\x36\xfa\x52\x31\x7a\x51\x2c\x7a\x57\x27\x7c\xca\x66\xf7\x0e\xc9\x75\xf6\x67\xb4\x9f\x86\xcd\x31\xe2\x4c\x50\xea\xfb\xa1\x39\x61\xe0\xd2\x0d\x2e\xbc\x2b\xc9\xee\xb3\xc9\x22\xb1\xd0\x4e\x3c\x6a\xdd\x83\xc3\xe2\x9a\x80\xa2\xaa\x91\x6f\x95\x5a\x3b\x24\xc8\x84\x4d\x31\xe3\x09\xef\x01\x4f\x81\x2d\x05\x4b\x59\xc6\x34\x0b\x7a\x1c\x17\xd8\x95\xb5\x64\xb9\xbc\x32\xcb\xec\xbd\x20\xef\x94\x8d\x97\xf3\xe9\x4b\x42\x07\x51\xc1\xb1\x42\x03\x5b\x30\x96\x62\x7d\x58\xd0\x54\xb0\xac\x84\x1a\x92\xc9\xc0\xe5\xb3\x2a\xec\x1e\x5a\x82\x53\xcd\x76\xf7\x02\x3f\x56\xc9\x0c\x01\x00\xa4\xaa\x94\x39\x51\x82\x16\x6a\x2e\x35\xb8\x4c\x68\x41\x13\xae\x17\x44\x97\x34\xb9\x34\x97\x40\x1c\x15\x1e\x37\x24\xc9\xc0\xa6\xb7\x87\xe4\x8b\x4b\xd6\xf4\xbc\x94\xd5\x6c\x0e\x35\x54\x78\x55\x92\x51\xe5\xbe\x7e\xe5\xfd\xd6\x86\x57\x24\x5d\x08\x9a\xf3\xc4\xf7\x0e\x29\xe5\x15\x57\x5c\xda\x48\x97\x1b\xf7\xd4\x77\x61\xc0\xe8\xd9\x41\x46\x79\x4e\xf6\x14\x63\xe4\xc8\xb1\x04\xfe\x72\x8e\x9a\x24\x7a\x12\xcb\x38\xa9\xce\x02\x3e\x5a\xe0\x01\x73\xa6\x16\xbd\x3e\x55\x01\x95\x01\xf3\xe6\x2b\x1f\x3a\xf0\xd3\xb5\xfa\x9d\x64\x09\x09\x6f\xae\x05\x10\x13\xa9\x0c\x32\x62\xf6\x4f\x8f\x55\x68\xdf\xda\x36\x8a\x38\x12\xfc\x90\x49\x31\x0b\x81\xef\x6a\xce\x34\x42\x5e\x40\x3f\xcc\x2b\x9e\x56\x34\x43\xf1\x6e\x5f\xe6\xe0\xfc\x18\x6f\xe7\xb3\xb9\x1e\x5d\x33\xf0\x7e\xe2\x2e\x58\xaf\x19\xf7\x50\xbe\x94\x69\xcb\x15\x6c\x07\xda\x7a\xd9\xd0\x93\x0c\x3d\x27\xe9\x02\x80\x77\x6d\x72\x67\x94\x8c\xe3\x60\xea\x71\x88\x55\x14\x87\xd7\xdb\xf7\x0d\x12\x8d\x4a\x04\xee\x61\x43\x62\xe0\xd4\xe5\x77\x83\x6e\x8f\x75\xcf\x0d\x7f\x5a\xd7\x9d\x1f\x41\x21\x6e\xdf\x39\x78\x6d\x8a\xec\x55\xcd\x26\x17\x2c\x2f\x32\xaa\xfb\x49\x2d\xd9\xf9\x39\x70\x7f\x07\xc1\x63\xb3\x1c\xa9\x48\x47\x34\x33\x1c\x79\xfa\xd3\x81\xad\x6c\xc3\x05\x16\xa5\xaf\x5d\xd4\x3d\x4a\x51\x39\x40\x2d\x69\xe5\xd2\x02\x2c\xb5\x09\x4b\x41\x18\xd9\x27\x83\x8f\xe2\x5a\x60\xeb\x5f\xf3\xc7\xe9\x4f\x07\x43\xc2\xc7\x6c\xec\xfe\xf2\x97\x3a\x69\xa8\xe5\x0c\x0b\x1c\x7c\x05\x0d\xf0\x33\x76\xe1\x0e\x9c\xbf\xe1\xbd\xff\xfa\xd6\xbc\xa4\xf9\xf5\x6f\xa3\x6f\x83\x5e\x46\x7f\xfb\x97\x11\xae\xa5\xb9\x20\x3e\x1b\xe6\x97\x83\xdc\x33\x7f\xfd\xeb\x54\xa6\xe7\x05\x4b\xc6\xf8\x59\xea\x5f\x98\x25\x40\x98\xd0\x46\xd7\x3e\x95\x90\x59\xc6\x53\xe4\x72\x78\x76\xc9\xfe\xed\x02\x04\xb6\x5d\xaa\x15\x24\x09\xd5\x4c\xc0\x06\xe0\x0a\x8d\x85\xd4\x78\x3b\x36\x5a\x85\xf7\xdf\x9b\x86\xad\x4f\xb5\x94\xb0\xcc\x51\x94\xec\x0b\xc2\x3e\x70\x05\xb8\x33\xf8\xad\x40\x0e\x6a\x93\xd7\xdd\x9e\x66\x86\x35\x14\xf6\x30\x43\xd8\x3d\x3c\xcb\xc8\x17\x42\xea\x2f\xfc\xf4\xbb\xc4\x44\xd8\xb8\x24\xa1\x57\x92\xa7\xa4\x82\xbe\x59\x66\x05\x0a\xf0\x6c\xd7\xad\x0b\x27\x0b\x92\x73\xa5\xe9\x25\x1b\x93\x73\xb3\x67\x85\x19\x06\x48\x3d\x41\xa0\x0b\x0d\x4b\x49\x25\x34\xcf\xe0\xd7\x7a\x1c\xf3\xca\xe1\x5e\x76\x3c\x25\xaa\x4a\xa0\x39\x6f\xc9\x46\x6e\x77\xb4\x57\x2d\xc9\x98\xfa\x5b\x86\x7e\xb2\xe7\x14\xed\xa7\x22\x85\x5b\xb1\xd5\xaf\xb0\xec\xb5\x94\x57\x6d\xde\x53\x8a\xa4\xde\x11\x81\x98\xd0\x35\xdb\x6c\x82\x99\x4b\x00\x42\x53\xce\x06\x0c\x04\x4b\x98\x52\xb4\x5c\x60\x37\x54\xee\x9b\x36\xda\x94\x57\xd8\xa9\x73\x2a\x2a\x18\xa0\x64\xd8\x5b\xb7\x4a\x80\x3a\x94\x4c\x4a\x79\xc9\x84\x2f\x21\xf0\x0d\xd2\x7d\x42\x75\x9d\x35\x0a\xf1\x7b\x49\x92\x39\x15\x33\x56\x57\x91\xe7\x34\x05\xda\xff\xe8\x35\x2d\xf7\x3d\x86\x02\x74\x6a\x14\x16\xae\x81\x14\x13\xb3\x3f\xf9\xb0\xc7\x7b\xe1\x71\x70\x87\x75\x5c\xc2\x7c\x12\xcf\x5a\xc9\x44\xd2\x8f\x23\xbc\xbb\x0b\x7c\x04\x0a\xc5\x1a\x93\xb7\x73\xa6\x69\x4a\x35\xed\x2d\x81\xfb\x0d\xf5\x5d\x3f\x6d\x52\x07\xb0\x43\x90\xec\x61\xf7\x58\xa7\x4a\xca\x82\x87\xb8\x02\x20\x0d\xe6\x6e\xf6\x01\x97\x4a\x1b\xbe\xb6\x41\x47\xcc\xcb\x06\x5d\x8d\x66\x99\xbc\xb6\x48\x75\x6e\x34\x14\x59\x2c\x25\x69\x05\x6a\x5f\x2d\xd2\xba\x04\xc5\x7b\x89\x99\x98\x89\xee\x8d\xca\x17\x75\xec\x3f\x89\x73\xb3\x57\x2a\x68\xb8\xd7\x31\xa1\x39\xb6\xc6\x77\x40\x10\x96\xf8\x95\xc0\xa5\xda\x98\x06\x98\xa7\x19\xd3\xaa\xce\xaa\xc4\xdd\xc4\x88\x48\xbb\x97\x5b\x27\x02\x6c\x35\x76\x6a\xac\x1d\xbe\x5a\x53\xc4\x89\x53\xd2\xee\x16\x66\xff\x5a\xfb\xcc\xf4\x17\x3c\xc2\xf6\xb7\x6f\x64\xda\x3d\x0a\xd5\xe8\xe3\x5a\x0f\x5c\x57\x9b\x60\xe5\x91\x02\x27\x0f\x5e\x00\x31\x79\x15\xc1\x64\xe0\x16\x30\xa7\x57\xed\xdd\xa9\xb5\x66\x3a\xf2\xcd\xda\xe0\x71\x23\x78\xdc\xe8\x45\x57\xc7\x75\xf7\xac\x45\x77\x74\xcc\x5e\x8c\x5f\xa8\x87\x48\x85\x11\xad\xe7\xbd\x04\x12\x1a\x28\x4a\x7e\x5c\xbb\xff\xda\xcc\x0c\x9f\x0d\x63\xeb\x69\x19\x37\x52\xf3\x25\xf9\x22\xd2\xb8\xac\x66\xeb\xad\x61\xac\x62\xda\x73\xe6\xf1\xd8\x4e\xbc\x83\xf3\x8a\x2f\x1f\x34\x06\x03\x55\x6f\xb5\xd5\xe8\xaa\xa5\xbc\xfa\x6d\x54\x65\xe8\xc3\xef\x6b\x54\x0d\x33\x97\x32\xcb\x5c\xef\x76\xb4\x90\x1b\xb9\x4d\xd0\x37\x08\xa3\x25\x43\xef\x86\xf0\xfa\xbe\x60\xd7\x5e\xb1\xa3\x0a\xe1\x4a\x5d\xac\x1e\x5c\x25\x2e\xe1\x6c\xd5\x78\xbe\xa2\x6b\x5f\x2c\xf0\xd5\x0f\x03\xd2\xa2\x7b\x81\xcc\xcc\x83\x8c\x05\x20\xe8\x24\xc3\x8c\x1c\xaf\xf8\xc0\xbb\xd0\xec\x9a\x2e\x14\xac\xb2\xda\x62\xf3\xcf\xb7\x58\xef\xf5\xc0\x67\x6c\xda\xa1\x9f\x7c\x78\xf4\x16\xcd\xef\x2f\x9e\x0f\x60\x2b\x5c\xb4\x4f\xd2\xad\x87\x69\xd1\x82\xbb\x79\xf4\x97\x16\x00\x99\x91\x90\x16\xd5\x47\x7c\x35\x5a\xce\xfb\xa7\xc7\x30\xb0\xb3\xdc\x66\xf0\x87\xdb\xd1\x7d\xa0\x70\xc2\xcc\x7a\xab\x21\xa2\x80\x77\xc3\x7b\x57\xe4\x8d\xd5\x4c\xff\x23\xf4\x43\xb2\xf1\x17\x57\x0f\x6c\x36\x84\xfd\xd3\x63\x7c\xe2\x18\x5a\xe2\x52\xb1\xb0\xba\x96\x9e\xf3\x32\x1d\x15\xb4\xd4\x0b\x74\x5e\x0c\xa3\xa7\xf9\xa2\xc8\x1e\xc8\xd1\x6b\x68\xb8\x4b\x0b\xb5\xf0\x88\xe6\x08\xc8\xe7\x02\x2f\x36\x72\x76\xe3\xcc\x6c\x1a\x45\xba\x96\x68\xba\x23\xa2\x48\xd8\x42\xc7\xf9\x2e\x1e\x05\x45\xd2\x50\x10\x3f\xd4\xbe\x6c\x64\xbc\x8a\xd3\x59\x70\x9b\x05\x1d\xda\xfa\x9b\x64\x58\x37\xe6\x75\x36\x30\xfe\xcd\x48\x43\xc2\xa7\x66\x83\x93\x62\x64\xab\xd5\xbd\x73\xdc\xea\x7d\x2e\xef\x13\x0d\x79\xb3\x74\xd1\xfd\x19\x3e\x2b\x1c\xc0\xaf\x75\xb2\x27\xa4\xc0\xf5\x8f\xd7\x0e\x30\xed\xf5\x06\xff\x2e\x5c\x32\x26\x3f\xcf\x99\x08\x37\xbf\xd0\x21\x3e\xf4\x9b\x30\x17\xa9\x99\x7c\xd8\x19\xc1\x1f\xa0\xaa\x24\x61\xcc\x7b\x90\xc2\x76\xf1\xb5\x7c\xb2\xaf\x9c\x53\x9d\xcc\x99\x22\x4a\x02\xec\xa8\xd2\x34\xcb\x6a\xcf\x8d\x25\x97\x04\x3d\xc2\x79\xd1\x03\xf5\x22\x2a\xf2\xb6\x4e\xac\x22\xa3\xd6\x53\x32\xad\x44\x82\x89\x55\x5c\x2f\xdc\x1b\x1c\x36\x55\x29\x30\x57\x15\x3a\x74\xf8\x14\x7d\xb7\x81\xd9\xe9\x89\x09\x02\x76\x81\x22\x35\xde\xf9\x2d\xb6\x9e\x91\xa6\x13\x9a\x5c\x5e\xd3\x32\x55\x50\xbf\x4e\x35\xc7\x16\x87\xc3\x68\xd8\xbd\xe0\x1d\xcc\xd3\x23\x4d\x61\xe0\x8d\x5b\xc5\x7c\x2b\xbb\xfa\x31\x84\x56\x5a\xe6\x54\xf3\x04\xdc\x36\x7c\x1a\x78\xe2\x73\xdf\x02\xc2\x47\x52\x51\xb2\xc3\x5e\x61\x3f\x03\x2c\xb8\x12\xcb\x2c\xf4\xb5\x24\x3c\x37\x1a\x18\x85\xd6\xcf\x53\x5f\xad\xee\x62\x06\xb7\xbd\xa9\x51\x33\x7f\x86\x40\x4d\x70\x15\x3a\x84\x8c\xa9\xae\x60\x78\x1f\x15\xf0\xee\x70\x5b\x96\x3d\x6c\x28\x48\xf6\x1e\xc3\xd3\xe6\x5d\x03\x56\x1d\x9a\xe9\xb9\x66\x46\xef\x52\xb7\x32\xac\x1a\xaf\x7a\x23\x3e\x13\x58\xb8\xcb\x95\x73\x21\xd8\x4c\xec\xbd\xb4\x94\x45\x61\x9d\x81\xf9\xa0\xf9\x46\x10\x7b\x2b\xaf\x98\x82\xb8\xb3\xcb\xed\x36\x64\x98\x31\xc1\x4a\xaa\xc1\x93\x6f\xe1\x08\x61\xe5\x36\x1f\x11\x2d\x98\x31\x82\xb2\x0c\xc8\x3b\xdb\xe0\xdf\x33\xae\xcf\x14\xbf\x93\x62\x8a\x9e\x45\xab\x9b\x6e\x35\xca\x5b\x87\xd9\x6a\x94\x5b\x8d\xb2\xc5\xb1\xd5\x28\x9b\xc7\x56\xa3\x0c\x0f\x9f\x8c\xdc\xaf\x36\x59\x57\x17\x04\x89\x1f\x61\x2a\x55\x7d\xc1\x4d\x2e\xbf\xe3\x29\x39\x63\x89\xbc\x62\x25\x6e\x22\x47\x1f\x0a\x2a\x8c\xae\xf4\x8a\xf2\xcc\x6c\x21\x6e\x2b\xa9\xdd\x1b\xd0\x47\x27\x76\xb1\x07\x1e\x25\x3f\x1f\x76\xb1\xe6\xf6\xa5\x2c\xd2\x85\xb9\xde\x06\xf2\x8b\x92\x5d\x71\x59\x29\x97\xf0\x55\x69\x14\x16\x4a\x5b\x7d\x66\xce\x67\xbe\xdd\x9d\x4f\xc7\x28\x59\x22\xcb\xb4\x86\xac\x52\x9a\xea\x4a\xc5\x35\xa4\x09\xfa\xb4\xfb\x73\x67\x7a\x3a\x6e\xd0\xee\xd9\xe7\x3e\x83\x19\x73\xbd\xaf\xd7\xdd\xd7\x98\x89\x87\x27\x27\x96\x0d\x5d\x72\x60\x9d\x98\x68\x54\xdf\x4a\xb3\x80\x5d\x2d\x63\xdd\x7b\x0e\x23\x3c\x9a\x67\xd8\x3c\x7c\xe4\x87\x1d\xd5\xb9\x80\xad\xfb\x23\x86\x47\x8f\xb3\x49\x7a\x07\x4e\x09\x8f\x47\x97\x3a\x18\x1f\xbd\x55\x2d\x90\x07\xa9\x5c\x20\xfd\x57\x2f\x90\x87\xaf\x60\x20\xbe\xa2\xac\xff\x75\x7f\xe6\x2a\xdc\x1a\x2b\xdf\x6e\x4b\xb7\xad\xfc\x08\x4a\xcd\x8f\xc3\x15\x91\x39\xd7\x9a\xb9\x04\x12\xbf\x92\xc1\xe1\x1f\x56\xf8\x58\x99\x03\xbe\x04\xcc\x12\x61\x1f\x7c\x0f\xa9\x40\x57\x05\x8d\xf3\x9a\x2b\x30\x90\xa8\x30\x76\x2d\x22\xda\x82\xec\x18\xd9\x74\x5f\x67\xab\x6f\xe5\x50\xf7\x71\xb7\x72\x28\x3c\xb6\x72\x88\x40\x37\xae\x0c\x8a\x47\x7a\x55\x8c\xdd\xa0\x16\x4a\x87\x4e\x58\x46\x7e\xab\x58\xb9\x20\x46\xd1\xad\xd3\x4c\xa1\xdd\x96\xe2\xa9\x4d\xd4\xb4\x8e\xc9\xae\xd6\xe5\x86\xea\x78\xe0\x38\x3d\xfa\x60\xec\x04\x40\x40\xe8\x5d\xea\x37\x1f\x10\x03\x19\xe1\x2c\xf8\x99\x09\xad\x03\xcc\x11\x89\xec\x05\x63\x2a\xec\x9f\x1c\xf6\x69\xea\xf7\x91\x3e\x40\xfa\x4b\x21\x20\x4b\x2e\x99\x5b\x48\x84\xa4\xf4\xbf\xc0\xc6\xe6\xd3\x3c\xbc\xa3\x91\x5c\xb2\xc5\xd0\x66\x53\xd9\x5e\x8b\xee\x62\x4c\x4c\x8c\x1b\xbe\x74\x03\x0a\x8c\x8f\x9e\x77\xa0\x3e\x7d\x83\x78\x74\x6d\xf0\x11\x8f\xe5\x88\xdb\xcf\xa6\xd8\xf3\x26\xdb\x43\x23\x90\xf0\xb8\xa9\x29\x08\x72\x2b\xf4\x10\x70\xd5\x52\x9e\x41\xa1\x42\x0c\x24\x6c\x3f\xec\x45\xfa\x76\x4f\xe1\xe1\xa6\xf1\x81\x88\xe5\x97\x60\x54\x96\x73\xc9\x16\xbb\xca\x62\x69\x48\xa1\xe6\xbc\x70\x5d\x22\x41\x4e\xda\x55\x49\x7e\x82\xfc\x37\x37\x04\x4a\xc4\x63\x31\x24\x27\x52\x9b\xff\x1c\x41\x42\x2f\xc6\x58\x24\x53\x27\x52\xc3\x99\x8d\x26\x37\x7e\xda\x03\x11\xdb\x86\x68\x38\x84\x58\x30\x75\x1d\x6a\x57\x5d\x9a\x27\x10\xd5\xe6\xf2\xf8\x89\xe1\x8a\x1c\x0b\x22\x4b\x47\x55\xed\x1a\x5f\x29\x3b\x84\xf3\x5e\x07\xd1\xb0\x15\x63\xd8\xc9\x90\x65\x34\x17\xb7\x0c\xe7\x03\x6b\xdc\xfd\x02\xde\x6d\x88\x44\xfa\xdc\x54\x68\xbe\x44\x35\x9b\xf1\x84\xe4\xac\x9c\x01\xee\x4a\x32\xef\x7b\x8a\xfb\xda\x17\xf1\xe8\x71\x77\xc4\xa3\x57\x3e\x04\x15\xe5\x35\x64\x1d\x3f\x8c\xfa\x83\x63\xe3\x76\x9d\xd3\xc2\xb0\xe0\xff\x31\xbb\x32\x70\xc1\xff\x85\xe6\x6e\x6a\x4c\xf6\x89\xe2\x62\x96\xb1\xe8\x37\xeb\xcf\x0c\x87\x31\x23\x18\xfb\xf5\xb7\x8a\x5f\xd1\x8c\x61\x95\x00\x15\xbe\xf5\x8a\x9c\x2e\x29\x5d\x43\xdb\xe1\xcd\xc8\x65\x1f\x83\xdf\xb9\x64\x8b\x9d\xe1\x12\xdb\xee\x1c\x8b\x9d\x1a\xc2\x29\x62\x54\xaf\x5c\x40\x78\x76\x07\x7e\xdb\xf9\x3c\x7a\xda\x23\x30\x63\x7b\xe3\x49\xeb\x72\x3e\xc8\xa8\x52\x7d\xa0\xc9\x34\x0a\xc2\x1b\xa3\xaf\x6a\x2c\x71\x1e\x5c\x53\x97\x84\xdb\x0a\x94\xde\xfd\xe8\x50\x01\xd9\x57\x3e\x70\x0f\xf4\xbf\xb2\xfd\xac\xbb\xc2\xd0\xad\x84\x02\x07\x10\x36\x57\x21\x1b\x21\x2a\xd4\x69\x3a\x37\x50\xfc\x27\x88\x88\xc8\x29\x79\x55\x37\x8c\xe0\x0a\x5c\x54\xdc\xd5\xcc\x0a\xa9\x09\x17\x49\x56\xd9\x60\x08\xdc\x0a\x0e\xae\x7e\x0c\xd8\xde\xc8\xdb\x3b\x63\xd7\xc3\x3a\x8e\x76\x29\x45\x4b\x85\x50\xcd\xec\x0f\xc8\xb7\xf1\xd9\x14\x48\xed\x75\x52\x6b\xda\xaa\xe4\x23\x6e\x74\x92\xc4\xfa\xe5\x2b\x3e\x29\x19\x39\x98\x53\x21\x58\x16\xa0\xc8\x58\x67\x28\xd5\x9a\x26\x73\x8c\xd9\x51\x62\xd6\x71\xc6\xf4\xae\xc2\x06\xfd\x39\x4d\xe6\x5c\x78\x5c\x05\xe1\xd1\x94\xea\xba\xb2\x35\xb4\x06\xea\x6a\x20\xf5\xd8\x55\x66\xd7\xb6\x95\xb1\x7c\x17\xf6\x73\x89\xbb\xcd\xd4\x00\xe5\xcd\x6b\x6a\xa4\x7e\xbb\xe6\x81\xf2\xb8\x2f\x43\xeb\x13\xb8\xf6\xf6\x7e\x35\xb9\x77\x68\x73\x31\x65\x65\x89\x33\x34\x61\xf6\x86\x46\x8f\xd9\xb1\x6d\x62\x31\x97\xd7\x24\x95\xe4\x1a\xba\xad\x5e\x19\x05\x02\x52\x91\x94\x53\x3d\x82\x37\x85\xc4\xc0\x44\xe6\x45\x29\x73\xae\x5c\xf9\xa3\x65\x8f\xb5\x01\xa6\x64\x55\x6b\xcc\xd9\x78\x16\xb3\x4a\xc4\xcd\x1e\x5f\x1d\x10\x4d\xcb\x19\xd3\xe6\x19\x44\x54\xf9\x84\x75\xc4\x85\x59\x37\x2a\x79\xaf\x5d\x40\x76\x7d\x1b\x90\x88\x6a\x9f\xe8\xef\x41\xce\xdc\x5d\x90\x40\x08\x69\x8a\x53\x59\xda\x64\x4b\xff\xa3\x85\xa1\x37\x5c\xf8\x93\xdd\x38\x2b\xa1\x55\x47\x54\xf8\x2e\xfd\x41\x90\x15\x7e\xfe\xf9\xa4\x1f\x58\xf7\xdd\x7a\xbc\x9b\xb8\xee\x5a\x96\x59\x7a\xcd\x53\x54\xce\x14\xd9\x33\x17\x0f\xba\x51\x60\x8d\x28\xef\x9d\x57\xfa\xf5\x35\x4f\x7b\x22\x3e\x0c\x15\x13\xdd\xe5\x51\x1b\xa2\x13\xa0\x3a\x4f\x99\xd0\x46\x58\x96\x8a\xec\xc1\x1d\x03\x72\xc4\xb1\x12\x1f\xee\x07\x10\xd5\x7c\xc2\x45\x8d\xf2\x50\x4f\xaa\xd9\x2e\x8d\xdc\x70\xe6\xbd\x62\x1a\x6b\xa8\xa1\x0c\x59\xea\x39\x51\x3c\xaf\x32\x4d\x05\x93\x95\xca\x16\x1d\x59\xfb\xb1\x4e\xec\x34\x63\x1f\x70\x85\x77\x57\x7a\xfc\x50\xb1\xf2\x03\x89\xb6\x35\x70\xca\x92\xf6\x53\xa7\x82\xa7\xcf\xbc\x26\xe4\x81\x00\xd8\x07\x96\xd8\x1a\xb1\x22\xab\x66\xbc\x55\x51\xf0\xb6\x0f\x62\xab\xbb\xef\xd6\x07\xb1\x6e\xf7\x56\x29\x56\x23\x97\x75\xeb\x43\xbe\x81\x6d\x0b\xd7\xab\x5f\x5e\xac\x6e\x59\x98\xb2\x82\x89\x14\xa0\xd3\x5f\xd5\xeb\x0f\x5f\x7e\x6d\xb4\xb7\x90\xe5\xfd\xec\x15\x0e\xff\x3c\xda\xa5\x83\xc4\xfb\xb9\xcc\x52\x45\xd8\x07\x5d\x52\xb3\x1d\xe4\x46\xf0\xfb\x7b\xa6\x84\x8a\xae\xa2\xfd\xa9\x34\xde\x22\x9f\x49\x03\x4d\x9f\xa8\x06\xaa\x7a\xed\xc8\xb9\xab\xc2\x3e\x9c\x35\xf5\xa2\xd3\x3d\x37\xe7\xc4\x0d\xd4\x4a\x07\x15\xd7\xa1\xad\x68\xa2\x69\x9f\x12\xd7\xbf\x74\x6b\xa6\xa9\x56\xb4\xd6\x6b\xbc\xd5\x1a\x17\xeb\xb6\xb3\xe6\xe3\xea\xac\x39\x05\xb8\xa7\xee\xe0\xc7\x76\x9c\x86\xcf\xce\x9e\xb4\x6a\xeb\x5d\x7c\x74\x76\x45\x05\x7b\x32\x74\xca\xb1\x03\x59\xd8\x04\xa2\xcc\x6c\xd4\xc5\x11\x95\x10\xed\xa4\xf9\xba\xfb\x0e\x52\x4d\x15\xd3\x5d\x3c\xc9\xb1\x82\x59\x8f\x67\x44\x4e\xc8\xf9\xf6\x27\xec\xde\x09\x85\x9e\x0e\x02\x89\x8c\xfe\x66\x75\x51\x11\x5d\x69\xb4\x50\x47\x77\x07\x8e\xcc\x7c\x66\x19\x8e\x91\x9a\xd9\x4e\xa8\xee\xd8\x90\xbe\xc3\x6e\x6c\xdf\xf6\xdd\xbb\xe3\xc3\x3e\x49\x68\xc6\x73\xda\x2a\xfc\x3b\x26\xa3\xe5\x52\x00\xd0\xe5\xbf\x55\xa1\xa1\x0d\xd0\x8d\x9e\x70\xf6\xfa\x75\x50\x67\x96\xb0\x3a\x4c\x70\xc8\xd5\x65\x77\x80\xf3\xa5\x21\xe3\xe5\xfe\xc3\xc1\x11\xb1\x67\xef\xe4\x9d\xbf\x8f\x7b\xbe\x2b\x2a\xf6\x2c\x61\x75\xe0\x2e\xe5\xea\x72\x0d\xe0\xe8\x5d\x6d\xe0\x22\x3d\x69\x57\xc7\xb9\x99\x91\x86\xa6\x85\xe7\x60\x54\x03\x7c\xdf\x85\xac\xc8\xb5\x85\x11\xb4\x16\xe2\x05\x2f\x5e\x92\x23\xa1\xaa\x92\xd5\x19\x5a\xcd\xa1\x8c\xbe\x75\x67\x7b\x11\x90\x1a\xd5\xcb\xde\xa2\x12\x7d\x73\xea\x53\x09\x73\x14\xb4\xd4\x60\xc8\xf5\xc3\x48\x7e\x38\x27\xa7\x83\x13\xe2\x2e\x9c\x74\x3c\x75\xc5\x17\x43\x8b\x29\xe6\x81\xd3\xdd\x45\x86\x77\x02\x90\xd1\x90\x5b\x5e\x79\x60\x5f\xf2\x2c\x65\x57\xcf\x54\x4a\x5f\x0c\xe1\x31\xae\x64\x30\x7e\x27\xaa\xc8\xce\x8b\x9d\x31\x39\xe7\x39\xcf\x68\x99\x2d\xa2\x06\x67\xf5\x75\x66\xdb\x75\x03\x42\x36\xcb\xf3\x1d\xb2\x27\x4b\x18\x39\xa1\x82\x64\xcc\x61\x2e\xd8\x55\xbd\x40\xbb\x63\xb0\x19\x22\x92\x6c\x4c\xa4\x08\xa5\x65\x4f\xbc\x96\x3a\x9d\xca\xee\xf7\x11\x68\xed\x61\xbd\xe1\x71\x61\x76\xc1\x31\x79\x67\xb7\x2f\xab\x17\x20\x33\xc0\x62\x76\x57\x6c\xd6\x64\x6d\x9e\x3f\xa4\x95\x67\x63\x39\x74\xb7\x69\x84\x6e\xeb\x3d\x99\x71\x7d\xc6\x0a\xd9\x83\x0e\x87\x03\x35\xe2\x0b\x5c\x9b\x13\x52\x71\x68\x4f\x43\x35\xa1\x28\x92\x92\x2a\xa3\xc6\xa8\xc3\xe8\xc2\x98\x1c\x1e\x9d\x9e\x1d\x1d\xec\x5f\x1c\x1d\xbe\x24\x3f\xd8\x91\x78\x68\x07\x8c\xc9\x45\x88\x3b\x1d\x54\xb4\x59\x70\x5f\xff\xac\xa1\x15\xb1\x54\xd4\x8d\x33\x00\x87\x93\x0a\x72\x2c\xb8\xae\x5b\x86\x61\x5d\x40\x26\x85\xcd\xf4\x37\x77\xdb\xe8\xc6\x8c\x63\x3e\xaa\xb0\x83\x99\x9f\xe3\xd1\x60\x85\x62\x83\x1d\xff\x2a\xad\x1c\x24\x6b\x56\xfe\xea\xe9\x59\x87\xa1\xea\x7a\xe1\xf4\x63\x63\xf9\x3e\x48\x0e\x06\x02\xa3\xc5\xf5\x79\xdc\x6c\x7d\xdb\x47\x07\xac\x2b\xcb\xa8\x2b\xe3\x78\xbc\x3b\x26\x66\x1b\xdf\x1d\xef\x3a\x95\x2f\x5b\x6a\x1d\xea\x07\x0d\xf1\xcb\x63\x86\x1f\x13\xf2\xd6\x95\x4d\x02\xf8\xd4\xea\x2e\xa4\x88\xbf\x18\xf4\x9c\x6c\x2c\x1b\x57\xba\x5f\x4d\xc2\x87\x5a\xc0\xf3\x19\xbf\x62\x02\x3f\x6c\x7d\x92\xda\xbd\x6a\x2f\xd3\x18\x7e\xb9\xb5\x94\xcf\x5e\xaf\xef\xdb\x50\xe2\xf4\xf4\x65\x56\x7c\xd9\xef\x4a\x64\x9e\x23\x42\xf7\xdc\x83\xc9\xd4\x78\x30\x5e\x3a\xae\xc5\xca\x47\x5c\xf2\x69\xab\x85\xdd\xd8\x19\xdc\x50\x0d\xab\xde\x9f\xb6\xe5\xcd\xa2\x36\xa7\xee\xdf\xc7\xcc\x02\xe3\x2b\x07\xb2\x6a\xb7\xd9\x67\xfe\xe1\xcf\xce\x8e\xf6\x0f\xdf\x1c\x8d\xf3\xf4\x11\x0a\x69\x26\xd2\x42\x72\xa1\x55\x5b\x0b\xbf\x5d\x3f\xf4\xae\xe2\xdd\xbf\x76\x3f\x3a\x9c\x1f\xce\xad\x1f\x77\x22\xe8\x72\x90\x32\x4d\x79\xa6\x02\xee\xd2\xb2\x90\x99\x9c\xad\x6e\x80\x76\x0f\xb6\xf9\x03\x22\xe4\x8e\xe8\xc8\xf0\xe3\xfa\x8c\xdd\xf6\x7d\x94\x9b\x76\x2e\xf6\x4d\x36\x84\xac\xa9\xe5\xed\x46\x68\x77\xfc\x04\x08\xf6\x19\xcd\x88\x25\x2a\xa2\x3b\x07\xc4\x9b\x6b\x42\x51\x77\x75\x08\xba\xab\xdf\xd5\xbe\x58\x0f\xf1\xdb\x9a\x16\x46\x92\xb7\x6d\xe3\x1f\x53\xdd\x8d\x14\x6f\x20\x45\xc9\x46\x1e\x36\x1b\xda\x7b\xcb\x32\x50\xcb\xc2\xfd\xc4\x79\x82\x9d\xdf\x18\xaf\xca\x16\x4d\x8f\x70\xad\xc9\x7b\x47\x3c\x62\x11\x66\xd9\xa2\x6e\x8d\x62\xbd\x61\x74\x86\x70\xd8\xa5\x0d\xc8\x15\x25\xbf\xe2\x19\x9b\x41\xdb\x23\x2e\x66\x01\x8c\x53\x08\xfc\x64\xdb\x20\xc5\xc1\xa9\x37\xe6\xaf\xa0\xf5\x1e\x70\xd6\xc9\xdb\x0b\xe8\xa0\x05\x29\x15\x9d\x0d\x4e\xf3\x40\x58\xf3\xa3\xd1\x08\x5c\x7f\x7b\xff\x36\x96\x4f\x9a\x0d\xc8\xcf\xcc\x3e\x47\x42\x8b\xaf\x12\xda\xdc\xcf\xa5\xef\xb7\x04\xef\x5a\x53\x16\x18\x1a\xd3\xf8\xec\x55\xcf\xcc\x95\x46\xa3\xc6\xad\x3c\xba\x9e\x33\x80\xec\xae\xf3\x0c\x1e\xa3\x95\xb4\xa6\x0d\xb4\x67\x69\xef\x82\x4d\xab\xd6\x88\x4f\x1f\x70\xfb\x02\x25\x6a\x91\x67\x5c\x5c\xd6\x18\xf1\x53\x69\xf8\x18\xcb\x99\xb9\xb8\x74\xab\xa6\x64\x34\xbb\x79\xc7\x68\xc3\xa3\x6b\xdb\x2d\x74\x6f\xf1\x08\x88\x17\x18\x69\xf1\x77\x27\xbc\x6c\x02\x58\x28\xea\x77\x76\x1e\x35\xc5\xb8\x4a\x14\xef\x2e\xde\x61\x98\x48\xb6\x0b\x72\x7c\x7e\x70\x7e\xfc\x59\xa3\x7e\x37\x6d\xae\xf0\x76\x8f\xda\x7a\xe0\xbf\xb5\xcb\xaa\x1a\x91\xac\x6a\x7b\x27\xba\x5e\x4e\x65\xa9\x69\xb6\x06\xc1\x99\xcc\x69\xb1\x5f\xe9\xf9\x21\x57\x80\xd6\xd8\x8f\xfa\xb7\x34\x6a\x50\xaf\x88\x7d\xe8\x5c\xc3\x0d\xee\xd8\xd7\x5e\x77\xf0\xf7\xfd\x53\x42\x2b\xc3\x8f\xda\xb6\x18\x5a\x5b\xb2\x9c\xfb\x8a\x73\xac\x81\xee\x95\x32\x76\xcc\x4f\xd0\xc5\x5d\xb5\x49\x54\xf9\x7c\x55\x6f\xdb\x78\x34\xec\x5c\x28\xf5\x9f\x48\x0c\x9a\x0b\xae\x39\xd5\xb2\xec\x2d\x36\x18\x8d\xe8\x1d\x86\x95\xd2\x32\xb7\xab\xe8\xd8\x5d\x01\x09\x59\xa0\xbf\x2d\xdd\x54\x7b\x13\xc1\xfa\x04\x9a\x1f\x0b\x63\x2b\xd2\x84\x35\xca\x6c\x86\xd0\xfa\x07\xc7\xe6\xfe\x9a\x6f\xad\x13\x1d\x50\xec\xb3\xbf\xbd\x8c\x9a\x63\x2e\x75\x30\x76\x5e\xcc\xba\x3d\xee\xda\xbc\xd2\xfc\xb7\x7e\x44\x1b\xff\x4d\x34\xe2\x09\x48\xa2\xff\xae\x68\x86\xa4\x3d\x59\xa7\xf3\x3d\x9e\xd2\x7e\xbe\x38\xe6\x12\xfb\xf1\x35\x4b\x9c\x78\x6f\x5b\xa5\x10\xa3\x1f\x29\xa2\x4b\x2a\x94\xe1\x93\xd8\x9f\xb1\x6b\x13\x20\x76\xc9\x9e\x4e\x8a\xc1\xda\x28\xd5\x57\x39\x6c\x56\x89\x50\x59\xc5\x6f\xbf\x40\xd6\x78\xed\xcb\x61\xbb\x7d\xe6\xda\x93\x1c\x60\xb5\xf7\xe3\xb7\xb5\x63\x79\x3e\x0a\xe9\x85\x0a\x22\x79\xcd\x95\x76\x0d\x84\xe1\x04\x57\xb6\xd7\x1a\xd8\x02\xa7\x44\x96\x84\x17\xff\xa4\x69\x5a\xbe\x44\x3d\xc2\xda\xaa\xf0\x6f\xe5\xe1\xf0\xa9\xf0\xd9\x36\x7b\x7a\x51\xd8\x26\x1e\x17\x07\xa7\x04\x1b\x85\x7f\xf3\x97\xe7\x60\x17\x7c\xfd\xd5\x5f\x9e\x77\x64\xc4\xc7\x5a\x55\x48\xfa\xf6\x89\xf6\x9e\x59\xf1\x44\xaa\x48\xa2\x6a\x11\x43\x0b\xd0\x76\xcf\xb1\x38\xc3\xec\x93\x56\x68\xe2\x42\x30\x5c\xe9\x77\xef\x3e\x75\xe2\x6d\xd5\xc5\xef\xa8\xea\x82\xf8\x6a\x7c\x14\xac\xbd\x30\x72\x38\x20\xc0\xea\x2c\x0b\x70\x94\xdd\xa7\x8f\x45\x76\xb7\xa4\x6e\x5b\x4e\x8e\x39\x38\x4c\xf1\x73\xad\xf3\xeb\xf2\xd4\xc3\x93\xf3\x7f\xbe\xde\xff\xfe\xe8\x35\x7c\xab\xcd\x0a\x34\xec\x69\x2d\xa1\x36\x39\xeb\x77\x67\xf7\xf6\xce\xad\xb6\x24\xed\x23\xc1\x40\x34\x52\x0b\x04\x39\x79\x75\x7e\xdf\xac\x82\xae\xe6\xac\x98\x76\xa0\xde\x63\x8b\x6b\x40\xa7\x75\x56\xae\xa7\x72\xbe\xe7\xa0\x48\x00\x7b\x1f\xf9\x51\x0c\x0f\xe1\x37\x76\x76\x75\xb4\xe4\x0d\xb2\x71\xba\xde\xed\xf1\x6f\x43\x31\xa4\x62\xef\x91\xef\xcf\x4a\xed\x6e\x3a\x64\xd9\x17\xac\xc3\x2e\x8e\xe5\xd4\x47\x23\xc2\x70\xef\x28\xcd\xae\x6a\xf6\x53\xa6\x7c\x37\xe6\x27\xc0\xad\xc5\xaa\xd6\x83\xdd\x77\x87\x95\xc3\xda\x1e\xdc\xae\xf5\x52\x90\x55\x10\xd5\x75\xdf\xd4\xc0\xd3\x65\x64\x52\xeb\x08\x53\x05\x4d\x7a\x6d\x08\x5f\x9f\xc2\x33\x00\xbd\xf7\x18\x37\x18\x78\xf1\x35\x95\x97\xf9\x67\xf7\xb3\x1c\xfd\x70\x4d\xa4\x95\x7b\x71\x89\x6b\x5f\x5e\x48\x87\xa4\x13\x42\xb2\x6c\x24\x0b\x91\x8d\xdb\x87\xfc\x36\xf4\x73\x4b\x77\xc3\x3a\x5d\x0d\xc5\x5c\x6a\x29\x7a\xae\xa1\x5d\x35\x68\x2c\xd8\x4e\xe1\x8a\x03\xac\x74\xcf\x58\x19\xc8\x5b\xac\x20\xf2\x61\x75\x63\x79\xb8\xad\x5b\x0a\x17\x60\x8f\xc3\xeb\x8f\x4f\x12\x15\xe9\xf1\xe1\x1a\x84\xd0\x53\x03\x3b\xba\x6f\x98\x70\x6d\x89\xb2\x69\x4f\x95\xfb\x66\x20\x47\xf3\xe3\x43\x6b\x2e\xb8\xb2\x7c\x65\x97\x15\xb9\x79\x5d\xad\x45\x95\x92\xa5\xbe\x96\x65\x5f\xf0\x71\xf1\x70\x8d\x2c\x4c\xfb\xdb\x12\x18\xc7\xd3\x94\x22\xf8\x95\x8f\x5e\x92\x9c\x83\x24\x69\xb4\x41\xbd\x49\xa2\x3c\x84\x40\x79\x3c\x82\xe4\x61\x14\x97\x87\x45\xe2\x5a\x9b\xf9\xeb\x96\x47\x2f\xc4\x72\x83\x59\x37\xa8\x61\x94\x5a\xee\x52\x70\x37\x07\x92\x67\x2d\x72\xb6\x94\x46\x0e\xb5\x13\x27\xb1\x88\x75\x23\x61\x70\x10\xdb\x36\x66\x99\x99\x59\x29\xc2\x86\x8f\x16\xac\x6b\x48\xb0\x67\x62\x4e\x0b\xdb\x34\x3f\x95\xd7\xe2\x9a\x96\x29\xd9\x3f\x3d\xfe\xfc\x72\xb5\x73\x25\x28\xae\x87\x2e\xbd\x05\xe2\x5a\xd0\x7a\x3c\xc8\xc0\x87\x24\x21\xf3\xc7\x84\x6b\x85\xa9\xfc\x90\x8c\xaf\x43\x6f\x94\xd9\xa7\x7c\x26\x8b\x91\x74\x46\xaa\xd9\x91\x02\xb5\x4a\x10\x99\x68\x9a\xb9\x46\xcc\x4c\x5f\x33\x26\xc8\xf3\xe7\xcf\x31\x40\xf1\xfc\xbf\xfe\xeb\xbf\x08\x74\xdd\x4c\x59\xc2\xf3\xe5\x0b\xe1\xaa\x3f\xbf\x78\x31\x26\xff\xd8\x7f\xf3\x9a\xd0\x04\x6c\x39\x44\xbe\xc5\x91\x61\x3e\xc3\x9b\xd5\x90\xfc\xef\xf3\xb7\x27\x6e\xfb\x52\x8d\x5f\x81\x5d\xfc\xe7\x8d\xc9\x61\x90\x7b\x1f\x06\x0f\xa8\x9e\x03\x35\x84\xd4\x84\x4e\xa7\xc8\x70\x20\xb9\xb9\x72\xc2\xc4\x61\xcf\xf1\xd9\xdc\x75\xa2\x37\xac\x96\x41\x51\x00\x37\xaf\x08\x01\x1b\x87\xe3\x88\x35\x0e\x30\x96\xdf\x44\xe0\x55\x86\x24\xe3\x97\x8c\x4c\x15\xf4\xa3\xaf\x1b\xa7\x94\x4c\x19\x03\x2c\xa1\xc2\x8c\x8e\x83\xd5\x33\xa3\x58\x47\x6c\xcc\x75\x67\x4e\x74\xec\x5c\x1e\x87\x90\xed\x9a\x77\x2d\xc4\x6c\x6f\x40\x57\xa3\x85\x22\xc3\xcc\xc2\x63\xcd\x64\x88\xbe\xf6\xd4\x7f\x0f\x32\x95\x45\x3f\xac\x25\x23\xcd\xa4\x98\x85\x3c\x58\x6b\x1f\x2e\x99\x72\x51\xb0\xb6\xc4\xe8\xa9\xa1\x4e\x3f\xed\xe9\x50\xb8\xbf\xa1\x45\xb7\x4e\x20\x71\x8e\xae\x1b\x33\xc2\xa1\xa4\x13\x59\x69\x97\xb3\x67\x7f\x07\xf8\x36\x2d\x1d\xe9\x3b\xbd\x42\x6f\x5d\x8a\xfa\xeb\xfb\xd7\x53\xd3\xad\x38\x67\x0e\x76\xed\x58\x65\x1d\x12\x46\x93\x39\xb9\x64\x8b\x11\xee\x00\x05\x05\xf4\x08\xa0\xf6\xa1\xa1\x71\xd4\x86\xdf\x7b\x9e\x53\x63\x4d\xda\xa9\x70\x09\x96\x81\x7e\xe0\xd0\x27\x9c\xc1\xa5\xac\x5e\x6e\x5b\x59\x89\xc0\x43\xe9\x7a\x57\x26\x52\x68\xdb\x17\xd3\xf7\xae\x82\x84\xd1\x06\x20\x81\x91\x30\x2c\x35\xb7\xa9\xdb\x9e\x5c\x67\x95\x9a\x1d\xc5\xea\x1f\x95\x58\xba\x1b\xf0\xdc\x21\xa7\x57\x31\x8b\x8c\x44\x5d\x4f\xc4\x20\x33\x75\xce\x13\xa8\x38\x32\x97\xdb\x6b\x1d\x95\x3c\x21\x22\xc0\x04\xc5\x74\x65\x49\x03\x79\xc2\xe6\xd9\x4c\x29\xc2\xe1\x0b\x73\x5a\x5e\x32\x07\x34\x4c\xb3\x31\x39\x35\x2f\xe9\xd1\xe6\xb1\x95\xe0\x15\x16\x88\x18\x19\x13\x22\x41\x98\x87\xec\x8e\xc7\xbb\xb8\x55\xae\xc0\x85\xe8\xcc\x35\x7d\x76\x91\xeb\xad\x7b\x5c\xc4\xca\x6f\x68\xa1\xb0\x9b\x9e\x31\x2d\xa0\x63\xa5\x04\xdc\x16\x3d\x77\xca\x04\xed\x08\x21\x1e\x1e\x3d\xb7\x31\xeb\xb7\x13\x6a\x7f\x7d\x50\x3b\xc4\xda\xe3\xa3\xef\xfe\xa7\x3d\x76\x3f\xbd\xa9\xf7\xa9\xe5\x21\x2b\x49\xfa\xea\xc8\xd8\x7b\xcb\xcd\xbc\x87\xc6\x66\xee\x88\x43\x47\xa0\xdf\x46\x58\xd2\x77\xb2\x45\x2c\x94\x7a\xc6\x1e\x95\xf1\x71\x3c\x05\x91\xba\x1a\xeb\x26\xb4\xcb\xdc\x0e\x63\x28\xb0\x7e\xab\xa3\x6b\x97\x3d\x77\x3c\x44\x9b\xfa\xee\x66\x49\xf3\xe8\x92\x44\xd3\x3c\x62\x47\x46\x00\x2b\xe1\xb7\xda\xb0\xfa\x18\xa6\x4a\x4b\xe8\xd6\x59\x0b\x87\x31\x79\x63\xb7\x62\x64\x72\x3a\x51\x32\xab\xb4\x47\xa2\x58\xb1\x4f\xc3\xa0\xae\xb7\x27\x82\x36\xb9\xcb\x82\x5d\x1b\xf4\x15\xdc\xca\xfa\xd9\xc0\xf1\xe8\x51\xf8\x74\x4d\x90\xc5\xe3\x77\x96\x26\x8b\x47\x8f\xb3\xe0\xd4\xc5\x9e\x67\xc2\x0d\xeb\xd1\x3b\x5d\x45\x64\xa4\xdd\x42\x8e\xac\x56\xa8\x3a\x3b\x45\x15\x6b\x28\xdb\x22\x60\xd7\x47\x77\xaf\xae\xfd\x2e\xeb\x60\xdc\x3f\x3d\xee\xd1\x2a\x0d\x46\xbd\xc1\x2e\x0d\xaf\xd8\x5a\xa6\x77\x39\x22\x02\x1f\xa3\x65\x6a\x54\x7a\xe7\x40\x3a\xac\x29\x6a\x43\x7a\x46\x28\xff\x0e\x4c\x9b\xa5\x0f\x7f\x65\x36\xa3\xb0\x98\x2b\xee\xd0\x81\xce\xe0\x7a\xdb\x0a\xba\x7a\xb8\x1c\x1e\x10\x71\x4f\xdf\x0c\xda\x50\xe3\x05\xa8\xdf\xa1\x62\xa7\x79\xc4\xbb\xe8\x99\x23\x22\x39\x67\x99\xd9\xf4\x48\xc3\x65\x53\xc8\xf4\x25\xf6\xfc\xa6\x42\x48\x0d\x7c\xa3\x86\x24\x83\x7e\xe4\x43\x74\xc5\x18\x0d\x34\xc8\xfe\x2a\x83\xa0\x69\xcf\x3a\x67\x6f\xcc\x43\x7a\x67\x20\x02\x4c\x04\xb4\x3b\xed\x87\x93\xc8\x03\x70\x93\x39\x6a\x55\xa5\xcf\xb6\xfc\x11\x5f\xd9\xf1\x1d\x13\xa9\x64\xce\x72\x8a\xfd\x48\x1c\x81\x8c\xbc\xbe\x2e\xb9\xd6\x0c\x51\xc7\x59\x99\x2b\x22\xa7\xc3\x28\x6e\xbc\x73\xf5\x62\xa7\x2f\x7d\x96\x3c\x84\x41\x4d\xdc\x0a\x6d\x0b\x03\x76\xd3\x11\xc7\x0d\x22\xe3\xc2\xac\x4e\xb0\xa6\x33\x68\x90\x24\x1a\x0e\x4b\xa3\x44\x5c\x21\xfd\x37\x9a\x74\x0f\xe7\x8b\x68\xeb\x83\x18\x7a\xc5\x74\xeb\x83\xd8\xfa\x20\xfa\x18\xf1\xc1\x7c\x10\xc1\xc6\xed\x84\xe9\x0a\x7f\x44\x58\x88\xe7\x9c\x12\x35\x94\x45\x00\x13\x6d\x58\xde\xb9\x23\x64\x19\xc7\x0a\x76\xc7\xe3\xdd\x5d\xe7\xa4\xb0\xeb\xa3\xd2\xd3\xd1\x37\x84\x89\x44\xa6\xc8\x54\x66\xfc\x52\x69\x50\x6a\x6b\xab\x3c\x7c\x97\xdc\x3d\x2b\x8c\x37\xc0\xd8\xfd\xb2\x44\x8f\x12\xca\xa5\xa4\xbc\x7a\x50\x15\xac\x56\xbc\x3c\x0c\x98\x25\xa0\x47\x4b\xb4\x1a\x58\x9d\x22\x93\xf1\x9c\x5b\x7c\x42\x23\x2e\x98\xd2\x8a\xec\xe1\xc9\x71\x52\x54\x43\x7b\xc1\x38\x67\xb9\x2c\x17\x43\x7f\x91\xf9\x31\xba\xcb\x5e\x31\x00\xad\x2d\xa9\xca\x92\x09\x9d\x2d\x7e\xbf\xfa\x9b\x23\xf1\x06\xab\x6f\x9e\x2b\xba\xd4\x7d\xac\x3a\x62\xb6\xac\x9b\x08\x80\xf7\xce\x53\x1b\xf6\x21\x5b\x81\x31\xac\x9d\x3f\xe6\x2c\x13\x57\xe4\x8a\x96\xad\x2b\x30\x56\x1d\x0f\xa2\xb1\xa5\xfc\x8a\x2b\xd9\xba\x86\x6d\xe5\x90\x21\xf1\xce\xed\xa6\x8c\x3e\x62\x59\xe9\xa2\xd2\x76\x77\x71\x6b\xdb\x41\xf6\xf9\x35\xdd\x50\x7c\x5f\xec\xf4\xf8\x72\x05\xd5\x9a\x95\xe2\x25\xf9\x9f\xbd\xf7\x5f\x7e\x1c\x0d\xbe\xdb\xdb\xfb\xe5\xf9\xe8\xaf\xbf\x7e\xb9\xf7\x7e\x0c\xff\xf8\x62\xf0\xdd\xe0\xa3\xfb\xe3\xcb\xc1\x60\x6f\xef\x97\x1f\xdf\xfc\x70\x71\x7a\xf4\x2b\x1f\x7c\xfc\x45\x54\xf9\x25\xfe\xf5\x71\xef\x17\x76\xf4\xeb\x1d\x07\x19\x0c\xbe\xfb\x63\x8f\x1f\x41\xc5\xe2\x6d\x6f\x22\x18\x8f\xd1\x83\xa8\x11\xf1\xd8\x3d\xb3\x2e\x21\x1f\x46\xb5\x47\x7b\xc4\x85\x1e\xc9\x72\x84\x0f\x79\x49\x74\x59\xf5\x25\xba\xea\xed\xef\xe1\x64\x4c\xad\xc4\xd4\x08\x98\xce\xb0\xd9\x40\x21\x82\x89\xa9\x3d\x7a\x86\x6d\x1f\xdb\xd5\x4e\x61\xfb\xe3\xd6\x1f\x7c\x97\xe3\x01\x33\x95\x2c\x9e\xcd\xef\x3c\x4d\xe9\xdc\x76\x53\xde\xe6\x28\x2d\x1d\xdb\x1c\xa5\xe5\x63\x9b\xa3\x74\xcf\x63\x9b\xa3\xe4\x8e\x6d\x8e\xd2\xd6\x3f\xd8\xfd\xf8\x9d\xfb\x07\xb7\x39\x4a\xf7\x3d\xb6\x39\x4a\xad\x8f\x47\x94\xa3\x84\x4a\xfe\xaa\x4c\x25\xab\xe6\xd7\x69\x4a\x1b\x9b\xa5\xa4\x0c\x3f\x24\x6c\x3f\x49\x64\x25\xf4\x85\xbc\x64\x1d\x03\xb9\x0d\x9b\x74\x69\x74\x80\x44\xbc\xc1\x46\x5d\xbe\x78\x23\x0d\xd6\xbe\xf4\xd1\x1e\xf4\xc7\xfe\x34\x47\x5a\xa5\xdc\xd8\xa8\x3d\x2f\x16\x37\x6c\x08\x8b\x2d\x52\x96\xd6\x3f\x58\x91\xa6\xcd\x7c\x8f\xc9\x3e\x29\x59\xc2\x0b\x6e\x36\x00\xc0\x0a\x82\xf3\xb8\x7c\x7c\x17\x67\xae\x15\xcb\xa6\xb6\x93\xad\xa8\xcb\x9c\xcb\xc0\xfe\xb4\x3b\xca\xca\xc7\xa0\x0e\x21\x5d\xaf\x51\xa2\xe6\xb2\xca\x52\x52\xb2\x7f\x3b\xe5\xc3\xbe\xcd\x45\x38\x42\xe8\x52\x85\x4f\xa9\x1f\x6b\x07\xa7\x05\xb7\xa0\x62\x9b\x24\x06\xd9\x87\x82\x97\xb0\xd8\xce\x59\x22\x45\xda\xb7\x87\x64\x69\xfc\x5a\x57\x80\xb8\x10\x4b\x49\x5a\xe1\x05\x50\x8e\x49\x33\x9e\x72\xbd\xf0\xf9\x1c\xb8\xec\x8d\xda\x8a\xbd\x83\x2d\x23\xa8\x7a\x22\x08\x2d\x8a\x52\xd2\x64\xce\x54\xf0\x34\x54\x42\x2d\x50\x86\xaf\xf2\xcc\xaa\x19\x17\xa8\x87\xc2\x3d\x46\x59\xc9\x16\xa4\x94\xda\xa5\xa6\xdd\xf0\xc0\x8b\x60\x30\xb8\x1d\x35\x0e\x5d\x2e\x20\x7f\x4d\x86\x43\xe0\x5b\xf1\x69\xf8\x87\x22\x32\x4b\x1d\x34\xeb\x37\xcf\x8d\xe2\x9f\x58\x2e\x36\x9b\x00\x80\x66\x6a\x49\x32\xa3\x3c\x99\x8d\xe1\xe6\x9b\xbf\xfa\x13\x99\xcb\xaa\x54\xe3\x10\xec\xef\x05\x9c\x43\x0f\x87\x33\x1c\x34\xc9\x18\x55\x9a\xbc\x78\x4e\x72\x2e\x2a\xb3\xe3\xf7\xc4\x78\x7d\xe9\xba\x81\x96\xfb\x97\x3f\x75\x1c\xad\x1f\xfd\xf6\x46\xcd\xb6\xc0\x8e\x79\x56\xbd\xb5\x6b\x1c\x01\x3d\xb0\x6b\x66\x43\xd9\xb5\x5b\x52\x38\x8b\x42\xcb\x35\xaf\xfc\xdf\x2a\x39\x59\xe8\xee\x10\x36\x76\x9c\x18\xbb\xe6\xbf\xed\xc9\xbb\x40\xc5\xd6\x48\xb1\x2d\x5e\x65\xed\x3d\xbe\x67\x5c\xe9\x56\x1d\xbe\x6b\xcc\x9b\x16\x37\x77\xdd\xcc\x67\xc6\x3e\xee\xa5\x92\x1e\x46\x72\x16\x9d\xf3\x48\x27\x09\x53\x20\x8a\x1c\x28\x1c\x38\x77\xf1\xda\x96\x0f\xdd\x50\xb4\x99\x55\x20\x32\x8e\xf9\x7b\xe8\x55\xda\x89\x58\x5d\x54\x7e\xc7\xd8\x3d\x51\x0b\x07\x8b\x65\x84\xe2\x62\x86\xad\x45\xf3\x2a\xd3\xbc\xc8\x6a\xca\x9d\xb9\x1b\xec\x06\x1c\x46\x0b\x68\xe0\x9e\xa6\x08\x7a\x85\xe8\xe7\x10\x59\xd9\xf3\x63\x31\xa1\xb1\x43\x66\x69\xf6\xf1\x82\x96\xd4\x93\x3f\x91\x79\x4e\xd5\xc0\x06\x1e\x28\x64\xc1\xd8\x36\x40\xe6\x2e\x9a\xd5\x6f\x1c\x64\x1d\xac\x8b\x71\x35\x13\x54\xb4\x0e\xff\xc5\x80\xf3\x30\x14\x91\xd7\x3e\xd1\x1e\x9b\xdc\x37\x38\xd6\x2a\xc4\xdf\xd3\xe4\x92\x89\x94\xbc\x53\x8e\x70\xe9\x42\xd0\xdc\xe2\xc7\x17\xa5\xc4\x2e\xea\x2c\x6d\xdc\xaf\x86\xd6\xed\x88\xd0\x27\x0e\xc0\x0a\xf5\xad\x75\x51\xb1\x52\x3d\x81\x07\x9b\x81\x3e\x25\xef\x14\xba\x74\x4b\x7e\x95\x30\xa7\x3b\x9a\xfb\xd6\xf5\xf1\x57\xad\xd1\xea\xc8\x6a\xe8\x28\xdb\xc6\x14\x57\x21\x6c\xe9\x3e\x72\x09\x30\xf1\x34\x33\x22\x6e\xe1\x31\x7f\x1a\x0c\x36\x59\x80\xdf\x6b\x2d\xc8\x63\xe5\xa4\x3b\xa6\xd4\x6e\x39\x49\x63\x61\x76\x46\x53\xa9\xc8\xf7\x99\x4c\x2e\xc9\x21\x03\xa3\xe1\x21\x9b\xef\x97\x93\xf4\x71\x37\xce\xcc\xe9\xac\x5d\xc6\xc8\x88\xe4\x52\x70\x2d\xcb\x36\xf2\x78\x83\x80\x02\xb7\xad\x0c\xef\x82\x98\x6e\xd6\xd9\x53\x69\x64\x68\x58\xbe\x1f\xd6\x81\xa1\xbc\xeb\x04\x24\x0f\x9e\x02\xa1\xda\x5a\x8e\xfc\x61\x2e\xaf\x47\x5a\x8e\x2a\xc5\x46\xbc\x75\x22\x54\x67\x42\x5d\xb2\x05\x64\x95\xf5\x42\x2a\x3b\x58\x64\xb9\x6b\x09\x7e\x76\x38\x6f\xf4\xbb\xb3\xef\x0f\xdf\x29\x56\x8e\x43\x6b\xe5\x19\xd3\xc9\xb3\x84\x15\xf3\x67\x76\x84\x47\x4f\x56\x27\x36\xfb\xa1\xab\x1b\x0d\x15\x81\x44\x66\x99\x05\x18\x93\x53\x72\xc0\x8a\xb9\x7f\xdc\x66\xd0\xed\x31\xf7\x94\x2b\xa4\xec\xa7\xdd\xd4\xae\x19\x29\x16\x1b\x70\x06\xa5\x46\xc0\xfc\xe5\xe4\x7e\x8d\xbc\x37\x91\xdd\x3f\x63\x77\x96\x36\xad\xf8\x36\x82\xbc\x9b\xd3\xd2\x6f\x37\xea\xe9\x17\xd6\x0f\xc5\x0d\xfb\x5c\x76\x6a\x24\xb6\x8f\xa7\x68\x8c\xa6\x2c\x25\xf2\x8a\x95\x25\x4f\x99\x22\x5e\x6e\x87\x3e\x28\x9e\x6d\x06\xe5\xb7\xbd\x03\x1f\x57\xc2\xc1\xe6\xb8\x1f\x76\xc1\xff\x10\x09\x71\x38\xb3\x24\xc4\x69\x9a\x73\xb1\x19\xdc\xde\x92\x6e\x2a\xa1\x19\x3b\x7e\xdb\xd9\x5a\xb7\xe3\xc4\x06\xfb\xb9\x3d\x19\xf4\x14\xf8\x04\xce\xfe\x8f\x9e\x77\x89\x90\x69\xbb\x00\xda\x9a\xcd\xee\x19\xd5\xec\xba\xa5\x22\x34\xaa\x45\x7e\xdb\xfb\xc1\x3c\x7b\xdc\x66\xfb\x46\x74\x0a\x09\x56\x39\x42\xfe\xaf\x4b\xc9\xb2\xfc\xd4\x4f\x20\x09\xc7\x0a\x9b\xb2\x35\x5b\xb1\xb9\x35\xbb\x7f\x7a\x4c\x7e\xc0\xcb\xd7\xd7\x05\xa5\x94\x1a\x4d\x9e\x43\x99\x53\xde\x4f\x03\xf4\xe6\xa0\xcd\x7e\x58\x21\x11\x4e\xfd\xb5\xc4\x5e\x6c\x94\xa2\x1a\x6e\xb8\x2a\x59\x4a\xac\x3f\xe5\x89\xb5\x78\x58\x52\xa7\x9f\x46\x8b\x87\x87\xea\x92\x1d\xb8\xe6\x5d\xfd\x4e\xad\x45\x3b\x76\x02\x25\xc2\xe7\x3a\x11\xc5\x84\xe2\x90\xde\x10\x64\xe0\x81\xaa\x0d\x69\xe9\xbe\x58\x07\xd5\xee\x21\x79\x2d\x67\x5c\x38\x29\x26\x6d\x56\xcd\x94\xf2\xac\x1b\x39\xb7\x7a\xf2\xef\x4c\x4f\x56\x2a\x3b\x12\x74\x92\xb5\x4f\x99\x8c\x17\x81\x1f\x8e\xbc\xca\xe8\x8c\x30\xf8\xe3\x59\xca\x95\xf9\x2f\x39\x3f\x7f\x0d\xc1\xe0\x4a\x38\xfb\x12\xc2\x9c\x76\x6f\xf1\xa5\xd1\x28\x64\xd6\x27\x17\x50\x88\xf7\xd6\xc1\x23\x18\x8f\x70\x91\x9a\x4f\x67\x2a\x4a\x4a\xb6\x57\x60\xaf\x14\x5f\x77\x87\xa9\x8f\x13\x46\x2e\xe6\x3c\xb9\x3c\x0d\xe2\xbf\xb2\x34\xe7\x44\x70\x2a\x52\x52\x9a\xbf\xad\x6b\x37\xb2\x9f\x75\xda\x97\x43\x2d\x18\xcf\xed\xd4\x4e\x9c\x9e\x5b\x0a\xc2\x6f\x54\x29\x99\xf0\x3a\xff\x00\x3c\xd1\xf5\xf6\x9d\xc2\xf6\xbd\x3e\xaa\x80\xc2\xd9\x0f\x41\x50\xcf\x5d\xa1\xb5\x38\x8e\xb2\x57\x50\x15\x6a\x29\x5c\x38\xba\xad\x8d\x08\xc8\xe3\xbd\xb5\x34\xad\x87\x5b\x6e\x69\xea\xcc\xcc\x46\x88\xdc\x15\xbc\x5a\x06\x72\x26\x83\xed\xa1\xbd\xcc\x42\xbe\xb5\xa9\x6d\x66\xb2\x16\xd2\xb5\x2f\x4d\x5f\xe5\xfe\x6b\xe4\x07\xe1\x39\x1b\x34\x07\xd9\x53\xc8\xa2\xca\x30\xb3\xb6\x7b\x67\x57\x17\x63\xc4\xe7\xac\x21\x88\xbe\x69\x9d\x9d\x76\xc3\xf2\xbc\xfb\xd7\x2b\x3e\x8d\xfe\x4e\x81\x69\xf1\xfc\x2f\x7f\xfa\xd3\x63\xef\xf8\xd4\xcd\x71\xb7\xee\x96\x4f\x9d\x42\x6f\x2b\xb0\x19\x8e\xb7\xd8\x0c\x5b\x6c\x86\xf8\x58\x7b\x7c\xf8\xf3\xa3\x2f\xf4\x52\xdd\xd6\x47\x65\x5b\x57\x7c\x85\x8e\x55\x71\xfd\x54\xc4\x75\x46\x50\xf8\x1c\xb8\x09\x3d\xd5\x88\x75\xc7\x48\xd8\x22\x23\xfc\xbe\x90\x11\xfa\xab\x11\xeb\x0b\x05\xa1\x7b\x6d\xd8\xef\x07\xf1\xa0\xb3\xd8\xe8\x5a\x57\xdf\xb9\x9a\xbe\xaf\xa6\x1f\x7d\x79\xf7\x7b\xf3\x30\xec\xd6\xe3\xad\xf4\xb7\x38\x88\x37\x87\xa6\xbf\xbb\xab\x02\xb0\x7c\x2d\x8d\x74\x59\xa3\xe9\x4c\x3a\x7b\x1e\xf0\x55\x64\xab\xbd\x7b\x95\x17\xef\xed\x79\x23\x41\xc0\x9f\xde\xfc\xbc\x80\x6d\x80\xbc\x5b\x9a\xfa\xd3\x0a\x8f\x3e\xd1\x0e\xf8\x0f\x15\x1e\x55\x11\x6a\xae\xf3\x3a\x82\x80\x04\x15\x4e\x4e\xc2\xce\x34\xb5\x58\xd8\x3f\x3d\x26\x49\xc9\x00\xda\x81\x66\x6a\x4c\x56\x68\x78\x2e\x80\x64\x35\x42\xa7\xd9\x51\xad\x59\x5e\xe8\xae\x9c\xb7\x8d\x8e\xfe\xce\xa2\xa3\x0f\x1e\xa5\x98\x57\x39\x15\x23\x23\x2d\x20\x3e\x1a\xe5\x9d\x34\xf6\xc3\x31\xb1\x72\x01\xd5\x0a\xf0\x85\x42\x49\x73\x25\xf8\x6f\x15\xab\xdd\x15\x5e\xeb\xd8\x80\xe0\x0e\xbc\x47\xcf\xb4\x43\x8d\xaa\x21\x45\x12\xb9\x54\xc4\x65\x09\xe2\xe9\xe8\x04\x46\xa0\x96\x45\xae\x37\x3d\x67\xa8\xbd\x9d\x02\x48\x42\x7d\x55\x6c\x1f\xa2\x81\x48\xb3\x4c\x5e\xe3\xb3\x43\x7d\xc4\xcc\x9f\x79\x17\x8b\x4b\x32\x61\x24\xe7\x65\x29\x4b\x1b\x46\x0a\x5f\x07\xd3\x87\x8c\x9d\xc9\x4a\x34\xd8\x4a\x9b\xf4\x71\xce\xb4\x9d\x6a\x60\x15\x2d\x09\x15\x58\xc0\x69\xfe\xed\x32\xae\xe1\xd9\x4e\xde\x4d\xd8\x9c\x5e\x71\x59\x95\x78\xb7\x96\x64\xc7\xfe\x04\x7b\xef\x42\x56\xde\x77\x5e\x41\x85\x96\xff\x3a\xb5\x82\x4e\x27\xf5\x8f\x60\xe0\xa6\xd2\xb9\x23\x47\xec\x03\x57\x7a\xf9\x5b\x1c\x89\x5c\xcb\x89\x75\x70\xde\x95\x2a\xcc\x06\xfb\x53\xeb\xda\xdb\x98\xdf\xc2\xd1\x62\x4d\xf5\xea\x1c\x7e\xfa\x94\x9e\x6a\x11\x6b\xb0\x64\xde\x95\xc3\x3d\xbe\x1c\x56\xfc\xca\x96\xbd\xae\x36\x52\x51\xde\x2a\xc9\xb7\x1e\x3e\xcb\x22\xe3\xc9\xe2\xf8\xb0\xdf\xcc\x0d\x1c\xd3\x6d\x7f\xca\x67\x6d\x98\xf3\xe4\x7b\xaa\x58\x4a\xde\x50\x41\x67\xe8\x75\xd9\x3b\x3f\xfd\xfe\xcd\xc0\x70\x11\x78\x75\x8e\x0f\x57\xa6\x76\x9c\x87\x83\x9f\xac\xab\xce\x9d\x34\x49\xd7\x9b\xda\xb0\x34\x6a\x4b\xf2\xad\x0d\x02\x80\x78\x9d\xa0\x4b\xfb\xb4\x15\xea\xc0\x69\x13\x24\x0a\xd3\x37\x1c\xfa\x9b\x6a\x8a\xea\xab\x3c\xbd\x7c\x48\x02\x04\x7e\xf3\xdb\xbe\xf2\x6e\x31\xb0\x3b\xc4\xb9\xe2\x6e\x24\xba\xa4\x9a\xcd\x16\x87\xac\xc8\xe4\xc2\x30\xc0\x69\xe0\xc6\xc7\x4b\x27\xa8\x36\x94\x13\x9a\x90\xb2\xca\x18\xf6\x16\x6a\xc2\xae\x09\xc6\xd2\x5a\xd2\x71\xa1\x34\x05\xd0\x35\x1c\xff\xd6\x37\xba\xf3\x66\x75\xd7\x6d\x69\x84\xef\xf9\xc9\xab\x62\x88\x4a\xb3\x4a\x6e\xbd\xe5\xee\x1b\x13\x3c\xfe\xd3\x3c\x7b\x9f\xb8\xe6\x9d\x23\x98\x71\x77\x40\x58\xe5\x67\x55\x66\x36\x9f\x2c\x6d\xb4\x78\x05\x3d\xcd\xce\x31\xa2\x5d\x80\x4c\x30\x6f\x3f\x24\x93\xca\x28\x71\x4c\x45\x3e\xee\x65\xa8\xcf\xeb\x39\x86\xb4\xcd\x4d\x84\x16\x45\xc6\x31\x85\x59\x96\x36\x2e\x1d\x38\x34\x97\x2f\xbb\x8b\x68\xb9\xa7\x2e\x73\x3f\xdd\x65\x44\xae\x58\x39\xb9\x0b\x4e\xc5\x7d\xd5\x12\x5a\x70\x88\xe3\xdc\x59\x8b\x89\x26\x6e\xff\xf4\x18\xef\x5e\xe5\x38\x76\x3f\xe2\x0c\xda\xb9\x71\xe1\x0d\xdb\x33\x08\x2d\x17\x8f\xb4\xb4\x7f\x7a\x8c\xd0\x5e\x16\x6c\xa9\x76\x7f\x18\x3b\x81\x62\x92\x63\x8d\xf0\x48\x67\x66\x44\x4d\xa4\xf0\x0f\x65\xa2\xca\x19\x02\x34\xd5\xcd\xc6\x8c\xf1\x28\x16\xf5\xe8\xb5\xf7\xc4\xd8\x3a\x77\x57\x48\xee\x1f\xe1\xbf\x67\x44\xff\xde\x7b\x91\x90\xe2\xcc\x7e\xe6\xbb\xb3\xd7\xed\x26\xf1\x24\x1e\xc3\x02\xf2\x30\xc0\x1e\x2c\x68\xa9\x39\xcd\x48\x55\x66\x2e\x24\x88\xf9\xfd\x36\x8d\x6e\x4e\xaf\x02\xd0\xa2\x31\x21\x5f\xe0\xcc\x59\xc2\xe2\xfa\xc4\xe6\xbb\xd6\x8d\x5b\x65\xd9\x90\x4c\x39\xb4\x5b\xd7\xac\x20\x61\x48\xea\x9c\x8b\xc4\x98\x72\x62\xe4\xbb\xe9\xc0\x1b\x39\x03\xcf\x2f\x52\x88\x78\x82\xbe\xcb\xb2\x14\x80\x2c\xe1\x11\x66\xc1\x26\xe0\x6e\x30\x16\xe8\x41\x56\x29\xcd\xca\x33\x69\x36\x83\x20\xe5\x06\x40\x3d\x68\xf8\xf3\xf7\x5c\xa4\x90\x63\x75\x06\x1b\x47\x42\x05\x61\x1c\x1c\x39\x66\x48\x88\x9d\x1b\xde\xa9\x19\x6a\x4f\x55\xc9\xdc\x7c\xd2\x4e\x21\x53\xb5\x63\xc4\xc8\x0e\xba\xfb\xd4\xce\xc0\xfc\xd5\xfc\x06\xcc\xa0\x09\xee\x7b\x46\x0b\xbe\x33\x18\x12\x20\x10\x04\xef\xa4\x9e\x3f\x5e\x3e\x74\xdf\x0a\xf6\x75\x2b\x2e\x3c\x0b\x47\x00\x1e\x14\x75\x98\xee\x7a\xce\x35\xf3\xad\xd1\xd1\x4b\xe4\x51\x6a\x9a\xc2\x9a\x90\x7d\x41\x58\x5e\x68\xf0\x3c\x93\x9c\x51\x17\xce\x66\x57\xac\x5c\x18\xfb\x1e\x50\x3c\x1e\xfd\xe2\xf7\xfc\xd8\x89\xe0\x8d\xbe\xf3\x35\x93\xc3\x0a\x5b\x22\xee\xee\x17\xbb\x91\xcf\x20\xcb\x02\x69\xfe\x68\x49\x09\xdb\x6b\x2b\x32\xfe\x64\xee\x8c\x49\x88\xa7\x50\x5a\x7a\xf9\xf1\xfa\xb5\x0d\x8a\x20\xad\x7e\xe4\x22\x55\xbe\x13\xa2\xcd\xd9\xb6\xf4\x5e\x49\x64\x78\xc3\xc7\x48\xe0\x65\xf5\xf5\xae\x2a\xe7\x2d\xc3\x3b\x8d\xfd\xa6\xa1\x6e\x1d\xc0\xaa\xfd\x6f\x64\xba\x7a\xe9\x44\xf3\x7b\x1c\x5c\xec\x13\x05\x6a\x9f\x89\x1d\xcb\xaa\xaa\x8b\x62\xa5\x3e\x7f\xfb\x74\xdc\x42\xfa\x9b\xde\xa4\x76\x16\x80\x9c\x0c\x7e\x01\x4f\x10\x62\x94\x93\x69\x46\x67\x35\x1b\x81\xd4\x43\x25\xe9\xe0\xfc\x27\xf7\x09\x8a\xf0\xd5\xea\xea\x27\xf5\xd9\x4f\x69\xb0\xa3\x9a\x4a\x37\x5e\x61\x1e\xb2\xf2\xc7\x4f\xab\xb1\x7e\xf0\x9b\xb9\xe9\x2e\x81\x42\x7d\xab\x13\xee\x26\xfa\x3b\x7f\x1b\x0d\x38\xc1\x81\xad\x39\xa3\x12\x72\x9f\x40\x0f\x39\xff\x29\x62\x93\x4f\xbc\xef\x0d\x4c\x7b\xc9\x16\xd7\xb2\x5c\x8d\xa3\xde\x9a\xbf\x6e\x7d\x62\x46\x27\x2c\xfb\xf4\x02\x79\x43\x0b\xf3\xd9\x75\xa2\x29\x5a\xde\x36\x4e\x89\xba\x3f\xe6\x84\xb9\x3c\x3c\x59\xce\xa8\xe0\xff\xc1\xec\xdc\xc4\xac\x63\x59\x9a\x3f\xf7\x30\xd6\x81\x76\x7b\xc6\x12\x3d\xb0\xfc\xb7\x52\xee\x7d\x82\x41\x69\x9a\x72\xd4\x1e\x4e\x3f\xc1\x4b\xb7\x13\x81\x8b\xcb\x87\xa0\xf9\x2d\x0b\xeb\xd3\xbc\x7f\x7b\xb0\xf4\x0e\xb2\xb9\x2a\x6f\xc9\xa3\xba\xf5\xfe\x9c\x72\xdb\x55\x77\xe3\xa8\xc2\x72\xca\xdb\x7e\x16\x1e\x1d\xe8\x9a\x53\x5d\x95\x5c\xaf\xdc\x90\x6e\xbf\x91\x8b\x1f\xab\x09\xb3\xf1\xe1\x7b\xdf\x2e\x20\x4d\x70\xff\xf4\xb8\xdf\xe9\x88\x56\x38\x58\xf1\xf6\x05\x8d\xde\x42\x2a\x41\xf3\x09\x9f\x55\xb2\x52\xd9\x22\x74\x4a\x52\x08\x6f\x1b\xa3\x1e\xbd\x32\xff\x1f\x7b\x57\xf3\xdb\xb8\x8d\xc5\xef\xfd\x2b\x08\x5f\x32\x13\xc4\x1e\x2c\xda\xd9\xc3\xdc\x82\x24\xc5\x06\x9b\x8f\x81\x9d\xb6\x97\x1e\xca\x48\xb4\x2d\x44\x22\xbd\xa4\x64\xc7\x2d\xfa\xbf\x2f\xf8\xf8\x48\x89\xb6\x44\x51\xb1\x93\xa6\xc5\xf8\x92\x19\x89\x7c\xe2\xe7\xe3\xfb\xfa\x3d\xf2\x93\x92\x50\x2e\xf8\xb6\xc0\xa2\x3c\xc9\xab\x94\x79\x14\xc1\x0b\xb8\x16\x59\x4a\x68\x55\x8a\x82\x96\x59\x42\x12\xc1\x64\x02\x1e\xc3\x26\xa5\x4a\x31\x42\x3b\xea\x26\x95\x2a\x45\x41\x0a\x2a\xd5\x92\xe6\x79\xd7\x1c\x1f\xe1\x54\x0b\xa5\x1e\x1f\x43\xff\x3b\x5f\xae\x4d\xab\x5f\xb8\xbe\x7b\x32\xad\x47\xac\x6f\xdd\xb8\x83\x08\xac\xbb\x57\x69\x04\x0d\xc4\xf8\xb7\x66\x2f\xea\x99\x98\xbe\xd1\x09\xed\xdc\xde\x7e\x05\xb8\x61\xb0\x2e\x04\xe9\xb2\xf4\xba\xa0\x8b\x08\x41\xf2\x46\x6b\x07\x94\x6f\x6d\x35\x93\x68\x53\x9d\x11\x21\x31\x6a\xc4\xdd\x8b\x8e\xaf\x5c\xb2\x56\x49\xee\xc1\x1d\x27\x24\x86\x6f\xe3\x2a\x85\xa0\x7e\x26\xe7\x42\x16\x5a\xae\xcb\x24\x99\x57\x1c\x8c\x64\x0a\xa3\xbd\x41\x25\x41\x5b\x0d\xcd\x95\x70\x3b\x10\xfc\x7b\xdc\x36\x82\x50\x45\x36\x2c\xcf\x27\xe4\x3c\xcf\x31\x03\x68\x23\xd7\x43\x8d\xd7\xae\x63\x0a\x1e\xb7\x24\xcd\x16\x4c\x95\xe4\xc3\xec\x3f\xe7\x1f\xe1\xd4\x06\x3b\xc6\x96\x94\xd4\xc2\xd5\x7c\xfb\x0c\x9c\xff\x69\x05\x72\x42\x42\x4b\x9a\x8b\x85\x71\xab\x83\x9d\x96\xa7\x64\x95\xd3\x2d\xa4\xf7\x5f\x51\x09\x11\xa7\x89\xb1\xd1\x10\x59\x71\x48\x6c\xfc\xa6\x27\x4e\x3f\x2b\x08\xe5\x1e\x1e\xc3\x9a\x7c\xe1\x56\xef\xc9\xf0\xfa\xba\x47\x99\x64\xab\x9c\x76\x58\x15\xbc\x15\xfd\xe0\x81\x91\xb5\x98\x0b\x2a\xac\xe0\xcc\xd1\x98\x90\x99\x59\x3b\x05\x2d\x13\xe3\xd3\xfc\xad\x60\x25\x4d\x69\x49\x27\x5a\x17\xfc\xcd\x47\xc6\x89\x3c\xd5\x84\xba\x27\xba\xa3\xcd\x46\x5e\x6c\xbf\x10\xdf\xdf\x85\x5a\xa8\x75\xc5\x41\x3e\xb7\xfb\x31\x68\xc6\x38\x90\x3f\x41\xf7\xaf\x9e\xb5\x2a\x16\xf4\xa1\x79\x6d\xdd\xad\xe4\x5b\x19\x72\xbf\x27\xb8\x5a\x0b\x06\x69\x22\x1f\xf0\x26\x24\xfb\x04\x4c\xa8\xe7\x77\x97\xdd\xe6\xae\x7e\x93\x41\x8f\x89\xc0\x77\x0c\x04\x9a\x67\x0d\xcc\xf8\xc6\xf7\x0e\x58\x38\x0c\x00\x08\x0d\xb8\x84\xda\x6c\x30\xb6\xb0\x99\x30\x1f\xfa\x68\xea\x75\xdb\x47\xa2\xdc\x33\x31\x4e\x99\x3e\xa4\xd9\xd8\x35\xb6\xb3\x50\x9c\x8f\xa6\x17\x0d\xd6\x85\xf6\x32\x23\x0f\xe0\x10\x6b\x22\x75\x83\x1d\xeb\xd3\x8a\xb4\xef\xd8\xae\x0e\x68\xa8\x9b\x4a\x2f\xf0\xe8\x89\x6d\x4f\x14\xa2\x5e\x04\x57\xcb\x6c\x65\xe0\x8a\xe8\x86\xc0\xd9\x25\x3f\xd3\x3c\x4b\x1d\x09\xb3\xaa\xaf\xf9\x19\xb9\x13\xa5\xfe\x73\xf5\x9c\xa9\xd2\xa8\x9f\x97\x82\xa9\x3b\x51\xc2\x93\xa3\x74\xd5\x34\x61\x40\x47\x51\x01\x36\x96\x6c\xd8\x57\x0d\x35\xd9\x76\xe8\x1a\xd9\x9e\x1d\x94\x4c\x91\x6b\xae\x25\x02\xec\x91\x83\xf1\x2a\x24\x61\x31\x28\x5c\xf0\x31\xd8\xb8\x5b\x69\xe0\x40\x08\xe9\x8d\x43\x80\x1c\x92\x32\x01\x80\xf0\x26\x53\x96\x89\xbb\x33\x9b\x5a\xb3\x5b\x96\x90\x82\xc9\x05\x78\x6d\x92\x1e\xaf\x45\xac\x29\x32\xca\x00\xd9\x3b\x57\xc0\x32\x6f\x3a\x0d\x17\x7b\x93\xd4\x28\x6f\xd8\x52\x61\xac\x19\x7f\x68\xee\x03\x23\xf5\x27\x60\xb9\xd5\x84\x9c\xdb\x6b\x66\x9a\xef\xd0\x7b\xd5\x24\xa3\x29\x64\x8a\x68\x56\xb2\xa6\x39\x33\x59\xf6\x29\x77\x78\x2b\x31\xdf\x63\xec\x67\x88\xe9\xd6\x7b\xd6\x89\x4c\xa3\x27\xb6\x1d\x9d\xed\x4d\xed\xe8\x9a\x8f\x6a\xd0\x9d\x37\x99\x8e\x89\x82\xb4\x35\x82\x77\xa3\x97\x9f\x05\x41\x66\x19\x6f\x5e\xe9\x9d\x37\xf5\x94\xb5\xbb\x9f\x5b\x85\x8d\x0f\xea\xa3\x1e\x42\x70\xf9\x4a\x52\x08\x09\xe6\x4c\xfd\xb4\x99\xde\x43\x8b\xaa\x4f\xd9\x6a\x55\x67\x43\xa9\x56\x0b\x49\x53\x46\x16\x92\xae\x96\x43\xc5\x12\x23\xdb\xb4\x91\xff\xdb\x08\xba\x1d\x83\x1f\xd0\xe8\x82\xf5\x36\xec\x71\x29\xc4\x13\x40\xe1\x60\x21\xbc\xa2\xfd\xe1\x17\xf3\xad\xcb\xfa\x99\x55\x25\x15\x49\x59\x49\xb3\x1c\x62\x39\xee\x6f\x6e\x31\xda\xc3\x9e\xe3\xb6\x95\xed\x81\x13\x47\x50\x00\x68\x8a\x51\x48\x53\xb6\xce\xd8\x06\xad\x12\x5d\x71\x1a\x63\xb2\x60\x1c\x82\x13\x02\x41\x3c\x63\xa2\xb2\x94\x5d\x01\xf0\xb6\x9b\xd0\x01\x86\xf3\x8e\x36\xf7\x6d\xde\x30\x07\xef\xe5\xde\x11\xa7\xac\x53\x7f\xbf\x0a\x19\x48\x04\x14\x87\x03\x8e\xc3\xf8\x62\x24\xf9\x17\xf2\xc3\x0f\xdf\x77\x16\x2a\xe8\x73\x56\x54\xc5\x17\xf2\xef\xcf\x9f\xbf\xff\xdc\x5d\x2c\xe3\xa6\xd8\xbf\xba\xfb\x87\xbb\xed\x62\x7a\xf9\x0e\xc6\x3b\x75\xd1\x74\x61\xa7\x5c\x04\xa9\x39\xcd\xf2\x4a\x62\x1c\x67\xa4\x8a\xf0\x63\xb3\x0e\x38\x54\x6a\xe0\x03\xb5\x14\x6d\xb0\x17\x06\x81\xcd\x33\xce\x14\x5c\xe0\x52\x71\xc9\x12\xb1\xe0\xd9\xef\x2c\xb5\xf7\xb7\x40\x60\x07\x64\x7a\xb7\x4b\x9c\x30\x9e\x9a\x7b\x34\xf5\x99\xb7\xa4\x3c\xcd\x43\x0e\xff\x88\x9e\x36\x77\xf0\x41\x43\x06\x27\xcf\xa0\x01\xbb\xad\x6b\xec\x0c\x17\xdc\x06\x8a\xee\x27\x73\xa2\x99\x61\x3b\xa8\xa7\x86\x31\xce\x02\x8a\x75\x4b\x1b\xf7\xf4\x3e\xa3\xb2\xc2\xb3\xff\x55\x4c\x6e\x01\xe4\x51\x0b\xf6\x8d\x40\xb0\x87\x3a\x87\x80\xed\x06\x4a\x54\x26\x89\xcb\x8e\x2e\x5c\x0b\x31\x75\xb8\xc7\xce\xb7\xa1\x0e\x33\xee\x73\xeb\x48\x22\xe7\x84\x57\x79\xde\x55\x94\x8b\x90\xcb\xa9\x39\x76\x3d\xaa\x64\x9c\x8e\x17\x6b\x16\x68\x19\xe9\x37\x35\x0e\x34\x3b\x7e\x24\x51\xfe\x7d\x9b\x0b\x9a\x1d\x8e\x8a\xe9\x8c\x8f\xe7\x8c\x4b\x55\x13\x61\x46\x30\xbf\x21\x01\x9f\x91\x09\x66\x5e\xd3\xb0\x60\x7e\x83\xe2\x73\xe2\x8c\x0c\x2d\x4d\x7f\x77\xa6\x86\x17\x74\x3e\xc6\xec\xd0\xd2\xf5\x6f\xc6\x87\xbd\x01\x8f\x8d\x86\x1a\x10\x09\x15\x39\x93\x11\x46\x09\xf3\xfb\x66\x9a\x18\x74\x12\x45\x30\xe6\x61\x66\x8a\xe8\x59\x95\x2c\xe3\x6b\x61\x12\x3d\x0f\x92\xe1\xa6\x7b\x15\x77\x44\xb9\x0d\x70\x56\x94\xe5\x9c\xf0\xdb\x14\x69\xb5\x42\x4b\x2a\xd5\x6f\xec\x0e\xf7\x20\x8c\xfd\x38\x8a\x0e\xe2\xf7\xbc\xca\xd9\x2f\x59\xb9\xbc\xb7\x89\xdd\x71\x55\x97\xd5\x2a\x87\xce\x36\x5e\xe8\x25\x34\xad\x25\xc3\x6b\x73\x95\x18\x4b\x44\x51\x30\x9e\x9a\x20\xa2\x82\x3e\x31\x52\x5f\x57\xa9\x65\x3c\x10\x83\x81\x1c\x7b\x5e\x51\x5e\xcb\x89\x6b\xcd\xcb\x43\x2b\x2a\x72\x3d\xc5\x9e\xb5\xd1\xa0\x8a\x30\x98\xa2\x81\x86\xf0\x40\x13\xe4\x91\xe5\x02\x60\xd8\x26\x52\xd4\xc4\x32\x63\x51\x60\xc9\xf8\x14\x4f\x3d\x4c\xfa\xc8\xf8\xa2\xce\x25\xa5\x72\xb8\x58\x16\x39\xb0\xe0\x6c\x42\xa6\x28\xc2\xc4\x49\x45\x31\xec\x34\x92\x95\x46\x1f\x88\x75\x1e\x85\xc1\x23\x6b\xeb\x35\xc7\x76\x6d\x9f\xc5\x8c\xae\x2d\xfc\x4f\x1e\x5f\x77\xe9\xc2\xb0\xe1\xf5\xb7\x74\x7d\x2a\xb8\xb1\xdd\x61\x5e\x89\xb9\xb6\x18\x4c\x75\x63\x72\x31\xbd\x3a\x7f\xb8\x3a\x23\x3f\x7d\xbd\x84\xbf\x97\x57\x37\x57\xfa\xef\xc5\xfd\xdd\xdd\xd5\xc5\x83\x96\x23\x4e\x4d\xfa\x78\xad\xc6\xe9\xd1\xd5\xe7\x91\xf0\xb9\x05\xe5\x5b\x32\xaf\x4a\xcd\x0e\xea\x8f\x79\xad\xa0\xc6\x06\x40\xd3\x54\xab\x8c\x7f\xbb\x39\x6c\x1f\xf0\x5d\xb3\x49\xf3\xde\x0c\x93\x71\x1f\xc1\x52\xfd\x62\x52\xf4\x22\x89\x46\x1d\x78\x4d\x1e\xbd\x10\x6e\xf0\x2b\x27\x3f\x0a\x49\xf0\xa2\x31\xb8\x79\x32\x55\x27\x08\xea\xd0\xff\x9e\x98\x47\x9f\x72\xb1\x38\x71\x58\x0f\x46\x72\xb1\x20\xaa\x7a\x74\x18\x1c\x38\x4d\xa1\xf4\xa9\x2d\xe6\x41\x17\xce\x1c\x10\xa7\x51\xcb\x11\xf7\xea\x34\x0b\x34\xe9\x7e\x82\xdb\xc1\xbc\x92\xfa\xc1\x2e\xc1\xd3\x4f\xed\x2d\xb0\x82\x53\x26\x77\x6a\xfc\xca\xf5\x72\xdd\x64\x79\x9a\x50\x99\xee\xad\x59\x38\xdc\xcc\x94\xc3\xe8\x99\x94\xb9\xe6\x26\xe7\x9a\x38\x26\xba\x10\x6b\x26\x73\xba\x32\x11\xe2\x90\xb3\x18\x42\x8f\xe0\x23\x97\x6c\xc5\x00\x07\x65\x6f\x1a\x67\x3c\xc9\x05\xe4\xd4\x30\x27\xe3\x99\xdf\x75\x13\x8a\x64\x13\x0f\x22\x98\xa6\xde\x21\xa3\x77\xcb\xe6\x20\xcc\x78\xd0\xea\x35\x81\xc9\x9d\x89\x59\x1c\x6e\xc3\x28\x8d\x4e\xf2\x65\x64\x84\x28\xb3\xd1\x19\x19\xb9\xdc\x23\x29\x4a\xc9\xa3\xd3\x51\x5d\xa0\x89\x53\x02\x21\x19\x5d\x42\x63\xf8\x4e\x13\xcd\x08\x13\x6c\x1d\x57\xee\xd3\x75\xfe\x18\x7d\xb4\xa1\x11\x0b\xda\xe0\x13\x9a\x78\x0d\xd9\xfb\x6a\x0d\xb1\xeb\xfd\xa2\x6e\x7e\xa3\x7a\x09\x70\x74\x03\xd5\xc3\xc1\x91\x4c\xcf\x86\x0d\x48\x9b\x79\x8b\xc7\x39\xde\x9a\x09\x6e\x32\x49\x56\x54\x6a\x55\xc4\x96\xf4\xaf\x28\x3b\xed\xbd\xa0\x2c\x62\x11\x34\xfc\x2b\x91\x52\xfb\xcc\xd5\xb8\xc8\xa9\x52\x2d\x96\x57\x60\x04\x9a\x30\x61\x86\x32\xa1\xd6\xf9\x04\xf9\xa7\x97\x74\x1d\x48\x50\x10\xd1\xe8\x92\xca\x05\x2b\xc3\x9e\x11\xca\xb7\xf7\xc1\x94\x66\xe3\xe8\x24\xaa\xe3\xb8\xdd\xf4\x3c\xae\x13\x68\x8d\x33\x5e\x8e\x85\x1c\x9b\x2a\x5f\x48\x29\xab\x2e\x1f\x57\x99\x15\x4c\x54\xe5\x8c\x25\x82\xb7\x23\x1a\xb0\xdc\xd1\x5c\x3d\x03\x60\x1e\xe8\x6d\x3c\xb7\x62\x44\x33\x09\xa1\x55\xcc\x6a\x19\xc3\x7a\x18\xfd\x34\x2a\xf7\x37\xb7\x87\x4c\x36\x01\x18\x73\x78\x26\x7f\x46\xb6\xcf\x17\xae\xa5\xd8\xf2\x60\xb5\xdb\xaa\x1c\x5e\xe9\xc2\x79\xae\xc2\xa5\x71\x30\xc2\xa9\x30\x3a\xfb\xaf\x4a\x5a\x56\x7b\xab\xc1\x9b\x1b\x64\x96\x33\x03\x29\x43\x99\x7e\x06\xf5\x9a\x46\xbe\x7d\xfc\xbf\xc9\x29\x02\xe5\x6c\xb0\xe2\x84\x60\x45\xbd\x3f\x4b\x49\x33\xa3\x40\xd2\xa4\xac\x00\x9b\x4c\x4b\x0c\x6c\xc4\x04\x38\xdf\xb5\x75\xa3\x55\x65\x0c\xa9\x89\x09\x93\xa5\xba\xa1\xaa\xfc\x69\x95\xd2\x0e\xf4\xd2\x4e\xc0\xa2\x2a\x61\xc3\x18\xc1\x7a\xc3\x59\xaa\x39\x3c\x0e\x81\xa1\x47\x36\x9a\xf5\x56\x86\xe2\x50\x4f\x7e\xbd\x81\x74\xf5\xb1\xfe\x54\x7b\xab\xa7\x42\x8f\xc9\x79\x2b\x03\xf2\x43\x35\xfa\x5a\xab\x8f\x13\x09\xd4\x08\x67\xcf\x6d\x1a\xf7\xe1\x2d\xce\x19\xe5\xed\xe1\xf2\x3b\x2b\x0a\xca\x0d\x5f\x43\xf8\x01\xb2\x59\x66\x5a\x64\x35\x28\x2f\x45\xac\x08\x95\xb2\x9c\x75\x80\xbd\x0e\x0c\x25\xc5\x2f\x5c\xe2\x07\xa2\xc2\x9c\xbe\xfa\x75\x9c\x41\x1f\x85\x70\x04\x4f\xd4\xc2\x32\x4a\x0f\x4e\x6b\xda\xed\x15\x88\x2f\x8f\xb9\x48\x9e\x4c\x42\x30\xc0\xf3\x67\xbf\x33\x69\xe3\xce\xeb\xcb\xc0\xf0\x86\xaa\x85\xbd\x7d\xd3\x8e\x9b\xbd\x8e\x08\xa8\x68\xda\x7a\x00\x1d\x7d\x21\x6b\xcb\x62\xc5\x11\x3d\xf7\x36\xa1\xab\x56\x51\x81\x78\x7d\xcf\x73\xb0\xaf\xb3\x98\xdc\x21\x90\xaf\x10\x55\x46\x5a\x20\xba\xe5\xd3\x7f\xbb\x91\x20\x47\x0d\x47\x0d\xe1\x51\x4c\x09\x18\x3e\x9e\x04\x53\xcd\x04\x91\x2b\xb1\x96\xaf\x1e\x84\x0a\x89\x17\xd2\x5d\x93\x63\xa8\x1d\x35\xb8\xf0\xe8\xde\xbe\x4e\x18\x40\xfd\x1b\xe2\xc3\x8b\x4d\x94\x3a\xc8\xcb\xc4\x87\x24\xb4\xf4\x93\x87\x38\xb5\x03\x41\x9e\xc6\x13\x3f\x17\xb2\x53\x81\x39\x5e\xe3\xc3\x78\xa6\x5e\x42\x5a\xfa\xec\x8e\x5d\xdb\x07\xef\x68\xee\xe5\xaa\x9c\x11\x4a\x96\x99\x2a\x85\x44\xd7\x1a\x5c\x26\x26\x29\x5c\x76\xda\x1e\x03\x76\x9c\x68\xb8\x0b\xd7\x04\x42\x57\x2b\x46\xdd\x3d\x43\x78\x36\xc1\x45\x41\x92\x25\x42\xa6\xad\x0d\xb3\xda\x7d\xab\x2c\xd5\xfa\xf9\x23\x60\x33\x73\xaa\xca\x07\xd7\x06\x2d\x20\x44\x72\x63\x5f\xfc\xc1\x2e\xd6\xbd\xb1\xe9\x5c\x04\xaf\x5f\x0a\x42\xb9\xb1\x6a\x1c\x26\x83\xf7\x0b\x19\x75\xdf\x8c\x34\xf7\xa2\x7e\x6d\x9c\xe4\xd6\xe8\xe2\xdb\xb4\xbc\x60\x4a\x05\x81\x46\x3b\x41\x1a\x90\xd3\x97\xb8\x9c\xbe\x58\xdd\x1e\xf6\x46\x40\x30\xe1\x98\x36\xeb\xd6\xb6\x7b\xa9\x11\x10\x13\x8c\x41\xc1\x6d\xab\x83\xa6\x6c\xb5\xa4\x2a\xb6\x33\x6e\x17\xb9\x10\xdf\xe8\xed\x10\xd9\x1a\xc9\xa8\x0a\x41\x25\x77\xc6\xf6\x51\x66\x6c\x4e\x2e\x68\xc1\xf2\x0b\xaa\x8e\x39\xb8\xc0\x01\x26\x84\x4d\x16\x13\x72\x32\x6d\x78\x5b\xef\x44\x79\x1b\xba\x73\xa1\x27\x3b\x40\xcc\x8e\x7e\xd5\xbd\x7c\xb0\x92\xd0\xbf\x73\x0f\xdc\xb3\x07\xb7\x30\xb0\x43\xdf\xc5\xde\x0c\xe3\x7d\xbb\xf6\xa3\xbf\x13\x2b\x09\x16\xbf\xe4\xa5\x3b\xb2\x07\xcc\xd8\xb5\x0b\xdf\xf3\xfe\xeb\xe9\x92\x23\x31\x6b\x35\x99\xec\xf5\xee\xc1\xd3\x5c\xc1\xec\xdf\x0c\xb0\x33\xb7\xfd\x67\x4a\xab\x60\xc7\x14\x5b\xfe\x5a\xb0\x3d\x4e\x60\xe7\xfb\x80\x5c\x3e\x0e\x9f\xc2\x87\x02\xf9\x53\x70\xb4\xe8\x15\xf0\x96\x01\x18\x97\xf6\xab\x68\xeb\x70\x99\x76\xe1\x7f\x73\xbc\xd1\x0c\xcb\x78\xeb\xe3\x03\xdc\x1d\xc7\xd6\xe6\xc2\x46\x00\x7c\x30\xc2\x99\xd2\x9b\xe2\x63\xe0\xf3\x91\x0a\x55\x9c\x32\xd5\xaf\xe8\xf6\x2a\xb1\xa4\x7f\x6a\x6d\xa1\xd0\x04\x9b\x5f\xac\xce\x16\xa1\x13\x0f\x50\xd6\xfa\x35\x9e\x01\xc4\x7a\xc5\xbf\x81\xf4\xda\x0d\xb8\xbb\xbf\x9d\xcc\xbe\xba\xca\x14\x98\xb4\x71\x0c\x27\x9a\x03\x27\x90\xef\xd9\xf0\x6e\x64\x4f\xbe\xfd\x76\xba\xcb\x03\x21\xdc\xd0\x5f\xe1\xc7\xea\x56\x55\x65\xc7\x1b\xf3\xde\x0c\x1a\xd1\xf4\xde\x41\x3a\x90\xde\x05\xf4\xba\x89\x0a\xcc\xaf\x6f\xd5\xfd\xf5\xeb\x2d\x26\x21\x53\x70\x8d\xbd\x52\x66\x16\xc5\xe4\x9a\xa5\x9e\xa7\x0e\xf3\xae\xfb\xcf\x1a\x7e\xdb\x9a\x3e\x0e\x3b\xf9\xe3\xcf\xef\xfe\x1f\x00\x00\xff\xff\x1b\xfd\x79\x5c\xe0\xce\x07\x00") +var _operatorsCoreosCom_clusterserviceversionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\xb6\x28\x8a\xff\x3f\x9f\x02\xe5\xc9\x3e\xb6\x67\x24\xb9\x7b\x5e\xbf\x99\xfe\xcd\xdd\x29\x6f\xdb\x49\x7c\xd3\xed\x56\xb5\x9d\xe4\x4c\x25\xd9\x19\x88\x5c\x92\xb0\x4d\x02\x1c\x00\x94\xad\x39\x39\xdf\xfd\x16\x16\x1e\x24\xf5\xb0\x25\x91\xdd\x96\xdd\x40\xaa\xd2\x96\x44\x82\xe0\xc2\xc2\x7a\x3f\x68\xc1\xbe\x07\xa9\x98\xe0\x6f\x08\x2d\x18\xdc\x6b\xe0\xe6\x93\x1a\xdc\xfe\x55\x0d\x98\x38\x99\xbd\xfe\xcd\x2d\xe3\xe9\x1b\x72\x56\x2a\x2d\xf2\x0f\xa0\x44\x29\x13\x38\x87\x31\xe3\x4c\x33\xc1\x7f\x93\x83\xa6\x29\xd5\xf4\xcd\x6f\x08\xa1\x9c\x0b\x4d\xcd\xd7\xca\x7c\x24\x24\x11\x5c\x4b\x91\x65\x20\xfb\x13\xe0\x83\xdb\x72\x04\xa3\x92\x65\x29\x48\x9c\xdc\x3f\x7a\xf6\x6a\xf0\xb7\xc1\xab\xdf\x10\x92\x48\xc0\xdb\x6f\x58\x0e\x4a\xd3\xbc\x78\x43\x78\x99\x65\xbf\x21\x84\xd3\x1c\xde\x90\x24\x2b\x95\x06\xa9\x40\xce\x58\x02\xee\x7e\x35\x10\x05\x48\xaa\x85\x54\x83\x44\x48\x10\xe6\x9f\xfc\x37\xaa\x80\xc4\xac\x62\x22\x45\x59\xbc\x21\x2b\xaf\xb1\xf3\xfa\xc5\x52\x0d\x13\x21\x99\xff\x4c\x48\x9f\x88\x2c\xc7\xbf\x1d\x10\xec\xe3\xaf\xed\xe3\x1d\xe4\xf0\xf7\x8c\x29\xfd\xed\xfa\x6b\xde\x32\xa5\xf1\xba\x22\x2b\x25\xcd\xd6\xbd\x08\x5e\xa2\xa6\x42\xea\xab\x6a\x59\x66\x19\x89\x9a\xd5\xff\x76\x17\x32\x3e\x29\x33\x2a\xd7\xcc\xf6\x1b\x42\x54\x22\x0a\x78\x43\x70\xb2\x82\x26\x90\xfe\x86\x10\xff\x2c\x3b\x79\x9f\xd0\x34\xc5\x8d\xa4\xd9\x50\x32\xae\x41\x9e\x89\xac\xcc\x79\x78\xb8\xb9\x26\x05\x95\x48\x56\x68\xdc\xac\x9b\x29\x20\xd4\x88\x18\x13\x3d\x05\x72\x76\xfd\x7d\xb8\x94\x90\xff\x51\x82\x0f\xa9\x9e\xbe\x21\x03\xb3\x01\x83\x94\xa9\x22\xa3\x73\xb3\x84\xda\x55\x76\x37\xcf\xed\x6f\xb5\xef\xf5\xdc\xac\x57\x69\xc9\xf8\xe4\xa1\xe7\xbb\x97\xd8\x6c\x09\xb3\xda\x3e\xd5\x1f\xff\xfd\xd2\xf7\x9b\x3e\xde\xbf\x3e\x35\x4f\x26\x7a\x4a\x35\xd1\x53\xa6\x88\xe0\x40\x24\x14\x19\x4d\x40\x3d\xb0\xa0\x15\x97\xd8\x15\x7d\x58\xfe\x61\xcd\x92\xea\x53\x6a\xaa\x4b\x35\x28\xa6\x54\x2d\x83\x78\xb8\xf0\xed\x8a\xe9\xec\x85\xb3\xd7\x34\x2b\xa6\xf4\xb5\xfb\x52\x25\x53\xc8\x69\x85\x03\xa2\x00\x7e\x3a\xbc\xfc\xfe\x8f\xd7\x0b\x3f\x90\x26\x74\x56\x62\x3f\x61\xca\x80\x0a\x29\x08\xf1\x24\x04\xf7\x6e\x5e\x00\xf9\xe7\xca\x7b\xae\x0b\x48\xfe\x39\x58\x5a\xb9\x18\xfd\x0f\x24\xba\xf6\xb5\x84\x7f\x95\x4c\x42\x5a\x5f\x91\x01\x90\x27\x4b\x0b\x5f\x1b\xf8\xd7\xbe\x2a\xa4\x21\x0b\xba\x76\xe4\xed\xa8\xd1\xc5\xc6\xf7\x0b\x6f\x7b\x68\x40\xe2\xde\x31\x35\x24\x11\x14\xe2\xa3\xc3\x38\x48\x1d\x1c\x2d\x9e\x32\x65\x90\x43\x82\x02\x6e\x89\x24\xa2\x10\x77\xef\x34\x20\x06\x00\x20\x95\x21\x00\x65\x96\x1a\xda\x39\x03\xa9\x89\x84\x44\x4c\x38\xfb\x77\x98\x4d\x11\x2d\xf0\x31\x19\xd5\xa0\x34\xc1\x53\xcb\x69\x46\x66\x34\x2b\xa1\x47\x28\x4f\x49\x4e\xe7\x44\x82\x99\x97\x94\xbc\x36\x03\x5e\xa2\x06\xe4\x9d\x90\x40\x18\x1f\x8b\x37\x64\xaa\x75\xa1\xde\x9c\x9c\x4c\x98\xf6\x54\x3f\x11\x79\x5e\x72\xa6\xe7\x27\x48\xc0\xd9\xa8\x34\x84\xf3\x24\x85\x19\x64\x27\x8a\x4d\xfa\x54\x26\x53\xa6\x21\xd1\xa5\x84\x13\x5a\xb0\x3e\x2e\x96\x23\xe5\x1f\xe4\xe9\x6f\xa5\xdb\x64\x75\xb8\x00\xbe\x95\xe8\x4c\x3c\x81\x7d\x10\xd6\x86\xbc\x5a\x4c\xb2\xb7\xdb\x77\xa9\x40\x6a\xbe\x32\x50\xf9\x70\x71\x7d\x43\xfc\x02\xdc\xb9\x44\x08\x57\x97\xaa\x0a\xd8\x06\x50\x8c\x8f\x41\xda\x2b\xc7\x52\xe4\x38\x0b\xf0\xb4\x10\x8c\x6b\xfc\x90\x64\x0c\xb8\x26\xaa\x1c\xe5\x4c\x2b\xc4\x39\x50\xda\xec\xc3\x80\x9c\x21\xd3\x23\x23\x20\x65\x91\x52\x0d\xe9\x80\x5c\x72\x72\x46\x73\xc8\xce\xa8\x82\x8f\x0e\x6a\x03\x51\xd5\x37\xe0\xdb\x1c\xd8\x75\x9e\xbd\x7c\xc3\xd2\x19\x23\xc4\xf3\xd2\xb5\xbb\xb3\xf6\x0c\x93\x14\x92\x8c\x4a\x2b\x14\x10\x0d\x59\x46\xde\xbf\x7d\x47\xa6\xe2\xce\x60\x31\xe3\x4a\xd3\x2c\xc3\x53\xe0\xf8\xb3\x25\xa7\x09\xe5\x24\xa7\x9c\x4e\x80\xd0\xa2\x50\x64\x2c\x24\xa1\x64\xc2\x66\xc0\xfd\xe9\x1a\x6c\xba\xf8\x75\x44\x82\x58\xe2\xbe\x92\x41\xf9\x5f\xdd\x02\x17\x7e\x59\x47\x36\xcc\x58\x92\x81\x1e\x80\xda\x69\x75\x2d\x62\x36\x27\x25\x57\x5a\x96\xb8\xd9\x29\xb9\x85\xb9\x43\xf2\x9c\x16\x44\x69\x61\xbe\xbc\x63\x7a\x4a\x68\x1d\xc1\xa9\x46\x2c\x1e\x01\x51\xa0\xc9\x68\x4e\x8c\x18\x87\x04\x41\x0b\x91\x21\xb5\xc0\x7b\x91\x30\x48\xd0\x92\xc1\x0c\x08\x95\x23\xa6\x25\x95\xf3\x80\x0d\x8b\x00\x7d\x04\xa8\xf8\xb2\x35\xe1\x61\x3d\x48\xc8\x43\xb8\x48\x2c\xb9\x75\xb2\x4b\x1a\x04\xcb\x0d\xa0\x37\xbc\x74\xf8\x56\x89\xa3\xca\xe1\x1b\x28\x62\xf0\xca\xc9\x07\x41\xae\xc5\x27\x39\xc4\x4a\x89\x90\x01\x33\x0c\xd8\xea\x48\x38\x02\x43\x4e\x24\xe5\xe6\x87\x95\xc8\xbd\x03\xb4\x1e\x42\x1b\x33\xc4\x1d\x5f\x85\xa3\xf5\xb9\xa9\x94\x0d\x81\xa9\x3e\x98\x86\x7c\xcd\xcc\x0f\xc2\x2e\x7c\x6d\x16\x38\x63\x29\x18\x20\x6a\xca\x2c\xea\x98\xd3\x4a\x47\xa2\xd4\x16\x76\xee\x92\x94\xcc\x18\x25\x74\x32\x91\x30\x41\x04\x5e\xfb\xd8\x47\x60\x62\xc7\xfa\x03\x5a\x8d\xbe\x95\xe4\x1f\xbc\xc2\x90\xc1\x07\x2f\xe0\xab\x8e\x79\xfd\x82\x65\x61\xb1\x39\x1e\xdb\x43\x3b\x68\x62\x60\xe2\x41\x2b\xe4\x83\x17\x6f\xb2\xb7\x76\x3c\xb2\xc3\x76\x34\xf7\x79\x61\x21\xee\xd7\x91\x39\x1f\x15\x69\x36\xe4\x00\x2f\xac\x88\xef\x08\x48\x01\x72\x2c\x64\x6e\x0e\x0a\x27\x94\x24\x56\x7e\x0b\x84\x07\x49\x23\x4f\x1e\x02\x27\xd9\x74\xff\xed\xd8\x04\x0b\xec\xe8\x93\x82\xea\xe9\x23\x97\x6d\xb6\x55\x76\xd4\x81\xf6\xe8\xc5\x8f\x50\xb3\xa5\xb9\x2b\x0e\xd3\xf9\xdc\x06\x0c\x9d\x4f\x8a\x3c\x67\x93\x59\x1b\xa8\xf6\x81\xde\xbd\x03\xa5\x0c\xcb\x46\x29\x4d\xd2\x3b\x02\x3c\x11\x86\x58\xfc\xbf\xd7\xef\xaf\xec\xb4\x03\x72\xa9\x09\xcb\x8b\x0c\x72\x23\x88\x91\x77\x54\xaa\x29\xcd\x40\x22\x77\xfa\x8e\xe7\x8d\xcf\x0e\x13\x4b\x05\xa9\xa1\x45\x29\x64\x74\x6e\x27\x4b\x21\x11\xa9\xa1\xd1\x42\x92\xc2\x08\xb8\x79\x51\x6a\x20\xd4\xfe\x8a\xcf\x65\x7c\xb2\x8a\x48\xb7\x02\x0d\x31\x92\x48\x4e\xf5\x1b\x32\x9a\xeb\xc7\x50\x9f\x90\xfb\x7e\xba\x29\x0d\xa8\x2f\xe6\x71\x4a\x60\xc7\x46\xf4\xa0\x3e\xf1\xa3\x6f\x69\x84\x50\xca\x38\xc8\xa1\x90\x7a\x13\xa2\x65\x94\x8f\x09\xc8\x07\xaf\xf4\x20\x63\x5c\xff\xf1\x0f\x0f\x5c\x99\x42\x91\x89\xb9\xc1\x8b\xc7\xcf\xca\x86\xef\xb3\xf1\xb9\xde\x74\xbe\x4d\xcf\xf2\x86\xf3\x59\xe3\x54\x17\x33\xad\x52\xa0\x76\x9a\x88\x77\xf5\x6e\x41\x09\x7c\x32\xe6\x37\xbc\xf4\xd6\x86\x0f\x30\x06\x09\x3c\x71\xb4\xe9\xdb\x72\x04\x92\x83\x06\x55\x13\xa4\xe7\x85\xa3\x34\x46\x16\x5c\x64\x77\x4f\xc3\xe5\x1e\x91\x67\xfc\x65\x8f\x48\x35\xfe\xb2\xc7\x64\x1b\x3b\xb6\x61\x9b\x8f\x23\x9d\x1d\x5b\xd1\xd8\xc7\x11\x70\x87\x49\x67\xab\xcd\x39\x2d\xe6\x35\x3a\xf1\x1e\x48\x78\xd7\x8d\x65\x34\xe4\xbb\x31\x83\x2c\x25\xcc\x08\x6f\x66\xb1\x64\x94\x89\xe4\xd6\xd9\x2d\x3f\x9c\x13\x25\xac\xb8\x67\x24\x7c\xc3\x68\x13\xc1\x55\x99\x03\x61\x8f\x61\x70\x14\xe9\xa2\x48\x17\x45\xba\xe7\x22\xd2\x59\xff\xc0\x3e\x50\xaa\x85\x85\xac\xa5\x55\x78\x5d\xa4\x56\x0f\x8d\x48\xad\x70\x44\x6a\xf5\xc8\x78\x76\xd4\x6a\x23\x39\xed\xd1\xb9\x1e\x3b\xc8\xd1\x98\x1a\x8d\xa9\xd1\x98\xea\x46\xe4\x65\x6e\x44\x5e\x16\x79\x59\x34\xa6\x3e\x34\x65\x34\xa6\x6e\x39\x51\x34\xa6\x46\x63\x6a\x34\xa6\x46\x63\xea\x63\x2f\x13\x45\xba\x28\xd2\x45\x91\x6e\xd3\xc5\x44\x63\x6a\x34\xa6\x3e\x34\x22\xb5\xaa\x8d\x48\xad\x1e\x18\x2f\x9b\x5a\xb5\x37\xa6\x26\x19\x50\xbe\x5a\xa9\x5a\x88\xff\xc6\xeb\x50\x34\x62\x63\xe6\xf2\x20\xdc\xdd\x64\x04\x53\x3a\x63\xa2\x94\xe4\x6e\x0a\xdc\xa7\xec\x90\x09\x68\x65\xb0\x00\x34\xac\x12\xcc\x1f\xa1\x35\x0f\xd3\x97\x3e\x01\x4e\x47\xd9\xca\x89\x1f\x23\x25\xee\xce\x87\x8d\xc7\x23\x21\xcc\xdb\x2d\x43\x0c\x55\x1d\xaf\xe9\x6c\x13\xcf\x7c\xb0\x2e\xc7\x6e\x75\x50\xf3\xd9\x87\xf3\xae\x42\x99\xc9\x4f\x9c\x5c\x86\x59\x09\x5a\xa6\x31\x51\xc2\xf0\x10\xf3\xed\xfb\x3b\x0e\x29\x26\xb9\xf5\x08\xd3\xe6\x02\x73\xe8\x59\xc2\x74\x36\x0f\x0f\x1e\x1c\x6c\xbf\x89\x7b\x14\x12\x7d\xf6\xe1\x7c\x73\xf3\xbd\xdf\x80\x4f\x61\xa9\x8f\x76\xf8\x68\x87\x0f\x23\x8a\x41\x3b\x4e\x1a\xc5\xa0\x07\xc6\xcb\x16\x83\xf6\xdd\x6e\x1d\xad\xcd\x24\x5a\x9b\x1f\xbe\x2c\x5a\x9b\xa3\xb5\x39\xda\x6f\xd6\x8c\x28\xb8\xe0\x88\x82\xcb\x23\xe3\xd9\x09\x2e\xd1\xda\x1c\xa9\x55\xa4\x56\x91\x5a\x3d\x0f\x6a\xf5\x1c\x43\x77\xa3\xd1\x2f\x1a\xfd\xa2\xd1\x2f\x72\xa3\xc8\x8d\x1e\x19\xcf\x8e\x1b\x45\xa3\xdf\xb6\x13\x45\xa3\xdf\xca\x11\x8d\x7e\x8f\x8c\x68\xf4\x8b\x46\xbf\x35\x23\x0a\x2e\x3b\x4e\x1a\x05\x97\x07\xc6\xcb\x16\x5c\xa2\xd1\x2f\x52\xab\x48\xad\x22\xb5\x7a\x1e\xd4\xaa\xbd\xd1\xef\x91\x93\xf4\xf0\xbd\x0f\x9f\x94\x07\xef\x65\xc9\x43\x0f\x5c\x07\xd1\x07\x20\xf8\x28\xe1\x7a\x8c\x5c\xf5\xc9\x88\x2a\xf8\xcb\x9f\x96\xea\x96\xd7\x2f\xc9\x21\x65\xd4\x3c\x6a\xe5\x15\x8f\x93\xb0\xea\x11\xeb\xf7\x6c\x83\xbd\x0f\xcb\xd8\x71\x16\x57\x58\xf9\xd1\xa0\x58\xb3\xb5\xe9\xa5\xbd\xf8\x5a\x4b\xaa\x61\x32\xaf\x15\xf2\x46\x9b\x6c\xc5\x79\xf8\x9a\x02\xf4\x41\x69\xbc\x9b\x82\x04\xbc\xc9\x97\x9e\x56\x7e\x52\xa6\x42\xf4\x72\xba\x43\x71\xdf\xc7\xc2\x91\xfd\x73\x56\xfc\xfc\xd8\xa6\xad\xaa\xbe\xbd\x12\x58\x1e\x40\xe7\xd6\x7a\x7d\x1e\x52\x80\x17\x21\x56\x50\x69\x28\xa4\xb7\x72\x23\xd3\xae\x5d\xbd\x00\xef\x75\x44\x71\x03\x4e\xfd\x38\x87\xee\xd7\x32\x95\xd7\x59\xd6\x37\x61\xcc\xae\x07\xc6\x10\x64\xce\x94\x5a\x17\x70\xdd\x5c\xfa\x63\x64\x73\x03\x72\xb9\x06\xfe\xfe\x8d\x6a\xcb\x09\xe2\x13\xee\x80\x1c\xd1\x84\xc8\x32\x33\xc2\x14\x4f\x89\x2b\x7f\x4d\x68\x92\x88\x92\x6b\xc2\x01\x52\x6b\xd9\x58\x85\xab\x1b\x10\xdb\x0d\xe4\xa7\x4d\xa5\xa7\xbe\x5d\xe7\xa3\x57\xb9\x77\x38\xb5\xaf\xb0\xb2\xa0\x7a\x7d\x6c\x2e\x6d\xe1\xe3\x1f\xe7\x5a\xdb\xb0\xc2\x8d\x19\x61\x63\x7f\x87\x22\x63\xc9\xfc\x43\x99\x01\x99\x8a\x2c\x55\x58\xd6\xdf\x70\xf7\xe0\x70\xa8\x8b\xc8\x05\x5e\x8d\xab\xef\x91\x51\xa9\x49\x2a\x40\x11\x2e\xb4\x2f\x0c\xd0\xb8\xdd\xba\x98\xee\xa6\xb6\xb5\x83\xb9\x89\xd0\xa2\xc8\x30\x95\x42\x18\xa1\xe5\x6e\xca\x92\xa9\xed\x57\x53\xd0\x04\x56\x5d\xb6\xb9\xf4\xb2\x91\x78\x4d\xb6\x12\xb1\x89\xb7\x59\x8d\x1e\x43\x15\xb2\xa5\xac\x4d\x6c\x89\xf8\xaf\xa5\x28\x8b\x0d\x2f\x5f\xb6\x2c\xda\xbb\x0d\x95\xd7\x0b\x0d\x6c\xfc\x8f\xce\x65\x64\xf7\xc6\x5e\x16\x4c\xa2\x03\x42\x2e\xc7\x24\x2f\x33\xcd\x8a\x0c\x6f\xb1\xd5\x06\x14\xa1\x12\x2a\xbe\xd1\x23\x94\xcf\xbd\x07\xca\xb5\x89\x80\x94\xd0\x89\x99\x51\x63\x7f\x18\x5f\x92\x9e\x97\x39\x98\xd3\x9c\x56\x0f\x41\x75\x8a\xcf\xab\xd9\xc9\x1d\xcb\x32\x23\xcf\xd2\x2c\x13\x77\x90\x0e\xc8\xc1\xc1\x22\x29\x4f\x84\xac\xad\x07\x89\xc9\xc1\xef\x1a\x57\x19\xca\x51\x2d\x78\x13\x1c\x21\x5b\x0b\x96\x64\x3b\xe1\x92\x6c\x2f\x46\x13\xc2\x05\xf7\xe6\xe1\xef\x3e\xbc\xdd\x0d\x11\xae\x9a\x73\xb8\x7e\x22\xa0\xcd\xb6\x14\x54\x6a\x46\x33\x52\xca\x4c\x59\x5c\xa0\x46\x91\x90\xbe\x21\xcb\x94\xa2\x77\x31\x01\x65\x3b\x7f\x90\xdf\xd9\xdd\x77\x9b\x63\xcf\xb8\xe0\xd9\x9c\x50\xbb\x35\xe3\x32\xcb\x7a\x64\xcc\x38\x35\xa4\x1b\x0a\x9f\x4d\x63\x74\x30\x72\xcd\x78\x02\xe6\x9d\xfa\x41\x38\xc1\x15\x99\x19\x0d\x8d\x08\x07\x3d\xed\xb9\xd6\x24\x56\xe3\x56\xee\x11\xe6\xd0\x27\x74\x94\x01\xf6\xc6\x70\x62\xcf\x07\x91\xa1\x89\xdc\x19\xcf\x53\xdb\xcf\x84\xd6\x7f\xfe\x2f\xc6\x51\xd1\x21\x1f\x90\xf9\x18\x85\x09\x98\x9e\x1a\xfd\xa9\x28\xb2\xb9\x21\x36\x06\x59\x2a\xa4\x3c\x52\x65\x32\x35\xaf\x74\x50\x88\x54\x1d\x18\x52\x74\xa0\x20\x91\xa0\xd5\xc1\xb1\xf9\xb4\xf8\x0e\xf8\x7e\xf5\xfb\x4e\x68\xc1\x0e\x8e\x7b\x04\x01\x84\xcd\x52\x84\x9e\x3e\x5f\x3c\xf4\xef\xda\xe8\xd1\xf5\xd8\x68\x6a\xbe\xf5\x19\x5c\xe7\x0f\x51\xd8\x46\x1a\x86\xce\x6b\xc0\x5c\x2b\x83\x94\x88\x06\xbe\xc5\xd4\x32\xc1\x27\xe4\x94\x13\xc8\x0b\x3d\x47\x2c\xce\x81\x72\x77\x35\xcc\x40\xce\xf5\xd4\x68\xbc\x4c\x05\x02\xf2\xec\x81\xde\x0e\xe0\xee\xc0\x7b\xe0\x56\x48\x6e\xbb\x33\x2d\x02\xf7\xf0\x77\x87\x8b\x84\xb4\xe2\x08\xcf\x16\x94\xc8\xa2\x77\x02\xe3\xf7\xe6\xce\x26\x08\xed\x57\x96\x5a\x06\xfa\xf1\xf6\xad\xed\xc4\xe4\x60\xf5\x2d\xe3\xa9\x0a\xd5\x90\x52\x4b\x06\x1d\xbc\x57\x02\x19\x57\xf8\x1c\x01\xbc\x2c\x02\x6f\x2a\xb6\x3e\x32\x7d\x4d\x47\xda\x07\xb5\x06\x3b\x3b\x35\x24\x25\x43\xa7\x7a\xd6\x6d\x65\x44\x90\x8c\x8e\x20\xb3\x6d\x9b\xcc\xaf\xd5\xf2\xc9\xe9\xdb\x77\xa1\xc3\x99\x04\xfa\x88\x4d\xec\x23\x28\x33\x1b\x38\x5f\x97\xfa\xc4\x2d\x8f\xcd\xe5\x57\x04\xc5\x76\x06\x65\x72\x0d\xda\x1e\xb3\x9c\x16\xe6\x94\xd9\x39\x56\xda\x43\xdf\x22\xa4\x1f\x3f\x2c\x5b\xc9\xfd\x9b\xf7\x75\x5a\xf5\x90\x8d\x8e\xca\x66\x5e\xe3\x6d\xce\xde\x03\x56\x92\x6a\x34\xc0\xbc\x80\xd0\x4e\x37\x70\xd2\x7c\x12\x7a\xf4\x59\x0c\x56\x36\xb9\xda\xa6\xb2\x4b\xff\x7d\x35\x45\xc7\x5b\xb0\x8d\xe2\x65\x74\xef\x0c\x12\x2d\x1e\x2e\x1d\xe7\x2f\xd6\x90\x17\xd9\x63\x27\x8f\x6c\xad\xa4\xe5\x8c\x7f\x00\x9a\xce\xaf\x21\x11\x3c\xdd\x90\xc0\x36\xf6\xe3\x1d\xe3\x2c\x2f\x73\xc2\xcb\x7c\x04\x08\x62\x65\xe7\x42\x42\x62\x15\x60\x4a\x38\xdc\x65\x73\x47\x3c\x52\x52\x88\xd4\xd3\x93\x91\x51\xd8\x68\x3a\xc7\x1e\x69\x58\x64\x95\xcf\xcd\x24\x4c\x57\xdc\x47\x92\x44\x52\x65\xc4\xa2\x1e\x4e\xca\xb4\xe1\x58\x23\x40\xff\x14\x4b\xc1\xec\x31\x9d\x51\x96\x19\xd1\x7a\x40\xce\x61\x4c\xcb\x0c\x5b\xfd\x91\x57\xe4\xc8\x3c\xcc\xeb\x64\xab\x6e\x30\xe2\xae\x12\x46\x9b\x57\x2e\x4f\x1e\x17\x74\xbc\x85\xc5\x7d\x93\x1a\x80\x7e\x6c\x5a\x0b\xd0\x8f\x82\x96\x6a\x53\x55\xbe\xb1\x31\x97\x3c\x35\xe7\xa1\x2e\x89\xd6\x48\x3a\x53\x6e\xe6\xcd\x58\xf6\xc3\xf5\x13\x56\xac\x5a\x8a\x89\x04\xa5\xce\x81\xa6\x19\xe3\xb0\x3b\x7e\xdd\x4c\x81\xe4\xf4\x1e\x71\x4c\xb3\x1c\x8c\x24\x52\xc7\x30\x5a\x7f\x2b\x2d\x48\x4e\x6f\x21\x3c\x9e\x8c\x60\x8c\xad\x1c\xf1\x85\x6b\xbb\x6f\xf1\x67\x4c\x59\x66\x34\xf4\x9b\x26\x6c\xaa\x0e\xc8\x16\x71\xcc\x67\xc6\x4b\x30\x77\x15\x52\xa0\x32\x69\x6f\xad\xf3\x78\xe4\xa1\xd4\x5c\x6c\xe9\xb0\xef\xfa\x37\x5c\x00\xc5\xc5\x7d\x62\x0d\x85\x12\xa8\xc2\xcb\x2c\x6e\xaa\x52\x8e\x8d\xea\xe8\x35\xce\xda\x82\x5c\xbb\x58\x72\x25\xb4\x6b\x1e\x18\x5e\x10\xef\x76\xcd\x2c\x41\x69\x96\xe3\x01\x4b\x4b\xe9\x5b\x6b\x22\xcc\xe8\xea\xad\x6f\x1c\x95\xbf\xbc\x7a\xb5\xa1\xfc\xf6\xf1\x91\x5e\x02\x6a\xca\xbb\xe0\xcb\x55\xa0\x43\x9e\xfc\x1b\x15\xd8\xec\x31\x73\x62\x30\xf6\x08\x05\x89\xbe\x46\xa6\x34\xe3\x93\x92\xa9\x29\x19\x81\xbe\x03\xe0\x04\xee\x6d\x95\x0c\xf2\x6f\x90\x02\x37\xd5\x80\xb7\x72\x33\x34\x80\xf6\x7a\x7f\x20\x36\x63\x8a\x09\xfe\x0d\x53\x5a\xc8\xf9\x5b\x96\xb3\x47\xca\x97\xfa\xb1\xdc\x29\x39\x40\x50\x64\x29\xf6\x37\x66\x09\xbd\x06\xfb\xc2\x12\xd0\x0a\xaa\x85\x55\x4f\x89\x39\x27\x23\x9a\xdc\x7e\x34\x00\xbf\xda\x17\x08\x7b\x76\xbd\x03\x54\x51\xde\x0b\x13\x20\xd9\xb2\x48\x79\x71\x6f\xe1\xd3\x80\xf2\xdd\x54\x28\xc0\x0b\xac\xa1\x12\x6f\xf3\x8e\x05\xa6\x02\xc1\x30\xa7\x5b\x70\x50\x84\x8e\xc7\xcd\x2b\xaa\xc3\x8e\x92\x67\x5e\x2a\x4d\x72\xaa\x93\xa9\x35\x65\x89\x34\x88\x13\x87\xca\x89\xfd\xdb\x40\x79\x63\x43\xf4\xf6\x26\x63\x62\xd7\x79\x71\x6f\x74\xcb\x47\x3d\x42\xcd\xd1\x00\xf9\xe2\x34\x4d\x0d\x38\x6b\x6e\x88\x93\xdb\x72\xdb\x66\xf8\x06\x8d\xc8\xd5\x37\xb8\x0b\xa7\x57\xe7\x9b\x9b\x62\x76\x51\x70\xb7\x56\x71\x17\xcd\xe5\x0f\xbc\x94\x37\x99\xba\x5f\x9a\x36\x73\xdb\x5e\xba\x47\x28\xb9\x85\xb9\xed\x44\xbd\xd4\xda\x57\x42\xe6\x24\x09\xc0\x0e\xb7\xe6\x22\xd7\x96\x7a\x8b\xf5\x6e\x8d\x3d\x76\x6c\xe7\xce\xf0\xa3\x6f\x16\xba\xe5\x1d\xfe\xa5\xb7\xb8\x6d\x7b\x04\xb7\xe3\x16\xe6\xdb\xdd\xb0\xb0\xdd\x66\x17\x9c\xee\x63\xf7\xdd\x7c\x11\x04\xbd\xb0\xd5\xdb\xf9\x99\xea\x63\x6b\x13\x95\x1f\x1e\x88\xad\x5e\x2f\xa0\x5f\xdd\xca\x64\xde\xf1\x50\x59\x64\x34\x67\x7a\xca\x0a\x64\x44\xde\x19\xe0\x1b\xa5\x7f\x4f\x33\x96\x86\x29\xec\xf9\xbd\xe4\x3d\x23\x3e\x99\x7f\x90\xe8\x5a\x71\xed\x5c\x80\xba\x12\x1a\xbf\xf9\x64\x00\xb2\xcb\x6c\x05\x1e\x3b\x85\xb3\x42\x23\x95\x41\xc5\xab\xd6\x63\x5d\x0d\x7c\x75\xb0\x00\x4a\xa6\xc8\x25\x27\x42\x7a\x38\x60\xd7\x7b\x3b\x91\x9d\x02\xf9\xc4\xc8\x3a\x38\xd0\x3e\xbd\x72\x0e\x07\x3e\x21\x1b\xd0\x7b\x60\x3a\x37\x15\xca\x07\xf6\x17\xdb\x55\x3f\x43\x69\xd7\x89\xaa\xd4\x3b\xca\x59\x42\x72\x90\x13\xf4\xb8\x24\x1b\x7b\x1c\x9a\x9b\xb2\x1d\xdd\xb5\x63\x6b\xea\x5b\x7f\xe0\x56\x58\x80\xac\xc9\x9a\x80\xda\x30\x37\x3b\x43\xc3\xe4\xf4\x7f\x0c\x05\xc7\x3d\xf8\xbf\xa4\xa0\x4c\xaa\x01\x39\x25\x8a\xf1\x49\x06\x8d\xdf\x9c\x86\x51\x9f\xc6\xcc\xc0\x14\x31\xa4\x76\x46\x33\xa7\x4b\x51\x4e\xc0\xda\xac\xcc\xec\x8b\x2c\xb5\xe7\x24\x15\x43\x79\x82\xa3\xeb\xe0\x16\xe6\x07\xbd\x25\xa4\x39\xb8\xe4\x07\x96\xb7\x2c\xa1\x49\x60\x44\xe8\x23\x3b\xc0\xdf\x0e\xba\xe4\xc2\x5b\x32\x9c\x5d\xed\x68\xcd\x87\x6e\x8c\x11\x3e\x3e\x64\x47\x61\xbd\xa1\x25\xba\xa8\x28\x2d\x48\xa9\xc0\x4a\xeb\x78\xca\x08\x78\x39\x13\xa5\x4a\x54\x4c\x39\xdc\xa1\xf4\xb8\x37\x82\x9f\xd1\x24\x18\x9f\x7c\x57\xa4\x54\x6f\x14\x98\x6a\x47\x03\x22\x87\x1f\xec\x24\xa4\xc4\x59\x0c\x6e\x8d\xd9\x84\x14\x54\xd2\x5c\x0d\xc8\xd0\x55\x48\x44\x4c\x63\xe3\xba\x2d\xd1\xc1\xee\x66\x5e\x00\xf9\x7f\xc8\x87\xfa\x5a\x06\xa4\xdf\xef\x93\x9b\xf7\xe7\xef\xdf\x10\xfb\x8d\x95\xb2\xb5\x20\x63\x81\x4a\x90\x28\xa5\x79\xd4\x0c\x38\x2a\xfe\x46\xbe\x17\x1c\xde\x8f\xcd\x09\xa1\x1a\x66\x20\xc9\x9d\xd9\xaa\x84\xa5\x10\xac\x57\x83\xc3\x8f\x8b\xc7\xbb\x49\x26\x39\xbd\xbf\x2e\xe5\x64\x8b\x0d\x20\x4b\x9b\x50\x37\xd9\x54\xca\x24\xa2\x5e\x3d\xc3\x57\x25\x53\x48\xcb\x0c\x52\x42\x47\x62\x06\x0d\x93\x6d\xf3\x36\x64\xe9\x25\xf8\x1b\x0d\xcf\x1b\x29\x91\x95\x3a\x28\xab\x47\x70\xff\x86\xfc\x19\x5d\xdb\x94\x14\x20\x13\xe0\x9a\x4e\x60\xd1\x0c\x60\xaf\x7b\xfd\xea\x3f\x8e\x1d\x3f\x32\x33\x3a\xeb\xc9\x2b\x83\x11\xef\xe8\xfd\x77\xbc\x32\x0d\x32\x45\x5e\x0d\xc8\xe9\xc2\xc3\xf0\xbe\x2c\x29\x33\xb4\xb5\xa0\xbb\xbe\xf6\xc8\xd1\x9c\x48\x51\xa2\xc3\x9e\x94\x45\x53\x9b\xfd\xc3\x9f\xff\xc3\x28\x7d\x34\x2f\x32\x78\xe3\x0b\xab\x5a\xb5\xd9\xc8\x30\x5a\x90\x3f\xbe\xfa\x0f\x4b\x3d\xcd\xf9\xac\xb4\xc2\x0a\x66\xd4\x00\xac\x2c\x08\xcb\x6d\x38\x27\x64\xf3\xaa\x42\xab\x6c\xa2\xbf\xd2\x54\x6a\xd5\x23\xe8\xd5\x0f\xc2\xa1\x16\x9a\x66\x0b\x5a\x3e\x6a\xe1\x70\x67\x81\x94\x0a\x84\x09\xa0\xa1\x8a\xbc\xfe\xe3\xab\xff\x58\x36\xa7\xbc\xe7\x09\xe0\x9d\x78\x07\x86\x59\x8c\x8c\x72\x7f\xcb\xb2\x0c\xd2\xde\xa3\xcb\x1f\x97\x52\x4f\x41\xf6\x08\x70\xe5\x8d\x55\x66\x7d\x0b\x6b\xc3\xd9\x65\xc9\x39\xca\x08\xd6\x3a\x8c\x16\xad\x9a\x85\xcb\xbd\xac\x61\x84\x9a\xe4\x42\xe9\xd5\x4b\xde\xfc\xb8\x99\x41\xf9\xfc\xfd\x78\x5b\x71\xa0\xbf\x83\x19\x62\xf9\xee\x1d\x44\xca\xfb\xfe\x6d\xc8\xb6\xec\x33\xae\xfb\x42\xf6\xed\x34\x6f\x88\x96\xe5\xe3\x5e\x83\x6a\xe4\x8d\x13\xf0\x09\xc8\x40\x59\x3b\x6f\x4b\xbb\xfa\x51\x4e\xfe\xee\xe7\x39\x15\x77\x7c\x3d\xe5\x40\xc2\xe9\x68\xc6\x8e\xa7\xbe\x69\x71\x5b\x38\x36\xe6\xe9\xe6\xea\xff\xdf\x32\x76\x6f\x41\x0e\xdc\xd9\x0d\xa7\xdd\xc8\x55\xe8\xf1\xe8\x6d\xf0\xf4\x70\x6c\x2d\xe7\xb3\x36\x27\x73\x81\x7d\xcc\x0a\xca\xb5\x74\xc2\x57\x50\x20\xbb\x8e\xca\x21\xa3\x31\xa2\xc0\x9c\x73\xb5\xf6\xa0\x67\x40\x95\x5e\x05\x8a\x78\xd0\x1f\x1f\x0f\x27\x01\x2c\x8e\xa6\xd0\x69\x24\x24\x04\x79\x65\x63\x3c\xb3\x88\x72\xf0\x01\xac\x87\xcf\x06\x9c\x35\x84\xa8\x83\x70\x24\xcc\xfe\x35\xe5\xab\x8f\x15\x36\xe3\x8d\x9c\xbb\x88\xd6\xee\xd6\x5a\x70\xb0\x33\x9d\x3a\xe2\x15\x3c\x8a\xd6\xa5\xb9\x37\x52\x74\x0e\x9a\x3e\x9c\x28\xb2\x38\x9a\x44\xfb\x5a\x53\x9e\x52\x99\xba\x55\x1e\x1e\xaa\x30\xe5\x80\xbc\x43\x5f\x1a\x1f\x8b\x37\x64\xaa\x75\xa1\xde\x9c\x9c\x4c\x98\x1e\xdc\xfe\x55\x0d\x98\x38\x49\x44\x9e\x97\x9c\xe9\xf9\x09\x3a\xd0\xd8\xa8\xd4\x42\xaa\x93\x14\x66\x90\x9d\x28\x36\xe9\x53\x99\x4c\x99\x86\x44\x97\x12\x4e\x68\xc1\xfa\x95\xcc\xac\x06\x79\xfa\x5b\xff\xa0\x8f\x2c\x18\x37\xce\x10\x5a\x97\xe4\x0c\xfa\x25\xbf\xe5\xe2\x8e\xf7\x51\x93\x55\x5b\x9d\xa6\xcd\xa2\x18\xfc\x58\x80\xf7\x36\x81\x0b\x85\x48\x3f\xfa\x26\x98\x97\xe9\x53\x9e\xf6\xad\xd3\xf1\x23\xef\xc5\x2e\xb6\xdd\x7e\x15\x18\xb0\x49\xd4\xba\x1d\xbb\x69\x43\x34\xd1\x6c\x06\x3b\x39\xb1\xfd\x68\x6c\xf7\x7b\x1f\x30\x9a\x96\xd2\xee\x78\xcd\x9b\xed\x7d\x33\x39\x9d\xa3\xac\x83\xcf\x26\xc2\xb2\x72\x2e\x52\x70\x96\xcf\x19\xaa\xf6\xd7\x86\x99\xdf\x18\x51\xd8\xf9\xb8\xd1\xee\x3b\x57\x1a\x72\x4b\x9c\xec\xfd\xd9\x9c\x68\x39\xb7\x8e\x71\x79\x6b\x94\x4f\xe7\xb9\x36\x12\xff\x2d\x5e\xa7\x94\x48\x18\x8a\x3e\x15\x5c\xbd\xdc\xe5\x6d\x78\x94\x14\x42\x31\x7c\xb6\xe3\x79\xdb\x59\xe6\x76\x67\x97\x35\x37\xdd\x5f\xfe\xb4\xcd\xd6\x8d\xb1\x15\xc3\x96\x56\xf6\x66\x04\xc5\xb8\x9e\x25\xe0\xb6\xe7\x50\x79\xc5\xd5\x88\x25\x89\xe0\x4a\x4b\xca\xd6\xe7\x41\xad\x1e\x3b\xba\x42\x76\xf7\x37\x10\xc4\xa0\xd3\x9d\x80\x42\x96\x63\xb0\x3c\x53\x44\xb4\xf4\xa0\xae\x03\xc6\xa6\x49\xf9\x58\x42\x43\xb8\x76\x34\xad\xee\x00\x23\xd2\x0a\x4e\xf6\x6e\x18\x83\x94\x90\x9e\xa3\xf4\x79\x1d\xde\xeb\x72\xc2\x45\xf8\xfa\xe2\x1e\x92\x72\xd3\x6c\xf2\xe5\xb1\x64\xcb\xf3\x06\x11\x17\x76\x62\x17\x61\x8e\xae\xff\xc1\xc9\x1f\x02\xc1\xee\x04\x11\x45\x35\x53\x63\x9b\x73\x16\x36\x02\x6a\x8e\xcf\x80\xc2\xc1\x3d\x8c\x2c\xce\xa6\x3e\x30\x8d\xe4\x26\x99\x0a\xa1\xcc\x29\xc7\xfd\xc4\x79\x67\x4c\x58\x9f\x1f\x26\xc0\x48\x92\x1b\x1a\xe3\x13\x61\xaa\xe9\xad\xa1\xb6\xba\x8d\x29\xab\x82\x07\x08\x7a\x2f\x95\x99\x06\x0d\x8f\xe6\xc3\x04\xa5\x26\xa5\x89\x2a\x73\x33\xe9\x1d\xb0\xc9\x54\xab\x1e\x61\x03\x18\x20\xd6\x00\x4d\xa6\xb5\x69\x73\x00\xdd\xe8\xa4\x52\x47\xb5\xba\x95\xf8\x28\x64\x35\xb8\x54\x9e\x5e\xe0\x31\x8b\x7b\xb9\x12\x5c\x3d\x02\x3a\x19\x1c\xf7\x48\x95\x6c\x6e\xd6\x38\x9a\x13\xa6\xc1\xd0\x6c\xd4\x45\xa4\x28\x27\xf6\x4d\xc0\xc7\x74\xe2\xba\x42\xca\x07\x7a\x51\x53\xd4\x19\x0f\xec\xcb\x1d\x98\x7d\xc3\x95\x97\xb9\xd1\x17\x03\x51\x47\xb3\x3a\x84\xc4\x20\x09\xaa\x10\x56\xdb\x5c\x34\xb8\xff\xff\xc3\x4d\x47\xea\xb8\x02\xe6\x94\x4d\xa6\x1e\x96\xd4\x31\x82\xe6\x1e\x6c\x7f\xf6\x48\x2b\x5f\x8a\x1d\x3b\x7a\x54\xec\x68\xfa\xb6\x7d\xbe\x44\x85\x55\xb5\xfd\xd7\x20\xf3\x00\x45\x44\x11\x24\x19\xce\xce\xed\x9b\xde\x38\x1c\x23\xaf\xc8\x11\x22\x19\xd3\x87\x0a\x11\xbe\x2f\x8a\xe3\x01\x39\x25\xbc\x0c\x67\xee\xa1\x07\x70\x11\xe6\x77\x13\x99\x87\x2a\x51\xcd\xb5\xe3\x1b\xb7\x22\x77\x76\xec\xe6\x29\xaf\x8f\xbe\x83\x00\x3c\x5e\x5a\xf1\xa1\x49\x2c\xac\x77\x9c\xa0\x1d\xe9\xf6\x73\xf8\xb7\xd8\x7d\x8e\xa5\x00\x0b\x3c\xae\x55\x14\x05\xc8\xbc\x57\x97\x9e\xc2\x81\x6c\x9e\x62\x0b\x8b\x5d\xb1\x82\x74\x83\x19\xa4\x23\xb8\x92\x56\x11\x3a\xab\xc7\x62\x18\x8b\xcf\xa2\x6a\x40\xbb\x41\xe4\x47\x73\xfc\x75\xcb\xe0\xa5\xf5\xa3\x2d\xa5\xab\x46\x2b\x9a\x57\x8d\x07\x11\x6f\xff\x02\x7b\x56\x8f\x8e\xd0\xd6\x8e\xf6\xa4\xad\x1a\xdb\x87\x06\xad\x9b\x67\x87\x80\xa1\xd5\xa3\xab\xb3\x69\xc7\x0e\xc1\x45\xab\xc7\x92\x88\xfa\x71\x62\x8d\x56\x8f\x9d\x8d\xa4\xab\xc7\xae\x71\x49\xab\xc7\x42\xaa\xe2\x47\x0a\x52\xea\x35\x23\x94\xc8\xd7\xda\x9e\xe3\xb7\xad\xf8\x49\x35\x3a\x06\xf1\x6e\x91\x4d\xab\xc7\xa2\x00\xf8\x4c\xa2\x9c\x56\x4c\xf5\xb5\x36\xd3\xbc\x5d\x7b\xb3\xcd\x51\xf7\x71\x3a\x4e\xa1\xe8\xb9\xd4\x19\x6f\x67\xc6\x88\xea\x42\x02\x96\x26\xc0\xb0\x2f\x6f\x87\xf9\x34\x81\x55\xab\x47\x77\x8c\xd3\x8e\x8e\xd8\xa7\x1d\x9d\x21\x37\x0a\x3c\x5f\x59\xbb\xf0\x13\xca\x3a\xd6\x32\x1d\x65\x9d\x28\xeb\x6c\x31\xa2\xac\xb3\xe9\x88\xb2\xce\xba\x11\x65\x9d\x15\x23\xca\x3a\x51\xd6\x69\x35\xf6\x4f\xd6\xb1\x96\xaa\xce\x0c\x66\x3f\x58\x83\xeb\xa2\x85\x0c\xa5\x29\x1f\xd2\xd3\x34\x95\x19\xde\x7f\xed\x48\xec\x0d\x9a\xd7\x5c\xa4\xba\xa4\x7c\x02\xe4\x75\xff\xf5\xab\x0d\xd3\x01\x57\x8f\x36\x41\x3b\xf5\xb1\x6d\xea\xe0\xe2\x58\xe7\x91\xf8\x68\xde\x25\x77\x52\x83\xc3\xa3\x21\x61\xae\x71\x10\x85\xaa\x56\x39\x68\x42\x75\xc3\x20\xce\x72\x08\x0e\xd1\x46\x0a\x72\x15\xd3\x2b\xb8\xf3\x77\x98\x4d\x1d\xec\xb6\x82\x04\xa8\x8d\x63\x1f\x41\x58\x85\xc8\xc1\x26\x98\xfa\x43\x6f\x96\x00\x1e\x56\xe4\x08\x06\x93\x01\x49\x6d\xb2\x36\xe5\x2e\x66\xec\xb8\x57\x77\x8f\xe7\x86\xb8\x4a\xfc\xc7\x2c\xdb\xf9\xc7\x61\x06\x5c\x97\x34\xcb\xe6\x04\x66\x2c\xd1\xe1\xfd\x30\x20\x90\x69\xeb\xec\x6c\xe3\x4a\x69\x21\x1e\xb6\x15\x09\xfb\x4b\x67\x6b\x3b\x7f\xb5\x1f\xed\x65\xb7\xa5\x75\xec\x4e\x6f\x16\xe4\x12\x0b\xa1\xc1\x5a\xb5\x4a\x9b\xa7\x59\x7f\x25\xfe\x89\x08\xfe\xfe\xc3\xae\xee\x31\xd2\x11\x4f\x68\xcd\x07\x16\x15\xa8\x32\xcb\x0c\x7a\x5b\x8f\xd9\x32\x08\x56\x78\xb2\x56\x64\xdb\x58\x37\x6b\x5e\xcb\xba\xc1\x6b\x6e\x44\x21\x32\x31\x99\xd7\x77\xd0\x76\x75\xa9\x95\xb7\xa1\x44\x95\x23\x27\x02\x9a\x43\x74\xb5\xb0\xe5\xd1\x17\xb2\x76\x44\x5f\xc8\xd2\x88\xf6\x81\xc5\x11\xed\x03\x5b\x8c\x68\x1f\x58\x31\xa2\x7d\x60\x79\x44\xfb\x40\xb4\x0f\xb4\x19\x2f\xdf\x3e\x40\xa2\x2f\x64\xdd\x88\xb2\x4e\x35\xa2\xac\xb3\xf9\x88\xb2\xce\xf2\x88\xb2\x4e\x94\x75\xa2\xac\x13\x65\x9d\x5d\x47\x0b\xe4\x2e\x44\xda\x79\x8a\x4c\x21\xd2\x07\x32\x64\xac\xbd\x3a\x11\xfd\x4c\x24\xa1\xb2\x88\xb9\xc5\x79\x3e\x14\xcd\xad\x09\xbd\x47\xfe\x2d\x38\xd8\xf4\x04\x5b\xb2\x36\x07\x22\xb0\x09\x44\x21\xd2\x23\x75\xbc\x43\xe0\x79\xcc\xb0\x89\x19\x36\x9f\x41\x86\xcd\x94\x2a\x57\xf8\x08\x49\xeb\xfa\x84\x9b\xda\xf1\xbf\x01\x99\x7f\xb6\xf9\x36\x06\xe1\x1c\xc2\x60\x9f\xb9\x0a\x29\x2c\xec\x52\xe7\xdb\x85\x74\xd8\x84\x98\xd3\xcb\x6c\x8b\x9d\x34\x85\x94\x14\x20\xfb\x16\xc9\x04\x19\x33\x57\xff\x6b\x01\x7f\x1d\x84\x9f\x79\xde\x4c\x13\x12\xcf\x3a\x79\xa6\xf9\x2a\x9d\xf9\xa6\xea\x2e\xba\x06\x57\x7c\x76\xa9\x34\xdd\x68\xa5\x7d\xa2\x9d\x3b\xed\xdb\x56\x7a\x69\x57\x4a\x24\x2a\x79\xd7\x5b\x95\x39\x5e\x3f\x56\x16\xa7\xfd\x57\x09\x72\x4e\xc4\x0c\x64\xa5\x18\x85\xee\x3c\xbd\xd0\x64\x26\xa1\xae\x00\x72\x37\x06\x9e\x4e\x4c\x11\x5d\x6a\xea\x5d\x7b\x0d\xc9\x9e\x55\x3f\x5e\x3f\xba\x55\x1c\x3a\x54\x1b\x9e\x5b\x2d\xe5\xf5\xa3\x53\xf3\x1b\xe9\xd8\x04\x47\x3a\x34\xc3\x91\x6e\x4d\x71\xa4\x73\x73\x1c\xe9\xd2\x24\x47\x3e\x79\x05\xe8\xf5\xa3\x63\xf3\x11\xe9\xdc\x4a\x47\x9e\x61\x3d\xe9\xf5\xe3\x23\x80\xbb\x4b\x8b\x1d\x89\xd5\xa9\x5b\x8f\xae\x0d\x6a\xa4\x6b\xa3\x1a\xe9\x1a\x0f\x77\xaa\x82\xbd\x7e\xc4\xfa\xd8\x1f\x41\x4e\xeb\x4c\x88\x68\x5b\x53\xfb\xb1\x85\x76\x80\x93\xa1\x77\xef\xa7\x52\x80\x2c\x97\xae\x1a\xc6\x9a\x67\xd7\x7a\x75\x61\xa8\x66\xbd\xb1\xa9\x8f\x5b\x45\x8c\xc6\xef\x53\x6f\xf0\x2a\x79\xad\x78\x5c\x6d\xb2\xa5\xd6\x31\x95\xe9\x2c\x34\x8f\x31\x4a\x41\xd5\x74\xaa\x76\x33\x5e\x3b\xb0\xe1\xa4\x95\x34\xc1\xd3\xc5\x00\xd3\xea\x0e\xd4\x2f\x6c\x3b\xdb\x03\x6f\xc7\x3e\x54\xd5\x15\x07\x83\x7a\xe7\x5b\x37\xe3\xd1\xff\xf9\xbf\xc7\x8d\xea\x2d\xd5\x84\x51\xfb\xdb\x78\x44\xed\xaf\xd5\x88\xda\xdf\xda\x11\xb5\xbf\x16\x23\x6a\x7f\x9b\x8d\xa8\xfd\xad\x1f\x51\xfb\x8b\xda\xdf\x0e\x23\x6a\x7f\x51\xfb\xdb\x75\x7c\xc6\xda\x5f\xb7\x51\xcd\x75\x5d\xcc\x05\x89\xa0\xfc\xa8\xa9\x66\x49\x15\xf1\xec\xaf\xb2\x7f\x75\xab\x03\xd6\xf5\xbb\xd5\x1a\x60\x5d\x4b\x5c\xd2\x82\x07\x8f\xa8\x7b\x41\x21\x5c\xba\xf3\x61\x4d\xf0\xa5\x45\x6e\x77\x86\x89\x35\x97\x70\xa7\xa8\x78\xe3\x03\xcb\xaa\xc6\xeb\x21\xea\x2c\x25\x47\xde\x17\x8f\x8d\x54\xb8\xd0\xcd\x1f\xb9\x66\xfd\xea\x8a\xe0\x9d\xc7\xa0\x9a\x46\x3e\x7f\xc3\x85\x1c\x62\xd8\x42\x7c\x54\x85\x3d\x86\x3c\x82\x6c\xac\x01\x1b\xd7\x8e\x19\xb7\x91\x8e\xbe\xe9\x8f\xe0\x3e\x68\xca\xd2\x53\xa4\x80\x1e\xcf\xad\xe8\x8b\xeb\x41\xf9\xb7\x82\x5d\x2d\xca\x87\xe2\x21\xa3\xdc\x25\xc3\x0a\xee\xbb\xd2\xdb\x4e\xf3\x95\xbc\x1c\x7a\xa9\x84\xa7\x0f\xc8\x05\x62\x7d\x7d\x62\xa6\x10\x3e\xd4\xf6\x3f\xe9\x06\x91\xf7\xab\x70\xc3\xdd\xd6\x85\x1b\x16\x22\x46\x62\xdd\x86\x58\xb7\xa1\x55\xdd\x06\xfc\xd1\x1e\xee\xce\x0b\x38\x90\x1f\x5c\x7b\x24\x09\x08\xaa\xbc\xcc\x34\x2b\xaa\x08\x6c\x65\x1f\x95\x59\x4d\x62\xec\x22\x41\x9b\xf8\x6e\x9e\x46\x93\xe9\x22\xde\xe3\x7c\x18\xb1\xad\x90\x9c\xb8\x68\x4b\x6c\x66\x84\x15\x07\xbc\xda\x61\x43\x4a\xd9\xf3\x8f\x14\x3c\x47\x82\xad\x2a\xad\xd9\xf6\xda\x32\x74\x3e\x33\x28\x61\x28\xf6\x03\x0c\xa2\xde\xd0\x02\xa3\x56\xd9\x0c\x78\xc5\x25\x8e\xd4\xf1\xb1\x97\x86\x3a\xe5\x5e\x1f\x85\xfb\xfc\xbd\xc6\x25\xfe\x73\x13\xfe\x83\x2f\x14\x38\x50\x05\xbe\x8a\xff\x3c\xef\x90\xc8\xf6\xd1\x6d\x5d\x58\xe4\x3a\x8b\x6a\x7b\xf2\x88\xb6\xcf\xa9\xf6\xc5\x5e\xfa\x30\xf6\x4e\xeb\x78\x19\x7e\x8b\x98\x30\xba\xf9\x78\x0e\x09\xa3\x4f\xe4\x9b\x78\x3e\x79\xa3\xcf\xd6\x1f\xf1\x5c\xf2\x46\xa3\x0f\x62\xab\xf1\x52\xd3\x39\x9b\xa3\x43\x9f\x43\xf4\x37\x74\x2c\x53\x75\xc2\xfc\x3f\x8e\x9f\xa1\x13\xfc\xeb\x34\xba\x2c\x46\x96\x3d\x65\x64\x59\xd4\xc2\xa2\x16\xd6\x1c\x51\x0b\x5b\x1a\x51\x0b\xdb\x62\x44\x2d\x6c\xfd\x88\x5a\xd8\xf2\x88\x5a\x58\xd4\xc2\x36\x18\x51\x0b\x8b\x5a\xd8\xa6\xe3\x33\xd3\xc2\xba\xab\xb7\x1e\x23\xbc\x3e\x42\x84\x57\x37\x94\xb0\x03\xfa\xd7\x09\xd6\x75\x14\xd1\x15\xa3\xb9\xf6\x3b\x9a\xab\x65\xd9\x39\xae\xd9\xc7\x29\x3d\x57\xdf\xed\x75\xf5\xe7\xe8\x4c\xb0\x94\x14\xa5\x76\xd5\xb7\x62\x0d\xba\x7d\xae\x41\xd7\xd8\xd1\x58\x88\x6e\xa3\x42\x74\xeb\x60\x16\xab\xd1\xad\x19\xfb\x13\x63\x16\xab\xd1\x6d\x3b\x62\x35\xba\xd5\x23\x56\xa3\x7b\x60\xc4\x6a\x74\xb1\x1a\x5d\xac\x47\xd0\x62\xc4\x7a\x04\x2b\x46\xac\x47\xb0\xfb\x88\xf5\x08\x36\x1a\xb1\x1e\x41\xac\x47\xd0\x1c\xd1\x0b\xd5\x6e\xc4\x7a\x04\x2d\x47\xf4\x4c\xc5\x7a\x04\xad\x26\x8c\xd5\xe8\x5e\x54\xcc\x20\x89\xda\x5f\xd4\xfe\x36\x1e\x51\xfb\x5b\x3b\xa2\xf6\xd7\x62\x44\xed\x6f\xb3\x11\xb5\xbf\xf5\x23\x6a\x7f\x51\xfb\xdb\x61\x44\xed\x2f\x6a\x7f\xbb\x8e\xcf\x58\xfb\x8b\xd5\xe8\xf6\x3e\x56\x91\xec\x63\x46\x52\xac\x46\x17\xe3\x17\x77\xda\xee\x58\x8d\xee\xf1\xf1\xd9\x57\xa3\x6b\xc4\xd2\x3d\x5d\x49\xba\xed\x97\x11\xeb\xd2\xc5\xba\x74\xb1\x2e\x5d\xac\x4b\x17\xeb\xd2\xc5\xba\x74\x9b\x8f\xfd\xf7\x66\xec\x9d\xfe\xf1\x32\x3c\x18\xb1\x22\xc2\xe6\x23\x56\x44\x58\x3b\x62\x45\x84\x58\x11\x21\x7a\x23\x76\x19\xb1\x22\xc2\x96\x23\x7a\x1e\x62\x45\x84\xad\x46\xac\x4b\xf7\x62\x62\xcc\xa2\x16\x16\xb5\xb0\xe6\x88\x5a\xd8\xd2\x88\x5a\xd8\x16\x23\x6a\x61\xeb\x47\xd4\xc2\x96\x47\xd4\xc2\xa2\x16\xb6\xc1\x88\x5a\x58\xd4\xc2\x36\x1d\x9f\x99\x16\x16\xeb\xd2\xed\x75\xac\x57\xac\x4b\xb7\x62\xc4\xb8\xae\xfd\x8e\xeb\xda\x11\x57\x68\xa9\x45\x2e\x4a\xae\xaf\x41\xce\x58\x02\xa7\x49\x62\x3e\xdd\x88\x5b\xd8\x32\x96\xa8\xa9\x86\x3e\x30\x2d\x61\x3c\x65\x09\x2a\x92\x77\x53\xc0\xb2\x72\x46\xbe\xc5\xeb\x08\xb5\x17\x12\x8d\x57\x56\xe8\x85\xeb\x34\x44\x0d\x03\x6c\x70\xea\x6d\xe1\x65\x21\x34\x12\x22\x03\xca\xb7\xb8\xd3\x71\x43\x90\x5b\x9e\xe6\x06\x40\xde\x3a\x52\x5c\x4d\x46\x46\x90\x09\x3e\x71\xf1\x3c\xee\x04\x0c\xc8\x59\x75\x41\x42\x39\x1e\x9e\x52\x4a\xe0\x3a\x9b\x23\x1c\xb0\xc0\x15\x6a\x0d\xb9\x98\x41\x8a\x24\x1b\xc3\x88\xac\x1c\x49\x35\xc9\x80\x9a\x67\x71\xa8\x1e\x66\x0e\x0f\x25\x43\x9c\xdf\x4e\x3a\x02\x17\xda\xb4\x13\x10\xb7\xa7\x8d\x3b\x51\xc3\x05\xcb\x86\x13\x9b\x90\x2f\x25\xa8\x1f\xd5\xde\x10\x8f\xe6\x5c\x94\xe4\x8e\x5a\x49\x49\x96\x1c\x0f\x33\xbe\xba\x01\xed\x96\x0f\x6f\x21\x93\xec\x6e\x7e\xe8\x23\x55\xdb\xf2\xb6\x36\xe6\x00\x2a\x27\x3b\x31\xa9\xc6\xd6\x1c\x9e\xca\x49\x69\x45\x42\x87\xca\xc0\xb5\x9c\x63\xbc\x9d\x95\x29\x6a\x98\x98\xd3\x09\x1c\x1e\x2a\x72\xf6\xee\xdc\x90\xbf\x52\x19\x6a\xed\xaa\xec\x39\x72\x58\x48\x31\x63\xa9\x41\xee\xef\xa9\x64\x74\x94\x19\xb9\x73\x0c\x12\xb8\x11\x0b\xbe\x38\xfa\xfe\xf4\xc3\x2f\x57\xa7\xef\x2e\x8e\x51\x02\x85\xfb\x82\x72\x73\x2a\x4a\x55\x05\x8a\xba\xc7\x99\x07\x01\x9f\x31\x29\xb8\x59\x1f\xea\x6a\x94\xcc\xfc\xac\x49\x38\x0c\x12\x94\xc8\x66\x90\x5a\x39\x39\x3c\xcd\x73\x1d\xc6\x8b\x52\x7b\xdd\x11\xc3\x17\xcd\x01\xe2\xc9\x94\xf2\x89\x59\xe7\xb9\x28\xcd\x7c\x5f\x7c\x81\x2b\x92\x90\x96\x89\x95\x9c\xa8\xc7\xda\x2f\x7a\x9e\x53\x18\x5a\xaf\x6c\x49\x44\x95\xd0\xc2\xaf\xb9\xfe\x5a\x6a\xce\x35\xbd\x7f\x63\xe3\xf7\x0e\xbe\xa8\xfd\x74\xe0\xcb\x49\x0a\xf3\x08\xcb\x6f\xec\xaa\x32\xac\x64\x98\x91\x83\xfa\xd5\x03\x72\x61\x9e\x01\x69\x1d\x80\x36\xfc\x12\x66\x20\x51\xf3\x74\xe0\xeb\x11\x09\x13\x2a\xd3\x0c\x14\x06\x1e\x7a\xda\x6c\xb5\x03\x07\x30\x08\x7a\x2d\x17\x7a\x15\x31\x21\xef\x04\x06\x21\x8e\xc5\x1b\x32\xd5\xba\x50\x6f\x4e\x4e\x6e\xcb\x11\x48\x0e\x1a\xd4\x80\x89\x93\x54\x24\xea\x44\x53\x75\xab\x4e\x18\x37\x87\xab\x9f\x52\x4d\xfb\xb5\x53\x7d\x62\x39\x77\x3f\x11\x79\x4e\x79\xda\xa7\x0e\xbb\xfa\x61\x5b\x4f\x7e\xeb\x78\x6a\x9f\x86\xab\x18\xef\xd3\xbe\x9a\x42\x96\x1d\xee\x80\xcf\xed\x64\xbe\x16\xb2\x5e\x2b\x19\xcf\xbd\x7b\xfb\x03\x7c\x11\xce\xab\x85\xc1\x80\x5c\x09\xed\xe2\x63\x5d\x28\x36\xd2\x51\x84\xef\xda\x23\x7d\x71\x75\xf3\xe1\x1f\xc3\xf7\x97\x57\x37\xf1\x64\xc7\x93\x1d\x4f\x76\x8b\x93\x0d\x7c\xd6\xfa\x54\x7b\x99\xb3\x76\x4c\xc2\x7e\x23\xa7\x56\xa0\xfd\x31\x08\x1b\xd0\x5a\x42\xb4\xe3\xc9\xa0\xde\x80\xc0\x05\x9f\x7d\x4f\x9b\x16\x76\xbe\x12\x1c\xc4\x5d\x60\x05\xe5\x20\x83\xb7\x89\x8f\x6f\x61\xcd\x6a\xeb\xbe\xda\x49\x8a\xb4\xa3\xbd\x6b\xc9\x3c\x7a\x77\x43\x43\x63\xfb\xae\x68\x5e\x55\xa8\x5e\xb1\x6b\x03\xf2\xce\xab\x3d\xe4\xec\x97\xcb\xf3\x8b\xab\x9b\xcb\xaf\x2e\x2f\x3e\xec\xae\x47\x77\x60\x71\x41\x9b\x42\x47\x00\x38\xdc\x91\x4b\x16\x12\x66\x4c\x94\x2a\x9b\x07\x2b\xc8\x6a\x22\xb0\x78\xfa\x9d\xdf\x77\x1e\xf4\xf1\x95\xb7\x45\x66\xdb\x2d\xb3\x3d\x87\x31\x2d\x33\xab\x3d\x1d\x1c\x0c\x76\xe1\x72\x76\x74\x85\xbe\x5f\x49\xd1\xa2\x02\x73\x03\x85\xaf\x6d\xed\xf6\xb1\x90\x6b\x8f\xf1\xa1\x8b\x3e\x68\xb0\x1e\x27\x3c\x5a\x0b\x9d\x93\x1e\xad\x93\xac\x25\x74\x5a\x7a\x19\xba\xf1\xbd\x27\x82\x8f\xd9\xe4\x1d\x2d\xbe\x85\xf9\x07\x18\xb7\x33\x13\x37\xe1\x8d\xd6\x47\xe7\x4a\x46\x5b\xa5\x61\x67\xf6\x61\xed\xdc\x34\x9d\x39\x69\xba\x8a\xce\x68\x1f\x99\xd1\x5d\x20\x45\x27\x41\x14\x4b\xf5\xf0\xad\x1d\xda\x59\x94\xbb\x8a\xb1\xe9\xc4\x73\xdf\x8e\xcb\xfb\xd1\x64\x76\x75\x76\xef\xe8\xac\xde\x54\xed\x48\x04\x4f\xa0\xd0\xea\x44\xcc\x0c\xe7\x82\xbb\x93\x3b\x21\x6f\x8d\x1e\x61\x74\xd7\xbe\xc5\x5a\x75\x82\x3e\x83\x93\xdf\x5a\x37\xd8\xcd\xfb\xf3\xf7\x6f\xc8\x69\x9a\xba\xe6\x26\xa5\x82\x71\x99\xb9\x76\x02\x03\x42\x0b\xf6\x3d\x48\xc5\x04\xef\x91\x5b\xc6\xd3\x1e\x29\x59\xfa\xe5\xee\xc4\xd9\x8f\x0e\x77\x41\x14\xd6\xd5\xd9\xf1\x4e\x5c\xa3\x8f\x65\xde\xe0\x5d\x81\x88\x18\xae\xc5\xb4\x42\xdc\xf4\x56\x67\x27\x64\x74\x04\x9a\xed\x4d\xf4\x8b\x03\xb7\xb0\x5b\xba\x7a\x58\x11\x56\xeb\xe2\x74\x88\x5a\x88\xf4\x0d\x51\x65\x51\x08\xa9\x15\xc9\x41\x53\xa3\xf4\x0e\x0c\x86\xf5\x9a\x1f\xd1\x57\xd5\x23\xff\x0c\x5f\xa2\xc3\x49\xfd\x78\x78\xf8\xf7\x6f\x2f\xfe\xf1\x9f\x87\x87\x3f\xff\xb3\xfe\x2b\xb2\x42\x1b\x05\xd4\xbc\x44\x15\x90\x0c\xb8\x48\xe1\x0a\x9f\x81\x1f\x55\xc3\xcd\xe2\x7e\xd0\x54\x97\x6a\x30\x15\x4a\x5f\x0e\xc3\xc7\x42\xa4\x8b\x9f\x54\x0b\x89\x83\xec\x27\x63\xc0\x2d\x1a\x52\x3d\xdd\x13\xf6\x50\xd1\x92\x8e\x8f\xaa\x9b\xb5\xde\x44\x27\xa7\xf8\xe7\x57\x1e\x04\x46\x7a\xba\x93\x4c\x6b\x74\xbd\xb9\x54\x70\x31\xee\x99\x53\x5b\x89\x9d\xb3\xd7\xad\xeb\xa3\x74\x4a\xda\xc2\x0e\x76\x0c\x30\x84\x88\x83\x96\x3d\xc8\x81\xc1\x2e\xbb\x98\x4f\x87\x97\x64\x66\x21\xbc\x37\xc0\xf1\xe9\xbd\x5f\x7d\x54\x1a\x17\x9a\x2e\x39\x50\x05\x0d\xf1\x8d\x0d\x0a\x0a\x49\xc6\x24\x63\x39\x73\xb1\x86\xae\x41\x93\x22\x47\xf6\xcb\x41\x52\x94\x3d\x77\xc1\x20\x87\x5c\xc8\x79\xf8\x08\xc5\x14\x72\xa3\x69\xf5\x95\x16\x92\x4e\xa0\x17\x6e\xb7\xb7\x85\x4f\xf6\xc6\xc6\x03\x96\xef\xb6\xaa\x70\xe5\x2a\x75\x14\x19\xd2\x97\x47\xdb\x3c\xe8\xf7\x84\xb4\x05\xcc\xb8\xfa\x08\x22\x61\xb0\xc4\x59\x81\x33\x40\x11\xf5\xc9\x99\xc8\xca\x1c\x54\x2f\x88\x41\xd6\x1a\xc0\x67\x46\xb3\x54\x7b\x25\xa8\xa5\x6c\xc6\x54\x17\x61\xc4\x2b\xe4\x34\xe6\x22\xf2\x45\xa9\x8b\x52\xbb\x7a\x33\xb5\xc6\x6e\x42\xa1\xdd\x22\x14\x05\x68\x90\xfd\xd7\x07\xed\xa3\xd1\xa9\xd6\x20\xf9\x1b\xf2\xdf\x47\x3f\xfd\xfe\xd7\xfe\xf1\x97\x47\x47\x3f\xbe\xea\xff\xed\xe7\xdf\x1f\xfd\x34\xc0\x3f\x7e\x77\xfc\xe5\xf1\xaf\xfe\xc3\xef\x8f\x8f\x8f\x8e\x7e\xfc\xf6\xdd\xd7\x37\xc3\x8b\x9f\xd9\xf1\xaf\x3f\xf2\x32\xbf\xb5\x9f\x7e\x3d\xfa\x11\x2e\x7e\xde\x70\x92\xe3\xe3\x2f\xbf\x68\xbd\x74\xca\xe7\xef\x5b\x12\x50\x3b\xfa\x9d\x95\x0b\x5a\x9c\xb1\xa3\x38\xeb\xfb\x7e\xa5\x34\xf5\x19\xd7\x7d\x21\xfb\x76\xea\x37\x44\xcb\xb2\x1d\x31\xa9\x98\x52\xd7\xe7\xdf\x77\xef\x7a\x53\x31\xa4\xc0\xae\xf7\xe6\x80\x2b\x48\x24\xe8\x4f\x61\xc9\xb1\x4f\xf2\x72\xca\x42\xcc\xe3\x4b\xe3\x73\x9f\x83\x71\x27\x84\x0c\xe2\xbe\x56\x92\xe8\x58\x8a\x7c\x40\x6a\xee\x8d\x19\x26\x7c\xb8\xeb\x6e\xa1\x85\x15\xd4\x8f\x68\x0c\x8a\xc6\xa0\x35\xe3\x51\x63\xd0\xb5\xc5\xc3\xbd\xb5\x04\x01\x9f\xed\xea\xc2\x58\xe9\x41\xf7\xba\x8e\x16\xa4\x10\x45\x99\x51\xbd\xc6\x33\xb6\xc2\x9d\xee\x8e\x7a\x15\x8f\x5c\x05\xd3\x58\x86\x96\xaf\xf6\x61\x92\xd3\x2c\x23\x8c\xdb\x83\x8f\x13\x78\x87\x99\x04\xab\xda\x10\x6a\xfd\xd9\x33\xb3\x84\x3b\x57\x56\xae\x1e\x97\xa3\x88\xd2\x54\x6a\x8c\x3d\xc6\xb2\x73\x96\x95\x38\xef\x13\xe3\x55\xf1\xb9\x20\x1c\x86\x5c\x90\x95\x9d\x31\x33\xaa\xb4\x5f\x36\xae\x46\xd3\x5b\xf4\x36\x26\x90\x02\x4f\x00\x13\xd3\x4a\xa8\xde\x75\x64\xf4\x36\x72\xc1\x67\x76\x0e\x4a\xd2\xd2\x06\x83\x58\xf2\xb7\x7a\x8e\x97\x15\x80\x60\x10\xf1\xda\x37\x30\x0e\x71\x08\x48\xf5\x83\x86\x1d\xf2\xfb\x82\x95\x55\x3d\x4d\xe4\x41\x7b\x9e\x19\x3c\x5b\xad\x84\xa1\x25\x66\x59\x99\x9f\x9b\x4c\xf2\x25\x38\x03\xdb\xb3\xcf\xcf\x8e\x75\x76\xc4\x36\xbb\x61\x99\x5b\xf8\x4e\xba\x64\x93\x5d\x38\x4b\x0a\x09\x63\x76\xdf\xd1\x39\x3d\xe5\x95\x25\x86\xa5\xc0\x35\x1b\x33\xdb\xf3\xbe\x90\x50\x00\x4f\x43\xe1\x52\x4c\x0e\xe7\x4d\xd8\xec\x65\x30\x8f\x15\xb8\xbb\x25\x65\xd7\xab\x84\xfd\x48\xc7\x48\xa4\x63\x3b\x8f\x4f\x44\xc7\x1c\xe6\xee\x0f\x11\xc3\xc8\xf3\xf6\xd1\xef\x67\xcd\x50\x76\x44\xe4\xad\x11\xad\xca\xec\x3a\xc1\x59\x94\xcd\x92\x0c\x69\xd8\x81\x34\x6a\x61\x83\xd7\xc8\x94\x4d\x0c\x64\x33\x98\x41\xe6\xe4\x26\x92\x53\x4e\x27\x36\xbf\x5b\x0b\x6f\xaa\x35\x8a\x96\xc1\x63\xc9\xd2\xa5\xb8\x7b\x94\xe3\x0d\x6e\x67\x82\xa6\xf8\xa3\x14\x59\x06\x52\x91\x8c\xdd\x02\x39\x87\x22\x13\x73\x97\xae\xcd\x53\x72\xad\xa9\x36\x58\x7d\x0d\x7a\x37\xb7\x6f\x2b\x8c\xc5\x15\x0f\xcb\x2c\x1b\x8a\x8c\x25\x3b\x19\x55\x9a\x3b\x77\x89\xfb\x55\x94\x59\x46\x0a\x9c\x72\x40\xde\x73\x24\x1a\xa7\xd9\x1d\x9d\xab\x1e\xb9\x82\x19\xc8\x1e\xb9\x1c\x5f\x09\x3d\xb4\xd2\x77\x33\xe0\xce\x5e\x48\xd8\x98\xbc\xc1\xea\x36\x9a\x68\x3a\x41\xdd\xc9\xbb\x01\x7b\x06\xfe\xf5\x09\x2c\x7d\xb8\x63\x6a\xa5\xb2\xd2\x1a\x71\x7e\x8b\x33\x19\x5a\x65\x3f\x7f\xf2\x6d\xca\xd8\x18\x92\x79\x92\xb5\x3f\x5a\xa7\x09\x06\x30\x54\x19\xe7\x35\xfc\x76\xd5\xd4\x5d\x8e\x27\x6a\x81\x8c\x13\x5b\xe6\xdc\xd6\x6f\xaf\x50\x3d\xac\xc8\x6a\xbb\xaa\x53\x25\x71\x67\xe6\xd9\x96\x6d\x16\x42\xe9\x6b\xa3\xa1\x77\x52\x0c\xfd\x70\xe8\xa7\x23\x58\xf2\x39\xcb\x20\x25\x2c\xcf\x21\x35\x5a\x7c\x36\x27\x74\xac\x31\xd7\xb6\x61\x21\x48\x24\x58\xac\x75\x55\x4c\xa6\x94\xa7\x19\x48\x32\xa6\x2c\x73\xf6\x80\xc6\xf5\x1a\x64\xce\x38\x9a\x05\xac\x47\x16\x4d\x0c\xe6\x53\x92\x08\xe9\xcb\xd3\x33\xad\xfc\x4f\xd5\xc1\x44\x3e\x52\x43\x80\x45\xd7\x32\x19\x65\x22\xb9\x55\xa4\xe4\x9a\x65\x76\x31\x42\xdc\x92\x44\xe4\x45\x86\x47\xa7\xc5\xc9\x0a\x7f\xf6\x03\x2a\xf5\xcd\xec\xea\xe4\xb7\xd5\x4f\xf8\xc5\xae\x0c\xbd\x03\x41\xac\x0b\x31\x0c\xee\x21\xe9\x2c\xcf\xff\xe2\x1e\x92\x5a\x61\x09\xec\xc7\x80\x27\x1a\xf3\x3c\xe9\x2d\xbc\xa0\x4a\x76\x2d\x72\xe9\xea\xa3\x01\xbf\x33\x3b\xa7\x2f\x84\xe5\x1e\x41\x32\xc6\x91\xbe\xb9\xfc\x3a\xc2\xb8\x32\x9c\xbd\x71\x18\xec\xd1\x73\x42\x2b\x49\x99\xc4\x2a\x08\xf3\x10\x48\xed\xe7\xc2\x02\x03\x42\x68\x72\x74\x78\x72\x78\xbc\x64\x7f\x3c\x34\x12\x48\x06\x96\xd6\xfa\xc4\xbd\xb0\x28\xc5\xf2\x22\x9b\xe3\x3a\x0e\xd3\x1e\x61\xda\x47\x5a\xcb\x92\xfb\x55\xb9\xa4\xbf\x1e\x51\x82\x68\x49\x7d\x75\x15\xfb\xad\xb9\x48\xcb\xd2\x51\xf9\xa3\xc3\x5f\x0f\x7b\x04\x74\x72\x4c\xee\x04\x3f\xd4\xb8\xfc\x01\xb9\x11\x46\x94\xae\x26\x9a\x8b\x92\x70\xb0\x81\xfd\x70\x5f\x64\x2c\x61\x3a\x9b\x23\xc5\x22\xa2\xd4\x36\x87\x98\x6a\x9f\x6c\x78\x71\xcf\xb4\x8b\x57\x33\x24\xe3\x15\x42\xd3\x52\x2d\x42\x8d\x98\x33\x83\x93\x29\xd0\x4c\x4f\x6d\x90\x08\x17\xbc\xff\x6f\x90\x02\x73\x10\xb9\xfb\xe5\xc5\x55\xfd\xeb\x44\x73\x30\x44\xf4\x6b\xe8\xae\x89\xcf\x37\x37\x37\xc3\xaf\x41\x2f\x90\x0c\xf3\x14\x1f\xba\x83\xd6\x00\x90\x63\x21\xf3\x3d\xa0\x1d\xdd\x38\x2b\xfb\xa4\x10\x72\x1f\x48\xd8\x54\xa8\x56\x7b\x49\x96\xf6\x53\x28\x8d\xda\x90\x93\xc6\x38\x24\x66\x07\x9b\x31\x24\xbe\xcf\xcd\xe5\x70\x40\xfe\x21\x4a\xf3\x36\x23\x3a\xca\xe6\xa1\x12\x83\x02\x4d\x0e\xcc\x54\x07\x86\x3c\x19\x6c\xf8\x06\x68\x6a\x54\x14\x43\x3d\x80\xee\x47\x3f\x2b\xe2\xce\x83\x5b\x5b\xb7\x7c\xa0\x54\x5a\xe4\x64\xea\x5e\xbb\x99\x7a\xe9\x4e\xc6\x00\x4f\x8f\xcf\x6b\x92\x50\x58\x0a\xe7\xee\x79\x71\xf4\x6b\x89\x6e\x58\xb8\xbb\xef\x47\x58\xc6\x2a\xa9\x83\xcd\x35\x74\xb2\x89\x41\xdc\x02\xcb\xa0\x1a\xec\xe6\x2a\xa9\x8f\x3d\xae\x3d\xba\x73\x22\xe7\xe2\x44\xe8\xd4\x6b\x1f\xeb\xd5\x69\xe5\xd1\x6e\xe2\x06\xc8\x2a\x23\xab\xc3\x19\x6b\x7d\xe9\x08\x88\x1f\xa7\xf4\xe5\xa7\x00\x40\x37\x9b\x4f\xba\x84\x40\xd1\x41\x68\xf7\x72\x60\xb7\x16\x46\x0f\xc5\xd4\x4b\x4b\x5c\x91\x4c\x28\x90\xb3\x5d\x93\xb9\xab\xd1\xdd\xab\x8b\xdd\x35\x7e\x3f\x56\xe4\x49\x4b\xc2\xcb\x7c\x04\xb2\xca\x4c\x91\x7a\x19\x20\xb5\xc8\x84\x2b\x7b\xb9\x37\xe7\x36\xdb\x27\x9a\x3b\xff\xf2\xe7\x3f\xff\xf1\xcf\x03\x3b\x7d\x88\x52\xe0\xe4\xf2\xf4\xea\xf4\x97\xeb\xef\xcf\x30\x39\xb6\x2d\x54\x3b\x0a\xc1\xec\x3a\x00\xb3\xd3\xf0\xcb\x8f\x1a\x7c\x89\x29\x1f\xad\xa9\x48\xd3\xf6\x8f\x53\x1a\x0c\x30\x7a\x9b\xd1\x38\x9d\xec\x57\x2b\x56\x66\x64\xcd\xa6\x21\xd5\x1c\xb5\xbd\x38\x63\x3a\x29\xae\x45\x72\xdb\xa1\x5e\x73\x0e\x85\x84\xc4\xda\xc9\x6e\xce\x86\x76\x76\xa3\x5f\x5e\xbd\xbf\xa9\x52\x0d\x30\x1e\x87\xbc\xf5\xf6\xa5\x6f\x9c\x25\xcd\xe8\xa4\xb7\x50\xe8\xa0\xba\x8f\x68\x72\x7b\x47\x65\x8a\x96\x2d\xaa\xd9\x88\x65\xcc\x16\xff\xf5\x4d\x21\xb9\xb0\x01\x7f\xb6\xc8\x99\x18\x2f\x96\xd6\xac\xcc\xa1\x68\xb2\xb2\x71\x34\x63\xca\x32\xb4\xa0\x96\x5c\xb3\x1c\x5c\x44\x50\x52\x04\x93\x5e\xdd\xa6\x1d\x95\x2f\x3f\xf6\x56\xf9\x3a\x7c\xef\xbd\x7a\x5b\xeb\x61\x6d\xe3\x12\xf7\x98\xd5\x39\x16\x67\x13\x42\x22\xab\xfb\x2c\x58\x5d\x21\xe1\x5a\x8b\xa2\x23\x2f\x89\x9d\x6c\x8d\x8f\x64\x04\x63\x61\x88\xf0\x5a\xa7\x87\xef\x11\xcc\x31\x39\xd0\x5b\xb5\x44\xc3\xb1\x61\x23\x32\x55\x99\x4c\xbd\x81\x92\x83\x52\x27\xe8\x0e\x29\x0b\xab\xb5\x22\xb9\x2e\x25\xf4\xcc\xdb\x41\x8e\xab\xeb\x55\x59\x0e\xe6\xf1\xc0\xed\x97\xa0\x13\x6b\xb9\xad\x11\x72\x2c\x0c\xea\x96\xbf\xe8\x46\x49\x24\x55\x53\xc0\xf2\x22\x70\xcf\x7c\x37\x94\xa1\x48\x0f\x0f\xab\x57\x31\x8c\x65\x22\x69\x02\xa4\x00\xc9\x84\x61\x46\x25\xd7\xa9\xb8\xe3\x64\x04\x13\xc6\x95\x07\x85\x99\xdb\xc3\x0c\xfd\x31\x4c\x85\xc2\x70\x03\xf2\xa1\x51\xec\xc4\xa5\x21\x25\xa2\x3a\x9a\x6e\xcd\x8b\x9e\x24\xe4\x58\xb5\x96\xc9\x01\xc2\x3e\x3c\x56\x6f\xb0\xe4\xa3\x92\xe3\x93\x53\xc8\xe8\xdc\x46\x9b\x8e\x19\xa7\x19\xfb\x37\x48\x75\xdc\x81\xc7\xc9\x80\xb0\xfa\x6d\xed\x3a\xb0\x54\x3f\x4d\xa6\xed\x9c\xbf\xd1\x45\xb5\xe1\x88\x2e\xaa\x36\x93\x44\x17\x55\x74\x51\x3d\x32\xa2\x8b\x2a\xba\xa8\x16\xc6\xde\x6a\x49\xd1\x45\xb5\xf3\x88\x2e\xaa\x87\x47\x74\x51\x6d\x30\xa2\x8b\x6a\xc3\x11\x5d\x54\xd1\x45\x15\x5d\x54\xd1\x45\xf5\x19\xd9\xed\xfc\x88\x2e\xaa\xa5\x49\xa2\x8b\x2a\xba\xa8\x36\x1e\x7b\xab\x7c\x45\x17\x95\x1d\xd1\x45\xd5\x1c\x9f\x17\xab\xf3\x0e\x9e\xa1\x51\xf5\xda\xe7\xb4\x0d\xd1\xa9\xc0\x12\xe7\x27\xaa\x37\x8d\x0b\x8f\xaa\xf5\x89\xab\x95\x05\xf1\xa9\x38\xce\x23\x54\xf9\x99\x56\xe6\x4b\x6d\xeb\xaa\xf0\x49\x86\xea\xa4\x10\xf6\x7f\x95\xa3\xa2\xe6\xa1\xb0\x0a\xef\xee\x39\x6b\x4f\x96\x8d\xd5\xc6\x2d\xf1\x69\x5c\x12\x7b\xe2\xbf\xe9\xc0\x0d\x11\x5d\x10\x2f\xce\x05\xf1\x72\xba\xe6\x3a\xcf\xfc\xcd\x54\x82\x9a\x8a\x6c\x67\x44\x6f\x20\xf9\x3b\xc6\x59\x5e\xe6\x06\xe7\x94\xc1\x67\x36\x0b\x21\x00\x2a\xa0\xab\xa5\xd8\xd6\x8a\x68\x2e\x64\x29\x60\xb1\x53\xca\x32\xb3\x8d\x98\xbf\x39\xa5\x33\x83\xeb\xaa\x4c\x12\x00\x6c\xa5\x56\xd7\x70\xfe\x38\x08\x4f\x0a\xad\x33\x5e\xb7\xa3\x37\xed\x98\xb8\x2d\x47\x8a\xb3\xfc\xf1\x0f\x3b\xcd\x31\x91\x45\x37\x74\xf9\xeb\x0f\xc3\xb3\x7a\x9b\x6c\xee\xc9\x32\xe3\x33\x91\xcd\x6c\x87\x7d\xbc\xc8\x08\x6b\xae\x19\x3f\x36\x73\x1f\x81\xa6\x35\xdd\xc6\xa9\x05\x8a\x00\xa7\xa3\xcc\xdc\x67\xee\x0a\x1c\x79\x68\xf9\x2e\x50\x5d\x4a\x20\x13\xaa\x9f\x92\xe0\xb7\x57\x61\x5a\xa9\x2f\x5d\xf0\x9b\xb6\x12\x7a\xd3\x06\x67\xe4\xf0\xa6\x15\x6a\x82\x78\x61\x2b\xe8\x6f\x2c\x87\xb7\xa6\x94\xed\x65\xe3\xf6\x47\x8b\x60\x89\x1b\x7c\xf1\xce\x00\x7c\xe0\x5a\x3e\x7b\x76\x5e\x57\x82\x7c\x57\x29\x2d\x48\x91\xd1\xaa\x2f\x14\xee\xc0\x37\xc8\x83\xce\xa6\x90\xdc\x7e\x70\x9e\xd8\x23\x05\x10\x64\xd3\x09\xd3\xd3\x72\x34\x48\x44\x7e\x62\x48\x82\xfd\xdf\x28\x13\xa3\x93\x9c\x2a\x0d\xd2\x88\xab\x8e\xc5\xf5\x13\x33\x0b\xe3\x93\x41\x9e\x1e\x0f\xc8\x4f\xdc\x66\xb7\x57\x7d\x28\x6b\xb5\x1d\xcc\xf3\x7d\x9d\x8d\x11\x18\xea\x2a\x64\xbd\x7d\xf8\x68\x8e\xcb\x1b\xb4\x29\x94\xdc\x9a\x25\xb5\xf4\x82\x7f\x7a\x0f\x78\xa4\x5c\xa4\x03\x83\xcb\x73\xf3\x74\x77\x16\xf1\xd1\x81\x87\x7b\x8f\xbc\xdb\x7b\x23\x1a\xef\x8b\x47\x7b\x0f\xab\x4d\x77\xe0\x80\xed\xc2\x83\xdd\x9d\xf7\xfa\x23\x14\x65\xfe\x38\x5e\xeb\x0e\x4d\x7b\x1d\x79\xab\x3f\x85\xa7\xba\x93\xb7\x6e\xeb\xa1\xfe\x74\xde\xe9\x6e\x5e\xb7\x4b\x45\xe0\xb9\x7a\xa4\x3b\x30\xd1\x77\x69\x9e\xef\xcc\x34\xff\xd1\x3c\xd0\xed\xbd\xcf\x7b\xe0\x79\x6e\x0d\x64\xc6\x99\x66\x34\x3b\x87\x8c\xce\xaf\x21\x11\x3c\xdd\x99\xc3\x2c\x54\xe9\x0c\xe7\x47\xd9\x69\x9d\x9d\xaa\x99\x68\x31\xa5\xae\x18\xb9\xd1\xa8\x6c\x62\x89\xf7\x65\x38\x81\x02\xbd\xca\x76\x95\x7b\xe9\x9d\x20\x7b\x63\x10\xb3\x59\x27\x5d\x6e\xe2\x37\xe2\x8e\x88\xb1\x06\x4e\x8e\x18\xf7\xfb\x78\x5c\x53\x03\x2b\xeb\x64\x40\x6b\xf3\xeb\xeb\x57\xfe\xe2\x97\x67\x76\x44\x03\xab\x52\x1f\xdf\x0a\xec\x1e\xf4\xb8\x19\xd8\x5d\x38\x2e\xb3\xa6\x29\xd8\x9a\x87\x9b\xf4\xe6\x75\x55\x4e\xf9\x35\xce\x1b\x4e\x1b\xe5\x29\x71\x99\x68\x2f\x6f\xd3\x5a\xc7\xd5\x34\x45\xbf\x10\x47\xf3\x98\xd5\xf8\xe6\x6c\x68\x8d\xc6\xd1\x5c\xb2\x2f\xe6\x92\x27\x8a\x4d\xd9\x43\x41\xf7\x99\xc6\xa3\x44\x41\x77\x8b\x51\xcb\x4d\xfd\x5a\xd2\x04\x86\x9d\xcb\x08\xfe\x38\x91\xb4\x94\xd4\x11\xc0\x20\xf2\xf9\xc3\xc3\x01\x52\x7b\x9a\x42\x3e\x2f\x66\xca\x8e\xcb\x2c\x9b\x93\xb2\x10\xbc\x99\xfd\x6c\x7d\xed\x8b\xc9\xb4\x68\x92\x5f\xf1\x94\x4a\xb0\x2c\xa4\x70\x3c\x53\x96\x9c\x1b\x1a\x5c\xf5\x44\x43\x41\x12\xcb\x34\xd3\x46\xca\xae\x62\x13\xb3\x7c\xc3\xff\x30\x9b\xb7\x0a\x40\x6c\x4c\x68\xee\x1e\x0b\x99\xb0\x51\x36\x27\x53\x9a\x85\x06\x38\x94\xdc\xb2\x2c\x73\xd3\x0c\xc8\x35\x68\xeb\x52\xb0\xbc\x33\x13\x7c\x82\x8b\xa3\xdc\x37\x5e\x84\xc4\xdc\x9b\x64\x40\x79\x59\xd8\xe7\x19\x4e\x3c\x17\xa5\xf4\xcf\x1b\x04\xc7\x44\xe0\xc0\x9c\x65\xbd\x5a\x7b\xb7\x07\x37\x36\xc4\xfe\x94\xca\x08\x00\xef\x7d\x59\xea\x5e\x7d\x4e\x5f\x39\x5c\xd5\x9a\xfb\x14\x52\xcc\x58\x6a\xbd\x1b\x1e\x6c\xd8\x48\xda\x36\xf0\x09\xe7\x99\x0b\xde\xe7\x30\xa1\x28\xa8\xb8\x53\x64\xf7\xcc\xce\x63\x23\x08\x78\x8a\x2d\x7d\x8c\x84\x2f\x8a\x46\x3a\xfd\x8c\xd9\x66\xc4\x35\xc8\x91\x23\x2e\x88\xc0\x78\xd4\x92\x33\x6d\x1b\xdc\x4f\x4b\x4d\x52\x71\xc7\x8f\xb7\xf2\xba\xa2\xa3\xf5\x66\x25\x80\x9a\xee\xd7\x55\x72\x8e\x7d\xdf\x87\xc1\xcb\x94\x33\x7d\x8e\x49\xc9\x15\xb4\x64\xef\x9d\x09\x47\x7f\xf9\xd3\x6e\x34\x82\xe5\x20\x4a\xfd\x49\xb4\xbf\xbb\x29\x4b\xa6\x75\x61\x96\xe5\xa0\x88\x28\x17\xd4\xe2\xd7\xee\xb6\xd5\x3b\x14\x55\xc0\x55\x63\x57\xc3\xee\x0a\xeb\xd7\x62\x39\x84\xaa\xf3\x35\xc6\x89\x9f\x5f\x5d\xff\xf2\xf6\xf4\xbf\x2e\xde\x0e\xc8\x05\x4d\xa6\xf5\x9a\x18\x9c\x50\x24\x1a\x48\x28\xa6\x74\x06\x84\x92\x92\xb3\x7f\x95\xce\xe1\x7b\x14\xee\x3d\xee\xb4\x56\xfb\x8e\xdc\x17\xbb\xf3\x77\xd6\x0e\xce\xf6\xfa\xb7\x71\x59\x42\x01\x36\x70\x59\x12\x9f\x82\x97\x79\x6e\x55\x04\x14\xb8\x30\x7c\xfe\xfc\xfd\xc5\x35\x86\xe5\x17\xd2\x56\x0a\xc1\x38\x2e\xfc\x1d\x67\x1a\x81\xb9\xc3\x75\xee\x1d\x90\x53\x3e\xb7\x3f\xda\x33\xc5\x14\xc9\x98\xd2\x80\x5c\xcf\x89\x6d\xde\x7f\x7d\xf0\x6a\x80\xff\x1d\x10\x9a\xa6\xd2\xc8\x75\x21\x3c\x2d\x59\x8a\x17\xb5\x92\x1f\x1b\x65\xb5\x17\xe0\xa0\x6d\x34\xda\x3b\x91\xba\x95\x23\x27\x41\xdf\x95\x65\x83\x4a\x4b\xaa\x61\xc2\x12\x92\x83\x9c\x00\x29\xa8\x4e\xa6\x24\xa7\x73\x92\x08\x29\xcb\xc2\xd6\xf9\x4f\xa9\xa6\x03\xf2\x95\x90\x24\xf7\x87\xd8\xe0\xbc\xe1\xc3\xd7\xab\x7d\xfa\xd5\xc9\xae\xff\xc9\x94\x2a\x41\x9d\xbc\x7e\xf5\xd7\x3f\xfc\xf9\xcf\x2f\xaa\x35\x5c\x15\x2e\x64\xf6\xb6\xd6\x1a\x8e\xfa\x5d\xb0\xbb\x6e\x5b\x05\x32\x3e\xc9\xea\xf8\xb5\x1b\x03\x68\xab\x65\xb6\xd5\x31\xfb\xd5\x1b\x0c\x77\x55\x35\x3b\x69\x51\x57\xad\xa1\xa3\xc6\x4e\x15\x1f\xf4\x8a\x95\xa3\x0d\xa2\xde\xab\xf7\x72\xe8\x0f\xa6\x93\x73\xf2\x85\x06\xaf\x45\x15\x9d\xd4\x23\xaf\xc8\xdf\xc9\x3d\xf9\x3b\x2a\x5a\x7f\x69\xdb\x06\xab\xad\x0a\xd4\x45\xb0\x91\xd1\xef\x2f\x87\x1d\x41\xfc\x07\x43\x34\xcd\x8c\x06\xaa\x5a\x90\x11\x73\x82\x3d\xdc\x6b\x90\x46\xd0\x74\x3b\xf1\xa4\x0d\xc4\xcc\x02\x3f\x21\x9a\x59\xc7\xc3\xe5\xb8\x19\xe0\xb4\x1d\xa2\x99\xdb\xbf\x11\x4a\x5f\x39\x2a\xd4\x6c\x85\x53\xcd\x96\x23\xe1\x6f\x90\x31\xc3\x37\x94\xae\x0e\x98\x22\xa9\xc0\x78\x2b\x1b\xc8\x3c\x65\x2d\xc2\x28\xf6\x07\x8d\xdb\x79\xd6\x1b\xfb\xf9\xd0\x4e\x2d\x98\x52\x50\x07\x72\x22\x56\xad\x46\x56\x21\x52\x27\x9d\x99\x65\xa5\x35\x9e\xf1\x80\x78\xe6\xac\x36\xc1\xde\x8c\xb8\x64\xce\x53\x42\xb9\x4d\x25\x19\x83\x94\x36\xf6\x7c\x34\xf7\x61\x7b\xad\x37\xaf\xd5\x49\x2a\xa4\xd0\x22\x11\x2d\x7a\x9c\x35\xbd\xdd\x6e\x3a\x04\x82\x8d\xf7\xf5\x06\xf3\xef\xce\x87\x3d\x72\x73\x36\xc4\xbe\x4f\xd7\x67\x37\xc3\xa6\xce\x72\x70\x73\x36\x3c\x78\x52\x50\x10\x2f\xf0\xa1\x89\x7a\x87\x49\x1a\x26\x28\x23\x4d\xf6\x73\x5a\xf4\x6f\x61\xbe\x23\x4f\xed\x82\xaf\xf7\xc3\x0e\x77\xf2\x42\x16\xcc\x39\x2d\xb6\x9e\x4d\x02\x4d\xd9\x27\xca\xe7\xf2\x01\xb1\xe1\x99\xab\x13\xbb\x72\x31\x83\xd4\x4a\xe9\xfe\x0e\xe0\x69\x21\x98\x91\x17\x63\xb6\xd7\xf6\x77\xc7\x6c\xaf\x8d\x47\xcc\xf6\x8a\xd9\x5e\xcb\x63\x6f\x42\x5a\x63\xb6\xd7\xcb\xf2\xe0\xc7\x6c\xaf\xcf\x3c\x08\x20\x66\x7b\xad\x1e\x31\xdb\x2b\x66\x7b\x6d\x36\x62\xb6\xd7\xf6\x63\xef\xc2\x97\x62\xb6\xd7\x56\x23\x66\x7b\x2d\x8f\x98\xed\xb5\x66\xc4\x6c\xaf\x35\x23\x66\x7b\xc5\x6c\xaf\x98\xed\x15\x83\x60\x1f\x9d\x6b\x3f\x83\x60\x49\xcc\xf6\x72\x23\x66\x7b\xbd\x88\x50\x3f\x12\xb3\xbd\x36\x1a\x31\xdb\x2b\x66\x7b\xed\x32\x62\xb6\xd7\x4b\x31\x97\xc4\x6c\xaf\x98\xed\xf5\xf9\x08\xba\x31\xdb\x2b\x66\x7b\xc5\x6c\xaf\x98\xed\xf5\xe0\x2a\x62\xb6\xd7\x4b\x50\x01\x7d\x47\xe0\xf6\xd9\x4b\x87\x67\x22\x2f\x4a\x0d\xe4\x83\x9f\x32\x48\x91\x96\x30\x30\x55\x97\x08\xda\x87\x10\x26\x82\x8f\xd9\xc4\x51\xf6\x13\xdb\x86\xb7\x1f\xde\xa7\x5f\x6b\x7d\xfb\x0c\xe3\x07\x33\x96\xb3\xdd\x52\xca\xc8\xd2\xc6\xbc\xc5\xb9\x6a\x7e\x19\x73\x92\x72\x7a\x8f\x47\x84\xe6\xa2\xb4\xad\x8b\x13\xb7\x7f\x01\x84\xd6\x7b\xb5\x77\x3b\x43\xba\x51\x71\x68\xea\xe3\xea\x86\x5d\x84\x95\x50\xad\x41\xf2\x37\xe4\xbf\x8f\x7e\xfa\xfd\xaf\xfd\xe3\x2f\x8f\x8e\x7e\x7c\xd5\xff\xdb\xcf\xbf\x3f\xfa\x69\x80\x7f\xfc\xee\xf8\xcb\xe3\x5f\xfd\x87\xdf\x1f\x1f\x1f\x1d\xfd\xf8\xed\xbb\xaf\x6f\x86\x17\x3f\xb3\xe3\x5f\x7f\xe4\x65\x7e\x6b\x3f\xfd\x7a\xf4\x23\x5c\xfc\xbc\xe1\x24\xc7\xc7\x5f\x7e\xb1\xf3\x92\x5b\x8b\xc4\xdd\x09\xc4\x1d\x89\xc3\x1f\x45\x18\x76\x0e\xdd\x8e\xce\xa2\x0b\x46\x59\x3a\x8d\x8e\x61\x3d\x74\x1a\x3d\x35\x45\x31\x2f\xcc\xc3\x14\x11\x39\xd3\x46\x38\x34\xf2\x20\xad\x87\xb3\x32\xdd\x50\x4a\x1d\x1d\xc0\x80\x6e\xaa\x6d\xa3\xf5\x10\x0a\x5a\x0b\x62\x11\x5e\xf2\x73\x9d\xe8\x59\x5e\x64\xd8\xe0\x1c\xcf\x73\xdf\xc7\xb2\x20\x73\x8d\xb4\xe1\xf1\x11\x69\xc3\x4b\xa4\x0d\x0a\x92\x52\x32\x3d\x3f\x13\x5c\xc3\xfd\x4e\x16\x96\x26\x69\xb8\x6e\x4e\xe8\x62\xc6\x94\x8b\x75\xb3\xbf\x11\x51\xd8\xb8\xef\x85\xc4\xfa\xa9\x28\xb3\x14\x93\x39\x4a\x8e\x0a\xa6\xcd\xd2\x03\x6d\xb5\x3f\xd4\x7b\x30\x94\x7b\xf1\x21\x5e\x9f\xb3\x6a\xe6\xbf\x4a\x36\xa3\x99\xd1\x76\xab\x3b\x86\xa8\xc1\xd4\x6f\xda\xf4\xcc\x6b\xaa\x6e\xab\x03\x0f\x7d\x23\x43\x87\x35\x9f\xf8\x57\xc2\xaf\xe0\x5e\x3f\x47\x29\x0d\x05\xa4\xa1\x64\x33\x96\xc1\x04\x2e\x54\x42\x33\xa4\x6b\xdd\xf0\x8a\xd3\x35\xb3\xe3\xc6\x4b\x91\x29\x72\x37\x05\x43\xab\x09\xf5\x26\x00\xcc\xb0\x9b\x50\xc6\x6d\x5e\x7c\xe1\x6f\x56\xd6\x96\x60\xc8\x7f\x41\xa5\xd9\xe0\x60\x33\x40\x15\x79\x24\x44\xe6\x32\x1e\xb2\x79\x35\xbf\xcb\xfd\xe1\xe2\x17\x0e\x77\xbf\x98\xd9\x14\x19\x67\x74\x12\x4c\x05\x0a\xf4\x92\xb5\xaf\x9a\x7a\xed\x0b\x60\x3a\x41\x09\x84\x66\x77\x74\xae\x2a\xc3\x49\xad\x02\x84\x7a\x43\x5e\x1f\x23\x3a\x53\x45\xc2\x1c\x29\xf9\xc3\x31\xba\xff\xce\x4e\x87\xbf\x5c\xff\xe3\xfa\x97\xd3\xf3\x77\x97\x57\xe4\x4a\x68\xb0\x4c\xad\xd6\x26\x30\x09\x1a\x86\x59\x25\x3e\x03\xb5\x74\xa1\x06\x68\xbb\x64\x8a\xdc\x31\x9e\x8a\x3b\xb5\xb3\x8d\xd6\xa2\x9f\x01\x1e\x50\xbe\xd3\x1c\x09\x2d\x28\x76\x3f\x6c\xc1\x61\x96\x22\x4c\xea\x93\x22\x0f\x4f\xd3\x93\x54\x8a\xc2\x02\xc1\x1b\xb9\x2a\x56\xdb\x54\xa3\xeb\x31\xac\xb8\xbf\xe3\xe6\x84\x13\x49\xb9\xae\xac\x3d\xd5\x9e\xb9\xb6\x8b\x83\xd6\xdb\xf1\xbc\x33\x9a\x68\xda\x5d\x36\xd3\x69\x9a\x42\xda\x00\xff\x8b\x8b\x1c\x3c\xf3\x2f\x37\xaf\xaa\x54\x90\xe1\xfb\xeb\xcb\xff\xbd\x80\xc7\xf3\xa2\x5d\xa0\x54\x37\x99\xb1\x52\x14\x9d\xed\xee\x07\x97\x79\x19\xf7\x77\x2f\xf6\x37\x70\xcb\x6e\xdc\xf3\x1f\x4a\xde\x2c\x69\x54\xcd\x4f\x72\x91\xc2\x80\x0c\x83\x9f\xa0\xf9\x6b\xad\xc0\x01\x95\x40\xcc\x25\x5c\x33\x9a\x65\xf3\xba\x88\xa6\x85\xcd\x42\x6c\xd4\x66\xa8\x13\xf2\x31\xcd\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x3e\xdc\xc9\x76\x84\xd9\x48\x0a\x5c\x68\x27\x58\x9b\x55\x62\xbd\x0b\x29\x12\x62\x95\xef\x5a\x30\x56\x83\xbf\x29\xeb\xab\xf0\xac\x91\x29\x0f\xec\x61\x98\xd9\x1a\xaa\x4b\x05\x8b\x02\xba\xef\x48\x1c\xd4\x71\x33\xbb\x04\x9a\x0a\x9e\xcd\x31\xf2\xd2\xc6\x52\xe4\x54\xdd\x42\x6a\xbf\x70\xa2\x59\xf0\x54\x98\x19\xc3\xa3\x6e\xcc\xba\xbd\x5b\x02\x45\x32\x1b\xe1\x81\xee\x0c\x48\x9f\x78\xd7\x5b\x1c\x42\x03\x94\xf7\x3c\x9b\x7f\x10\x42\x7f\x15\xd2\x68\x3b\xc1\x80\x1f\x9c\xb4\xdc\x34\x45\xa3\x38\x49\xf1\xb9\x7d\xdc\x0d\x3c\x54\xf5\x0c\xde\xf3\x6a\xc7\x9f\xfb\x91\x92\x25\x3f\x55\x5f\x4b\x51\xee\xcc\xc4\x96\x84\xcd\xaf\x2f\xcf\x91\x14\x95\xce\x55\xc9\xb5\x9c\x63\xe9\x80\xe5\xfa\x6f\x41\x31\xf8\xce\x39\x5b\xeb\x67\xa2\xf2\x8b\x91\x77\x74\x4e\x68\xa6\x84\x87\x25\xe3\x2b\xb5\x50\xa7\xe2\x9a\x9f\x47\x42\x4f\x97\x74\x5b\x73\xa0\x96\xef\xeb\xd5\x3c\x97\x55\x41\x3a\xc6\x97\x6e\xd7\xf4\x16\x14\x29\x24\x24\x90\x02\x4f\x9e\x7a\xdb\x9f\xda\xe1\x87\xa8\x73\x25\xb8\x39\x98\x9d\x20\xcf\x65\xf0\xf4\x3a\x90\xd6\x51\x05\x7d\xc6\x4e\xfb\xa3\xe8\x39\xc6\x63\x59\x2a\x90\xd6\xcd\x2d\x4b\xb0\x3b\xf9\x6d\x39\x82\xcc\x40\xde\xa8\xa4\xae\x67\xbc\x35\x67\xb0\x9c\x4e\x80\x50\x1d\x30\x4d\x0b\x02\x5c\x19\x8a\x69\x0d\xa0\x9a\xa4\x02\xaa\xec\x7b\xaa\xc8\x77\x97\xe7\xe4\x15\x39\x32\xcf\x3a\x46\xfc\xc1\x96\xf2\x5a\xd8\x20\xb7\x45\x1d\x75\xec\xa7\xc0\x25\x21\xf2\x12\x21\x2d\x91\xe8\x11\x2e\x88\x2a\x93\x69\xbd\x8f\xbd\x57\x9b\x5d\x20\x24\xba\x56\xf6\x13\xd7\x9f\x96\x42\x7d\xa7\x40\x76\x46\xa0\xbe\xdb\x81\x40\xd5\xc5\x28\x83\x73\x4d\xe8\x59\xc4\xca\x41\xd3\x94\x6a\xea\x08\x97\xbf\x60\x6f\xb7\xf4\xf3\x26\x5f\x0a\xde\x32\x5e\xde\xdb\xc0\xa3\xee\x4c\x2d\xd7\x17\x38\x2d\x49\x3c\xd4\x71\xd7\x69\x51\x64\xcc\x56\xdb\x58\x08\x84\xbb\x6c\xe0\x4a\x6f\x8d\x98\x88\x74\x82\x66\x99\x30\xf4\xd1\x08\x27\x94\xa7\x22\x5f\x7a\x98\x11\x22\xa1\x51\x39\x75\x40\x22\xf6\x35\xc7\x9e\x18\x85\x32\x98\x41\x8b\xda\x62\x8b\x95\x62\xcd\x6c\x06\x38\x1e\x23\x70\x7a\x92\xd1\x11\x64\x16\xc6\x16\x03\xd5\x32\x06\x3e\x75\x34\xaa\x14\x59\x77\xe9\x33\x1f\x44\x06\x36\xbc\xcb\x03\xc2\x4c\xff\x2c\xe0\x80\x93\x74\x05\x07\xd4\x06\x1b\x70\x40\xbd\xf6\x39\xc0\xa1\x6c\xc1\xea\xc9\x22\x1c\x8c\xdc\xd0\x84\x03\x32\xef\x7d\x87\x83\x82\x24\x11\x79\x31\x94\xc2\xa8\x9d\x9d\xf1\x26\x37\x6d\xe5\x33\xb4\x86\x8d\x15\xc1\x58\xc8\x0b\x9a\x17\x53\x59\x0b\xec\xa4\xda\x32\x09\x1f\xdd\xf9\xbf\x6a\x3c\x0b\x49\xcf\x22\x23\xf3\xb3\x34\xdc\x8b\xe6\x4e\xf7\xc3\x73\x66\x07\x5d\xe4\x46\xb4\x30\x76\x76\xc2\x8d\x44\x42\x33\xac\x1d\xdb\x0e\xe5\xc8\x22\xda\x2d\x4e\x5c\x0b\xe7\x45\x1f\x25\x7e\xe7\x03\x48\xb0\x8c\x28\x7e\xe3\x4c\x98\x5c\xa4\x50\xf3\x65\xdb\x38\xe4\x1b\x1b\xf6\x89\xd7\xf9\x48\x62\x23\x57\x78\xb7\x72\xda\xb8\x5b\x0b\x57\x01\xed\x5d\xa8\x48\x6b\x16\x08\x3c\x65\x7c\x82\x76\xb5\x1e\x91\x90\xd9\x18\x64\x47\x04\x6e\xad\x06\x79\x88\x47\xc2\x4f\xea\xcf\x83\x7f\x34\xca\x62\x4c\x70\x37\x33\x5a\x8a\xbc\x84\x35\xb6\xe4\x96\x29\x72\xf0\xd6\x03\xa0\x45\x09\xcf\x7d\xe4\x30\x07\xf6\x0d\xc3\x6e\x5a\x4b\xe7\x2d\xe3\xa9\x0b\xd7\x6d\x00\x2b\xd4\x80\xb7\x72\x30\x06\x82\xb3\xb4\x4e\x5b\xde\x90\x9f\x38\x09\xc0\x22\xfd\x9d\xd1\xe3\x83\x15\x99\xbd\x8d\xae\xff\xb0\xe1\x35\x3c\x64\x71\x9a\xef\x38\xee\xbd\x79\x6e\xdf\x68\xee\xcb\xd7\xf9\x77\x79\xd2\xd2\x3d\x8e\xfa\x75\xad\xc5\xfc\x60\xa7\xf5\x22\x7d\x62\xd0\x5a\x33\x3e\x51\x75\x4d\x86\x66\x59\xc3\x18\xbe\x4a\x95\xf1\x3b\x1c\x2a\xfe\x2f\xab\x10\x0b\x69\x06\xcf\x45\x0d\xc9\x8c\x38\xf1\xcc\x95\x90\x49\xae\xe8\x99\x34\x90\xd0\x8c\x66\xd7\xc5\xee\x25\x4a\xc9\x52\x39\xbc\x77\xd7\xa7\xcd\xa9\x91\x59\x63\x43\x0a\xb3\x57\xe6\x77\x42\xd3\x9c\x29\x85\x86\x30\x18\x4d\x85\xb8\x25\x47\x0f\x76\x6a\xe8\x2b\x36\x51\x27\x0e\xe7\xfb\x66\xf5\xc7\x84\xf1\x2c\x44\x45\xa1\x1e\xcc\xb5\xf2\x86\x1c\x7c\x48\x12\x56\x81\x7b\xe8\xea\x56\xbb\x60\x85\xe5\x65\xda\x4a\xd5\x06\x0b\x9e\x9c\x60\x2f\x6f\xcf\x55\xcb\xb2\x2b\x8f\x6c\xd1\x95\xc3\xed\xc5\xca\x6a\x2b\xe1\x68\xa5\xc7\x27\x07\x92\x13\x2e\x12\x50\xdd\x15\x74\xfa\xa6\x9a\x93\xa4\x60\xb3\x78\x00\xa3\x9f\xe8\xda\x20\x3b\xb4\x4b\x1f\x62\x32\xa8\xbb\xf5\xb0\x2e\x51\xdf\x54\xc4\xc5\xe8\x23\x59\x31\xa5\x7d\xab\xa4\x1b\x8a\x86\x24\xd0\x8b\x10\x53\xc1\x85\x4b\x92\x30\x4c\x54\x70\x44\x69\x24\x51\xd6\x9b\x87\x7b\xe2\x48\x74\x6d\xa9\x67\x95\x97\xb8\xee\x08\xc4\x64\x32\x1d\x5a\xab\xd8\x35\xdc\x31\x3d\xc5\x3a\xaf\xd3\x05\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\x4f\x87\xaa\xee\xa8\xae\x4a\xc1\x63\xbc\xa2\xc1\x26\x18\x8f\x21\x41\x41\xab\x0e\x60\x4b\xb5\x8f\xaa\xc2\xb7\x2e\xcb\xc0\x20\x98\x2b\x25\x9f\xb3\x7b\xf3\x94\xfa\x5d\x75\x97\xb8\x2b\x38\xbb\xfa\xe7\xe3\x01\x21\x97\x3c\x44\xf0\xf6\xcc\x2e\xd6\xaf\xf4\xa1\x67\xda\xbc\x62\xbd\x0f\x01\xbe\x40\xdd\x70\x66\xa4\x43\x59\x76\x80\xf1\x6d\xcc\xe1\xa4\x6e\x12\xef\x94\x1c\xa0\x69\xdc\x4d\x6a\xb6\xde\xcb\x00\x6d\x4c\xe5\xe6\x92\x8f\x65\x2e\x7f\x1e\x0e\x10\xd2\x96\xce\xb9\x6a\x0a\x1d\x15\x87\xbf\xae\xcd\x56\x93\xde\x83\xc3\x6d\x28\x52\x5b\x4d\x25\x54\x83\xc8\xe6\xbe\xba\x0b\xfb\xb7\x97\xcf\x2a\x19\x8f\x0b\x9b\x1d\x50\x2f\xb3\xe2\x4a\x6a\xa7\xc4\x88\xda\x99\xb7\x2d\xe4\x45\x06\x98\xc5\x59\x9b\xb9\x4a\x50\xad\x55\x93\xef\x85\x85\x54\x05\xe9\x5d\x71\x97\x1e\xf9\x1f\x3c\x94\x21\x10\xd5\xd7\x9d\x18\x86\xdb\xad\x86\xc8\x94\x6f\x2d\x81\x19\x96\x5a\x78\xd3\x05\x49\xd9\x78\x0c\x3e\xe0\xd5\x68\x8e\x54\xd2\xdc\x90\x78\x45\x1c\x08\x46\x30\x61\x36\x20\x32\x10\xb6\x43\x23\xee\xb9\x5c\xbf\x9e\x25\x86\x4c\x93\x9c\x4d\xa6\x16\x51\x08\xc5\x0c\x5d\xe2\x9d\x8a\x99\xa0\x29\xb6\xa4\x22\x42\x92\x3b\x2a\x73\xc3\x37\x68\x32\x45\x0f\x25\xe5\x24\x2d\x25\x56\x59\xd6\x40\xd3\x79\x5f\x69\xaa\x8d\xa4\x0c\xd2\x29\x94\x7e\xfd\xb1\xa4\xfe\x83\x23\x96\xd4\xdf\x70\xc4\x92\xfa\xb1\xa4\xfe\xf2\xd8\x9b\xe8\xd0\x58\x52\xff\x65\x95\x49\x8a\x25\xf5\x9f\xda\x9b\x10\x4b\xea\xc7\x92\xfa\x0f\x8d\x58\x52\xff\x91\x11\x4b\xea\xef\x30\x5e\x00\xe5\x8a\x25\xf5\x77\x18\xb1\xa4\xfe\xea\x11\x4b\xea\x2f\x8f\x58\x52\x7f\xed\x88\x25\xf5\x77\x1e\xb1\xa4\x7e\x2c\xa9\x1f\x2b\x8d\x6e\x37\xd7\x7e\x56\x1a\x25\xb1\xa4\xbe\x1b\xb1\xa4\xfe\x8b\xa8\xa7\x48\x62\x49\xfd\x8d\x46\x2c\xa9\x1f\x4b\xea\xef\x32\x62\x49\xfd\x97\x62\x2e\x89\x25\xf5\x63\x49\xfd\xcf\x47\xd0\x8d\x25\xf5\x63\x49\xfd\x58\x52\x3f\x96\xd4\x7f\x70\x15\xb1\xa4\xfe\x4b\x50\x01\x95\x4e\xd9\x4e\x15\x40\x37\x29\x56\xe4\x82\xd0\x6b\xb5\x01\x46\xe5\x78\x0c\x12\x29\x17\x3e\x79\x29\x78\xaa\xaa\xcb\xb8\xe8\x64\x05\xdd\xc3\xba\x47\x2e\x5f\x67\xcd\xed\xae\x18\x01\x56\xea\xac\x22\xc5\x2f\xde\x7f\xb5\xa2\x32\xd2\xce\x51\x85\xbb\xc6\x48\xe3\x9a\xdf\xf3\xdd\xfc\xe3\x6b\x00\xbe\x2a\x7f\xcc\xc1\x3d\xc9\x84\x72\x11\xee\x08\xac\x64\x4a\x39\x07\xaf\xef\x31\x8d\x76\x94\x11\x00\x27\xa2\x00\xe7\x9d\xa6\x44\x31\x3e\xc9\x80\x50\xad\x69\x32\x1d\x98\x27\x71\x0f\xec\x2a\x1a\xdd\x7d\xa3\xb4\x04\x9a\xfb\xb8\xfc\x9c\x32\x3b\x15\xa1\x89\x14\x4a\x91\xbc\xcc\x34\x2b\xc2\x64\x44\x01\x26\xd4\x58\x46\x15\x80\x81\x51\x71\x55\x08\x7b\xaf\x7a\x9a\x5b\x96\xa8\x97\xa6\x43\x6d\xb3\x87\xf5\xc0\xf3\x42\xcf\x43\x1c\x2f\x90\x31\x93\x4a\x93\x24\x63\xc8\xad\xf1\x89\x36\x77\x1a\xe7\xeb\x79\x5e\xcd\xdd\x4a\x95\x5b\x2a\x4f\x51\x6c\x2d\xb4\xb2\x51\xb1\xd5\x84\x6e\xaa\x94\x29\x27\xe6\xab\x1e\xa1\xbe\x6e\x9a\x05\xb4\x5f\x29\x82\xda\x73\x16\x3b\xbb\xfb\xaa\x36\x5d\xad\x5e\x6c\x15\x36\x5c\x21\x3a\xa6\x38\x78\xe4\xec\x35\xb2\x39\x2a\x81\x02\xa3\xf4\x96\x8e\x01\x6e\x00\x87\x99\xc1\x01\x48\xc0\xf0\x57\xba\x06\xeb\x3f\x39\xd2\xd7\x98\xe2\x3b\x50\x8a\x4e\x60\xb8\xa3\xa3\x61\x9d\x46\x86\xbe\x86\x6a\x63\x10\x15\x32\x9b\x5d\x1b\xbe\xa9\xa2\x33\x9b\x62\x10\xc9\xed\x9a\x82\xf0\x73\x27\x99\xd6\x80\x9b\x8a\x15\xf6\xd0\x57\xb9\x98\x80\x7f\xb8\x10\xe3\xf9\xce\x4f\x52\xdd\x6c\x88\x3a\x4f\x6d\xc4\xe5\x08\xc8\x48\x32\x18\x93\x31\xc3\x30\x4e\x0c\xac\xec\xd9\x82\x4b\xd4\x5a\x01\x94\x32\xfa\xae\xe0\x5e\x96\xf5\xeb\x1a\x90\x1f\xdc\xc2\xb4\x2c\x79\x42\x6b\xb5\x6c\x31\xc3\x94\x8d\xc9\x04\x03\x33\x9d\xb4\xf8\xa7\x57\x7f\xfb\x0b\x19\xcd\x0d\x4b\x43\xc9\x4a\x0b\x4d\xb3\xf0\x92\x19\xf0\x89\x81\x95\x3d\x9e\xcd\x1c\xc9\x00\x01\xec\xe6\x61\x17\xfe\xfa\x0f\xb7\xa3\x26\x8f\x3d\x49\x61\x76\x52\x83\x5f\x3f\x13\x93\x55\xfd\x51\x76\x0f\xd9\xde\x51\x25\x5a\x81\x66\x22\x63\xc9\xbc\x35\xa2\xf9\xca\x5f\x64\x2a\xee\xac\xac\xbf\x02\x7b\xaa\x74\xab\x42\x14\x65\x66\x8d\xce\x5f\x85\xec\xe2\x52\xc1\x72\x0e\xe0\xca\x73\x81\x66\x52\x37\xc5\x62\xdd\x74\x1b\x8f\xeb\x1f\x29\x5c\x6e\x89\x33\xe4\x85\x02\x60\xa8\x08\x7d\x45\xb3\x6c\x44\x93\xdb\x1b\xf1\x56\x4c\xd4\x7b\x7e\x21\xa5\x90\xcd\xb5\x64\xd4\x50\xcb\x69\xc9\x6f\x6d\x07\x87\x50\x22\x41\x4c\x8c\x68\x55\x94\xda\x27\x32\xac\x7a\x61\x9b\x2f\xef\x89\xb0\x57\x83\xaa\x59\xe0\x9e\x55\xba\x8e\x4b\xd5\xb2\x18\x59\x9f\x5f\xd5\x91\xed\x0f\xaf\xfe\xf4\x57\x8b\xba\x44\x48\xf2\xd7\x57\x18\xb3\xad\x7a\xf6\x10\x23\x6d\x33\x8c\x22\xa7\x59\x66\xd4\x86\x3a\x52\x1a\x40\xaf\x42\xc2\x4f\x8e\x83\xba\x3d\xba\x6d\x2c\x4a\xdd\xdc\xfc\x03\xe5\x28\xa6\x15\x64\xe3\x9e\xcd\x4a\x0a\x6a\xcd\x21\x32\x86\x43\x47\x7d\x30\x35\x6c\x0f\x04\xa0\x99\xc8\xca\x1c\xce\x61\xc6\xba\x68\xe2\xd4\x98\xcd\xab\xfa\x19\x53\x98\x00\x36\xca\x44\x72\x4b\x52\xf7\x63\x2d\xf2\x64\xb1\x12\xf8\xee\x50\xd8\x35\x06\xa7\x45\xec\xcd\xda\xf7\x6f\x44\xdd\xe4\xb4\x28\x42\x8e\x90\xa4\x77\x0d\x60\xe0\x99\xc4\x72\x05\x2d\xeb\xc9\xb4\x36\x33\xb7\x35\x32\xf7\xdd\x1b\x19\xba\xb9\xf3\x14\x3b\x47\x9d\xb4\xb7\x51\x57\xab\xdf\xdd\x30\xd9\x40\x88\x6a\x42\x7f\x1a\x0a\xfc\xdb\x66\x95\x2c\x65\x45\x86\xc4\xba\x80\x18\x56\x00\x30\xe8\x83\x24\x79\x77\x83\x6b\x07\xd6\xcd\x76\x21\x47\x0d\xb8\xf0\x60\x55\xce\xa9\x76\x02\xa1\x37\x5f\x53\x52\x80\x54\x4c\x19\xbe\xfc\x3d\x1e\xa8\xb3\x8c\xb2\xbc\x66\x02\x7c\x1a\x20\xd8\xc3\x8d\xe5\x93\xdb\x53\xca\xa1\x48\xdd\x84\x48\x0a\x6d\xe9\xe8\x15\x62\x6d\x53\xaa\xed\x90\xa1\x3e\x35\xa9\xfc\xbe\x82\x66\x93\x52\x9a\x6f\x02\xa9\xb4\x57\xbd\x24\x02\x89\xef\xf7\x5c\xe9\x63\x58\x7c\x47\x64\x00\x09\xa3\xdb\xdc\x26\x25\x6c\x28\x8f\xf6\xa0\xd4\x44\x7a\xa7\x07\x0e\x88\xf5\x82\x9b\x33\xe1\x6e\x25\x87\x6f\x0e\x9f\x94\x48\x5a\x10\x49\x51\xd0\x49\xab\x5e\x3e\x0b\x90\x5a\x9c\xb6\x5e\x68\xc2\xa8\x41\xf8\x7b\x28\xbb\x86\x57\x41\x5a\xd5\xd1\xc1\x2a\x49\xd6\x3b\xea\x01\xec\x14\x04\x9b\x8f\x7d\x47\xe7\x84\x4a\x51\xf2\xd4\xd9\x97\x82\x81\xef\xdd\xc2\x83\xaf\x04\x07\x6f\x38\x5f\xac\x53\x81\x16\x7d\xc6\xc9\xeb\xc1\xeb\x57\x2f\x85\x53\xe1\x1b\x2e\x70\xaa\xab\xc0\xa9\x2c\x7d\x7a\xd2\x77\xf5\x15\xef\x3b\x7a\xdf\x77\xce\xc4\x52\x15\xb4\x67\xbe\x5c\x36\x7e\x75\x27\x99\x86\x5a\x8f\xbf\x23\x54\x5c\x8c\x7e\x58\xab\xca\x70\xbc\xaa\x93\x44\x4b\x20\xb5\x2b\x83\xa1\xca\xd1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x65\xe1\x52\x0f\x90\xb0\x3a\xa0\x0e\x0e\xc8\x91\xbd\xf2\xd0\x26\x34\x1f\x3f\x29\x6a\x39\xa0\x5d\xdc\x17\x2d\x6a\x6c\x2e\xe4\xce\x17\x14\x6d\x70\x45\x87\x10\xfc\x2f\x98\xd2\x19\x60\x22\x37\xcb\xa8\xcc\xd0\xe7\x78\x6d\xd7\x4e\x46\xa5\x26\xc0\x67\x4c\x0a\x9e\x03\xd7\x64\x46\x25\xc3\xaa\x38\x12\xb0\xb2\x83\xd1\x45\xbf\x38\xfa\xfe\xf4\x03\x06\x34\x1c\xbb\x92\x14\x6e\x95\xa5\xf2\xe5\x6b\xea\x2b\xa9\x4d\xf7\xe8\xf6\xf9\x75\x18\x18\x22\xcd\xf5\xeb\x32\xcf\xc9\x4b\x5d\xda\xb6\x2c\xf7\x49\x56\x2a\x36\x7b\x2a\x4a\xe2\x32\xec\xcf\xd9\x4e\xfb\xbc\x90\xed\x5f\x01\x6a\x29\x71\x1f\x4d\xeb\x2b\x12\xf4\x96\x1c\x26\x87\x2a\x24\xed\xd5\x7d\xe0\xce\xf4\xe4\x6a\x69\xd8\xf0\x39\x5f\x71\x71\x49\x84\xc0\xba\x31\x4f\x6b\x84\x4a\xb9\x3a\xc3\x15\x6e\x07\xd6\x66\x40\x72\x23\x8f\xef\xfc\xea\xba\x5e\x84\xc4\xaa\x4b\x22\x1d\x90\x61\xf5\x65\x55\xa9\x06\xeb\xa7\x05\x25\x12\xe4\xa4\x2a\x2a\x3e\x01\x0e\x12\x85\x04\x33\x65\xa3\xad\x2a\x19\x51\x65\x9d\x3c\xe7\x57\xd7\xd6\x66\xbb\x1d\xcc\x76\x16\xb3\x77\x97\x50\x0d\xc7\xb7\x69\x0c\x3b\x08\xb7\xcd\x9e\x69\xc1\x60\x65\x00\x83\x4a\xa9\x9d\x98\x5c\x0e\x09\x4d\x53\x89\x6e\x1f\x27\xfa\xd4\x2a\x55\x06\xdf\x02\x56\x85\xa1\x0a\xea\x6b\xaa\x81\x1b\x49\x5c\x05\x58\x72\x5e\x16\x19\xb3\x6e\x84\xfa\x0d\x55\x35\x1b\x6c\xf2\xb5\x3d\xd2\xb6\x51\xf3\x76\x56\xf2\x5a\x50\x21\xb1\x6b\x51\xca\x07\x76\x4f\x82\x12\xd9\xac\x2a\x28\xbc\xb0\x6b\xee\x44\xa0\x49\x3c\xec\x9a\xaf\x41\xb9\xd1\x8e\x01\xd7\xd2\x1c\xcd\xc5\xdd\xc2\x2e\xf6\x59\x89\xa7\x29\x4c\xc8\x66\x80\xfe\x71\x57\x7e\xd3\x95\x71\xab\x4a\x1c\x5b\xdf\xb0\xad\x32\x0d\x54\x7a\x8a\x86\xab\xda\xf1\x24\x92\xa7\x42\x84\x45\x63\xc7\xf9\xd5\xb5\xa5\x84\xf6\xe5\x43\x77\xda\x55\xbb\x54\x51\xb5\x9d\x31\xf0\xc9\xaa\x0c\xb5\xd1\x3c\x16\x9a\xfb\xb9\x76\xdd\xad\x02\x59\x5a\x88\x7f\xad\x92\xed\x5a\x3c\x5d\x01\x95\xc9\x74\x17\xf8\x3f\x40\x08\xec\xa4\x24\x15\x36\x12\x60\x2c\x24\xaa\xc4\x7d\x24\xef\x99\x10\xb7\x65\xb1\x09\x45\x77\xd3\xd8\x86\x6b\x1b\x11\x88\xc6\x1d\x9f\x15\x4d\x4f\xb9\xda\xc5\xdf\xdb\x94\x7d\x40\x5b\x89\x07\x27\xaa\x12\x28\xc4\xa2\xde\x74\x96\x95\x4a\x83\xfc\x8a\x49\xa5\x0f\x7c\xbd\x68\xc4\x60\x6b\x13\x39\xac\x5f\xf0\x03\xd3\x53\x57\xba\xf1\xb0\xd7\xfc\xc9\x7c\x76\x13\x1f\x1a\x9d\xf6\xf0\x4a\x70\x38\x1c\x2c\x8a\x5d\x81\x94\x07\xb2\xb6\x96\xa7\xb8\xa5\x2b\xc8\x6c\xbc\x28\xfe\x50\xc3\x95\x1b\x57\xb6\xd2\x3c\xc1\xd3\x3f\x05\x9a\x50\x2c\x11\x87\x57\x4f\xab\x32\x93\xb6\x6e\x94\xad\x93\x29\x9c\xa0\x37\xaf\x83\xa8\x56\x4a\x4a\x8b\xf5\xaf\xbd\x8b\x3c\xb7\x35\x06\xd8\xf2\xa3\xae\x5e\xc8\x5b\xc6\x6f\xb7\x44\xbf\x66\x74\xc9\xc5\xd2\x6c\x8d\x7a\xe2\xd6\x47\xcb\xb8\x0d\xbe\x33\x2c\x86\x8e\x44\xa9\x7d\x4d\x12\x55\x53\x1c\x19\xff\x1f\xbb\x17\x68\x6f\x2f\x6c\xc5\xbe\x55\x3a\xa2\xea\x59\xa3\x8f\x57\x02\xd5\x9c\x6b\x8a\xb5\x45\xcf\x45\x72\x0b\x92\x64\x66\x19\x03\x52\x05\xbe\x34\xaa\x59\xca\x12\xb6\x8c\xba\xd8\xd5\xd2\x01\xc5\x14\x72\x90\x34\xab\x8a\xba\xb6\x00\xf5\x5b\x47\x38\xc3\xac\xf5\x98\x14\x5b\x14\xcd\x95\x61\x34\xe7\xf0\x62\xd5\x55\x39\x9d\xfb\x4a\xb7\x8c\x63\xb8\xc1\x3d\x53\x68\xd6\x2f\x44\x5a\x4f\x3c\x2b\x15\xc8\x7e\x48\x0b\x74\xb9\x37\x2a\x04\xe2\xa4\x30\x2a\x27\x13\xc6\x27\x8e\x3a\x23\x4d\xaf\x95\xdb\x0e\x9a\x0e\x46\x7a\x27\x12\x6c\xc1\x59\x94\x1e\x6c\x7c\x19\xab\x5f\x9f\x8b\xd4\x5e\x3e\x9a\x5b\x6d\xd0\xef\x6c\x15\x20\x7d\xc9\x89\x90\xae\x34\x02\x4d\x53\x5c\xfb\xf2\x1b\xe2\xaf\xcd\xb7\xea\x85\x38\x0e\x1b\xd9\x1d\xee\xaa\x81\x45\x95\x23\x23\xec\x94\x72\xdb\x0a\xa1\xbb\x12\xfe\x9d\x88\x7e\xb3\xde\xcf\x29\xaf\xb6\xf8\xac\x1e\x30\x47\x89\x86\xbc\x10\x92\xca\xf9\xa2\x0b\xd3\x10\x29\x83\x02\x06\x80\x0b\x90\x1a\x8a\x14\xe9\xf8\x8a\x8d\x9f\xd9\x4e\xbe\x2b\xf6\x7e\x25\x8e\x21\x15\xe4\x82\x78\x88\x1a\x7a\xad\x92\x29\xa4\x25\x46\x8f\x4f\x4a\x8a\x9d\xc6\xcd\x29\x76\xc6\xee\xb9\x0b\xcb\xb3\xc8\x10\x02\xfe\x42\x9a\xc0\x1c\x83\x64\xb0\x0a\xa7\xf9\x06\xab\x79\xda\xd0\x40\xdb\x68\x19\x9b\xae\x86\x28\xc1\x9b\xaa\xf7\x03\xbe\x2c\xcc\x58\xa2\xfd\x4d\xe3\x75\x88\x93\xd0\xd0\xdf\x75\x28\x5c\xf5\xbf\x04\x0c\x31\xd2\xaa\x7a\x15\x17\x55\x82\xf5\x3d\x7f\xe2\x86\x49\xac\xc7\xc5\x0a\xf1\x1e\x41\x39\x94\xab\x9b\x5b\xf1\xc0\xf1\x0d\x50\x5a\xf1\xee\xdb\x16\x4b\x6a\x21\x94\xef\xee\x71\xdb\xc9\x53\xd6\x46\xfe\xa7\x72\xd2\x5e\x57\x3a\x3c\x95\x93\x32\xb7\x35\xbc\xc5\x42\x19\x65\x8b\x73\x68\xd7\x32\x2c\xeb\xec\xdd\x79\x3d\x85\xa1\x1e\x9b\xed\x13\x40\x8c\x28\xd4\xd2\xde\xb9\x68\xf0\xbc\x34\xca\x59\xb0\xa2\x56\xb4\xd5\x69\x71\xce\xa2\x17\x9e\xe6\xb5\x58\xc6\x0b\xc3\x8d\x51\x86\xa8\x6c\x7a\x3c\x99\x52\x3e\x41\x33\xb8\x28\xcd\x7c\x5f\x7c\x81\x2b\x92\x90\x96\x89\xeb\x1b\xe1\xe3\x9f\xbf\xf0\xd6\x3f\x57\xc2\x07\xdb\xd7\xa9\x84\x16\x7e\xcd\xf5\xd7\xb2\xac\xfa\x0d\x61\x03\x18\x90\x83\x2f\x6a\x3f\x1d\xd8\xa7\x17\x52\x98\x47\xb8\xd0\x69\x5c\x55\xc6\x34\x1e\x84\x83\xfa\xd5\x03\x72\x61\x9e\x81\x1e\x91\x00\xc0\x5a\x74\xef\xa8\x02\x5f\x8f\x48\x98\x50\x99\x66\x98\x71\x37\x0e\x42\x89\xcd\xcb\x71\x00\xc3\xd3\x87\xf1\x74\x5c\xe8\x55\xd6\xc9\x0d\xd3\x22\x34\x55\xb7\xea\xc4\x8a\x32\xfd\x94\x6a\xda\xc7\x5e\x1b\x96\x68\x9c\x58\xf5\xba\xef\xaa\x9c\xf6\xa9\xc3\xa9\x7e\xd8\xd6\x93\xdf\xba\xcc\xaa\x3e\x0d\x57\x31\xde\xa7\x7d\xac\x37\xba\x7b\xac\xe8\x13\x84\x15\xb4\xd2\x74\x5b\x14\xbb\x5d\x14\x4f\x43\xb1\x73\x84\x01\xb6\x0a\xa9\x8a\x5b\x87\x08\x06\x57\xcf\xb5\x71\x90\x2f\xae\x6e\x3e\xfc\x63\xf8\xfe\xf2\xea\x26\x9e\xe7\x78\x9e\xe3\x79\x6e\x71\x9e\x81\xcf\x5a\x9f\xe5\xa0\xff\xac\x52\x09\x17\x8a\xcb\xd5\x32\xaa\x5f\x50\x70\xd6\x05\x9f\x7d\x4f\x8d\xc0\x57\x48\x50\x28\x8b\x18\xb9\x71\x95\x17\xd5\x5d\x60\xbb\x6d\x9d\x3d\xfb\xe8\xac\x27\x8c\xad\xea\x30\x66\xe5\xaa\x56\x08\x60\xd5\xae\xd5\xdb\xdb\x9d\xfd\x72\x79\x7e\x71\x75\x73\xf9\xd5\xe5\xc5\x87\x27\x0d\x36\x68\x59\xdc\xad\xc9\x8d\x77\xe4\x92\x85\x84\x19\x13\xa5\xca\xe6\xa1\x3e\xec\x6a\x22\xb0\x1c\xaf\xc6\x8d\x7a\x36\x0f\x25\x70\x57\xde\x16\x99\x6d\xb7\xcc\xb6\x19\x7b\xd1\xa2\xae\x47\x57\xe8\xfb\x95\x14\x79\x47\x28\x7c\x6d\x55\x76\x6f\xf2\x5e\x85\x4f\x87\xae\x04\x40\x83\xf5\x38\xe1\xb1\xaa\x37\x60\xa4\xd0\xbc\xd0\x2d\x8a\xff\x77\x52\xce\xb3\x9b\xca\x97\x36\x4e\xe1\x1d\x2d\xbe\x85\xf9\x07\x68\x59\x3e\x64\xc1\xd5\x90\x41\x62\x18\x1d\xb9\x85\xb9\xf5\x40\x9e\xf9\x87\xb5\x29\x73\xb2\x97\xd5\x50\x6f\xa1\x4d\xa5\xda\x2e\xcb\x98\xde\x42\x8b\xc0\x45\x3f\x96\x0a\x7a\x9a\x2d\x44\x39\xcd\xec\x69\xbb\xdd\x23\xdd\x96\x30\xfd\x08\x65\x5b\x0f\xeb\xec\xde\xd1\x59\xbd\x75\x75\x05\x31\x33\x9c\x0b\xee\x4e\x5c\xd0\x56\xdf\x68\xac\x7d\x8b\xb5\xea\x04\x23\x53\x4e\x7e\x8b\xff\x90\x9b\xf7\xe7\xef\xdf\x90\xd3\x34\x75\xc1\xc3\xa5\x82\x71\x99\xd9\x30\x60\x35\x20\xb4\x60\xdf\x83\x54\xd8\x3d\xed\x96\xf1\xb4\x47\x4a\x96\x7e\xd9\xa6\xe8\x92\x1d\x1d\xee\x82\xf0\x0e\x9b\x6e\x77\xe2\xda\xf9\xe3\xea\xbc\x2b\x10\x11\x62\x33\x03\x11\x37\x7d\xfd\x15\x27\x64\x74\x04\x9a\xb6\x8d\xe2\x88\xdd\xc2\x6e\xe9\xea\x61\x45\x58\x6d\x9c\x78\x28\x50\x95\xbe\x21\xaa\xc4\x42\x31\x2a\x74\x77\xc3\x7e\xa9\xbd\xe6\x47\x55\xd0\x04\x7a\xe4\x9f\xe1\x4b\xec\xc7\xae\x7e\x3c\x3c\xfc\xfb\xb7\x17\xff\xf8\xcf\xc3\xc3\x9f\xff\x59\xff\x15\x59\x21\x6a\xcd\x0b\x97\xa0\x7f\x87\x8b\x14\xae\xf0\x19\xf8\xd1\x89\x6b\xa7\x49\x22\x4a\xae\xdd\x0f\x98\xd5\x3b\x98\x0a\xa5\x2f\x87\xe1\x63\x21\xd2\xc5\x4f\xaa\x55\x25\xb1\xbd\x64\x0c\xb8\x45\x2d\xb2\x53\xec\xe8\x8e\x3d\x54\xb4\xa4\xe3\xa3\xea\x66\x0d\x9d\x2b\x92\x29\xe4\xb6\x96\xd1\x57\x1e\x04\xd8\x81\xd6\x97\x0f\xe0\x98\x73\x6d\x24\xd3\x66\x59\xb9\x83\xd9\xeb\x56\xad\xba\xed\xe8\x90\xb4\x85\x1d\xec\x18\x60\x08\x11\x07\x2d\x7b\x90\x03\x83\xf5\x5a\x4a\xe5\x8d\x3d\x1d\x5e\x92\x99\x85\xf0\xde\x00\xc7\x7b\xc1\xbe\xfa\xa8\x34\xae\xee\x6b\x6b\x68\x88\x6f\x6c\xc3\x56\xff\xbb\xcb\xb3\x57\xa1\xf4\x15\x18\xc5\xe6\xc8\x7e\x39\x48\x8a\xb2\xe7\x2e\x18\xe4\x90\x0b\x39\x0f\x1f\x83\x8f\xaf\xaf\xb4\x90\x74\x82\x79\x19\xf6\x76\x7b\x5b\xf8\x64\x6f\x6c\x3c\x60\xf9\x6e\xab\x0a\x27\xa5\x34\x42\x43\x36\xf7\x14\x79\xc7\x7a\x11\xd5\xd8\x43\xda\xe6\x41\xbf\x27\xa4\x2d\x60\x46\xdb\xb6\xac\x76\x34\x11\xb2\x72\xd4\xa3\xc0\x19\xa0\x88\xfa\xa4\xcb\x3b\xed\x05\x31\xc8\x5a\x03\xf8\xcc\x68\x96\x3b\x57\xce\xaa\x46\x87\xd4\x2c\x65\x33\xa6\x44\x8b\xec\x93\x30\xd1\xfa\x90\x7a\x57\xfa\xc2\x06\x0e\x05\xb3\xd9\x7d\x81\xc5\x82\xc2\x79\x5d\x20\xfb\xaf\xdb\xf4\x0b\xb2\xa3\xa0\x5a\x83\xe4\x6f\xc8\x7f\x1f\xfd\xf4\xfb\x5f\xfb\xc7\x5f\x1e\x1d\xfd\xf8\xaa\xff\xb7\x9f\x7f\x7f\xf4\xd3\x00\xff\xf8\xdd\xf1\x97\xc7\xbf\xfa\x0f\xbf\x3f\x3e\x3e\x3a\xfa\xf1\xdb\x77\x5f\xdf\x0c\x2f\x7e\x66\xc7\xbf\xfe\xc8\xcb\xfc\xd6\x7e\xfa\xf5\xe8\x47\xb8\xf8\x79\xc3\x49\x8e\x8f\xbf\xfc\xa2\xf5\xd2\x3b\xa8\xdd\x69\x47\x97\x15\x3c\x9b\x33\x76\x82\x7e\x1f\xb1\x6c\xbd\x1d\x1e\xbd\xba\x3e\xff\x3e\x7a\xf8\x4d\xc5\x90\x02\xbb\xde\x9b\x03\xae\x20\x91\xa0\x3f\x85\x25\xc7\x3e\xa9\x56\x41\xe0\x50\x91\xa0\x5a\xbc\x34\x3e\xf7\x39\x18\x77\x42\xc3\x39\xdc\xd7\x4a\x12\x1d\x4b\x91\xfb\xac\x70\x74\x6f\x60\x17\x7a\x7f\xdd\x2d\xb4\x6a\x81\x6a\x47\x34\x06\x45\x63\xd0\x9a\xf1\xa8\x31\xe8\xda\xe2\xe1\xde\x5a\x82\x80\xcf\x76\x75\x61\xac\xf4\xa0\x7b\x5d\xa7\x5e\x42\x6d\x33\x87\xda\xc0\x1f\xf5\xaa\x53\x63\x15\x42\x63\x19\x5a\xbe\xda\x87\x49\x4e\xb1\x23\xb3\x3d\xf8\x38\x41\x95\x76\x61\x55\x1b\x57\xe1\x0f\x66\x66\x09\xa1\x44\x74\xa3\x18\x24\x06\x3a\x62\xe8\xe9\x0f\x36\x12\xf4\xd6\x06\x87\x1a\x25\x8d\xf1\xaa\x8c\x66\x10\x0e\xab\xda\xcb\x54\x29\x91\xd8\xa0\xd6\x90\x04\x80\x95\xdd\xdc\xb2\x71\x35\xd8\x06\xbe\x90\x90\x40\x0a\x3c\x01\x57\x97\xb9\xd1\x95\x92\x72\x72\xc1\x67\xbe\x36\x75\xea\x53\x4a\x70\x25\xab\xe7\x78\x59\x01\x08\x06\x11\x9d\x13\xac\x16\x87\x80\x54\xbf\x8a\x66\xc5\x50\x0c\x31\xae\xac\xac\xbb\x35\xae\x6b\xcd\xc5\xdb\xf3\xcc\xe0\xd9\x6a\x25\x0c\x2d\x31\xcb\xca\xfc\xdc\x64\x92\x2f\xc1\x19\xd8\x9e\x7d\x7e\x76\xac\xb3\x23\xb6\xd9\x0d\xcb\xdc\xc2\x77\xd2\x25\x9b\xec\xc2\x59\x52\x48\x18\xb3\xfb\x8e\xce\xe9\x29\xaf\x2c\x31\x2c\x05\xae\xd9\x98\xd9\x14\x93\x42\x42\x01\xdc\x66\x09\xd0\x64\x8a\xb4\xdf\x71\xca\xca\x39\xbd\x8f\xc1\x3c\x56\xe0\xee\x96\x94\x5d\xaf\x12\xf6\x23\x1d\x23\x91\x8e\xed\x3c\x3e\x11\x1d\x73\x98\xbb\x3f\x44\x0c\x23\xcf\xdb\xc7\xbc\x9f\x35\x6b\xad\x20\x22\x6f\x8d\x68\x55\xda\xd1\x09\xce\xb2\x93\x01\xba\x15\x3e\xe0\x63\x87\x65\x96\x75\x54\x9f\xfa\xf0\x12\xa1\x51\x94\x59\xe6\xd2\x72\x07\xe4\x3d\xc7\x23\x79\x8a\x7d\x10\x7a\xe4\x0a\x66\x20\x7b\xe4\x72\x7c\x25\xf4\xd0\xca\xb6\xcd\x70\x36\x7b\x21\x61\x63\xf2\xc6\x68\x4d\x4a\x13\x6d\x6b\xd1\xd7\x2a\xe7\x08\xd9\x98\xa0\x2a\xca\xd5\x22\x0c\x7d\xfd\xb6\xfc\xd6\x27\x4c\xf6\x9f\x68\x9b\x42\xb3\x8f\x0e\xd4\x53\x37\x93\x0f\x90\xc3\xa0\x48\xe7\x1d\x59\x95\xf5\xfa\x0c\x0b\x51\x14\x42\xe9\x6b\xa3\xc5\x76\xd3\x08\x66\xe8\xa7\xc3\xde\x0a\x34\xcb\x20\x6d\x74\x02\xb2\x1d\x2c\x68\x53\x8b\xc6\x7c\xdc\xd0\x50\x01\xc8\x94\xf2\x34\x03\x89\x45\xd1\xd5\x62\xe5\x27\x56\x75\x01\x08\x7d\x1b\x7c\x82\x26\x4d\x12\x21\x53\xd7\x81\xd5\x25\x4a\xe2\x62\xc2\xf1\x42\x5a\x9b\x53\x4e\x27\x80\x96\x85\xa5\xd2\xba\x58\x70\x59\xd5\x9a\x3f\x4c\x85\xb8\x25\x89\xc8\x8b\x0c\x0f\x40\x8b\xf3\x51\xf5\x9e\x09\x28\xda\x37\xb3\xab\x93\x5a\x5b\x1a\xfc\xa2\x5d\x57\x9a\x56\xc2\x4a\x17\xa2\x0a\xdc\x43\xd2\x59\xdf\xba\x8b\x7b\x48\x6a\x8d\x17\xcd\x96\xb8\xce\x8b\x5a\xa0\x6d\xa3\x7d\x3f\xdd\xd6\x66\xf9\xae\x4c\xe1\x2d\xb2\xcc\xea\x63\xa1\xd0\x1a\xce\xe9\xeb\x4a\xbb\x47\x60\x89\x7e\x9b\x55\x8c\x99\x67\xbe\xd4\x74\xe3\x30\xd8\xa3\xb7\x54\x9d\x2d\x04\x1b\xfb\xb9\x30\xf7\x59\x08\x4d\x8e\x0e\x4f\x0e\x8f\x97\x6c\x74\x0b\xc5\x89\x6f\x6a\x77\x32\xac\xc6\x57\x60\x69\x3b\x48\x0e\xd3\x1e\x61\xda\x13\x5b\x5b\x14\x00\x57\xe5\xd2\xe1\x7a\x44\x09\xa2\x25\x4d\x99\xd3\x82\xf0\x5b\x73\x91\x96\xa5\xab\x08\x70\x74\xf8\xeb\x61\x8f\x80\x4e\x8e\xc9\x9d\xe0\x87\x1a\x97\x8f\xe5\x33\x4a\x55\x9b\x68\x2e\x4a\xec\x52\x67\x41\x10\x6a\x61\x18\x8a\x45\x44\x69\x5b\xda\x4c\xa9\xf6\x69\x78\x17\xf7\x4c\xfb\x36\x0e\x62\x4c\x5e\xd9\x8e\x3a\x40\x9d\x95\x30\x63\x33\x38\x99\x02\xcd\xf4\xd4\x06\x52\x70\xc1\xfb\xb6\x29\x9a\x21\x25\xee\x97\xb6\x3e\x85\x76\x26\xb7\xfa\x68\x61\x7e\x5b\x5e\x50\x4b\xe9\xda\x10\xd1\xaf\x77\xef\xd4\x4a\x96\x9a\x18\xdf\xdc\x0c\xbf\x6e\xf4\x6a\x45\x2a\xae\x75\xe1\xc3\x5b\x6a\x75\x25\xf6\x80\x76\x74\xe3\xd0\x6b\xd5\xb4\x95\x74\x48\xc2\xda\x36\x6f\x25\xcb\x4d\xa9\xb7\xeb\xda\x4a\xfe\x21\x4a\xec\x36\x47\x47\xd9\x9c\xdc\x51\xae\x7d\x2a\xde\x81\x99\xea\xc0\x90\x27\x83\x0d\xdf\x00\x4d\x41\x2a\xa4\x1e\x40\x77\xae\x9f\xe5\x47\x67\x8e\xa6\xda\xda\xba\xe5\x03\xa5\xd2\x22\x27\x53\xf7\xda\xcd\xf4\x44\x77\x32\x06\x78\x7a\x7c\xee\x8f\x84\xc2\x52\x38\x77\xcf\x8b\xa3\x5f\x4b\x74\xc3\xc2\xbd\x51\x67\x3e\xa9\x83\xad\xde\x8d\x84\x71\x0b\x2c\xdb\x47\xb0\x23\x5a\xda\x41\x80\x00\xe9\x30\x48\x80\xb4\x4b\x76\x5c\x9c\x08\x1d\x5f\xed\xe3\xa1\x3a\x8b\x3b\x20\x9d\xf9\xd6\xc9\x2a\x43\xa4\xc3\x19\x1b\x05\xdb\x11\x10\x3b\xf5\x68\x93\xf6\xe9\x94\xf5\xf1\x30\x00\xba\xd9\x7c\xd2\x25\x04\x8a\x0e\xc2\x9f\x97\x83\x9f\x97\xba\x69\x23\x99\xb0\xf5\x5a\xf7\x86\xcb\xb4\x6d\x2d\x4e\x56\xe7\x12\x4b\xc2\x43\x27\xd8\xe7\xd1\x5e\x9c\x74\x17\xa6\xd8\x75\x90\x62\xa7\x21\x8a\x1f\x35\x40\x11\xd3\x22\x5a\x53\x91\xa6\x7d\x1c\xa7\x34\x18\x60\xf4\x36\xa3\x71\x3a\xd9\xcf\x59\x77\x7c\xb7\x8a\xa6\x39\xd4\x1c\xb5\xbd\x38\x63\x3a\x29\xae\x45\x72\xdb\xa1\x5e\x73\x0e\x85\x84\xc4\xda\xc9\x6e\xce\x86\x76\x76\xa3\x5f\x5e\xbd\xbf\xa9\xc2\xf1\x31\x66\xa5\x32\x5c\x7e\xe3\x2c\x69\x46\x27\xbd\x85\x42\x07\xd5\x7d\x44\x93\xdb\x3b\x2a\x53\xb4\x6c\x51\xcd\x46\x2c\x63\x7a\x8e\xca\xb9\x04\x8c\xf5\xe7\xc2\x06\xc5\xd9\x22\x89\xc2\xb7\x3a\x0d\x7d\xb8\x83\x0d\x0b\x2d\x64\x2e\x7a\x66\x4c\x99\xd1\xc7\x43\x3f\x5b\x1b\x35\x93\x14\xc1\xa4\x57\xb7\x4c\x47\xe5\xcb\x8f\xbd\x55\xbe\x6a\xbd\x5a\xb7\xd5\xc3\xda\xc6\xee\xed\x31\xab\x73\x2c\x4e\x86\x56\x64\x91\xd5\x75\x34\xdf\xfe\xb2\xba\x42\xc2\xb5\x16\x45\x47\x5e\x12\x3b\xd9\x1a\x1f\xc9\x08\xc6\xc2\x10\xe1\xb5\x4e\x8f\xb4\x04\x57\x2e\xf3\x74\x78\x19\xac\x5a\xa2\xe1\xd8\xb0\x51\x8b\xbe\x46\x66\xc6\x66\xc0\x41\xa9\x13\x74\x87\x94\x85\x6b\xc7\xef\xba\xce\xf6\xcc\xdb\x41\x8e\xab\xeb\x55\x99\x00\xae\xe7\x2d\x7e\x09\x3a\xb1\x96\xdb\x1a\x21\xc7\x76\x5a\x6e\xf9\x8b\x6e\x94\x44\x52\x35\xb5\xfd\x60\xe1\x9e\x69\xd7\xd3\x78\x68\x6b\xe8\xd6\xdb\xd2\x4e\x24\x4d\x80\x14\x20\x99\x30\xcc\xa8\xe4\x3a\x15\x77\x9c\x8c\x60\xc2\xb8\xf2\xa0\xc0\x2a\x98\x0e\x66\xe8\x8f\x61\x2a\x94\x4c\x1b\x90\x0f\x8d\x82\x20\x2e\x55\x27\x11\xd5\xd1\x74\x6b\x5e\xf4\x24\x21\xc7\x42\x38\xd9\xee\x2a\x01\xc2\xf5\x86\x33\x8f\x2d\xf9\xa8\xe4\xf8\xe4\x14\x32\x3a\xb7\x11\x99\xd8\x2b\x9a\xfd\x1b\xa4\x3a\xee\xc0\xe3\x64\x5b\x26\xf9\xdf\xd6\xae\x03\xcb\x8f\xd2\x64\xda\xce\x85\x1b\x5d\x54\x1b\x8e\xe8\xa2\x6a\x33\x49\x74\x51\x45\x17\xd5\x23\x23\xba\xa8\xa2\x8b\x6a\x61\xec\xad\x96\x14\x5d\x54\x3b\x8f\xe8\xa2\x7a\x78\x44\x17\xd5\x06\x23\xba\xa8\x36\x1c\xd1\x45\x15\x5d\x54\xd1\x45\x15\x5d\x54\x9f\x91\xdd\xce\x8f\xe8\xa2\x5a\x9a\x24\xba\xa8\xa2\x8b\x6a\xe3\xb1\xb7\xca\x57\x74\x51\xd9\x11\x5d\x54\xcd\xf1\x79\xb1\x3a\xef\xe0\x19\x1a\x55\xaf\x7d\x23\x5e\x54\x18\x1d\x8d\x7d\x91\x69\x4f\x6d\xec\xff\x9f\xc6\xf6\xbf\x27\x8e\x92\x0e\xec\xfd\xd1\xd6\xff\xe2\x6c\xfd\xdd\xd8\xc9\x3a\xb0\x91\xb5\xa6\xc9\xce\x05\x7e\x33\x95\xa0\xa6\x22\xdb\x19\xd1\x1b\x48\xfe\x8e\x71\x96\x97\xb9\xc1\x39\x65\xf0\x99\xcd\x82\xaf\x5d\x55\xdd\x89\xd1\x05\x6f\xcd\x75\xe6\x42\x96\x02\x56\xde\xa4\x2c\x33\xdb\x88\x89\x92\x53\x3a\x33\xb8\xae\xca\x24\x01\xc0\xbe\x5e\x75\x55\xe2\x8f\x83\xf0\xa4\xd0\xc7\xe1\x75\x3b\x7a\xd3\x8e\x5b\xda\xda\x98\x38\xcb\x1f\xff\xb0\xd3\x1c\x13\x59\x74\x43\x97\xbf\xfe\x30\x3c\xab\xd1\x65\xca\x3d\x59\x66\x7c\x26\xb2\x99\xed\xfe\x8a\x17\x19\xa9\xc8\xb5\x8d\xc5\x6e\xa5\x23\xd0\xb4\xa6\x44\x38\xf9\x5b\xd9\x36\xc5\xe6\x3e\x73\x57\x48\x69\x1f\xda\x40\x0a\xa0\xba\x94\x40\x26\x54\x3f\x25\xc1\x6f\xaf\x2b\xb4\xd2\x13\xba\xe0\x37\x6d\x45\xe1\xa6\x1c\x63\x04\xde\xa6\xb9\x67\x82\x78\x61\xcb\xb9\x6f\x2c\xf0\xb6\xa6\x94\xed\x85\xd0\xf6\x47\x8b\x60\xbd\x15\x7c\xf1\xce\x00\x7c\xe0\xfa\x6c\x7b\x76\x5e\xd7\x36\x7c\x8b\x23\x2d\x48\x91\xd1\xaa\x49\x11\xee\xc0\x37\xc8\x83\xce\xa6\x90\xdc\x7e\x70\x2e\xcf\x23\x05\x10\xe2\x55\x26\x4c\x4f\xcb\xd1\x20\x11\xf9\x89\x21\x09\xf6\x7f\xa3\x4c\x8c\x4e\x72\xaa\x34\xc8\x93\x54\x24\x8e\xc5\xf5\x13\x33\x0b\xe3\x93\x41\x9e\x1e\x63\x1b\xdc\xcb\x66\x53\xc4\x5a\x29\x04\xf3\x7c\xa7\x0c\x92\x11\x18\xea\x2a\x50\xe1\xaf\xd5\x53\x33\xcb\xdb\xba\x71\x6d\x7d\xb4\x66\x49\x2d\xdd\xcd\x9f\xde\xd5\x1c\x29\x17\xe9\xc0\xb2\xf1\xdc\x5c\xca\x9d\x85\x56\x74\xe0\x4a\xde\x23\x37\xf2\xde\x88\xc6\xfb\xe2\x3a\xde\xc3\xd2\xc7\x1d\x78\x3a\xbb\x70\x15\x77\xe7\x26\xfe\x08\x15\x82\x3f\x8e\x7b\xb8\x43\x1b\x5a\x47\x6e\xe1\x4f\xe1\x12\xee\xe4\xad\xdb\xba\x82\x3f\x9d\x1b\xb8\x9b\xd7\xed\x52\x11\x78\xae\xae\xdf\x0e\x6c\xe1\x5d\xda\xc1\x3b\xb3\x81\x7f\x34\x57\x6f\x7b\x37\xef\x1e\xb8\x78\x5b\x03\x99\x71\xa6\x19\xcd\xce\x21\xa3\xf3\x6b\x48\x04\x4f\x77\xe6\x30\x0b\x25\x23\xc3\xf9\x51\x76\x5a\x67\xa7\x6a\x66\x34\x4c\xa9\xab\x8c\x6d\x34\x2a\x9b\xc1\xe1\xfd\x13\x4e\xa0\x40\xd7\x82\x5d\xe5\x2e\x45\xe7\xee\x84\xbc\xcd\x04\x4d\xd5\x49\x21\xec\xff\xaa\x7c\x85\x5a\xa2\x82\x7d\x56\xbb\x4c\x85\xa7\x36\x88\xd9\xf4\x8e\x2e\x37\xf1\x1b\x71\x47\xc4\x58\x03\x27\x47\x8c\xfb\x7d\x3c\xae\xa9\x81\x95\x75\x32\xa0\xb5\xf9\xf5\xf5\x2b\x7f\xf1\xcb\x33\x3b\xa2\x81\x55\xa9\x8f\x6f\x05\x76\x0f\x7a\xdc\x0c\xec\x2e\x1c\x97\x59\xd3\x14\x6c\xcd\xc3\x4d\x7a\xf3\xba\xaa\xed\xfb\x1a\xe7\x0d\xa7\x8d\xf2\x94\xb8\x94\xaf\x97\xb7\x69\xad\x03\x58\x9a\xa2\x5f\x08\x58\x79\xcc\x6a\x7c\x73\x36\xb4\x46\xe3\x68\x2e\xd9\x17\x73\xc9\x13\x05\x81\xec\xa1\xa0\xfb\x4c\x03\x3f\xa2\xa0\xbb\xc5\xa8\x25\x81\x7e\x2d\x69\x02\xc3\xce\x65\x04\x7f\x9c\x48\x5a\x4a\xea\x08\x60\x10\xf9\xfc\xe1\xe1\x00\xa9\x3d\x4d\x21\x71\x16\x53\x52\xc7\x65\x96\xcd\x49\x59\x08\xde\x4c\x33\xb6\xbe\xf6\xc5\xac\x55\x34\xc9\xaf\x78\x4a\x25\x58\x16\x52\x38\x9e\x29\x4b\xce\x0d\x0d\xae\x1a\x74\xa1\x20\x89\x55\x8d\x69\x23\x37\x56\xb1\x89\x59\xbe\xe1\x7f\x98\x36\x5b\x45\xfa\x35\x26\x34\x77\x8f\x85\x4c\xd8\x28\x9b\x93\x29\xcd\x42\x37\x16\x4a\x6e\x59\x96\xb9\x69\x06\xe4\x1a\xb4\x75\x29\x58\xde\x99\x09\x3e\xc1\xc5\x51\xee\xbb\x00\x42\x62\xee\x4d\x32\xa0\xbc\x2c\xec\xf3\x0c\x27\x9e\x8b\x52\xfa\xe7\x0d\x82\x63\xa2\xea\xba\xcf\xb2\x5e\xad\xd7\xd8\x83\x1b\x1b\xfa\xd3\x94\xca\x08\x00\xef\x7d\x15\xe7\x5e\x7d\x4e\x31\x03\x29\x59\xea\xec\xfc\xf6\xbb\x42\x8a\x19\x4b\xad\x77\xc3\x83\x0d\xbb\x1a\xdb\x6e\x32\xe1\x3c\x73\xc1\xfb\x1c\x26\x14\x05\x15\x77\x8a\xec\x9e\xd9\x79\x6c\x04\x01\x4f\xb1\xbf\x8c\x91\xf0\x45\xd1\xc8\x5b\x9f\x31\xdb\x19\xb7\x06\x39\x72\xc4\x05\x11\x18\xf8\x59\x72\xa6\x6d\xb7\xf5\x69\xa9\x49\x2a\xee\xf8\xf1\x56\x5e\x57\x74\xb4\xde\xac\x04\x50\xd3\xfd\xba\x4a\xce\xb1\xef\xfb\x30\x78\x99\x72\xa6\xcf\x31\x29\xb9\x82\x96\xec\xbd\x33\xe1\xe8\x2f\x7f\xda\x8d\x46\xb0\x1c\x44\xa9\x3f\x89\xf6\x77\x37\x65\xc9\xb4\x2e\xcc\xb2\x1c\x14\x11\xe5\x82\x5a\xfc\xda\xdd\xb6\x7a\x87\xa2\x0a\xb8\x6a\xec\x6a\xd8\x5d\x61\xfd\x72\x0d\x4b\x97\xe3\xf7\x6a\x0d\x99\x31\x34\xfb\xfc\xea\xfa\x97\xb7\xa7\xff\x75\xf1\xd6\x9d\x4f\x5e\x67\xfa\x25\x67\xff\x2a\x81\xd0\x5c\x18\x59\x38\xab\x87\x01\xf6\x50\xa3\xaf\x7d\x81\x27\xb9\xdb\x80\xc1\x1d\x19\x32\x76\x8f\x6f\x1f\x16\x89\x3d\xe8\x3f\x7e\x54\xe4\x53\x77\xd5\xaa\x82\x5b\x8c\xdc\x58\xeb\xaa\x45\x09\x07\x6d\x4e\x9e\x95\x28\x6d\x97\x35\xc6\x27\x59\x5d\x98\xdc\x8d\x5c\xb5\xd5\x89\xda\x6a\x44\xfd\xea\x0d\x86\xbb\x2a\x46\x9d\x74\xf7\xaa\xd6\xd0\x51\x4f\x9c\x8a\x6a\x7b\x35\xc0\x36\x2d\xf6\x6a\x80\x15\x3d\x2e\x87\x84\xa6\xa9\x44\x31\x05\x4f\x7d\xbe\xd0\x1b\xb3\xa8\x62\x69\x7a\xe4\x15\xf9\x3b\xb9\x27\x7f\x47\xb5\xe0\x2f\x6d\x3b\x08\xb5\x15\xd8\xbb\x08\x8d\x31\xda\xe8\xe5\xb0\x23\x88\xff\x30\xa5\x1a\x67\x34\x50\xd5\x82\x8c\x98\x13\x43\xe1\x5e\x83\x34\x62\x91\xdb\x89\x27\xed\xbd\x64\x16\xf8\x09\xd1\xcc\x9a\xc9\x2f\xc7\xcd\x70\x9c\xed\x10\xcd\xdc\x6e\xf4\xfb\x2b\x47\x85\x9a\x7d\x4e\xaa\xd9\x72\xaa\x93\x69\x93\x8c\x19\x01\x43\x35\x98\x53\x2a\x90\x8c\xdb\xb0\xdb\x29\x6b\xe1\xf4\xdf\x1f\x34\x6e\xe7\x07\x6e\xec\xe7\x43\x3b\xb5\xa0\xf8\x23\x9f\x77\x82\x41\xad\x74\x52\x21\xd2\x01\xb9\xa0\xc9\x14\x97\x95\xd6\x78\x86\xd1\x40\x70\xb2\x29\x9d\x99\x8d\x77\xf7\xda\xbe\x40\x28\xad\x04\xeb\x28\xe2\x92\x39\x4f\x09\xe5\xb6\x39\xe7\x18\xa4\xb4\x91\xd2\xa3\xb9\x0f\x32\x6b\xbd\x79\xad\x4e\x52\x21\x85\x16\x89\x68\xd1\x1e\x6a\x31\xfb\x02\xa7\x43\x20\xd8\xe8\x54\x6f\xde\xfd\xee\x7c\xd8\x23\x37\x67\x43\x6c\xea\x73\x7d\x76\x33\x6c\x4a\xd8\x07\x37\x67\xc3\x83\x27\x05\x05\xf1\x66\x36\x34\xa8\xee\x30\x49\xc3\x60\x92\x31\xa5\xfb\x39\x2d\xfa\xb7\x30\xdf\x91\xa7\x76\xc1\xd7\xfb\x61\x87\x3b\x79\x21\x0b\xe6\x9c\x16\x5b\xcf\x26\x81\xa6\x2c\xa6\xf9\x6c\x3e\x62\x9a\xcf\x86\x23\xa6\xf9\xc4\x34\x9f\xe5\xb1\x37\xb1\x8c\x31\xcd\xe7\x65\xb9\x6e\x63\x9a\xcf\x67\xee\xfd\x8d\x69\x3e\xab\x47\x4c\xf3\x89\x69\x3e\x9b\x8d\x98\xe6\xb3\xfd\xd8\xbb\xb8\x95\x98\xe6\xb3\xd5\x88\x69\x3e\xcb\x23\xa6\xf9\xac\x19\x31\xcd\x67\xcd\x88\x69\x3e\x31\xcd\x27\xa6\xf9\xc4\xe8\xc7\x47\xe7\xda\xcf\xe8\x47\x12\xd3\x7c\xdc\x88\x69\x3e\x2f\x22\xc6\x8b\xc4\x34\x9f\x8d\x46\x4c\xf3\x89\x69\x3e\xbb\x8c\x98\xe6\xf3\x52\xcc\x25\x31\xcd\x27\xa6\xf9\x7c\x3e\x82\x6e\x4c\xf3\x89\x69\x3e\x31\xcd\x27\xa6\xf9\x3c\xb8\x8a\x98\xe6\xf3\x12\x54\x40\xdf\x73\xb5\x7d\x8e\xca\x07\x3f\xd3\xe6\x61\x7d\xe4\x62\xc5\xb7\x68\x09\x51\x85\x99\x44\x56\x53\x66\x12\x68\x3a\xc7\x29\xb1\xcf\x43\x4d\xc8\x7a\x86\xd1\x81\x19\xcb\xd9\x6e\x69\x41\x64\xe9\xd0\xbc\xc5\xb9\x6a\x5e\x17\x03\x96\x9c\xde\xe3\x01\xa0\xb9\x28\x6d\xeb\xd7\x44\xe4\x45\xa9\x9b\x30\xc5\xed\xd9\xa5\x6b\xeb\x98\x4d\x1c\x47\x3d\xb1\x0d\x66\xfb\x61\xda\x7e\xad\xa9\xeb\x13\xb6\x6a\xa5\xa9\x8f\x9a\x1b\x76\x11\x34\x42\xb5\x06\xc9\xdf\x90\xff\x3e\xfa\xe9\xf7\xbf\xf6\x8f\xbf\x3c\x3a\xfa\xf1\x55\xff\x6f\x3f\xff\xfe\xe8\xa7\x01\xfe\xf1\xbb\xe3\x2f\x8f\x7f\xf5\x1f\x7e\x7f\x7c\x7c\x74\xf4\xe3\xb7\xef\xbe\xbe\x19\x5e\xfc\xcc\x8e\x7f\xfd\x91\x97\xf9\xad\xfd\xf4\xeb\xd1\x8f\x70\xf1\xf3\x86\x93\x1c\x1f\x7f\xf9\xc5\xce\x4b\x6e\x2d\xf0\x76\x27\xee\x76\x24\xec\x7e\x14\x51\xd7\xb9\x6b\x3b\x3a\x8b\x2e\xd4\x64\xe9\x34\x3a\x76\xf4\xd0\x69\xf4\x1a\x37\x0a\x71\x61\x1e\xa6\x88\xc8\x99\xd6\x8e\x8a\xd2\x7a\xb0\x2a\xd3\x0d\x95\xd3\xd1\x01\x6c\x88\x4d\xb5\x6d\x54\x1d\x02\x3d\x6b\x21\x2a\xc2\xcb\x75\xae\x93\x37\xcb\x8b\x0c\x1b\x44\xe3\x79\xee\xfb\x48\x15\x64\x9d\x91\x36\x3c\x3e\x22\x6d\x78\x89\xb4\x41\x41\x52\x4a\xa6\xe7\x67\x82\x6b\xb8\xdf\xc9\x7e\xb2\xce\x80\x74\xdd\x9c\xda\xc5\x86\x29\x17\xd3\x66\x7f\x23\xa2\xb0\xf1\xdd\x6b\x33\xa7\xa7\xa2\xcc\x52\xcc\x4b\x2a\x39\xaa\x94\x36\xc5\x0d\xb4\xd5\xf7\x50\xd3\xc1\xe0\xed\xc5\xc7\x79\x0d\xce\x4e\xfd\xaf\x92\xcd\x68\x66\xf4\xdb\xea\x8e\x21\xea\x2c\xf5\x9b\x76\x32\x62\x3d\xb1\x8c\x85\xe2\xcd\x50\xb2\x19\xcb\x60\x02\x17\x2a\xa1\x19\x52\xa5\x6e\x28\xfd\xe9\x9a\xd9\x71\x8b\xa4\xc8\x14\xb9\x9b\x02\x76\xe0\xa7\x5e\x3d\xc7\x44\xb2\x09\x65\x9c\xe4\x86\xa8\x16\xfe\x66\x65\xf5\x7c\x43\xbc\x8d\xd4\xcb\x75\xa5\xcf\xa3\xfa\x3a\x12\x22\x73\xd9\x08\xd9\xbc\x9a\x9f\x59\xd3\x1b\x17\xbf\x70\xb8\xfb\xc5\xcc\xa6\xc8\x38\xa3\x93\xa0\xc6\x2b\xd0\x4b\x96\xb8\x6a\xea\xb5\x2f\x80\xa1\xfe\x25\x10\x9a\xdd\xd1\xb9\xaa\x8c\x1a\xd5\x1c\x4c\xbd\x21\xaf\x8f\x11\xf1\xa8\x22\x61\x8e\x94\xfc\xe1\x18\x5d\x73\x67\xa7\xc3\x5f\xae\xff\x71\xfd\xcb\xe9\xf9\xbb\xcb\x2b\x72\x25\x34\x58\x96\x54\x6b\x92\x96\x50\x6e\x34\x04\xb7\x4a\x7c\x06\x6a\xd0\x42\x0d\xd0\xae\xc8\x14\xb9\x63\x3c\x15\x77\x6a\x67\xfb\xa9\x45\x3f\x03\x3c\xa0\x7c\xa7\x39\x12\x5a\x50\xec\xfd\xd6\x82\x3f\x2c\x45\x7f\xd4\x27\x45\x0e\x9c\xa6\x27\xa9\x14\x85\x05\x82\x37\x40\xd5\x95\xa4\xf3\x05\xbb\xb2\x8f\x2f\xc5\xfd\x1d\x37\x27\x9c\x48\xca\x75\x65\x89\xa9\xf6\xcc\x35\x9d\x1b\xb4\xde\x8e\xe7\x9d\x6d\x44\xd3\xee\x32\x8d\x4e\xd3\x14\xd2\x06\xf8\x5f\x5c\x54\xdf\x99\x7f\xb9\x79\x55\x8c\x81\x0c\xdf\x5f\x5f\xfe\xef\x05\x3c\x9e\x17\xed\x82\x98\xba\x49\x00\x95\xa2\xe8\x6c\x77\x3f\x40\x2e\x66\x71\x7f\xf7\x65\x7f\x03\xb7\xec\xc6\x75\xfe\xa1\xe4\x75\x86\xc6\x6b\xf3\x93\x5c\xa4\x30\x20\xc3\x60\xc3\x6f\xfe\x5a\x2f\x32\x23\x81\x98\x4b\xb8\x66\x34\xcb\xe6\x75\x61\x4a\x0b\x9b\x21\xd8\x28\x41\x50\x27\xe4\x63\x9a\xa9\xa7\xa6\xc6\x6d\x78\xa3\x91\x23\xde\x19\x6d\xb6\x93\xed\x08\xb3\x91\x14\xb8\xd0\x4e\x18\x36\xab\xc4\xb2\x0e\x52\x24\xc4\xaa\xce\xb5\x40\xa9\x06\x7f\x53\xd6\x8f\xe0\x59\x23\x53\x1e\xd8\xc3\x30\xb3\x35\x22\x97\x0a\xd4\x6a\xd6\x58\x29\xd3\x66\x76\x09\x34\x15\x3c\x9b\x63\x54\xa4\x8d\x73\xc8\xa9\xba\x85\xd4\x7e\xe1\x44\xb3\xe0\x45\x30\x33\x86\x47\xdd\x98\x75\x7b\x97\x01\x8a\x64\x36\xfa\x02\x5d\x0d\x46\xc3\x7f\xd2\x5d\x6f\x71\x08\x0d\x50\xde\xf3\x6c\xfe\x41\x08\xfd\x55\x48\x71\xed\x04\x03\x7e\x70\xd2\x32\x02\xa4\x19\xe9\x45\xf1\xb9\x7d\xdc\x0d\x3c\x54\xf5\xec\xda\xf3\x6a\xc7\x9f\xfb\x91\x92\x25\x3f\x55\x5f\x4b\x51\xee\xcc\xc4\x96\x84\xcd\xaf\x2f\xcf\x91\x14\x95\xce\x8d\xc8\xb5\x9c\x17\x82\x59\x1b\xd4\x1a\xc5\xe0\x3b\xe7\x08\xad\x9f\x89\xca\x67\x45\xde\xd1\x39\xa1\x99\x12\x1e\x96\x8c\xaf\xd2\x17\x89\x53\x46\xcd\xcf\x23\xa1\xa7\x4b\x5a\xa8\x39\x50\xcb\xf7\xf5\x6a\x5e\xc5\xaa\x36\x18\xe3\x4b\xb7\x6b\x7a\x0b\x8a\x14\x12\x12\x48\x81\x27\x4f\xbd\xed\x4f\xed\x8c\x43\xd4\xb9\x12\xdc\x1c\xcc\x4e\x90\xe7\x32\x78\x61\x1d\x48\xeb\xa8\x82\xfe\x5c\xa7\xfd\x51\xf4\xea\xe2\xb1\x2c\x15\x48\xeb\x82\x96\x25\xd8\x9d\xfc\xb6\x1c\x41\x66\x20\x6f\x54\x52\xd7\x31\xdb\x1a\x1e\x58\x4e\x27\x40\xa8\x0e\x98\xa6\x05\x01\xae\x0c\xc5\xb4\xe6\x4b\x4d\x52\x01\x55\x66\x3c\x55\xe4\xbb\xcb\x73\xf2\x8a\x1c\x99\x67\x1d\x23\xfe\x60\x43\x6d\x2d\x6c\x00\xda\xa2\x8e\x3a\xf6\x53\xe0\x92\x10\x79\x89\x90\x96\x48\xf4\x08\x17\x44\x95\xc9\xb4\xde\xc5\xdb\xab\xcd\x2e\x48\x11\x1d\x23\xfb\x89\xeb\x4f\x4b\xa1\xbe\x53\x20\x3b\x23\x50\xdf\xed\x40\xa0\xea\x62\x94\xc1\xb9\x26\xf4\x2c\x62\xe5\xa0\x69\x4a\x35\x75\x84\x2b\x74\x55\xdf\xd7\x2d\xfd\xbc\xc9\x97\x82\xb7\x8c\x97\xf7\xd6\x44\xda\x9d\xa9\xe5\xfa\x02\xa7\x45\x1c\x42\xa8\xe3\xae\xd3\xa2\xc8\x58\xe5\x40\xae\x05\xa9\x5d\x36\x70\xa5\xb7\x46\x4c\x44\x3a\xe1\xfd\xd0\x46\x38\xa1\x3c\x15\xf9\xd2\xc3\xd0\xe9\x4d\x93\x69\xfd\x01\x11\xfb\x9a\x63\x4f\x8c\x42\x19\xcc\xa0\x45\x09\xad\x05\xcc\x7b\x6b\x66\x33\xc0\xf1\x18\x81\xd3\x93\x8c\x8e\x20\xb3\x30\xb6\x18\xa8\x96\x31\xf0\xa9\x23\x45\xa5\xc8\xba\x4b\x6d\xf9\x20\x32\xb0\xa1\x57\x1e\x10\x66\xfa\x67\x01\x07\x9c\xa4\x2b\x38\xa0\x36\xd8\x80\x03\xea\xb5\xcf\x01\x0e\x65\x0b\x56\x4f\x16\xe1\x60\xe4\x86\x26\x1c\x90\x79\xef\x3b\x1c\x14\x24\x89\xc8\x8b\xa1\x14\x46\xed\xec\x8c\x37\xb9\x69\x2b\x3f\x9f\x35\x6c\xa0\xdd\xbe\xae\x01\x3b\xaf\x5e\xf3\x62\x2a\x6b\x41\x97\x54\x5b\x26\xe1\x23\x2f\xff\x57\x8d\x67\x21\xe9\x59\x64\x64\x7e\x96\x86\x23\xd0\xdc\xe9\x7e\x78\xce\xec\xa0\x8b\xbc\x85\x16\xc6\xce\x4e\xb8\x91\x48\x68\x86\x25\x52\xdb\xa1\x1c\x59\x44\xbb\xc5\x89\x6b\xa1\xb6\xe8\xa3\xc4\xef\x7c\xf8\x07\x56\xcb\xc4\x6f\x9c\x09\x93\x8b\x14\x6a\x5e\x67\x1b\x23\x7c\x63\x43\x32\xf1\x3a\x1f\xe5\x6b\xe4\x0a\x17\x05\x02\x69\xe3\x6e\x2d\x5c\x75\xb2\x77\xa1\xf0\xaa\x59\x20\xf0\x94\xf1\x09\xda\xd5\x7a\x44\x42\x66\xe3\x83\x1d\x11\xb8\xb5\x1a\xe4\x21\x1e\x09\x3f\xa9\x3f\x0f\xfe\xd1\x28\x8b\x31\xc1\xdd\xcc\x68\x29\xf2\x12\xd6\xd8\x92\x5b\xa6\xc8\xc1\x5b\x0f\x80\x16\x95\x2a\xf7\x91\xc3\x1c\xd8\x37\x0c\xbb\x69\x2d\x9d\xb7\x8c\xa7\x2e\x94\xb6\x01\x2c\xaf\xe7\x3a\x39\x18\x83\xb4\x59\x5a\xa7\x2d\x6f\xc8\x4f\x9c\x04\x60\x91\xfe\xce\xe8\xf1\xc1\x8a\xcc\xde\x46\xd7\x7f\xd8\xf0\x1a\x1e\xb2\x38\xcd\x77\x1c\xf7\xde\x3c\xb7\x6f\x34\xf7\xe5\xeb\xfc\xbb\x3c\x69\x59\x1d\x47\xfd\xba\xd6\x62\x7e\xb0\xd3\x7a\x91\x3e\x31\x68\xad\x19\x9f\xa8\xba\x26\xd3\xac\x87\xbf\x5a\x95\xf1\x3b\x3c\x96\xc2\xa6\x60\x2e\xab\x10\x0b\x29\x00\xcf\x45\x0d\xc9\x8c\x38\xf1\xcc\x95\x90\x49\xae\xe8\x99\x34\x90\xd0\x8c\x66\xd7\xc5\xee\xe5\x43\xc9\x52\xa9\xba\x77\xd7\xa7\xcd\xa9\x91\x59\x4f\x41\x5a\xde\x6f\x7e\x27\x34\xcd\x99\x52\x68\x08\x83\xd1\x54\x88\x5b\x72\xb4\xa2\x56\x56\x2d\xca\x4a\xb1\x89\x3a\x71\x38\xdf\x37\xab\x3f\x26\x8c\x67\x21\x92\x09\xf5\x60\xae\x95\x37\xe4\xe0\x43\x92\xb0\x0a\xdc\x43\x57\x9e\xd9\x05\x2b\x2c\x2f\xd3\x16\x64\x36\x58\xf0\xe4\x04\x7b\x79\x7b\xae\x5a\x96\x44\x79\x64\x8b\xae\x1c\x6e\x2f\x56\x3d\x5b\x09\x47\x2b\x3d\x3e\x39\x90\x9c\x70\x91\x80\xea\xae\xd8\xd2\x37\xd5\x9c\x24\x05\x9b\x61\x03\x18\xfd\x44\xd7\x86\xc3\xa1\x5d\xfa\x10\x13\x35\xdd\xad\x87\x75\x89\xfa\xa6\x22\x2e\x46\x1f\xc9\x8a\x29\xed\x5b\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x0a\x2e\xa4\x45\x51\xc3\x44\x05\x47\x94\x46\x12\x65\xbd\x79\xb8\x27\x8e\x44\xd7\x96\x7a\x56\x79\x89\xeb\x8e\x40\x4c\xf4\xb2\xb5\x1d\xaa\x35\xdc\x31\x3d\xc5\x1a\xac\xd3\x05\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\x4f\x87\xaa\xee\xa8\xae\x2a\x9e\x63\x8c\xa1\xc1\x26\x18\x8f\x21\x41\x41\xab\x0e\x60\x4b\xb5\x8f\xaa\xa2\xb4\x3e\x85\x43\x0b\x5f\x31\x3d\x67\xf7\xe6\x29\xf5\xbb\x16\xfa\xae\x70\xc1\xfb\xab\x7f\x3e\x1e\x10\x72\xc9\x43\xfc\x6d\xcf\xec\x62\xfd\x4a\x1f\x7a\xa6\xcd\x2b\xd6\xcb\xed\xe3\x0b\xd4\x0d\x67\x46\x3a\x94\x65\x07\x18\xdf\xc6\x1c\x4e\xea\x26\xf1\x4e\xc9\x01\x9a\xc6\xdd\xa4\x66\xeb\xbd\x0c\xd0\xc6\x54\x6e\x2e\xf9\x58\xe6\xf2\xe7\xe1\x00\x21\x6d\xe9\x9c\xab\x74\x10\x6b\xa0\x6f\x36\x62\x0d\xf4\x0d\x47\xac\x81\x1e\x6b\xa0\x2f\x8f\xbd\x09\x19\x8c\x35\xd0\x5f\x56\x5d\x9b\x58\x03\xfd\xa9\x4d\xcc\xb1\x06\x7a\xac\x81\xfe\xd0\x88\x35\xd0\x1f\x19\xb1\x06\xfa\x0e\xe3\x05\x50\xae\x58\x03\x7d\x87\x11\x6b\xa0\xaf\x1e\xb1\x06\xfa\xf2\x88\x35\xd0\xd7\x8e\x58\x03\x7d\xe7\x11\x6b\xa0\xc7\x1a\xe8\xb1\x34\xe4\x76\x73\xed\x67\x69\x48\x12\x6b\xa0\xbb\x11\x6b\xa0\xbf\x88\x02\x78\x24\xd6\x40\xdf\x68\xc4\x1a\xe8\xb1\x06\xfa\x2e\x23\xd6\x40\x7f\x29\xe6\x92\x58\x03\x3d\xd6\x40\xff\x7c\x04\xdd\x58\x03\x3d\xd6\x40\x8f\x35\xd0\x63\x0d\xf4\x07\x57\x11\x6b\xa0\xbf\x04\x15\x50\xe9\x94\xed\x54\x16\x72\x93\x0a\x36\x2e\x32\xb9\x96\x30\x3e\x2a\xc7\x63\x90\x48\xb9\xf0\xc9\x4b\xc1\x53\x55\xb1\xbe\x45\x27\x2b\xe8\x1e\x16\xc3\x71\x49\x1c\x6b\x6e\x77\x19\xea\x58\xbe\xb1\x0a\x1f\xbe\x78\xff\xd5\x8a\x72\x39\x3b\x47\x15\xee\x1a\x38\x8b\x6b\x7e\xcf\x77\xf3\x8f\xaf\x01\xf8\xaa\xa4\x22\x07\xf7\x24\x13\xca\x85\x3d\x23\xb0\x92\x29\xe5\x1c\xbc\xbe\xc7\x34\xda\x51\x46\x00\x9c\x88\x02\x9c\x77\x9a\x12\xc5\xf8\x24\x03\x42\xb5\xa6\xc9\x74\x60\x9e\xc4\x3d\xb0\xab\x10\x65\xf7\x8d\xd2\x12\x68\xee\x83\xb5\x73\xca\xec\x54\x84\x26\x52\x28\x45\xf2\x32\xd3\xac\x08\x93\x11\x05\x98\x65\x61\x19\x55\x00\x06\x46\xc5\x55\x71\xcd\xbd\xea\x69\x6e\x59\xa2\x5e\xaf\x0c\xb5\xcd\x1e\x96\x78\xce\x0b\x3d\x27\xe6\x95\x33\x57\xf6\x55\x2a\x4d\x92\x8c\x21\xb7\xc6\x27\xda\x84\x5a\x9c\xaf\xe7\x79\x35\x77\x2b\x55\x6e\xa9\x3c\x45\xb1\xb5\xd0\x8a\x60\x18\x70\x35\xa1\x9b\x2a\x65\xca\x89\xf9\xaa\x47\xa8\x2f\xa6\x65\x01\xed\x57\x8a\xa0\xf6\x9c\xc5\xce\xee\xbe\xaa\x4d\x57\x2b\x22\x6a\x70\xd3\x1a\xb0\x2a\x44\xc7\xb8\x77\x8f\x9c\xbd\x46\x88\x7f\x25\x50\x60\x94\xde\xd2\x31\xc0\x0d\xe0\x30\x33\x38\x00\x09\x18\xfe\x4a\xd7\x60\xfd\x27\x47\x7a\x4d\xe5\x04\x74\x88\x67\xda\x35\x56\xbc\x19\x16\x52\x2f\xf7\x5b\x57\x44\x2a\x90\x21\x74\x86\x22\xc5\x94\x9f\x2a\xaf\x6a\x55\x3d\x61\xbb\x42\x57\x46\x6d\xd5\x05\x5e\x30\xb2\x21\x9a\xe1\xa1\xaa\xa0\x09\x28\x72\x74\x39\x3c\xeb\x91\xe1\xe5\xb9\x8b\xc3\x14\xe3\x55\x79\xcc\x8e\x86\x59\x0c\x5c\x57\xd9\x38\x54\x68\xab\x4d\x5f\xcb\xfd\x74\xcf\x1e\x06\xf9\xea\x27\xee\xc2\x4b\x17\x29\x00\x8a\x5c\xa1\xba\x39\x51\x25\x8a\x48\xce\x26\xc4\x42\x62\x86\x43\x3e\xa8\xd2\x11\x7d\xdd\x21\x7f\x47\x58\x88\x83\x92\xcb\xba\xf0\xbe\x6e\x24\xb0\xc8\xaf\x97\x52\x3b\x30\x14\xd4\xc5\xbd\xec\x14\xef\xd2\x4a\x43\xaa\x89\x62\xef\x40\x29\x3a\x81\xe1\x8e\xee\xad\x75\x76\x00\xf4\x70\x55\xe4\x00\x09\x50\x66\x13\x7d\xc3\x37\x55\x4c\x70\x53\xf8\x26\xb9\x5d\x53\xc0\xac\x3b\xc9\xb4\x06\x24\x25\x58\xec\x0f\x37\x7b\xb1\x16\xc0\xe1\x42\x64\xf1\x3b\x3f\x49\x75\xb3\x11\x25\x78\x6a\xe3\x7c\x47\x40\x46\x92\xc1\x98\x8c\x19\x06\x0f\x63\x38\x6f\xcf\xd6\x7e\xa2\xd6\xf6\xa4\x14\x48\x5c\x8f\xd3\xa0\xfc\xba\x06\xe4\x07\xb7\x30\x2d\x4b\x6e\x9b\x8e\x38\xe1\x1e\x93\x5d\xd9\x98\x4c\x30\x1c\xd8\xe9\x28\x7f\x7a\xf5\xb7\xbf\x90\xd1\xdc\x08\x52\x88\x90\x5a\x68\x9a\x85\x97\xcc\x80\x4f\x0c\xac\x2c\x53\x68\xa6\x6b\x06\x08\x60\x5b\x10\xbb\xf0\xd7\x7f\xb8\x1d\x35\x25\xbb\x93\x14\x66\x27\x35\xf8\xf5\x33\x31\x19\x90\xb3\x90\x1d\x59\x16\x29\xda\xf9\x77\x2f\xd5\xdd\x1d\x9a\x89\x8c\x25\xf3\xd6\x88\xe6\x8b\x90\x91\xa9\xb8\xb3\x1a\xe6\x0a\xec\xa9\x32\xbf\x0a\x51\x94\x99\x75\x75\x7c\x15\x12\x9d\x4b\x05\xcb\xe9\x88\x2b\xcf\x05\x1a\xe7\xdd\x14\x0b\x74\xd4\x45\x81\xfb\x47\x0a\x97\xe6\xe2\xcc\xc7\xa1\x16\x19\x12\x93\xaf\x68\x96\x8d\x68\x72\x7b\x23\xde\x8a\x89\x7a\xcf\x2f\xa4\x14\xb2\xb9\x96\x8c\x1a\x1e\x3d\x2d\xf9\xad\x6d\x05\x11\xaa\x35\x88\x89\x11\xe8\x8b\x52\xfb\xe2\xde\xab\x5e\xd8\xa6\xee\x7b\xd6\xef\x95\xef\x6a\x16\xb8\x67\x95\x86\xed\xb2\xc6\x2c\x46\xd6\xe7\x57\x75\x64\xfb\xc3\xab\x3f\xfd\xd5\xa2\x2e\x11\x92\xfc\xf5\x15\x66\x0a\xa8\x9e\x3d\xc4\xc8\x51\x8d\x78\x92\xd3\x2c\x33\x84\xbc\x8e\x94\x06\xd0\xab\x90\xf0\x93\xe3\xa0\x6e\x8f\x6e\x1b\x0b\xf0\x37\x37\xff\x40\x2e\xc2\xb4\x82\x6c\xdc\xb3\x09\x52\x41\x99\x3e\x44\x71\xe4\xd0\x51\x1f\xcc\x52\xdb\x03\xb1\x7b\x26\xb2\x32\x87\x73\x98\xb1\x2e\x7a\x3d\x35\x66\xf3\x06\xa6\x8c\x29\xe4\x83\xa3\x4c\x24\xb7\x24\x75\x3f\xd6\xe2\x9d\x16\x8b\x92\xef\x0e\x85\x5d\x23\xbf\x5a\x44\x7c\xad\x7d\xff\x46\xac\x57\x4e\x8b\xc2\xc8\x00\x98\x87\x29\xe9\x5d\x03\x18\x78\x26\xb1\x72\x42\xcb\xd2\x36\xad\x9d\x1b\x6d\x5d\x1b\x7d\xf7\x46\x86\x6e\xee\x3c\xc5\xce\xb1\x4e\xed\x3d\x23\xd5\xea\x77\x37\x87\x37\x10\xa2\x9a\xd0\x9f\x86\x02\xff\xb6\xb9\x4c\x4b\x82\x79\x28\xaa\x19\x10\xc3\x0a\x00\x06\x7d\x90\x24\xef\x6e\xe6\xef\xc0\xa6\xde\x2e\xd0\xad\x01\x17\x1e\x7c\x19\x39\xd5\x4e\x20\xf4\xba\x0a\x25\x05\x48\xc5\x94\xe1\xcb\xdf\xe3\x81\x3a\xcb\x28\xcb\x6b\x86\xe7\xa7\x01\x82\x3d\xdc\x58\xc9\xb9\x3d\xa5\x34\x7a\x8a\x9d\x10\x49\xa1\xad\x62\xbd\x42\xac\x6d\x4a\xb5\xd7\xe5\x08\xf1\x07\x2f\xdf\xa6\xa1\x5e\x87\x9c\xf8\xa9\x69\xec\xf7\xd5\x36\x34\x49\xac\xf9\x26\xd0\x58\x7b\xd5\x4b\xa2\xac\xf8\x7e\xcf\x95\xb0\x86\xc5\x77\x44\x3f\x90\xa2\xba\xcd\x6d\x92\xd0\x86\xd6\x69\x4f\x58\x4d\x17\x70\x0a\xe4\x80\xd8\xa0\x0d\x73\x26\xdc\xad\xe4\xf0\xcd\xe1\x93\x52\x57\x0b\x22\x29\x0a\x3a\x69\xd5\x8f\x68\x01\x52\x8b\xd3\xd6\x8b\x65\x18\xfd\xa9\x46\x4a\x0a\x77\x95\xa1\x24\xbe\x16\x10\x56\x7a\xb2\xce\x7c\x0f\x60\xa7\x59\x60\xbf\x38\x72\x47\xe7\x84\x4a\x51\xf2\xd4\x99\x43\x83\x3d\xfa\xdd\xc2\x83\xaf\x04\x07\xef\xe7\x59\xac\xb5\x81\x0e\x28\xc6\xc9\xeb\xc1\xeb\x57\x2f\x85\xc5\xe1\x1b\x2e\xb0\xb8\xab\xc0\xe2\x2c\x7d\x7a\xd2\x77\xf5\x55\xfb\x3b\x7a\xdf\x77\xce\x36\x53\x15\xe5\x67\xbe\xe4\x37\x7e\x75\x27\x99\x86\x5a\x97\xc1\x23\xd4\x78\x8c\x62\x59\xab\x2c\x71\xbc\xaa\x1b\x46\x4b\x20\xb5\x2b\xe5\xa1\xca\xd1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x65\x1a\x53\x0f\x90\xb0\x3a\xa0\x0e\x0e\xc8\x91\xbd\xf2\xd0\xe6\xdf\x1f\x3f\x29\x6a\x39\xa0\x5d\xdc\x17\x2d\xea\x84\x2e\x94\x7a\x28\x28\x1a\xef\x8a\x0e\x21\xf8\x5f\x30\xa5\x33\xc0\xba\x03\x2c\xa3\x32\x43\x17\xf9\xb5\x5d\x3b\x19\x95\x9a\x00\x9f\x31\x29\x38\xda\x89\x67\x54\x32\xac\xec\x23\x61\x0c\x12\xb8\x51\x62\xbf\x38\xfa\xfe\xf4\x03\xc6\xdf\x1c\xdb\xae\x2f\x7e\x95\xa5\xf2\x25\x78\xea\x2b\xa9\x4d\xf7\xe8\xf6\xf9\x75\x18\x18\x22\xcd\xf5\xeb\x32\xcf\xc9\x4b\x5d\xda\xd6\x32\xf7\x49\x56\x2a\x36\x7b\x2a\x4a\xe2\x0a\x42\x9c\xb3\x9d\xf6\x79\xa1\x38\x45\x05\xa8\xa5\x3a\x13\x95\x9b\xe0\x91\x32\xdc\x87\x2a\xe4\x98\xd6\x43\x36\x9c\xcd\x8a\xe4\x6c\x32\xd5\x2e\xda\x73\xc1\x73\x50\x73\x41\xe5\x68\xe6\x7d\x4a\xeb\x95\x61\xbb\xa7\x19\xa3\x6a\x5b\x91\x6b\x29\x91\xd1\xcd\x82\x81\x1e\xdc\xd5\xfa\xa3\x59\x30\xca\x98\x07\x59\x4b\xe5\xe5\xd0\x79\xd0\x3c\xdc\x18\xff\x1f\x1b\x58\x13\xd4\x12\x1b\x28\x63\x6f\xb1\xe6\xc6\x31\xa9\x15\x05\xf2\x01\x25\x48\xfc\xb1\x12\x15\x6a\x24\x5c\xf0\xfe\xb4\x56\xb4\xa9\x10\xe9\x96\x49\x7e\xbb\x2a\x1e\x3b\xa9\x1c\xab\x21\x48\xa6\x22\x4b\x7d\x0f\x6d\x6b\xcb\x19\x81\xbe\x03\xe0\xe4\x72\x88\xf0\x33\xaf\x88\x1e\xa1\x35\x50\xb4\x6e\x05\x2c\xcf\x54\x53\x65\x1b\xf0\xdc\x16\xc1\x5a\x68\x25\x6d\x44\xfa\xf0\xa6\xad\xcf\xfc\x37\x01\x66\x3e\x22\x9b\x8e\xc4\x0c\x10\xa4\x69\x2a\x41\xb5\x28\x6f\xf4\x04\x7a\x6a\x2b\x52\xca\x76\x6a\xef\xd3\x74\x8c\x04\xb0\x79\xd3\x12\x8a\xef\x78\x54\x11\xf1\x3e\x31\x05\xbb\x1c\x9e\xb5\xa0\x5e\x87\xdf\x39\xbf\x88\x99\xea\xf0\x50\x11\x56\x24\x95\xcf\x75\x40\x2a\x77\x63\x2d\x51\xc2\x4a\x8c\xdb\xf9\xba\x76\x15\x13\x6b\x44\xad\x25\x91\x26\xdc\x4e\x63\xc8\x8a\x4b\x92\x76\xe6\x1c\x74\x3a\x14\x22\xc5\xfe\x4b\x15\x34\x94\xbf\xa3\x0e\x10\x1f\x2c\x61\x89\xbc\x0b\x1d\xe9\x85\x20\xe4\x05\xc2\x84\xa6\x77\x1f\x7e\x58\xa3\xe2\x4b\xc0\xfc\x64\xb0\x1c\x5e\x9e\x77\x89\x2e\x05\x4b\xf7\x0e\x5d\xbe\x53\x5b\x27\xdb\x3f\xfc\x92\x58\xb9\xef\xb1\xb7\xb4\xce\x26\x57\x8c\xcf\x7d\xc6\x30\x75\xa1\x89\xeb\xee\x18\x22\x61\x57\x05\x74\x20\x15\x69\x3e\xa9\x67\x3e\x8f\xcb\x0c\x91\xb4\x0a\xee\x0d\x91\xc9\x34\xc4\x85\xa2\x34\x40\x67\x94\x65\xb6\x2e\xa6\x58\x3f\xa5\x77\xbf\x67\x82\xa6\x36\xdd\xe3\x16\x24\x87\x8c\xe4\x22\x2d\x33\x6b\xcd\x0b\x5d\x84\xdf\xbd\x3f\xff\xee\xed\x85\x0f\xc2\x82\x6a\x3b\x7b\x84\x12\x0e\x77\x38\x3b\x47\x81\x24\x71\xe5\xb9\x42\xda\x8f\x39\x4f\xbe\xe2\xa6\x55\x43\xad\x61\xc2\xbf\x50\xce\x34\x9b\xd8\x32\x9a\x95\x58\x38\x92\x40\x6f\x45\xa9\xc9\xac\xcc\x38\xc8\xaa\x0b\x26\xcc\x80\x5b\x1b\xac\xb9\xc1\x3c\xb6\x5e\x91\x91\xc9\x46\x21\x4c\x57\x1e\xcd\x17\xf7\xa4\x89\x93\xe4\x5d\x8a\x11\xfe\x58\x6b\x01\xdd\x68\x14\xf9\x70\x81\x52\x2f\x79\xd5\x6a\x93\xda\x74\xe2\xe5\xc2\xa4\xbe\x86\xa4\x0d\xa3\xb9\xf6\x11\x30\x2e\xf0\xe5\xd3\x1d\x87\xed\xcd\x2d\xcd\x0c\xd1\x66\x61\x15\x37\xa1\xe7\x7d\x43\x91\xae\xd1\x1a\x2a\xb9\x0b\xaf\xaf\x37\xc6\xd6\x82\x50\x62\xcd\xed\x7d\x5f\x98\x06\x23\x65\x77\x21\x83\x5b\x33\x4d\xd4\x3c\x86\x65\x96\x5d\x43\x22\x61\x5b\x37\x43\x93\x52\x5c\x2e\xcc\xb5\x4e\x03\xa8\xa9\xb3\x58\xad\xc3\x5d\xcc\xab\x9a\xb0\xb5\x38\xa7\x2a\x17\xb7\x28\x33\x0c\x0d\xa7\x7c\xee\x01\x8e\xab\x57\x35\x9f\x2e\x53\x3e\xca\xcc\x52\x9f\xc6\x2e\x28\x08\x0f\x0b\x2d\xd6\xa8\x52\x36\xf2\x80\xf1\x94\xcd\x58\x5a\xd2\x0c\x1f\x84\x4a\x99\x0b\xd8\xa2\xae\x5a\xb9\x3d\xcb\xb9\xaf\x71\xbc\x6d\x0c\x73\x75\x26\x4f\xec\xba\x7f\x6b\x97\x37\x67\x7c\xd2\xc7\x6f\xcc\x83\xdd\x0a\xfb\x82\xf7\x69\xdf\xa0\xcd\x33\xd1\x5b\xb0\x4a\xff\x7b\x54\x0c\x3e\xf8\xfd\xf5\x64\x48\x11\xe0\xa2\x9c\x4c\x11\x58\x32\xa7\xbe\x60\x66\x06\x1a\x6b\x21\xba\x78\x06\x1b\xc4\xe6\xee\x4d\x9d\x96\x51\xaf\x0d\xd9\xc4\x8d\x67\xa2\xbb\xec\x6a\xe0\x5d\x08\xc6\xaf\x91\x19\x07\x23\xbd\x35\x06\x8a\x19\xc8\x19\x83\xbb\x13\x27\xf9\xf5\x0d\x4f\xe8\x5b\x88\xa8\x13\x04\xec\xc9\x6f\xad\x76\x74\xf3\xfe\xfc\x3d\x36\x16\x77\x56\x77\xcf\xaa\x0c\x2b\x50\x03\x42\x0b\xf6\x3d\x48\x85\xa5\x93\x6f\x19\x4f\x7b\xa4\x64\xe9\x97\x9f\x30\xe0\x8b\x71\x56\x45\xb1\xb6\xa2\x5a\x6f\x1d\x55\x72\x59\xf4\xec\xdf\x16\x3d\x6b\x1c\x74\x04\x99\xe0\x93\x5a\x0d\x00\xe4\xe6\x97\x9c\xe9\xa5\x1e\xcc\xb6\x9e\x29\x5a\x78\x84\x4c\x31\x56\x98\x09\xd9\x70\x67\x98\xf9\xb0\xca\x63\x2d\xe2\xd8\x90\x34\xd6\x98\x0f\xc3\xb8\x54\x25\x23\xd9\x40\x20\x9f\x2e\xec\x8b\x60\xfb\xea\x91\x96\x17\x4f\x29\x4f\xf1\x63\x92\x08\x99\xba\xf5\x32\x1d\xc2\x9b\x6d\x30\x9c\x8d\xc0\x42\x36\x64\x28\x1a\xe5\x8b\x4f\x46\x31\x4d\xe6\x8d\x50\x58\x2f\xb5\x97\x9c\xfd\xab\x04\x42\x73\x61\x08\xf1\x62\xab\x87\x05\x88\xe4\x74\x8e\xbc\x10\x97\xfa\xd6\xa7\x6b\xb8\x1c\x5b\xd5\x23\x1f\xc0\x08\x5d\x55\x99\x80\x1e\x79\xdb\xac\x1b\xd0\x33\x6b\xb9\xb6\x09\xcd\xee\x2b\xbb\x7a\x09\x4a\x94\x32\x81\x0f\xd6\xc7\x99\xfb\x78\xba\xe5\x97\x31\xbb\xa2\xe9\x2d\x70\x6b\x53\x32\xa0\x41\x37\x6e\x29\xff\x3f\xf6\xfe\x86\xbb\x6d\x1b\xdb\x17\xc6\xbf\x0a\x96\x67\xd6\xdf\xf6\x54\x92\x93\x76\x3a\xa7\x27\xb7\xff\xe9\x72\x6d\xa7\xf5\x6d\xe2\xf8\xc4\x4e\xfb\xcc\xd3\xf4\xcc\x40\x24\x24\xe1\x98\x04\x58\x02\xb4\xa3\xb9\xb9\xdf\xfd\x59\xd8\x7b\x03\x04\x25\x39\xb1\x49\x26\x92\x5d\x71\xd6\x9a\xc6\x12\x05\x82\x78\xd9\xd8\xaf\xbf\x1f\xcc\x41\x32\x13\x69\x05\xa7\xca\x78\xce\x26\x12\xf9\x5f\xe0\x68\x97\xd3\x99\x30\xd6\xdb\x46\x07\x90\xa3\x56\x53\xe9\xf9\x0e\xc0\xf2\x8d\x92\xd9\x6b\x2f\x6c\xce\x01\x9d\x1c\xb6\x2c\xb7\xbe\x5e\x0b\xb5\x41\x53\xe5\x7e\x2f\x2f\x8e\xb4\x19\xb1\x17\xee\x51\xb8\x9e\x22\x5e\x0d\xb9\x30\xb8\x10\x63\x26\x37\x32\x9b\x70\x33\x03\xd6\x99\xc5\x29\x20\xca\x8a\xa4\x2a\x9d\xc0\x40\x24\x79\x9e\xa6\x4e\xba\x96\xac\x44\x62\xf9\x55\x7e\xc7\x8e\xf5\x39\xae\xb3\xc3\xe8\xbc\x7b\x28\x87\xd8\x61\xa8\xb7\x70\x03\x9f\x2c\x48\x02\x9c\x49\x77\x60\x79\xc4\x35\xa7\x70\x87\x80\xbf\x93\x0a\x9f\xef\x48\x6a\x1f\xde\x6f\x15\x96\xef\x72\x02\xf2\x72\xda\xdd\x71\xb7\x7b\x58\x4e\x2b\xdc\xe8\x24\x85\x6b\xdc\xf9\xd1\x42\xde\x3d\x28\x53\xce\x56\x3d\x7a\x79\x1c\x17\xfa\xc5\x15\x4c\xbe\x4c\x72\xc4\x7e\xee\x1a\x66\x59\x8c\xb3\x38\x81\x5e\x07\x6f\x6a\xd6\x18\x27\x34\xb2\x6b\x6f\x12\x84\xa7\x79\xcd\x57\xaa\xa2\xb2\x74\x12\xd6\x3e\x13\x95\xcc\xb8\x9a\x82\x9b\x44\x57\xae\xbd\x3f\xff\x19\x7a\x54\x8a\xb4\x4a\x88\x72\xc7\xaf\xda\x3f\xfb\xa0\x03\x01\xdd\x81\xb8\x32\x09\x2f\x7c\x9f\xe3\xd7\x32\x73\x65\xf9\xbb\x67\x4c\x8e\xc4\x88\xed\xfc\x39\xfa\x6a\x07\x9f\x5e\x94\xda\x3d\x82\x0a\x8c\xa0\x57\x99\xb4\x90\xe8\xb3\x13\xdf\x3d\x62\x27\xee\x19\x10\x88\x0d\x03\x18\xd5\xc0\x8c\xeb\xe1\x1b\xb0\x52\x4c\x79\x99\x66\xe4\x30\xbc\x89\x0a\xa7\xc2\x80\x89\x77\xd2\x58\x43\xde\x82\x0e\xc2\xc9\x72\x73\xe5\x44\x91\xdb\x5c\xc3\x94\x5b\x3e\x8c\x76\xf5\x01\x9a\x5a\x43\xc2\x02\x1f\x72\x5a\x5d\xb5\xd4\x3a\xf8\x13\xd5\x1f\x0f\x79\xb8\x4b\x3a\xa5\x1c\x50\xb9\xdb\xab\x3a\x0f\xcd\x4b\xdc\x01\x12\xbe\xb9\x81\x4f\x6a\x9e\x08\x18\x03\x60\x59\xaa\x55\xa6\x20\x47\x09\xf5\xfc\x96\x2d\x7d\x72\x76\xf9\xfa\x1f\xe7\xaf\x4e\xcf\x2e\xb7\x3b\x7b\xbb\xb3\xb7\x3b\xbb\xc3\xce\x16\xea\xba\xf3\xae\xf6\xd6\xd3\xaa\xbc\x85\x45\x30\xd6\xa8\x04\xef\x11\x65\x87\x9e\xa8\xeb\x9f\xb9\x53\xa6\xc9\xaf\x4d\x41\xd7\x15\x69\x1c\x74\x03\xaa\xee\x47\x0f\x3e\x3d\x74\x8d\xc9\x9d\x3d\x26\xcd\xc5\x8e\x95\x55\xb3\x16\x73\x84\x1e\xfd\xf3\xf4\xf8\xe4\xec\xf2\xf4\xf9\xe9\xc9\xeb\xb5\x66\x3b\x75\x04\x43\x6d\x9e\xcb\x2d\x4f\xc9\xa2\x14\xd7\x52\x57\x26\x9b\x07\x3c\xf5\xd5\x42\x60\x39\x61\x56\xa5\xe0\xf1\xf0\x90\xf1\x2b\x7f\xb6\x3d\x6c\xfb\x3d\x6c\x9b\xc9\x5f\x1d\x70\xb0\xfa\x5a\xbe\xcf\x4b\x9d\xf7\xb4\x84\x2f\xd0\x17\xe3\x83\x6d\xab\xd6\xd3\x2e\x41\xe6\x34\x8e\x1e\x52\x1e\x6b\x7c\x1e\xa7\x8f\xe6\x85\xed\x40\x96\xd3\x0b\xfc\x75\x3f\x48\xd1\x98\x70\xf6\x92\x17\x3f\x89\xf9\x6b\xd1\x11\x6e\xab\x39\xde\x22\x13\x89\x3b\xe8\xd8\x95\x98\x63\x76\xf1\x91\x7f\x58\x17\x58\xb0\x8d\x44\x0f\xbf\x12\x5d\x90\xdd\xfb\x84\xfd\xbe\x12\x1d\x32\xa7\xfd\xb5\x04\x80\xed\xa6\x10\xf4\x34\x37\xa7\xdd\x66\x8f\xf5\x0b\xf9\xfd\x09\x60\xce\x1f\x6f\x1c\xa5\x79\xf5\x38\x0b\x3e\x7c\xdb\xf3\x4c\x60\x24\x7d\xde\x38\xbb\x82\x10\x61\x58\xd3\x0c\x6b\xd3\x87\x1e\x48\xc9\xe8\x69\x68\xba\xb2\x6d\x32\x9c\xc2\x7e\xe5\xea\x6e\x2d\x58\x31\xe7\x22\x00\x3a\xa6\xcf\x3c\x06\x88\x09\x14\x99\x40\x3a\x3d\x68\xfe\x49\x69\x2d\xff\x0a\x1f\x66\x7c\x2c\x32\xf3\xeb\xee\xee\xb7\x3f\x9d\xfc\xe3\xef\xbb\xbb\xbf\xfd\x2b\xfe\x16\x8e\x42\x0c\x6f\x37\x6f\x01\x40\x13\xa5\x53\x71\x06\xcf\x80\x3f\x49\x5d\x3b\xc4\x10\x0a\x7d\x01\x78\x04\x23\x4c\xbd\x0b\x7f\x16\x3a\x5d\xfc\xcb\x74\x42\xde\xdc\xc8\x83\x01\xa6\xa8\x43\x79\x1c\x5e\xfd\x1d\x0f\xb5\x2c\xe9\x79\xab\x52\xab\x81\xe9\x29\x99\x89\x1c\xb1\xff\x9e\xfb\x21\x00\x1a\x6f\x0f\x7c\xa2\x00\x2d\xc2\x69\xa6\x4d\x18\xd6\x9d\xeb\xa7\x3b\x1b\x75\xc0\x84\x19\xec\x79\xc0\x60\x44\x68\xb4\x70\x23\x87\x03\x36\xa4\xb9\x04\x9a\xd9\xc3\xf3\x53\x76\x8d\x23\xbc\x31\x83\xe3\xc3\x9b\xcf\x3f\xa9\x8c\x0b\x41\xd4\xc5\xaa\xf4\x67\x98\x56\xe6\xbf\x27\x84\x10\x13\xa0\x22\x85\x33\x6c\xf6\xf0\xc3\x51\x52\x54\x03\xba\x61\x94\x8b\x5c\x97\xf3\xf0\x67\xa8\x4c\x1e\x1a\xab\x4b\x3e\x85\xc2\x30\xfc\x39\xfe\x2c\xfc\x85\x3f\x6c\x3c\x60\xf9\xd7\x68\x0a\xd7\xb1\x54\x92\xc8\x2d\x91\x6e\xea\x6b\x03\x65\x9b\x1f\xfa\x0d\x11\x6d\x49\x57\xbc\xb2\xe6\xd5\x5c\x90\xc1\x13\x87\x0a\x67\x18\x45\xb0\x27\xa9\x62\x7e\x50\x67\xb1\x81\x37\x40\x5d\x3b\xcb\xb2\x35\xd2\x64\x7d\xf5\x28\xcd\x52\x79\x2d\x8d\xee\x50\xfe\x16\x1a\xba\x3d\xe3\x91\x40\x7b\x30\x8b\x2b\xb8\xcd\xde\x15\x00\xae\x17\xf6\xeb\x82\xd8\x7f\xda\x85\x5f\x0f\xaf\x82\x5b\x2b\x4a\xf5\x8c\xfd\xf7\xde\xdb\x2f\xde\x0f\xf7\xbf\xdb\xdb\xfb\xf5\xc9\xf0\x3f\x7f\xfb\x62\xef\xed\x08\xfe\xf1\x97\xfd\xef\xf6\xdf\xfb\x3f\xbe\xd8\xdf\xdf\xdb\xfb\xf5\xa7\x97\x3f\x5c\x9e\x9f\xfc\x26\xf7\xdf\xff\xaa\xaa\xfc\x0a\xff\x7a\xbf\xf7\xab\x38\xf9\xed\x8e\x8d\xec\xef\x7f\xf7\xe7\xce\x5d\xef\x01\xeb\x1a\xaf\x3e\x11\xaf\x9b\x2d\xf6\xb2\xfc\x3e\x21\xcd\x0b\x5e\x7e\x79\xf5\xbd\xff\x5f\x7b\xa9\x19\x65\xf5\xf8\xe3\x7a\x63\x36\x38\xa6\x85\x7e\x0e\x4f\x0e\x3e\xa9\x59\x30\x16\x4c\x8b\xc7\x76\xce\xfd\x11\x9c\x3b\x81\xa0\x15\xe6\xb5\xd6\x44\x27\xa5\xce\x3d\x2c\x05\x84\x37\xb0\x80\x92\xee\xbb\x12\x9d\x28\xc3\xf1\xda\x3a\x83\xb6\xce\xa0\x5b\xae\x8f\x3a\x83\xb0\x88\x60\x73\x3d\x41\x42\x5d\xb7\x0d\x61\xac\x8c\xa0\x7b\x5b\x27\x06\x7f\xbc\x5b\x40\x6d\xe4\xb7\x7a\xcd\x6c\x5c\x27\xd3\xe0\x81\x96\xaf\x8e\x61\xb2\xc3\x2c\x63\x52\xe1\xc6\x87\x06\x42\x2d\x96\x40\xd3\xc6\x17\x11\x5f\xbb\x2e\x84\xaa\xab\x06\x78\x32\xe4\x16\x4b\x35\xa5\xc2\x28\x3c\x4a\x28\xfa\x24\x55\x0d\x3b\x1d\x94\xc3\x9a\xab\x80\x1b\xa3\x13\x20\x05\xc3\x4a\xab\x80\x49\x49\xdd\x86\xde\x58\x7e\x05\xd1\xc6\x44\xa4\x42\x25\x82\x78\x0c\x1a\x2c\xce\x5c\xb1\x13\x75\xed\xb9\x1c\xd2\x0a\x93\x41\x50\xfc\xad\x6e\xe3\x71\x25\x20\xb8\x85\x48\x41\xb0\x28\x0f\x01\xa4\x7e\xb0\xb0\x39\xa4\x62\xe8\x49\xed\x65\x6d\x47\xf4\xda\xf9\x14\xef\x7e\x66\x86\xc8\x56\x27\x65\x68\xe9\xb0\xac\xdd\xcf\xcd\x43\xf2\x31\x04\x03\xbb\x1f\x9f\x7f\xb8\xa3\xb3\xa7\x63\xb3\x9f\x23\xf3\x1e\xb1\x93\x3e\x8f\xc9\x3e\x82\x25\x45\x29\x26\xf2\x5d\x4f\xfb\xf4\x30\xaa\x27\x94\xa9\x50\x56\x4e\x24\x72\x59\x17\xa5\x28\x84\x02\x57\x2b\x94\x68\x38\xd9\x4f\x27\x65\x1d\x9c\xde\xc4\x64\x1e\x54\xb8\xfb\x15\x65\x17\xab\x94\xfd\xad\x1c\x63\x5b\x39\xd6\xfa\xfa\x4c\x72\x8c\x56\xee\xe6\x08\x31\xc8\x3c\xef\x9e\xfd\x7e\xd4\x4c\x65\x87\x85\xdc\xbd\x84\x78\xa1\x40\x3f\x88\x46\xab\x31\x79\x0d\xeb\xd8\x4a\x86\x35\xfb\xa8\x37\xb1\x9c\x2b\x3e\x45\x2a\x0a\xab\x03\x78\x95\x2e\x03\x9d\xd8\x62\xde\x3d\xe8\xf1\xbe\xc4\x0b\xbe\x2c\x75\x96\x89\xd2\xb0\x4c\x5e\x09\x76\x2c\x8a\x4c\xcf\x73\xca\x7d\x4d\xd9\x85\xe5\xd6\xad\xea\x0b\x61\xdb\x85\x7d\xbb\xa1\xda\xf8\x2a\xf4\x9e\xb0\xff\xb1\xac\x1d\x8a\xc2\x59\x41\x15\x94\xaf\x14\x08\x8d\x43\x60\x36\x1a\xb0\x33\x71\x2d\xca\x01\x3b\x9d\x9c\x69\x7b\x8e\xda\x77\x33\xe1\x0e\x6f\x64\x72\xc2\x9e\x39\xbb\xce\x58\x66\x91\x5d\x26\x2a\x50\xd7\x65\xa3\x81\x1a\xb7\xb0\x8f\xfa\xbc\xe5\xda\x73\x68\x29\x54\x9e\xb7\x8a\x64\x74\x9a\xa6\x40\xdf\xd5\x79\x82\x0e\xb1\x9e\xb4\x86\xb2\x8e\xd6\x37\xe2\x2a\x78\x24\x3e\xb0\x02\xa5\x62\xa5\x30\x85\x56\x46\x34\x61\x46\x43\x8f\xd0\xda\xed\x17\xc3\xb8\xf5\xe1\xd9\xf5\xd8\x2c\xb4\xb1\x50\x42\xdb\x0f\x29\xdc\xb9\x6f\x0e\x2a\x92\x79\x96\x89\xb4\xc1\x0a\x88\x6c\x56\xbc\xe9\x21\x20\x34\x94\xc0\x6f\x83\x85\xca\x8d\x1a\xe7\xc6\xfd\x81\x61\xd2\x73\x38\x79\x7a\xf1\xdb\x2a\x9b\xeb\x8d\x09\xe7\x48\xb4\x00\x96\x00\xcf\x01\x06\xdf\x44\x44\x50\x33\xad\xaf\x58\xa2\xf3\x22\x83\xad\xd3\x61\x67\xd5\x3c\x74\x61\x29\x0d\x5d\xeb\xe6\x20\xa2\xa8\x83\x0f\xba\x31\xd4\x75\x52\xc4\xfa\x50\xc3\xc4\x3b\x91\xf4\xc6\x61\x7b\xf2\x4e\x24\x11\x09\x33\x40\xb2\x25\x1e\x21\xc2\xed\xd8\xee\xdc\xfa\x9d\x43\x0e\x7d\xb9\xf9\x3b\xd4\xd2\xc5\xd7\x02\x8a\x25\xb4\xe9\xd1\xfe\xe9\x11\x40\x9c\x02\xb6\x10\xd6\xd7\xc5\x30\x1a\x61\x31\xe2\xd6\x5b\x82\xbe\x0c\x89\xd4\xbe\x2d\xa0\x48\xd3\xda\xb2\xbd\xdd\x83\xdd\xfd\x25\xff\xe3\x02\x64\xfc\x65\xf4\x4b\x09\x50\xa7\x05\xe0\x86\x8a\x64\x37\x1d\x30\x69\x7d\xa6\x35\xc2\x3d\x41\xaf\xa8\xe8\x6f\xc0\x8c\x66\xb6\xe4\xa9\x24\x35\x06\x3e\x75\x37\xd9\xb2\x22\x29\xbf\xb7\xfb\x7e\x97\xa8\xbd\x6e\xb4\xda\xb5\xd0\xfd\x11\xbb\x44\x9c\x98\xd0\xd0\x5c\x57\x80\x0b\x85\x43\x50\x64\x32\x91\x36\x9b\x83\xc4\x62\xba\x42\x4c\x2a\x77\x5e\x50\xb1\xe1\xc9\x3b\x69\x3d\xb9\x8e\x9e\xb0\x27\xc8\xae\x87\x18\x4e\xdc\x00\xc3\xfa\xc1\x4c\xf0\xcc\xce\x30\x49\x44\x69\x35\x44\x82\x54\x27\x4a\xe8\x9b\xae\xf1\x92\x6e\xee\xc4\xf8\xea\xe0\x5a\x5c\xee\x50\x47\xcb\xc1\x09\xd1\x1f\xda\xb3\xb6\xb3\x25\xf4\xba\xcb\xcb\xf3\x1f\x1a\xbc\xed\x20\xc5\xad\x2d\x7c\xea\x0e\x78\x03\x44\x39\xd1\x65\xbe\x01\xb2\xa3\x9f\x60\x65\x27\x02\x77\xd6\xa3\x08\xeb\x4a\xe4\xce\x56\xa3\x11\xde\x9d\xc1\x9d\xfd\x43\x57\x00\x06\xc2\xc7\xd9\x3c\x20\x31\x18\x61\xd9\x8e\x6b\x6a\xc7\x89\x27\xb7\x1a\x7e\x14\x3c\x45\xa0\x0c\x63\x05\x6f\xa5\xba\xc5\x57\x6f\x41\xb4\xa8\x6f\xfd\x9e\x03\x95\xb1\x3a\x67\x33\x7a\xed\x66\xe9\x25\xed\x8c\x11\xec\x1e\x5f\xd7\x54\x8a\x02\x25\x1c\xfd\xe6\xd1\xc9\xaf\x25\xb9\x81\xe3\xde\x20\xf1\x48\xe2\x61\x8b\x39\xa2\xa4\xc2\xc1\x42\xdc\x99\x9e\x64\x69\x0f\xc9\x0f\xac\xc7\x04\x08\xd6\xad\x90\x73\xb1\x21\x08\xea\x75\xcf\xf5\xea\x2d\xa7\x82\xf5\x96\x37\xc0\x56\x39\x59\x69\xcd\xa0\xf7\xa5\xa7\x41\xec\x35\x5a\xcf\xba\x97\x8a\xc6\xd7\x87\x07\xa0\x9f\xc9\x67\x7d\x8e\x40\xd1\x43\x6a\xf7\x72\x62\x37\xc2\x48\x41\xe9\x25\x0a\x57\x10\x13\x08\x7c\xb9\x31\xa7\x8c\xd3\x16\x7a\x7d\x75\x74\x94\x97\x4c\x05\x56\x78\x8f\xf2\xbb\x3c\x20\x51\x66\x02\x91\xc8\x7b\x77\xae\x3f\x8e\xb8\x9a\x0a\xf6\xd4\xfd\xf2\x6f\x5f\x7f\xfd\xd5\xd7\x23\x6c\x3e\x64\x29\x28\x76\x7a\x78\x76\xf8\xcf\x8b\x9f\x8f\xa0\x38\xb6\xeb\xa8\xf6\x94\x82\xd9\x77\x02\x66\xaf\xe9\x97\x9f\x34\xf9\x12\x4a\x3e\x3a\x4b\x91\xa6\xef\x1f\x9a\x8c\xf1\x3d\x49\xf7\x8b\x70\xf6\x10\x83\x36\x76\xa4\xba\xad\xb6\x11\x7b\xcc\x26\xc5\x85\x4e\xae\x7a\xb4\x6b\x8e\x45\x51\x8a\x04\xfd\x64\x97\x47\xe7\xd8\xba\xb3\x2f\xcf\x5e\x5d\xd6\xa5\x06\x90\x8f\x53\x83\xe9\xfd\x48\x9e\x34\x67\x93\x5e\x89\xc2\x06\xd3\x7d\xcc\x93\xab\x1b\x5e\xa6\xe0\xd9\xe2\x56\x02\x74\x30\x62\xff\x95\x82\x68\xdc\x30\xe1\x0f\x41\xce\x3c\x4d\x36\xca\x72\x74\x20\x78\x77\x28\xb8\xac\x30\x8f\x66\xc2\x65\x06\x1e\x54\x62\xa8\xc6\x8c\xa0\xa4\x08\x2e\xbd\xd8\xa7\xbd\x35\xbe\xfc\xb5\xb1\xc6\x57\xc4\xa0\x7d\x5f\x3b\xac\x6b\x5e\xe2\x06\x1f\x75\x74\xc4\x95\x0d\x32\xfb\xed\x51\xd7\x43\x7b\x9b\x7b\xd4\x15\xa5\xb8\xb0\xba\x15\x23\x06\x5b\x8e\x92\x60\x63\xb7\xc4\x48\xc6\x62\xa2\x9d\x10\xbe\x35\xe8\x91\x56\xb0\x09\xb9\x82\xe2\x40\xef\xd5\xd2\x8d\xc0\x06\x66\x64\x06\xfc\x7a\x02\x4e\x3d\x30\x31\x5a\xaa\xe7\x02\x1f\xb8\xb7\x13\x39\xf4\x6e\x50\x57\x39\x10\x13\x39\x7c\x28\x6c\x82\x9e\xdb\x48\x90\x03\x72\x28\x75\x7f\x31\x8c\x92\x94\xdc\xcc\x90\xa5\x5b\xbc\x93\x96\x70\x59\xcf\x75\xba\xc8\xad\x3f\x2d\x79\x22\x58\x21\x4a\xa9\xdd\x61\x54\x29\x9b\xea\x1b\xc5\xc6\x62\x2a\x95\xf1\x43\x01\xe0\xe9\x34\x66\x10\x8f\x91\x26\x00\xc3\x8d\xd8\xeb\x06\xd8\x09\x95\x21\x25\xba\xde\x9a\xd4\xe7\xc5\x48\x12\x9c\x58\x30\x4e\x08\x78\x1f\x46\x38\x66\xf3\xfa\x58\x97\xf7\x2a\x05\x4f\x4e\x45\xc6\xe7\x98\x6d\x0a\x0c\xfe\xf2\xdf\xa2\x34\xfb\x3d\x44\x9c\x90\x8f\xce\x7f\x77\x6b\x3f\xa4\x61\xa5\xe0\xc9\xac\x5b\xf0\x77\x1b\xa2\xba\xe3\xb5\x0d\x51\x75\x69\x64\x1b\xa2\xda\x86\xa8\x3e\x72\x6d\x43\x54\xdb\x10\xd5\xc2\xb5\xb1\x56\xd2\x36\x44\xd5\xfa\xda\x86\xa8\x3e\x7c\x6d\x43\x54\x77\xb8\xb6\x21\xaa\x3b\x5e\xdb\x10\xd5\x36\x44\xb5\x0d\x51\x6d\x43\x54\x7f\x20\xbf\x9d\xbf\xb6\x21\xaa\xa5\x46\xb6\x21\xaa\x6d\x88\xea\xce\xd7\xc6\x1a\x5f\xdb\x10\x15\x5e\xdb\x10\x55\xf3\xfa\x63\x1d\x75\x3e\xc0\x73\xee\x4c\xbd\xee\x35\x6d\xe7\x10\x54\x90\x09\xc5\x89\xf4\xa4\x51\x07\x85\x8f\x1a\xd5\x1c\x15\x11\x2c\x88\x2f\xc5\xa1\x88\x50\x1d\x67\x5a\x59\x2f\xd5\x91\x47\xae\xd0\x69\x1d\xa8\x88\x22\x14\x68\xf0\xb6\xaf\x59\x5b\x5b\x35\x56\x97\xb0\xc4\xe7\x09\x49\x6c\x48\xfc\xa6\x87\x30\xc4\x36\x04\xf1\xe8\x42\x10\xfd\xb8\xef\x7a\x70\xdd\x75\x3e\x2a\x28\x32\x7f\x39\x2b\x85\x99\xe9\xac\xf5\x42\x6f\x2c\xf2\x97\x52\xc9\xbc\xca\x81\x29\xd6\xad\x67\x79\x1d\x52\x00\x4c\x4d\x45\x0f\x12\x1b\xbd\x88\x11\xa5\xac\xa7\x92\x85\xfa\x4d\xa2\x86\x37\x55\x92\x08\x01\x54\x6a\xb1\x85\xf3\xd5\x28\x3c\x29\x50\x67\x3c\xed\x26\x6f\xba\x1d\xe2\x08\x47\x0a\xad\x7c\xf5\x65\xab\x36\xa6\x65\xd1\x8f\x5c\xfe\xe1\xf5\xf9\x51\x24\x97\xb9\xf2\x62\x59\xaa\x6b\x9d\xc1\xa8\x72\xbc\xc9\x29\x6b\x44\xb0\x2f\x9d\xc1\x34\x16\x96\x47\xb6\x0d\x99\x05\x06\x49\xf4\xdd\xef\xdc\xaf\xc2\x89\x7c\x8e\xe7\x2e\xf2\xe7\xb3\x29\xb7\xeb\x14\xf8\xdd\x4d\x98\x4e\xe6\x4b\x1f\xe7\x4d\x57\x0d\xbd\xe9\x83\x73\x7a\x78\xd3\x0b\x35\x85\x75\x81\x08\xfa\x77\xd6\xc3\x3b\x4b\xca\xee\xba\x71\xf7\xad\xc5\x00\xe2\x06\x5e\xbc\xb7\x01\xde\xb9\x20\xea\x28\x3a\xce\x63\x23\xc8\xb3\x4a\x59\xcd\x8a\x8c\xd7\xbc\x50\x30\x03\x3f\xc2\x19\x74\x34\x13\xc9\xd5\x6b\x8a\xc4\xee\x19\x21\x82\x6e\x3a\x95\x76\x56\x8d\x47\x89\xce\x0f\x9c\x48\xc0\xff\x1b\x67\x7a\x7c\x90\x73\x63\x45\xe9\xd4\x55\x3a\xe2\x86\x89\x6b\x45\xaa\xe9\x28\x4f\xf7\x47\xec\xad\xc2\xea\xf6\x9a\x87\x32\xc2\x76\x70\xcf\xf7\x38\x1b\x63\xe1\xa4\xab\x06\x3f\x44\x04\x61\xe7\xba\x37\xea\x02\x94\xdc\xf9\x48\xea\x18\x05\xff\xfc\x11\xf0\xad\xe4\x62\x3d\x38\x5c\x1e\x5a\xa4\xbb\xb7\x8c\x8f\x1e\x22\xdc\x1b\x14\xdd\xde\x18\xd5\x78\x53\x22\xda\x1b\x88\x36\xdd\x43\x00\xb6\x8f\x08\x76\x7f\xd1\xeb\x4f\x00\xca\xfc\x69\xa2\xd6\x3d\xba\xf6\x7a\x8a\x56\x7f\x8e\x48\x75\x2f\x6f\xdd\x35\x42\xfd\xf9\xa2\xd3\xfd\xbc\x6e\x9f\x86\xc0\x43\x8d\x48\xf7\xe0\xa2\xef\xd3\x3d\xdf\x9b\x6b\xfe\x93\x45\xa0\xbb\x47\x9f\x37\x20\xf2\xdc\x79\x90\xa5\x92\x56\xf2\xec\x58\x64\x7c\x7e\x21\x12\xad\xd2\xd6\x27\xcc\x02\x4a\x67\xd8\x3f\x06\x9b\x25\x3f\x55\xb3\xd0\x62\xc6\x09\x8c\xdc\x59\x54\x58\x58\xe2\x63\x19\xa4\x50\x40\x54\x19\x7b\xb9\x91\xd1\x09\xb6\x31\x0e\x31\xac\x3a\xe9\x73\x12\x7f\xd4\x37\x4c\x4f\xac\x50\x6c\x4f\x2a\x3f\x8f\xfb\x91\x19\x58\x7b\x27\xc3\xb2\x76\xdf\x3e\x7d\xe2\x6f\x7e\x7c\x6e\x47\x70\xb0\x1a\xf3\xe9\xbd\xc0\xf4\xa0\x8f\xbb\x81\xe9\xc6\x49\x95\x35\x5d\xc1\xe8\x1e\x6e\xca\x9b\xa7\x35\x9c\xf2\x53\x68\x37\xec\x36\xae\x52\x46\x95\x68\x8f\x6f\xd2\x3a\xe7\xd5\x34\x55\xbf\x90\x47\xf3\x31\xaf\xf1\xe5\xd1\x39\x3a\x8d\xb7\xee\x92\x4d\x71\x97\xac\x29\x37\x65\x03\x15\xdd\x07\x9a\x8f\xb2\x55\x74\xef\x71\x45\xb5\xa9\x3f\x94\x3c\x11\xe7\xbd\xeb\x08\x7e\x3b\xb1\xb4\x2a\x39\x09\xc0\xa0\xf2\xf9\xcd\xa3\x84\x48\x71\x37\x85\x7a\x5e\xa8\x94\x9d\x54\x59\x36\x67\x55\xa1\x55\xb3\xfa\x19\x63\xed\x8b\xc5\xb4\xe0\x92\x5f\xf1\x94\x5a\xb1\x2c\x4a\x4d\x67\x66\x59\x29\xe5\x64\x70\xcd\x89\x06\x8a\x24\xc0\x34\xf3\x46\xc9\xae\x91\x53\xd7\x7d\x77\xfe\x41\x35\x6f\x9d\x80\xd8\x68\xd0\xfd\x7a\xa2\xcb\x44\x8e\xb3\x39\x9b\xf1\x2c\x10\xe0\x70\x76\x25\xb3\x8c\x9a\x19\xb1\x0b\x61\x31\xa4\x80\x67\x67\xa6\xd5\x14\x3a\xc7\x95\x27\x5e\x14\x89\xfb\x6d\x92\x09\xae\xaa\x02\x9f\xe7\x4e\xe2\xb9\xae\x4a\xff\xbc\x51\x08\x4c\x84\x13\x58\xc9\x6c\x10\xd1\xbb\x7d\x70\x62\x43\xee\x4f\x65\x9c\x02\xf0\xca\xc3\x52\x0f\xe2\x36\x3d\x72\xb8\x89\xc8\x7d\x8a\x52\x5f\xcb\x14\xa3\x1b\x7e\xd8\x80\x48\x1a\x09\x7c\xc2\x7e\x56\x5a\x0d\x95\x98\x72\x50\x54\x68\x17\xe1\x9c\x61\x3b\x98\x41\xa0\x52\xa0\xf4\x71\x1a\xbe\x2e\x1a\xe5\xf4\xd7\x12\xc9\x88\xa3\x91\x63\x7b\x4a\x33\x0d\xf9\xa8\x95\x92\x16\x09\xee\x67\x95\x65\xa9\xbe\x51\xfb\xf7\x8a\xba\x42\xa0\xf5\x72\xe5\x00\x35\xc3\xaf\xab\xf4\x1c\x7c\xdf\x0f\x0f\xaf\x34\xe4\xfa\x9c\xb0\x4a\x19\xd1\xf1\x78\xef\x4d\x39\xfa\xdb\x5f\xdb\xc9\x08\x99\x0b\x5d\xd9\xcf\x62\xfd\xdd\xcc\x64\x32\x8b\x95\x59\x99\x0b\xc3\x74\xb5\x60\x16\x3f\xa5\x9f\xad\x9e\xa1\xad\x09\xb8\xea\x6a\xeb\xd8\x5d\xe1\xfd\x5a\x84\x43\xa8\x99\xaf\x21\x4f\xfc\xf8\xec\xe2\x9f\x2f\x0e\xbf\x3f\x79\x31\x62\x27\x3c\x99\xc5\x98\x18\x8a\x71\x10\x1a\x20\x28\x66\xfc\x5a\x30\xce\x2a\x25\x7f\xaf\x28\xe0\xbb\x17\x7e\xbb\xdf\x2b\x56\x7b\xcb\xd3\x17\xd8\xf9\x7b\xa3\x83\x43\xae\x7f\xcc\xcb\xd2\x46\x00\x81\xcb\x92\xfa\x14\xa2\xcc\x73\x34\x11\x40\xe1\x82\xf4\xf9\xe3\x57\x27\x17\x90\x96\x5f\x94\x88\x14\x02\x79\x5c\xf0\x3d\xb4\x34\x16\xee\x17\xc4\xdc\x3b\x62\x87\x6a\x8e\x5f\xe2\x9e\x92\x86\x65\xd2\x58\x01\xa7\x1e\xa9\x6d\x3e\x7e\xbd\xf3\x64\x04\xff\xdb\x61\x3c\x4d\x4b\xa7\xd7\x85\xf4\xb4\x64\x29\x5f\x14\x35\x3f\x39\xce\xa2\x17\x50\xc2\x62\x36\xda\x4b\x9d\x52\xcf\xe1\x24\x81\xd8\x15\x1e\x83\xc6\x96\xdc\x8a\xa9\x4c\x58\x2e\xca\xa9\x60\x05\xb7\xc9\x8c\xe5\x7c\xce\x12\x5d\x96\x55\x81\x38\xff\x29\xb7\x7c\xc4\x9e\xeb\x92\xe5\x7e\x13\xbb\x35\xef\xce\xe1\x8b\xd5\x31\xfd\x7a\x67\xc7\xff\x94\xc6\x54\xc2\x1c\x3c\x7d\xf2\xcd\x97\x5f\x7f\xfd\xa8\xa8\xe1\xea\x74\x21\x37\xb7\x11\x35\x1c\xf7\xb3\x80\xb3\x8e\x54\x81\x52\x4d\xb3\x78\x7d\xb5\x3b\x00\xba\x5a\x99\x5d\x6d\xcc\x61\xfd\x06\xe7\x6d\x4d\xcd\x5e\x28\xea\xea\x3e\xf4\x44\xec\x54\x9f\x83\xde\xb0\x22\xd9\xa0\x63\xae\xde\xd3\x73\xbf\x31\x49\xcf\xc9\x17\x08\x5e\x8b\x3a\x3b\x69\xc0\x9e\xb0\x6f\xd9\x3b\xf6\x2d\x18\x5a\x7f\xeb\x4a\x83\xd5\xd5\x04\xea\x23\xd9\xc8\xd9\xf7\xa7\xe7\x3d\x8d\xf8\x2f\x4e\x68\xba\x16\xdd\xa8\x5a\xcd\xc6\x92\x14\x7b\xf1\xce\x8a\xd2\x29\x9a\x34\x13\x6b\x25\x10\x73\x1d\xfc\x8c\xcb\x0c\x03\x0f\xa7\x93\x66\x82\xd3\xfd\x16\x9a\xfb\xf9\x8f\xda\xd8\x33\x92\x42\x4d\x2a\x9c\xba\xb5\x1c\x04\x7f\x43\x8c\xb9\x73\xc3\xd8\x7a\x83\x19\x96\x6a\xc8\xb7\xc2\x44\xe6\x99\xec\x90\x46\xb1\x39\xcb\xb8\x5b\x64\xbd\x31\x9f\x1f\x9a\xa9\x05\x57\x0a\xd8\x40\xa4\x62\x45\x18\x59\x85\x4e\x49\x3b\x73\xdd\x4a\xa3\x33\xe3\x03\xea\x19\x79\x6d\x82\xbf\x19\xd6\x92\xdb\x4f\x09\x57\x58\x4a\x32\x11\x65\x89\xb9\xe7\xe3\xb9\x4f\xdb\xeb\x3c\x79\x9d\x76\x52\x51\x6a\xab\x13\xdd\x81\xe3\xac\x19\xed\xa6\xe6\x60\x10\x30\xdf\xd7\x3b\xcc\xdf\x1c\x9f\x0f\xd8\xe5\xd1\x39\xf0\x3e\x5d\x1c\x5d\x9e\x37\x6d\x96\x9d\xcb\xa3\xf3\x9d\xb5\x0e\x05\xf3\x0a\x1f\xb8\xa8\x5b\x34\xd2\x70\x41\x39\x6d\x72\x98\xf3\x62\x78\x25\xe6\x2d\xcf\xd4\x3e\xce\xf5\x61\x98\xe1\x5e\x5e\x08\x87\x39\xe7\xc5\xbd\x5b\x2b\x05\x4f\xe5\x67\xaa\xe7\xf2\x09\xb1\xe1\x99\xab\x0b\xbb\x72\x7d\x2d\x52\xd4\xd2\xfd\x2f\x84\x4a\x0b\x2d\x9d\xbe\xb8\xad\xf6\xba\xff\xaf\xb7\xd5\x5e\x77\xbe\xb6\xd5\x5e\xdb\x6a\xaf\xe5\x6b\x63\x52\x5a\xb7\xd5\x5e\x8f\x2b\x82\xbf\xad\xf6\xfa\x83\x27\x01\x6c\xab\xbd\x56\x5f\xdb\x6a\xaf\x6d\xb5\xd7\xdd\xae\x6d\xb5\xd7\xfd\xaf\x8d\x4b\x5f\xda\x56\x7b\xdd\xeb\xda\x56\x7b\x2d\x5f\xdb\x6a\xaf\x5b\xae\x6d\xb5\xd7\x2d\xd7\xb6\xda\x6b\x5b\xed\xb5\xad\xf6\xda\x26\xc1\x7e\xb4\xad\xcd\x4c\x82\x65\xdb\x6a\x2f\xba\xb6\xd5\x5e\x8f\x22\xd5\x8f\x6d\xab\xbd\xee\x74\x6d\xab\xbd\xb6\xd5\x5e\x6d\xae\x6d\xb5\xd7\x63\x71\x97\x6c\xab\xbd\xb6\xd5\x5e\x7f\x1c\x45\x77\x5b\xed\xb5\xad\xf6\xda\x56\x7b\x6d\xab\xbd\x3e\xd8\x8b\x6d\xb5\xd7\x63\x30\x01\x3d\x23\x70\xf7\xea\xa5\xdd\x23\x9d\x17\x95\x15\xec\xb5\x6f\x32\x68\x91\x28\x18\xa4\x89\x35\x82\xee\x29\x84\x89\x56\x13\x39\x25\xc9\x7e\x80\x34\xbc\xc3\xf0\x3e\xc3\x88\xfa\xf6\x01\xe6\x0f\x66\x32\x97\xed\x4a\xca\xd8\xd2\xc4\xbc\x80\xb6\xa2\xb8\x8c\xdb\x49\x39\x7f\x07\x5b\x84\xe7\xba\x42\xea\xe2\x84\xe6\x2f\x0c\x21\x46\xaf\x36\x6e\x66\x58\x3f\x26\x0e\x4f\x7d\x5e\xdd\x79\x1f\x69\x25\xdc\x5a\x51\xaa\x67\xec\xbf\xf7\xde\x7e\xf1\x7e\xb8\xff\xdd\xde\xde\xaf\x4f\x86\xff\xf9\xdb\x17\x7b\x6f\x47\xf0\x8f\xbf\xec\x7f\xb7\xff\xde\xff\xf1\xc5\xfe\xfe\xde\xde\xaf\x3f\xbd\xfc\xe1\xf2\xfc\xe4\x37\xb9\xff\xfe\x57\x55\xe5\x57\xf8\xd7\xfb\xbd\x5f\xc5\xc9\x6f\x77\x6c\x64\x7f\xff\xbb\x3f\xb7\xee\x72\x67\x95\xb8\x3f\x85\xb8\x27\x75\xf8\x93\x28\xc3\x14\xd0\xed\x69\x2f\x52\x32\xca\xd2\x6e\xa4\x03\xeb\x43\xbb\xd1\x4b\x53\x50\xf3\x42\x3b\xd2\x30\x9d\x4b\xeb\x94\x43\xa7\x0f\xf2\x38\x9d\x55\xda\x86\x51\x4a\x72\x00\x12\xba\xb9\x45\xa2\xf5\x90\x0a\x1a\x25\xb1\x68\xaf\xf9\x11\x13\xbd\xcc\x8b\x0c\x08\xce\x61\x3f\x0f\x7d\x2e\x0b\x1c\xae\x5b\xd9\xf0\xf1\x6b\x2b\x1b\x1e\xa3\x6c\x30\x22\xa9\x4a\x69\xe7\x47\x5a\x59\xf1\xae\x95\x87\xa5\x29\x1a\x2e\x9a\x0d\x52\xce\x98\xa1\x5c\x37\xfc\x8e\xe9\x02\xf3\xbe\x17\x0a\xeb\x67\xba\xca\x52\x28\xe6\xa8\x14\x18\x98\x58\xa5\x27\x2c\x5a\x7f\x60\xf7\x40\x2a\xf7\xe2\x43\xbc\x3d\x87\x66\xe6\xef\x95\xbc\xe6\x99\xb3\x76\xeb\x5f\x9c\x83\x05\x13\xff\xe8\xae\x7b\xde\x72\x73\x55\x6f\x78\x31\x74\x3a\x74\xe8\xf3\x81\x7f\x25\xf8\x48\xbc\xb3\x0f\x51\x4b\x03\x05\xe9\xbc\x94\xd7\x32\x13\x53\x71\x62\x12\x9e\x81\x5c\xeb\xe7\xac\x38\xbc\xa5\x75\x98\xf8\x52\x67\x86\xdd\xcc\x84\x93\xd5\x8c\x7b\x17\x00\x54\xd8\x4d\xb9\x54\x58\x17\x5f\xf8\x1f\x1b\xf4\x25\x38\xf1\x5f\xf0\xd2\x4d\x70\xf0\x19\x80\x89\x3c\xd6\x3a\xa3\x8a\x87\x6c\x5e\xb7\x4f\xb5\x3f\x4a\xff\x53\x89\x9b\x7f\xba\xd6\x0c\x9b\x64\x7c\x1a\x5c\x05\x46\xd8\x25\x6f\x5f\xdd\xf4\xad\x2f\x00\xe5\x04\x95\x60\x3c\xbb\xe1\x73\x53\x3b\x4e\x22\x04\x08\xf3\x8c\x3d\xdd\x87\xe5\xcc\x0d\x0b\x6d\xa4\xec\xcb\x7d\x08\xff\x1d\x1d\x9e\xff\xf3\xe2\x1f\x17\xff\x3c\x3c\x7e\x79\x7a\xc6\xce\xb4\x15\x78\xa8\x45\x34\x81\x49\xb0\x30\x5c\x2f\xe1\x19\x60\xa5\x6b\x33\x02\xdf\xa5\x34\xec\x46\xaa\x54\xdf\x98\xd6\x3e\x5a\x5c\x7e\x6e\xf0\x04\x57\xad\xda\x48\x78\xc1\x81\xfd\xb0\xc3\x09\xb3\x94\x61\x12\x37\x0a\x67\x78\x9a\x1e\xa4\xa5\x2e\x70\x10\xbc\x93\xab\x3e\x6a\x9b\x66\x74\x9c\xc3\x0a\xf3\x3b\x69\x36\x38\x2d\xb9\xb2\xb5\xb7\xa7\x9e\x33\xa2\x5d\x1c\x75\x9e\x8e\x87\x5d\xd1\xc4\xd3\xfe\xaa\x99\x0e\xd3\x54\xa4\x8d\xe1\x7f\x74\x99\x83\x47\xfe\xe5\xe6\x35\x4a\x05\x3b\x7f\x75\x71\xfa\xff\x2c\xac\xe3\x79\xd1\x2d\x51\xaa\x9f\xca\xd8\x52\x17\xbd\xcd\xee\x6b\xaa\xbc\xdc\xce\xef\x46\xcc\x6f\x38\x2d\xfb\x09\xcf\xbf\xae\x54\x13\xd2\xa8\x6e\x9f\xe5\x3a\x15\x23\x76\x1e\xe2\x04\xcd\x6f\x23\x80\x03\x5e\x0a\xe6\x6e\x51\x56\xf2\x2c\x9b\xc7\x2a\x9a\xd5\x58\x85\xd8\xc0\x66\x88\x05\xf9\x84\x67\x66\xdd\xd2\xb8\xcb\xd9\xe8\xf4\x88\x97\xce\x1e\xee\x65\x3a\x42\x6b\x2c\x15\x4a\x5b\x52\xac\x5d\x2f\x01\xef\xa2\xd4\x09\x43\xe3\x3b\x4a\xc6\x6a\x9c\x6f\x06\x63\x15\xfe\x68\x94\xc6\x0f\xf6\x79\x68\x19\x1d\xd5\x95\x11\x8b\x0a\xba\x67\x24\x0e\xe6\xb8\x6b\xbd\x14\x3c\xd5\x2a\x9b\x43\xe6\x25\xe6\x52\xe4\xdc\x5c\x89\x14\x3f\x20\xd5\x2c\x44\x2a\x5c\x8b\xe1\x51\x97\xae\xdf\x3e\x2c\x01\x2a\x19\x66\x78\x40\x38\x43\xa4\x6b\x9e\xf5\x0e\x9b\xd0\x0d\xca\x2b\x95\xcd\x5f\x6b\x6d\x9f\x87\x32\xda\x5e\x56\xc0\x2f\xa4\x2d\x37\x5d\xd1\xa0\x4e\x72\x78\xee\x10\x66\x03\x36\x55\x5c\xc1\x7b\x5c\xcf\xf8\x43\xdf\x52\x65\xa5\x0e\xcd\x0f\xa5\xae\x5a\x1f\x62\x4b\xca\xe6\x0f\xa7\xc7\x20\x8a\x2a\x0a\x55\x2a\x5b\xce\x01\x3a\x60\x19\xff\x2d\x18\x06\x6f\x28\xd8\x1a\xef\x89\x3a\x2e\xc6\x5e\xf2\x39\xe3\x99\xd1\x7e\x2c\xa5\x5a\x69\x85\x92\x89\xeb\xbe\x1e\x6b\x3b\x5b\xb2\x6d\xdd\x86\x5a\xfe\xdd\x20\x8a\x5c\xd6\x80\x74\x52\x2d\xfd\xdc\xf2\x2b\x61\x58\x51\x8a\x44\xa4\x42\x25\xeb\x9e\xf6\x75\x07\xfc\x60\xe9\x9c\x69\xe5\x36\x66\x2f\x8b\xe7\x34\x44\x7a\x69\x48\xe3\xa5\x02\x31\x63\xb2\xfe\x38\x44\x8e\x61\x5b\x56\x46\x94\x18\xe6\x2e\x2b\x81\x33\xf9\x53\x35\x16\x99\x1b\x79\x67\x92\x12\x67\x3c\xba\x33\x64\xce\xa7\x82\x71\x1b\x56\x9a\xd5\x4c\x28\xe3\x24\x26\x3a\x40\x2d\x4b\xb5\xa8\xab\xef\xb9\x61\x6f\x4e\x8f\xd9\x13\xb6\xe7\x9e\xb5\x0f\xeb\x07\x28\xe5\xad\xc6\x24\xb7\x45\x1b\x75\xe2\x9b\x80\x2e\xc1\xe2\x65\xba\x44\x21\x31\x60\x4a\x33\x53\x25\xb3\x98\xc7\xde\x9b\xcd\x94\x08\x09\xa1\x95\xcd\x5c\xeb\xeb\x95\x50\x6f\x8c\x28\x7b\x13\x50\x6f\x5a\x08\xa8\x58\x8d\x72\x6b\xae\x39\x7a\xb8\xb0\x72\x61\x79\xca\x2d\x27\xc1\xe5\x6f\xd8\xd8\x29\xfd\x63\x8b\x2f\x23\x5e\x48\x55\xbd\xc3\xc4\xa3\xfe\x5c\x2d\x17\x27\xd0\x2c\x4b\xfc\xa8\xc3\xac\xf3\xa2\xc8\x24\xa2\x6d\x2c\x24\xc2\x9d\x36\xd6\xca\xe0\x16\x35\x11\xe4\x04\xcf\x32\xed\xe4\xa3\x53\x4e\xb8\x4a\x75\xbe\xf4\x30\xa7\x44\x8a\x06\x72\xea\x88\x6d\x57\x5f\xf3\xda\x10\xa7\x50\x26\xae\x45\x07\x6c\xb1\x45\xa4\x58\xd7\x9a\x1b\x1c\xbf\x22\xa0\x79\x96\xf1\xb1\xc8\x70\x8c\x71\x05\x9a\xe5\x15\xb8\xee\x6c\xd4\x52\x67\xfd\x95\xcf\xbc\xd6\x99\xc0\xf4\x2e\x3f\x10\xae\xf9\x07\x31\x0e\xd0\x48\x5f\xe3\x00\xd6\x60\x63\x1c\xc0\xae\x7d\x08\xe3\x50\x75\x38\xea\xd9\xe2\x38\x38\xbd\xa1\x39\x0e\x70\x78\x6f\xfa\x38\x18\x91\x24\x3a\x2f\xce\x4b\xed\xcc\xce\xde\xce\x26\x6a\xb6\x8e\x19\xa2\x63\x63\x45\x32\x16\x9c\x05\xcd\x9b\x79\x19\x25\x76\x72\x8b\x87\x84\xcf\xee\xfc\xff\x45\x67\x16\x88\x9e\xc5\x83\xcc\xb7\xd2\x08\x2f\xba\x5f\xd2\x17\x0f\xf9\x38\xe8\xa3\x36\xa2\x83\xb3\xb3\x97\xd3\x48\x27\x3c\x03\xec\xd8\x6e\x4b\x8e\x2d\x2e\xbb\xc5\x86\xa3\x74\x5e\x88\x51\xc2\x67\x3e\x81\x04\x60\x44\xe1\x13\x72\x61\x2a\x9d\x8a\x28\x96\x8d\x79\xc8\x97\x98\xf6\x09\xf7\xf9\x4c\x62\xa7\x57\xf8\xb0\x72\xda\xf8\xb5\xd5\x84\x80\xf6\x32\x20\xd2\xba\x0e\x0a\x95\x4a\x35\x05\xbf\xda\x80\x95\x22\xc3\x1c\x64\x12\x02\x57\x68\x41\xee\xc2\x96\xf0\x8d\xfa\xfd\xe0\x1f\x0d\xba\x98\xd4\x8a\x5a\x06\x4f\x91\xd7\xb0\x26\x28\x6e\xa5\x61\x3b\x2f\xfc\x00\x74\x80\xf0\xdc\xc4\x13\x66\x07\xdf\x30\xcc\x26\x7a\x3a\xaf\xa4\x4a\x29\x5d\xb7\x31\x58\x01\x03\x1e\xf5\x60\x48\x04\x97\x69\x2c\x5b\x9e\xb1\xb7\x8a\x85\xc1\x62\xc3\xd6\xcb\xe3\x35\xaa\xcc\xde\x47\x37\xfc\xb0\xe3\x35\x3c\x64\xb1\x99\x37\x0a\xe6\xde\x3d\x77\xe8\x2c\xf7\xe5\xfb\xfc\xbb\xac\x15\xba\x87\xa4\x5f\xdf\x56\xcc\x2f\xd8\xac\x57\xe9\x13\xb7\xac\xad\x54\x53\x13\x5b\x32\x3c\xcb\x1a\xce\xf0\x55\xa6\x8c\x9f\xe1\x80\xf8\xbf\x6c\x42\x2c\x94\x19\x3c\x14\x33\x24\x73\xea\xc4\x03\x37\x42\xa6\xb9\xe1\x47\xa5\x1b\x09\x2b\x79\x76\x51\xb4\x87\x28\x65\x4b\x70\x78\x2f\x2f\x0e\x9b\x4d\xc3\x61\x0d\x84\x14\x6e\xae\xdc\xf7\x8c\xa7\xb9\x34\x06\x1c\x61\x62\x3c\xd3\xfa\x8a\xed\x7d\x90\xa9\x61\x68\xe4\xd4\x1c\xd0\x9a\x1f\xba\xde\xef\x33\xa9\xb2\x90\x15\x05\x76\xb0\xb2\xc6\x3b\x72\xe0\x21\x49\xe8\x05\xcc\x21\xe1\x56\x53\xb2\xc2\x72\x37\x11\xa9\xda\xad\x82\xb5\x0b\xec\xe5\xe9\x39\xeb\x08\xbb\xf2\x91\x29\x3a\xa3\xb5\xbd\x88\xac\xb6\x72\x1c\x51\x7b\x5c\xfb\x20\x91\x72\x91\x08\xd3\x1f\xa0\xd3\x8f\x75\x9b\x2c\x15\x58\xc5\x23\x20\xfb\x89\xdf\x9a\x64\x07\x7e\xe9\x5d\x28\x06\xa5\x9f\xee\xc6\x1a\xf5\x65\x2d\x5c\x9c\x3d\x92\x15\x33\x3e\x44\x23\xdd\x49\x34\x10\x81\x5e\x85\x98\x69\xa5\xa9\x48\xc2\x1d\xa2\x5a\xc1\x92\x06\x11\x85\xd1\x3c\x98\x13\x12\xd1\x51\x57\x8f\xea\x28\x71\x1c\x08\x84\x62\x32\x1b\xa8\x55\xb0\x0f\x37\xd2\xce\x00\xe7\x75\xb6\x10\x35\x84\x9e\x94\xc2\x40\x00\x46\x31\x51\x96\xba\xa4\x84\x2c\xef\xb7\x86\x96\x40\x92\x43\x46\x97\x5b\x24\xdc\xfd\xb5\x6b\xe2\x40\x75\x0d\x05\x0f\xf9\x8a\x6e\x35\x89\xc9\x44\x24\xa0\x68\xc5\x03\x8c\x52\x7b\xaf\x06\xbe\xa5\x2a\x03\xb7\xc0\x08\x4a\x3e\x97\xef\xdc\x53\xe2\x5f\xc5\x21\x71\x02\x9c\x5d\xfd\xf5\xfe\x88\xb1\x53\x15\x32\x78\x07\x6e\x16\xe3\x3b\x7d\xea\x99\x75\xaf\x18\xf3\x10\xc0\x0b\xc4\x8e\x33\xa7\x1d\x96\x55\x0f\x2b\xbe\x8b\x3b\x9c\xc5\x2e\xf1\x5e\xc5\x01\xb8\xc6\xa9\x51\x37\xf5\x5e\x07\xe8\xe2\x2a\x77\xb7\x7c\x2a\x77\xf9\xc3\x08\x80\xb0\xae\x72\x8e\xd0\x14\x7a\x02\x87\xbf\x88\x5a\x8b\xb4\xf7\x10\x70\x3b\xd7\x29\xa2\xa9\x04\x34\x88\x6c\xee\xd1\x5d\xe4\xbf\xbd\x7e\x56\xeb\x78\x4a\x63\x75\x40\x0c\xb3\x42\x90\xda\x29\x73\xaa\x76\xe6\x7d\x0b\x79\x91\x09\xa8\xe2\x8c\x5a\xae\x0b\x54\x23\x34\xf9\x41\xe8\x48\x0d\x48\x4f\xe0\x2e\x03\xf6\x3f\xb0\x29\x43\x22\xaa\xc7\x9d\x38\x0f\x3f\x47\x0b\x51\x1a\x4f\x2d\x01\x15\x96\x56\x7b\xd7\x05\x4b\xe5\x64\x22\x7c\xc2\xab\xb3\x1c\x79\xc9\x73\x27\xe2\x0d\xa3\x21\x18\x8b\xa9\xc4\x84\xc8\x20\xd8\x76\x9d\xba\x47\xb5\x7e\x03\x14\x86\xd2\xb2\x5c\x4e\x67\xb8\x50\x18\x87\x0a\x5d\xe6\x83\x8a\x99\xe6\x29\x50\x52\x31\x5d\xb2\x1b\x5e\xe6\xee\xdc\xe0\xc9\x0c\x22\x94\x5c\xb1\xb4\x2a\x01\x65\xd9\x0a\x9e\xce\x87\xc6\x72\xeb\x34\x65\x51\x92\x41\xe9\xfb\xbf\x85\xd4\xff\xe0\xb5\x85\xd4\xbf\xe3\xb5\x85\xd4\xdf\x42\xea\x2f\x5f\x1b\x93\x1d\xba\x85\xd4\x7f\x5c\x30\x49\x5b\x48\xfd\x75\x47\x13\xb6\x90\xfa\x5b\x48\xfd\x0f\x5d\x5b\x48\xfd\x8f\x5c\x5b\x48\xfd\x16\xd7\x23\x90\x5c\x5b\x48\xfd\x16\xd7\x16\x52\x7f\xf5\xb5\x85\xd4\x5f\xbe\xb6\x90\xfa\xb7\x5e\x5b\x48\xfd\xd6\xd7\x16\x52\x7f\x0b\xa9\xbf\x45\x1a\xbd\x5f\x5b\x9b\x89\x34\xca\xb6\x90\xfa\x74\x6d\x21\xf5\x1f\x05\x9e\x22\xdb\x42\xea\xdf\xe9\xda\x42\xea\x6f\x21\xf5\xdb\x5c\x5b\x48\xfd\xc7\xe2\x2e\xd9\x42\xea\x6f\x21\xf5\xff\x38\x8a\xee\x16\x52\x7f\x0b\xa9\xbf\x85\xd4\xdf\x42\xea\x7f\xb0\x17\x5b\x48\xfd\xc7\x60\x02\x1a\x9b\xca\x56\x08\xa0\x77\x01\x2b\xa2\x24\xf4\x08\x1b\x60\x5c\x4d\x26\xa2\x04\xc9\x05\x4f\x5e\x4a\x9e\xaa\x71\x19\x17\x83\xac\xc2\x0e\x00\xf7\x88\xea\x75\x6e\xf9\x39\x81\x11\x00\x52\x67\x9d\x29\x7e\xf2\xea\xf9\x0a\x64\xa4\xd6\x59\x85\x6d\x73\xa4\xa1\xcf\xaf\x54\xbb\xf8\xf8\x2d\x03\xbe\xaa\x7e\x8c\xc6\x3d\xc9\xb4\xa1\x0c\x77\x18\xac\x64\xc6\x95\x12\xde\xde\x93\x16\xfc\x28\x63\x21\x14\xd3\x85\xa0\xe8\x34\x67\x46\xaa\x69\x26\x18\xb7\x96\x27\xb3\x91\x7b\x92\xf2\x83\x5d\x67\xa3\xd3\x27\xc6\x96\x82\xe7\x3e\x2f\x3f\xe7\x12\x9b\x62\x3c\x29\xb5\x31\x2c\xaf\x32\x2b\x8b\xd0\x18\x33\x02\x0a\x6a\xf0\xa0\x0a\x83\x01\x59\x71\x75\x0a\xfb\xa0\x7e\x1a\x75\x4b\xc7\xd0\x74\x60\x6d\x0e\x00\x0f\x3c\x2f\xec\x3c\xe4\xf1\x0a\x36\x91\xa5\xb1\x2c\xc9\x24\x9c\xd6\xf0\x44\xac\x9d\x86\xf6\x06\xfe\xac\x56\xd4\x53\x43\x5d\x55\x29\xa8\xad\x85\x35\x98\x15\x5b\x37\x48\x4d\xa5\xd2\x90\x9a\x6f\x06\x8c\x7b\xdc\x34\x1c\x68\xdf\x53\x18\x6a\x7f\xb2\x60\xeb\xf4\x51\xd4\x5c\x84\x17\x5b\xa7\x0d\xd7\x0b\x1d\x4a\x1c\xfc\xe2\x1c\x34\xaa\x39\x6a\x85\x02\xb2\xf4\x96\xb6\x01\x4c\x80\x12\xd7\x6e\x0d\x88\x44\xb8\xf3\x95\xdf\xb2\xea\x3f\xfb\xa2\x8f\x0e\xc5\x97\xc2\x18\x3e\x15\xe7\x2d\x03\x0d\xb7\x59\x64\x10\x6b\xa8\x27\x06\x96\x42\x86\xd5\xb5\xe1\x93\x3a\x3b\xb3\xa9\x06\xb1\x1c\xfb\x14\x94\x9f\x9b\x52\x5a\x2b\x60\x52\x01\x61\x0f\x62\x95\x8b\x05\xf8\xbb\x0b\x39\x9e\x2f\x7d\x23\xf5\x8f\x9d\x50\x57\x29\x66\x5c\x8e\x05\x1b\x97\x52\x4c\xd8\x44\x42\x1a\x27\x24\x56\x0e\x10\x70\x89\xa3\x17\xc0\x18\x67\xef\x6a\xe5\x75\x59\xdf\xaf\x11\xfb\x85\x3a\x66\xcb\x4a\x25\x3c\xc2\xb2\x85\x0a\x53\x39\x61\x53\x48\xcc\x24\x6d\xf1\xaf\x4f\xfe\xf3\x6f\x6c\x3c\x77\x47\x1a\x68\x56\x56\x5b\x9e\x85\x97\xcc\x84\x9a\xba\xb1\xc2\xed\xd9\xac\x91\x0c\x23\x00\x6c\x1e\xd8\xf1\xa7\x5f\x5e\x8d\x9b\x67\xec\x41\x2a\xae\x0f\xa2\xf1\x1b\x66\x7a\xba\x8a\x1f\xa5\x7d\xca\x76\x4b\x93\x68\xc5\x32\xd3\x99\x4c\xe6\x9d\x17\x9a\x47\xfe\x62\x33\x7d\x83\xba\xfe\x8a\xd5\x53\x97\x5b\x15\xba\xa8\x32\x74\x3a\x3f\x0f\xd5\xc5\x95\x11\xcb\x35\x80\x2b\xf7\x05\xb8\x49\xa9\x89\x45\xdc\x74\xcc\xc7\xf5\x8f\xd4\x54\x5b\x42\x8e\xbc\x00\x00\x06\x86\xd0\x73\x9e\x65\x63\x9e\x5c\x5d\xea\x17\x7a\x6a\x5e\xa9\x93\xb2\xd4\x65\xb3\x2f\x19\x77\xd2\x72\x56\xa9\x2b\x64\x70\x08\x10\x09\x7a\xea\x54\xab\xa2\xb2\xbe\x90\x61\xd5\x0b\x63\xbd\xbc\x17\xc2\xde\x0c\xaa\x5b\x11\xef\x64\x6d\xeb\x50\xa9\x16\xae\xc8\xb8\x7d\x13\x2f\xb6\x2f\x9f\xfc\xf5\x1b\x5c\xba\x4c\x97\xec\x9b\x27\x90\xb3\x6d\x06\xb8\x89\x41\xb6\xb9\x83\x22\xe7\x59\xe6\xcc\x86\x78\x51\xba\x81\x5e\xb5\x08\x3f\xfb\x1a\xb4\xdd\x97\xdb\x9d\x55\xa9\xcb\xcb\x7f\x80\x1e\x25\xad\x11\xd9\x64\x80\x55\x49\xc1\xac\xd9\x85\x83\x61\x97\xa4\x0f\x94\x86\x6d\x80\x02\x74\xad\xb3\x2a\x17\xc7\xe2\x5a\xf6\x41\xe2\xd4\x68\xcd\x9b\xfa\x99\x34\x50\x00\x36\xce\x74\x72\xc5\x52\xfa\x32\xca\x3c\x59\x44\x02\x6f\x3f\x0a\x6d\x73\x70\x3a\xe4\xde\xdc\xfa\xfe\x8d\xac\x9b\x9c\x17\x45\xa8\x11\x2a\xf9\x4d\x63\x30\x60\x4f\x02\x5c\x41\x47\x3c\x99\xce\x6e\xe6\xae\x4e\xe6\x21\xbd\x91\x93\x9b\xad\x9b\x68\x9d\x75\xd2\xdd\x47\x5d\xf7\xbe\xbd\x63\xb2\xb1\x20\xea\x06\xfd\x6e\x28\xe0\xdf\x58\x55\xb2\x54\x15\x19\x0a\xeb\xc2\xc2\x40\x05\xc0\x2d\x1f\x10\xc9\xed\x1d\xae\x3d\x78\x37\xbb\xa5\x1c\x35\xc6\x45\x05\xaf\x72\xce\x2d\x29\x84\xde\x7d\xcd\x59\x21\x4a\x23\x8d\x3b\x97\x7f\x86\x0d\x75\x94\x71\x99\x47\x2e\xc0\xf5\x0c\x02\x6e\x6e\x80\x4f\xee\x2e\x29\xcf\x75\x4a\x0d\x82\x28\x44\xe8\xe8\x15\x6a\x6d\x53\xab\xed\xf1\x40\x5d\xb7\xa8\xfc\xb9\x1e\xcd\xa6\xa4\x74\x9f\x04\x51\x89\x77\x3d\x26\x01\x09\xef\xf7\x50\xe5\x63\xe8\x7c\x4f\x62\x00\x04\x23\x4d\x6e\x53\x12\x36\x8c\x47\xdc\x28\x91\x4a\x4f\x76\xe0\x88\x61\x14\xdc\xed\x09\xfa\x29\xdb\x7d\xb6\xbb\x56\x21\x89\x43\x54\xea\x82\x4f\x3b\x71\xf9\x2c\x8c\xd4\x62\xb3\x31\xd0\x84\x33\x83\xe0\xfb\x00\xbb\x06\x77\x89\xb4\xc6\xd1\x01\x94\x24\x8c\x8e\xfa\x01\x26\x03\x01\xeb\xb1\x6f\xf8\x9c\xf1\x52\x57\x2a\x25\xff\x52\x70\xf0\xbd\x5c\x78\xf0\x99\x56\xc2\x3b\xce\x17\x71\x2a\xc0\xa3\x2f\x15\x7b\x3a\x7a\xfa\xe4\xb1\x9c\x54\xf0\x86\x0b\x27\xd5\x59\x38\xa9\x50\x3e\xad\xf5\x5d\x3d\xe2\x7d\x4f\xef\xfb\x92\x5c\x2c\x35\xa0\xbd\xf4\x70\xd9\xf0\xd1\x4d\x29\xad\x88\x38\xfe\xf6\xc0\x70\x71\xf6\x61\x84\xca\xb0\xbf\x8a\x49\xa2\xe3\x20\x75\x83\xc1\x30\xd5\xf8\x13\xca\x2d\x12\x50\xb0\xdd\x56\x79\xb8\xcc\x07\x44\x58\x3c\x50\x3b\x3b\x6c\x0f\xef\xdc\xc5\x82\xe6\xfd\xb5\x2e\x2d\x1a\xb4\x93\x77\x45\x07\x8c\xcd\x85\xda\xf9\x82\x83\x0f\xae\xe8\x71\x04\xbf\x17\x33\x7e\x2d\xa0\x90\x5b\x66\xbc\xcc\x20\xe6\x78\x81\x7d\x67\xe3\xca\x32\xa1\xae\x65\xa9\x55\x2e\x94\x65\xd7\xbc\x94\x80\x8a\x53\x0a\x40\x76\x70\xb6\xe8\x9f\xf7\x7e\x3e\x7c\x0d\x09\x0d\xfb\x04\x49\x41\xbd\xac\x8c\x87\xaf\x89\x7b\x12\x35\xf7\xd1\xe9\xf3\xfd\x70\x63\x08\x32\xd7\xf7\xcb\x3d\x27\xaf\x6c\x85\xb4\x2c\xef\x92\xac\x32\xf2\x7a\x5d\x92\x84\x2a\xec\x8f\x65\xab\x79\x5e\xa8\xf6\xaf\x07\x6a\xa9\x70\x1f\x5c\xeb\x2b\x0a\xf4\x96\x02\x26\xbb\x26\x14\xed\xc5\x31\x70\x72\x3d\x11\x96\x06\xa6\xcf\x79\xc4\xc5\x25\x15\x02\x70\x63\xd6\xeb\x84\x52\x3a\x15\xf7\x47\xdd\x69\xa6\xf7\x50\x13\x18\x33\x8f\x2a\xf8\x4c\x32\x13\x69\x05\xf0\x4e\xd2\x20\x38\xaa\x33\x1f\x78\x8d\xc2\xa7\x80\x25\xe8\x74\x12\x20\x0d\xd4\x10\x9c\x83\x38\xe6\xfe\xf7\xa5\x07\x40\xf0\x1f\x98\x85\x16\xc1\x28\x75\x6d\x0d\x18\x37\xa6\xca\x71\x4b\x20\x01\xc2\x44\x5a\x13\x38\x66\xbd\x76\xec\x36\xc6\x3d\x0b\xaa\x3a\x8c\xef\x85\xc8\x60\x71\x75\x18\xe3\xdd\xb3\xa8\x1d\x1c\x68\xe3\xff\xa2\x05\x47\x09\x13\x10\x6d\x0b\x79\x9c\x1a\xbc\xa4\x13\x09\x24\x4a\x9c\xc6\xfb\x62\xc5\x2f\x51\x75\xc0\x3b\x00\x1e\x86\x8f\x45\x66\x16\x1b\x1a\xd7\x93\x42\xa8\xa4\x34\xf0\x1d\x59\x72\xb9\x31\x72\xaa\x80\x3f\xd3\xb5\x76\x4f\xa6\xcc\xd6\x36\x53\x1f\x2c\xb8\xad\xa5\x5a\x23\x0b\x2b\xe7\xc5\x90\xac\x5e\xab\x73\x99\xdc\xa3\x25\x7d\xcf\x2e\x2f\xd4\x4a\x37\x6a\x70\x5f\x5d\x2c\x79\x7c\x4c\xe4\xd5\x18\xb1\x0b\x9d\x53\x8a\x93\x8a\x58\xbc\x3c\x99\xaa\x3b\x31\x4a\xe1\xc6\x02\x12\x8f\x64\x1d\x8d\x07\xd6\x1b\x5f\x05\x0d\xcf\x09\x2a\x39\x85\x71\x01\x7e\x92\xc8\x5c\x75\x96\xe9\x1b\x48\x2c\xc6\x76\xfd\xda\x86\x14\x98\x67\x6c\xb8\xc0\x4c\x3b\x6a\x82\x86\x7e\xf8\x39\x74\xef\xe0\xe3\x4f\xc1\xfc\x1c\x80\xe3\x3b\x3d\x8e\xff\x3c\x3d\x3f\x8a\xff\x7c\x63\xdc\x28\xd1\x07\x8b\x5d\x6b\xb2\x32\xdc\x7e\x57\x8c\x8f\x7d\xdb\x5d\x13\x24\x36\xfa\xc8\xd7\x47\x33\xae\x7c\x20\xeb\xd6\xe7\xcd\x4d\x62\xb3\xba\x3b\x33\x5e\x0a\xc2\x8f\x73\x92\xdc\x14\x3c\xb9\xb5\x17\x01\xac\xed\x83\x37\x7c\xb0\xa7\xa6\x2a\x3c\xe1\x76\x06\x37\x86\x9e\xd4\xcb\xee\xd7\xbf\xfc\x76\xc7\xc1\xfc\xd8\x6f\x56\x0d\xed\x87\x7f\xd3\xa0\xed\xbb\xd3\x2f\x56\x93\x7a\xdd\xed\xb7\x11\x2f\xde\x9d\xee\xbf\x8d\x93\xf7\xae\x4f\xf3\x5c\x6e\x77\x7b\xb1\xc5\xd9\xbe\xc3\xed\x30\xa5\xf7\x43\x2b\x68\x2d\xc2\xdb\xba\xbb\x5a\x38\xa9\xda\x3b\xa7\xda\x19\xfb\x0b\x0a\xc0\x2d\x50\xa6\x04\xb3\xa6\xa6\xac\x01\x1e\x55\x95\xa5\x50\x40\x7b\x5f\x41\xa6\xa3\xa7\xb3\x47\x21\x0d\xc2\x96\x80\x3a\x11\x6d\x9e\x1d\x86\xb3\x90\x32\xe0\x72\x0e\xe0\x9d\x11\x58\xf5\xa4\x82\x84\x46\x10\xfd\x08\x46\xa7\x95\xeb\xc7\xb3\x55\x08\x19\xba\x10\x2a\xe2\xba\x27\xad\x79\xe8\xd6\x50\x03\x33\x03\x15\x81\x51\x9e\xfe\xa9\xc8\xb8\x9d\xe8\x32\x1f\x7a\xf5\x70\xd8\x50\x12\xd8\x11\xa4\xd6\x18\x6f\x5f\x61\x7e\x2b\x82\x6a\xaa\x34\x13\xd1\x69\x1e\x5e\x55\xa5\x08\x41\xc5\x2a\x55\x8a\x44\x4f\x95\xfc\x77\x3d\x10\x70\xae\x05\xe7\x10\x37\xee\x24\x65\xaa\xca\xb2\xfb\xe7\x21\xb4\x54\x02\xf4\xb5\x28\x67\x82\xdf\x73\xf1\x2e\xa4\xb4\x50\x1b\x35\xf7\xa8\x21\x4c\x01\x52\x79\xfd\x43\x9c\x6a\xac\x13\xa8\x6d\xc3\x10\xbb\x4f\x5c\xe6\x70\xa0\x3b\x4d\x8f\xb3\xa9\xbc\x16\xca\x43\x8e\x1f\x65\x3c\xf0\x67\x7b\x94\x55\x82\x3d\xaf\xac\x0e\x49\x0b\x8c\xdb\x08\xf8\x18\x72\x9c\x28\x5e\x1a\xb7\x13\xdd\x42\xec\xdb\x99\x67\x3a\xbb\xcb\x9d\x90\x37\x80\xd4\x8f\x83\xfa\x95\x72\xef\x5b\x6d\x20\x6b\xb2\x04\xb2\x5b\xbc\x29\x42\x59\x2d\x1f\x7f\x04\xa5\xa4\x39\x19\xb4\xaa\x19\x52\x97\x03\x04\x6c\x3d\xb0\x99\x13\xff\x73\x54\x72\x4e\x27\xcd\x27\xc9\x06\xe8\x3e\xd4\x3e\x81\xfa\x5d\xdb\x83\xe7\x3a\x75\x5a\xd8\x80\x85\xa9\x8c\xc9\xc7\x29\xde\x82\x7b\x32\xda\x8c\xa8\xa4\x95\xa5\x30\x85\x46\xec\xff\xf8\xb1\x83\xc8\xff\x25\x6d\x23\xd9\x0e\x59\xdc\xc2\xd6\x40\x74\xb6\x7f\x8b\x52\xaf\xd4\xe1\xa7\xd2\x8e\xae\xbe\x01\x05\x5e\xa8\x19\x57\x09\xda\x4e\x07\x57\xa2\x30\x07\x46\x4e\x51\x5f\xff\xdb\x37\xdf\x80\xf2\xee\x87\xe4\xe0\xf5\xc9\xe1\xf1\xcb\x93\x51\x9e\x3e\x20\x4d\xbe\xe0\xd6\x8a\x52\x3d\x63\xff\xbd\xf7\xf6\x8b\xf7\xc3\xfd\xef\xf6\xf6\x7e\x7d\x32\xfc\xcf\xdf\xbe\xd8\x7b\x3b\x82\x7f\xfc\x65\xff\xbb\xfd\xf7\xfe\x8f\x2f\xf6\xf7\xf7\xf6\x7e\xfd\xe9\xe5\x0f\x97\xe7\x27\xbf\xc9\xfd\xf7\xbf\xaa\x2a\xbf\xc2\xbf\xde\xef\xfd\x2a\x4e\x7e\xbb\x63\x23\xfb\xfb\xdf\xfd\xf9\x9e\x1d\x6d\x59\x97\xd2\xb5\x16\xa5\x53\xfd\x49\x8f\x35\x27\x45\x29\x44\x0e\xe2\xaf\x4d\xb6\x56\xd3\x4b\xba\xd0\x94\x3f\x60\xe9\x2f\x27\x13\xfd\xd3\xd4\xd4\x89\x49\x83\xa2\x33\xd3\x37\x90\x61\x29\xb5\x53\x7e\x46\xec\x15\x9c\x83\xec\x4c\x5c\x8b\x72\xe0\x5b\x7d\xe1\x6e\x3a\x0f\xf7\xc4\x6e\xb8\x55\x77\xb4\xcc\xf1\x6f\x39\x27\xbe\xef\x1d\x06\x0f\x79\x4b\xa8\xf3\x20\x9f\x46\xec\x67\x5e\x4a\x5d\x19\xd2\x45\x62\xb8\x6f\x4c\x21\x0b\x27\x09\x78\x25\x28\xc0\x13\x1a\x09\x95\x61\x3e\xc6\x13\xc6\xe6\x30\xc8\xeb\xa3\xd5\x47\x82\xb4\x6e\xa6\xae\xfd\xa3\x4a\x9f\xea\xba\x84\x14\x8e\x87\xc1\x4a\xf9\xef\x4f\x34\x13\x77\x14\x9a\xf1\xfd\x00\xd9\xea\x34\x31\x6c\x65\x26\xa7\x3e\xa1\x1a\xde\x1f\xcd\xd7\xe8\xd3\xb0\x42\x5a\x4c\x69\x9b\x6d\xda\x36\xaf\xbf\x58\x7c\xbf\x0e\xcb\xa2\x89\xa7\x1c\x43\x32\xfb\x8a\xa2\x7a\xdf\xec\xe0\x3a\x81\x43\x64\x98\x94\xd2\xca\x84\x67\x3b\x70\x38\xf9\xaf\x92\xac\x72\x7a\x62\xfc\x6d\x29\x98\xbd\xd1\xf8\x14\x9e\xb1\x2b\x31\xbf\xd1\x65\xea\xcf\x67\xff\xc4\x7a\x2e\x8c\xf5\x8f\x74\xf6\x1c\x6c\x60\x74\x33\x94\xb9\x28\xd9\x58\x78\x0f\xfa\xc2\xcd\xf3\x11\x3b\x54\x73\x0a\x3f\xaa\xb8\xc8\x30\x42\x66\x03\x1d\x01\xb5\xa8\xc6\x22\xa1\x43\xcc\x3f\x8d\x63\xf9\xe7\x6d\xde\x65\xa7\x80\x85\x5d\xe0\x4f\x7f\xef\x5e\xd6\x25\x55\x39\xc1\xee\x28\xb1\x46\x4b\xfb\xaf\x3f\x8b\xb4\x70\xfa\x8d\x54\xc2\x98\x1f\xdc\x54\x76\x51\x57\x9b\xab\x83\x83\x5a\x42\x6d\x43\xa5\x54\x9d\x52\x2c\xdc\x96\xc2\x18\xb1\x13\xc3\x3a\xad\xef\x1c\xb1\x43\xf8\x00\x72\xe2\x9d\xe6\x05\x55\x74\xae\x31\x69\xcd\x22\xb9\x3c\xde\x71\x78\x76\xec\x73\x97\x51\x53\x30\x4d\xb8\x74\x54\x99\x9b\x3d\x01\x4d\x8f\x32\x68\xc5\xef\x15\x07\x9e\xdc\x9d\xcb\xb2\x12\x3b\xed\x54\x25\x04\xe2\x3f\xf8\xfa\x9b\x27\xa0\x2d\x85\xe7\x0d\xe1\x79\x6d\x54\xa5\xfb\xe7\xc8\xb4\xca\x8e\x59\x4c\x0c\x7a\x1d\xaf\x07\x3f\xe0\xde\xee\xa0\xa0\x15\xd4\xf6\xc2\x34\x85\x31\x6f\xe5\x5a\x6d\x95\x0b\xd3\x3e\x0b\x66\x58\x77\xf7\xf2\xfe\x1c\x66\x5d\x12\x58\x1a\xcf\xed\x23\xca\x55\xb7\x86\xb3\x62\x70\x4a\xc2\x73\x22\xcf\x2e\x52\x5d\xd0\xc7\x90\x0e\x0b\x82\x0b\xa2\x02\x20\x1e\xe7\x45\x87\xd4\xdf\x16\xf2\x06\x2a\x5d\x3a\xeb\x77\xbb\xaf\xb1\x21\x56\xd4\x0a\xdd\x52\x05\x43\x88\xf0\x82\xde\x41\xaa\xdc\x21\x94\x83\x0d\xd8\x2b\xf5\x1c\xf3\xe3\x07\xa8\xdd\x35\xd0\x47\xf0\xa6\x5e\xcb\x04\x0f\xfe\x44\xef\x3e\xc4\x2e\xb7\x11\x0a\xf7\x1f\xee\xc8\x72\xec\x78\xfa\xef\xbe\x5e\x68\xab\xb1\xf4\x1a\x96\x31\x9d\x90\xb2\xe6\x3e\x23\xf1\xc9\xa6\xa5\xae\x0a\x1f\x49\x6d\x12\x99\xd5\xec\x1d\x18\x00\x44\x9e\x5f\xa5\x9b\x4d\x07\xe7\x07\x2c\x60\x51\x7b\xcd\x52\x96\xa0\x79\xec\x4f\x5d\xac\x82\x42\x0f\x42\x59\xa9\x26\xcf\x79\x14\x8b\xdc\xc9\xc4\x94\x27\xf3\x9d\xe6\x73\x56\x45\x7e\x25\x14\xe7\xc8\x1c\x01\xd3\xf1\x79\x75\x4d\x03\x94\x3e\x80\xfe\x80\x7b\x0d\x54\x83\xca\x50\x17\xfd\x91\xef\x8b\xf2\xd0\xb3\x55\x76\xb0\xcc\xbf\xfe\xe6\xeb\xa1\xf7\xbd\x41\x57\x3e\xcb\x82\x0a\x91\xdb\x5e\x75\xc9\xc6\x9c\x39\x05\x49\x9a\x02\xe6\x17\x34\xb1\xfa\x38\x0f\x4f\xff\x90\xba\xb5\xba\x11\x3f\x01\x75\x13\x9f\x65\xb8\x9a\x5e\xf4\x2e\xdb\x6f\x91\xf6\x65\xa6\xb3\x14\x36\x0a\x91\x33\xf9\x47\x31\x6e\x6d\x29\xc7\x95\x25\x37\x69\xa2\xf3\xbc\x59\x33\x49\x04\x79\x23\x56\x17\xcd\xc5\x26\x2c\xac\xe4\x11\x63\x17\x42\x20\x39\x64\xd4\x0f\x90\xb3\x7e\x28\xc9\xdb\xaa\x27\xc8\xe4\x8d\x46\xd8\x67\x72\x0b\xb5\x3f\x8e\x29\x98\xd6\xd1\x6b\xbf\x73\x18\xac\x94\x38\xe6\x85\x02\x6e\x89\xaf\x77\xe1\x64\x82\x74\xe2\x3a\xea\x4a\xd9\x45\x6e\x2c\x0c\x62\xc4\xc2\x5a\xfe\x09\xb9\x3d\x21\x75\x12\x22\x7f\xe8\x9b\xbc\x71\x4d\xcc\x64\x81\x36\x35\xb7\xe1\xe7\x10\xc4\x77\x5f\xc7\xd0\x0b\x40\x56\xf9\x14\x8d\x5a\x7d\x03\x5e\xe1\x1f\x4e\x8f\xc3\x1e\x71\x77\x3d\xbf\xc0\x90\xde\x97\x23\xa2\xde\xb5\x53\x99\xb2\x31\x26\x6e\x38\x79\xb9\xa7\xc4\x0d\xa6\x82\x93\xe3\x34\xe8\xd5\xd7\x3e\x45\x1a\x5b\x0b\x0f\xa7\x26\xf7\xd9\x57\x44\x82\x2a\x4a\x6f\x95\x8f\x25\xa5\x8a\xbe\x7a\xbd\xeb\xdd\xd5\x37\xc3\xf2\x66\x38\x1c\x0e\x29\xbe\x0b\x52\x7a\xd0\x18\x83\x20\xcc\x73\x9d\xca\xc9\x7c\x61\x24\xdc\x32\xaf\x1f\x01\x2b\x92\xab\x39\xf5\xae\x3b\x5f\xef\xfd\xe1\xb9\xbb\xb9\xe3\xba\xc0\x31\xac\x08\x15\x77\x8d\x4f\xad\x8a\x3e\xa3\x9d\x6c\x6a\x54\x73\x3d\xc1\x45\x0a\xd9\xf3\xb7\x4c\x8c\xf7\x02\xd1\xaa\x21\xac\x3e\xb4\xd2\xc5\xbb\x42\x23\x12\x30\x54\xa7\x00\x63\xdb\x62\x78\x02\x32\x42\xdd\xae\x82\x24\xbb\xc6\xae\x21\x85\x02\x23\x62\x7e\x10\xd8\x98\xbb\x26\x43\x77\xf6\x16\xd6\xc9\xfe\x88\x9d\xd2\xd2\x02\x83\x50\x69\xe2\x7d\x63\x5a\x31\x51\xcc\x44\x2e\x4a\x9e\x35\x1f\x44\x55\xba\xcf\x9c\xb8\x2d\xdd\x2a\xc5\x10\x40\xce\x0b\x94\xb6\x20\x3c\x53\x59\x7a\xde\xd8\x28\x34\xb7\xf3\x4a\xbd\xd6\xda\xbe\x94\x06\x74\x17\x72\x86\xa0\xa6\xb9\xb3\xea\x40\xf3\xdf\xd5\x29\xcf\x5d\x57\xf2\x67\x8b\x7f\x31\xcf\xfd\xd6\x87\xac\x75\x12\xc4\x09\xad\xfb\xd2\xbb\xbd\x21\x10\x9f\x06\x8b\x6e\xf0\xc5\xae\x22\x6f\x5b\x62\x6e\xfb\xcc\xd4\x6d\x94\x95\xc5\x6d\x03\x2d\xeb\x73\xd3\x8d\xaf\x4f\x7a\xc1\x92\x39\xd3\xb0\x4f\x3a\x2e\x9a\xd3\x65\xc6\xb8\x7a\x89\x80\xbb\x2f\x50\x61\x2a\xad\x86\xc0\xe0\x54\x19\x1f\xb8\x2c\xbd\xcb\xb7\x71\x00\x11\xad\x24\x1e\x9b\x48\x0d\xc8\x6b\x95\xde\xa9\x4e\xca\x54\xa5\x08\x19\x8a\xa9\x16\x35\x9b\x13\x37\xec\xcd\xe9\x31\x7b\xc2\xf6\x20\x3b\x37\x54\x68\x23\x26\x85\x33\x65\x17\x52\x48\x27\xbe\x89\xa6\xe9\x42\x80\x10\x4a\xa3\x2c\xf2\x54\x97\x5a\x85\x63\x98\x80\x35\x6f\x21\x28\x5c\xf7\x1a\x6f\xbb\x1e\xdb\xe5\xe0\x87\x2c\x97\x1e\x64\xd0\x9b\x16\x32\x28\x56\xac\xfb\xa0\x97\x5c\xf7\xec\xfd\xd1\x25\x54\x33\x51\xad\x87\x45\x75\x71\x02\x0d\x22\x18\xc4\x3b\x4b\x6a\xfc\x3d\xb9\xcb\x97\x41\x7f\x08\xf9\x28\xe0\x03\x94\x5c\xa5\x3a\x5f\x7a\x9a\x9b\x4d\x30\xde\xa2\xd9\xdc\x2e\xbb\xdb\xae\x4e\x25\x9c\xdd\x2a\x20\xc1\xc6\xef\xa1\xf4\xf5\x05\xf8\x0a\xa4\x09\x2b\x01\x9d\x07\x90\x14\xbe\x64\xb6\x76\x46\x46\xe8\x5c\x09\x54\xea\xac\x65\x31\x5d\xe3\xad\x5f\xeb\x8c\x8a\x18\xfc\x6b\xbb\x86\x37\xf6\xad\x6d\xcb\x30\xc1\xa2\x78\x99\x17\x0b\x6f\x0d\xee\x9c\x4d\x7d\xeb\xaa\xd5\x29\xcd\x16\xdf\x1a\x52\x5a\x1b\x6f\x0d\xe7\xee\x26\xbe\x75\x33\x83\xb9\x87\xc3\x84\x1a\x64\x9a\xf2\xa8\x89\x49\x60\x11\xe4\xa4\xce\x90\x04\x27\xd4\xc3\x92\xa3\x5d\xca\xe0\x31\xd1\xe9\x73\x8b\x6e\x9d\xf0\x8c\xb8\xff\xdb\xcd\x33\x5b\x9c\xeb\xc5\x26\xa3\x64\x0c\xee\x7a\x0b\x9f\x45\x29\x85\x1c\x11\x9a\x74\x1d\x90\x59\x08\xbe\x90\x9b\x8e\x7e\xe9\xb3\x21\xdc\xf9\x5b\x67\x38\xc6\xbf\xb6\x9a\xa8\x65\x3d\x12\x3c\x87\x0e\x0a\xcc\x57\x2c\xb8\x9d\x0d\x58\x29\x32\x04\x77\xa5\x7d\x76\x85\xa6\xd4\x6e\x23\x6d\xd2\xaf\x58\xff\x68\x50\x58\x80\x5a\x1a\x5a\x06\x97\x8f\x57\x43\x26\x28\xbf\xa4\x61\x3b\x2f\xfc\x00\xec\x3c\x64\x01\xbd\x83\xef\x13\xe6\x0e\xbd\x58\x57\x52\xa5\x84\x7a\xda\x18\x9a\x90\xa2\x8b\xba\xa1\xf7\x30\xf9\xbd\xce\x4b\x01\xce\xde\x30\x34\x6c\xd8\x7a\x31\x50\x28\xcc\x07\x44\x87\xb7\x28\x99\xde\xa7\xe2\x1f\xb2\xd8\xcc\x1b\x05\x33\xad\xa0\xfe\x41\xe9\x15\xf7\xf9\x77\x69\xc7\x80\xd8\x45\xf4\x2e\x15\xaa\x74\x14\xbf\x87\x01\x6b\x6a\x8a\x75\x2f\x91\x0a\x5f\xe3\x51\x92\x5d\x48\xf4\xce\x0b\xaa\xf7\x00\x66\x87\xf2\x5d\x97\x4e\x27\x4c\xaf\xca\x79\x39\x67\x3f\x9c\x1e\xa3\x06\xde\x30\x04\x94\xf6\x8f\x0e\x2b\x25\x25\xc8\x41\xae\xe6\x1b\xa0\x38\xb7\x83\x7d\x69\x0d\xfa\xd2\x15\x4e\xb7\x93\x99\x88\x65\x58\x1d\xd7\xd4\x05\x15\x73\xcd\x74\x96\x32\x1e\x16\x98\xf2\x85\x5c\xa9\x7f\x0e\x06\xd0\xa3\x92\xce\x91\x33\xbe\x28\x38\x5d\xa9\xba\x52\xc4\xdf\xbf\xb7\xa8\x12\xf8\x3d\xbd\x4f\xf5\xcd\xde\x33\x95\xf1\x4a\x25\xb3\x3f\xca\x92\x59\x31\xfa\x21\xd4\xc1\xd9\x95\x28\x95\xc8\x58\xc1\x4b\x9e\x0b\x1b\x18\x0c\x8d\x68\x83\xe7\xd3\x11\x0e\xa8\x1b\x18\x50\x07\x20\x9f\xf6\x4c\x84\x5d\x21\x80\xba\x00\xab\xac\xa0\x67\x9b\xe0\xe9\xe8\xba\x34\x27\xd6\xce\x96\x8d\x77\x46\xbb\xe8\xc4\x2d\xd8\x44\xb6\x42\x58\xfe\x8d\x78\xb7\x66\xed\x6e\x0f\xd6\xcd\x2f\xd8\x60\x0d\x32\xe0\x33\x19\xee\xeb\x2e\xf3\x2a\xd3\x32\xb4\xd7\xae\x59\x72\x45\x35\x79\x10\x3e\xb3\xaf\xbc\xb5\xdc\x85\x3a\xc0\x07\xe5\xe1\x9a\xe6\x86\x1f\x95\xee\xbd\xad\xe4\xd9\x45\x21\x5a\x32\xf3\x37\x79\xf9\x5f\x5e\x1c\x36\x1b\x85\x43\x09\x92\xad\xdd\x9c\xb8\xef\xa3\x92\x81\x1b\x31\x9e\x69\x7d\xc5\xf6\x56\x94\x3d\x46\x55\x2e\x46\x4e\xcd\x01\x2d\xef\xa1\xeb\xf7\x3e\x93\x0a\xf0\x69\x97\x71\x7d\xfd\x43\x92\xd0\x0b\x98\x2b\xca\x59\xa3\x63\x78\xb9\x9b\x20\xa3\x30\xa3\x66\x1d\x06\xce\xf2\x64\xdc\x3f\xdf\xcb\x5f\x1f\x99\x90\xdb\xca\x5f\x57\x8e\x1a\x3a\x34\xd6\x32\x24\x64\x6e\x3b\xf5\xbd\x87\x71\xf8\xb1\x6e\x2d\x86\x53\x93\x93\x06\xd2\x7b\x6d\x28\x85\x60\xe5\x2e\x30\x4e\xd1\x4f\x77\x63\xad\xbe\x89\x87\xc6\xb3\x62\xc6\x29\x35\x0c\xcb\x81\x7d\x06\xc5\x58\xb0\x99\x56\xba\xa4\x32\x87\xba\x90\x07\xc4\x0c\xd6\xdd\xc0\x0c\x90\xbc\x8d\xba\x7a\x54\x7b\x90\x3c\x09\xca\x24\xe3\x53\x60\xac\x59\xa8\xc6\x01\xe1\xaa\x2b\x8c\x6a\xc6\x37\xfb\x92\x45\xcf\xc6\x00\x60\xd0\x06\xa5\x98\x0f\x66\x52\xd9\x06\x64\x81\x1c\xba\x7e\xbb\x61\x39\xf7\xc9\xcc\xbe\x0b\xe0\xa6\x08\x45\x9b\xc6\xad\x1d\xcc\xdf\x90\xd7\xa2\x31\xc0\x28\x79\xf7\x3c\x14\x8d\xc5\x24\x2b\x3c\x2f\xe0\xf7\x9c\xe5\xf2\x9d\x7b\x4a\xfc\xab\xb8\xda\x40\xa5\x10\x25\x5e\xfd\xf5\xbe\x33\xc6\x6a\xcb\x6d\xe0\x66\x31\xbe\x33\x62\x4a\x50\xf0\xc5\x19\x96\x0b\xe0\x0b\xc4\x91\x16\x22\x3d\xe8\xb2\xbe\xdb\x43\x95\x85\x50\x69\x4f\x5b\x1d\x42\xa6\xd4\x9c\x9b\x68\x7f\x7c\x77\x09\xa1\xba\x5b\xfa\x08\xa3\x2e\x9f\xd1\x9f\xfd\x68\xff\x9c\x32\xcc\x88\xf2\x5a\x26\xe2\x30\x49\x74\xa5\x3a\x65\xa1\x1e\x0b\xf7\x0a\xdc\x8a\xf4\xa2\xd1\x26\x7a\xdc\x53\xf8\x16\x2b\xd1\x79\x26\x39\xc2\x0c\x35\xef\xc4\x22\xbb\xba\x1d\xf0\xd8\x2f\xf4\x90\x96\x8c\xb1\x82\xb7\xcb\x28\xed\x38\x42\x5d\x53\xe5\x97\xdf\x78\xd5\x09\xb7\x30\x82\xe4\xac\x5f\x4a\x83\xbf\x5b\x0d\x82\xe5\xe6\xaa\x06\x5f\x12\x50\x86\x14\x36\x53\xf4\x39\xbd\xe8\x90\xe3\x53\x5b\x01\x32\xb5\x18\x5d\xeb\xe4\x9e\x7b\xf9\x43\xf3\xfc\xbf\x8e\xcf\xba\x65\x8e\x07\xde\x19\xac\x6f\x99\x51\xd3\x41\x55\x8f\xcb\xf2\xe3\xf2\x44\xf7\xe4\x01\x2b\x39\x41\xea\x13\x9d\x5a\x26\x38\xfa\x54\xd8\x5e\x94\xa9\xbf\x3f\x72\x32\xbd\x8e\x96\xa3\xa8\x27\xf6\xb3\x5c\x70\x65\xa2\x12\x54\x01\x4d\xfb\xac\xd8\xd0\x1f\x3c\x08\x69\xb6\xc9\x7b\xb0\xe7\x9d\xae\xcd\x3b\x8c\x2d\xab\xc4\xb2\xca\x1a\xf7\x39\x3e\xdc\x0b\xcc\x3b\x3c\xbe\x14\x53\x69\x6c\x39\xf7\xbc\x6c\x93\xa8\x13\xe4\x15\x0a\xb7\x5c\x89\x39\xfb\xf1\xa7\x93\x7f\xfc\xf3\xc5\xab\xa3\xc3\x17\xff\x7c\x79\x78\xf4\xe3\xe9\xd9\xc9\xdb\xb7\x17\xff\xb8\xb8\x3c\x79\xf9\xf6\xed\x11\x22\x8c\x50\x39\xee\x85\xb0\x6f\xdf\xd2\x4a\x35\x6f\xdf\x5e\x26\x85\x2c\xde\xbe\x3d\xf7\x3e\x10\x64\x5c\xf8\xaf\xe3\x33\x90\x9f\x58\x15\x16\xd2\x9e\xe0\x6c\xc5\x41\x87\x7e\xcf\xb8\xa9\x93\x2c\x1b\xf5\x36\x2d\x50\x3a\xdb\x1e\x77\x2b\x21\x91\x3a\x6d\x76\xd7\x60\x4d\x95\xe4\x5d\xbc\xc1\x4b\xc7\xc6\xc2\xde\x08\x2a\x63\x5c\x09\xc2\xc5\xa3\xc2\xe8\x08\x57\x6b\x15\x1d\x0b\x2a\x67\x9a\x5d\x4b\x71\x83\x98\x13\xc8\x7c\x57\x73\x02\x41\x59\x33\x96\xb6\x2e\x43\x7d\x81\x92\x54\xe8\x34\xf0\x1f\x2d\xf8\xa5\x97\x7c\xd2\x8d\x32\x1a\x04\x73\x13\x29\x3b\x3f\x3d\x66\x4f\x47\xa8\xe4\x9c\x1e\x23\xb6\xe4\x4a\xa4\x29\x6f\xa9\xba\x03\x15\x4f\xdf\x15\x55\x07\xf5\x02\x68\x23\x8c\x5a\xac\x80\x6a\x9c\xea\x9c\xdf\x97\xe9\xec\x23\xf5\x2b\xc8\x43\xf9\x7b\xc5\x33\xd4\x01\xce\x75\xba\x2c\x99\x76\xbe\xf5\x1f\xfd\x7d\xf4\x6d\xe8\xc7\xdf\x47\xdf\x02\xc3\xa5\x1f\xb6\xbf\x8f\xcc\x75\x32\xfa\x96\x0a\xa4\x19\xdd\xb4\x32\x47\x78\xa9\xda\x89\xf4\x59\xfc\x0d\x3c\x9b\x83\xbe\xfb\x59\xca\x5d\x7a\xa4\x0a\xed\x99\x20\x14\xb5\x40\xa8\xbd\x4e\x4a\xc1\x31\xd5\x9c\xa5\x22\x13\x35\x0e\xcc\x06\x30\x54\xde\x4e\xd9\xe9\x63\x6d\x0d\x42\xd3\xd8\x37\x15\xf4\xa5\x3f\x3c\xef\x69\x6c\x30\x7c\x55\xd3\xc8\xb7\xd8\x00\x1d\x91\x1a\xee\x15\x36\xb2\x3a\x13\x38\x3f\x5d\x76\xca\xca\xba\xba\x5d\x13\xb7\xde\x66\x20\xd6\x51\x8d\x7e\xe9\xd1\x49\xdd\x8a\xb8\x0c\xfd\x07\x4b\x03\xf9\xfc\x30\xb8\x8a\xdf\x40\xb5\xdb\x9c\xb9\x53\xcb\xa2\x27\x23\xae\x10\xb5\x25\x30\x0f\x7e\x7b\x25\xe6\x03\x04\xf4\x40\x25\xe4\xef\x11\xcc\x72\x28\x89\x46\xe0\x35\x5d\xb2\x6f\xfd\xbf\xfe\x7e\x5f\x6b\xad\x83\x1f\xb5\x8b\x17\x15\x5f\xaa\x73\xe4\xeb\x04\xab\x60\x9a\x08\x1f\x38\xb2\x54\x20\x63\x35\x0e\xd7\x88\x9d\x40\xdd\x2b\x6a\xa4\x04\x35\x9b\x65\x8d\x9b\x8d\xa7\x8d\x6c\xa0\x43\x80\xff\x25\xaa\x8e\x39\xd3\x17\x54\x99\x09\x30\x3b\x13\x51\xd6\x9f\x80\x80\x39\xd3\x27\xef\x44\x52\xd9\xcf\x59\xad\x8e\xd7\x95\xe8\x4e\xe4\xf5\x93\x08\x10\x44\x38\x36\x4e\x0b\x0f\x95\x09\xf5\xee\x8c\x92\xd3\x3e\x3c\xb6\x57\x62\x6e\x02\xc8\xda\x15\xb6\x4e\x55\xcd\x61\xfd\xfa\x83\xec\xe4\x9d\x34\xd6\xfc\x2f\xcf\x22\x96\x8f\x6b\xfe\x36\x8e\x59\x62\x75\xeb\x11\xc0\x9e\xfb\x13\x1e\xf3\xb9\x07\xdc\xbf\x40\xe7\x51\x7f\xe5\x47\x22\x82\xd0\xe3\xee\x9d\x76\x0d\xa5\x27\x69\x05\x85\x6a\x31\x16\x5b\x9d\x58\x83\x3f\xc6\xf5\x89\x63\x08\xe3\x72\xe2\x94\xbc\xe6\x31\x43\x1f\xd1\x4d\x12\x50\x45\xe4\x35\xcf\x84\x22\x68\xda\x2c\x4d\x78\x89\x21\x7a\x02\x14\x32\x84\x6e\x4d\x48\x1a\xee\x8c\x23\x49\x56\xcf\xb2\xa1\x50\x1e\x2f\xad\x4c\xaa\x8c\x97\xcc\xed\xc7\xa9\x2e\xef\x89\x3b\x84\x57\x37\x36\xbb\xb0\x44\x3b\x90\x3c\x37\xe5\xfb\x62\x8b\x8b\x40\x87\xa4\xbd\x38\x93\x09\xea\x6b\x9a\x1b\x65\xaf\x89\x8e\xad\x27\x5e\x36\x05\x41\x11\x43\xe5\xd9\x86\x73\x5c\x4e\xc1\xff\xbd\x1f\x1d\x1e\x61\x67\x8e\xd8\xf7\xa1\x5a\x7c\xc0\x6a\x9f\x31\xd4\xa4\xd2\x33\x69\xdb\xd0\x74\xd5\x9b\x7a\xa2\x4b\xa0\x26\xdc\x4b\x35\xfc\x46\x5c\xcb\xc4\xee\x8f\xd8\xff\xeb\x34\x45\x70\x22\x7b\x75\x92\xb6\x59\xa8\xc3\xad\x01\xfb\x9e\xb0\x3d\xf8\x59\xac\x4a\xee\xfb\x40\x11\x21\x81\x3e\xb0\x6c\x98\x0e\x11\xee\x15\xd1\xed\x86\x18\x45\x4d\x71\x61\x69\x84\x93\x5f\x07\x09\x19\x64\xa2\x34\xb4\x4b\x1b\x9e\xdb\x10\x67\xf1\x22\x34\x2c\x9c\xff\x01\x1f\x3d\x2b\xc5\x14\xf6\x1f\xee\x9e\xcf\xb8\xfb\xac\x2e\x74\xa6\xa7\xf3\x8b\xa2\x14\x3c\x3d\xd2\xca\xd8\x12\x44\x43\x17\x7c\xb7\xdb\xda\x8c\xd8\xb0\x66\xfa\x86\x71\x2a\x67\xd7\x13\x44\xc8\xd3\xd5\x74\x86\xf8\xff\xf0\x43\xcf\x1c\xeb\xbb\x48\x46\xa7\x19\xb1\x8b\x80\xef\x0f\x0b\x3c\xd0\x05\x40\x2b\xe0\xf0\xb8\xe1\x73\xda\x4c\x7c\x2c\x53\x61\xa2\x1c\x65\xdf\x19\x0c\xfd\xdc\xfa\xfe\x20\x95\x0f\xcf\x8e\xef\x4b\xaa\xb0\x46\x85\xf6\x96\x57\x09\x9a\x11\x8e\x7a\x3d\xbe\x41\x23\x85\x71\xe3\xb9\x26\x4d\x15\xb1\x5c\xfd\xc8\x7c\x46\xdd\xb4\x0b\xf8\x52\xce\xdf\x5d\x5c\x89\x9b\x16\xbf\xf4\x2f\xfa\x93\xb8\x7f\x2a\xd8\x10\xec\xd1\x37\xca\x70\x2b\xcd\x04\xd8\x57\x3e\xa3\x3e\x0e\x45\x07\xed\x48\x22\xf0\x6a\xd6\xee\xc4\xad\xf9\xa2\xf0\x80\xb7\xd8\x58\x2c\x94\xff\x57\xdb\x41\x78\x00\x62\x11\x44\xe0\x97\x70\x3b\x28\x21\xce\x25\xab\xeb\x38\x34\x46\x2a\xaa\x7c\x2c\xca\xb0\xf7\xd1\x19\x20\xcb\x05\x68\xda\x85\xbd\xdf\x5e\x30\xb6\xce\x84\xeb\x9a\x56\x06\xc3\x73\xf2\xce\x69\x1e\xa6\x5d\xa2\x12\x5e\x4d\xca\xb4\x85\x46\x31\x3c\xe6\x13\x38\x17\xa6\xa1\x41\x5d\x02\x66\x6f\xfc\x49\x5b\x39\x57\x5f\xdd\x48\x17\x59\x37\xe2\x45\xb6\x22\x51\xfa\xd6\xd7\x5f\xe0\x3f\x89\x0b\xfe\xc8\x29\x64\x06\xa8\xc0\xa3\x03\x9b\xab\xfa\x60\x27\x2e\xfc\x2c\x68\x73\xce\x28\x72\x37\xe1\xef\xba\xb2\x1b\x75\x20\x6e\x64\x3d\x90\x37\x32\x90\x65\x57\x2d\x24\x60\xfc\x7b\x3f\x58\xad\x1b\xe9\x4e\xe3\xc8\xda\x1b\xd4\xf5\xd5\x58\x50\x57\xb5\x69\x8d\x2b\xab\x61\x5a\xd7\xc2\xae\x36\xac\x3b\x3d\xbb\x07\x6e\x33\xd6\xd1\xc6\xad\xaf\xc6\x40\xe8\x7b\x58\xbb\x1c\x02\x4c\x7a\xe2\x77\xc7\x4a\x9b\xf7\x54\x0d\xd8\x99\xb6\xee\x3f\x91\xf9\x7b\xac\x85\x39\xd3\x16\x3e\xd9\x88\xa1\xc4\x57\xe8\x71\x20\x3d\x8d\x00\xe0\xbd\x81\xdc\xa4\x10\xad\x3b\xf1\xfc\x80\xad\x30\x2c\x4e\x15\xd3\xa5\x1f\xb1\x60\x5d\x18\x6a\x22\x0e\x2b\x10\xc6\xd6\xad\xc6\x89\x6b\x27\x1e\xe7\x0f\x34\x47\x4d\x41\xf6\x17\x7e\x03\xe0\xa9\x45\x06\x05\x02\x69\x55\x22\x86\xad\xd3\x35\xad\x98\xca\x84\xe5\xa2\x9c\x02\x17\x74\x32\xeb\x63\xfa\xba\x9c\x2b\x78\x75\x3c\x5d\xe2\xce\x74\x58\x4b\x70\x64\x83\x8a\xd5\xa3\x0a\x80\xed\xe1\xb1\x96\x73\xb0\xa4\xfe\x4f\xf0\x41\xff\x5f\x56\x70\x59\x02\xe6\x2d\xc5\x8e\xe3\xef\x28\xfa\x12\x37\xe3\x5a\x58\xf2\x2d\x71\xc5\x04\x56\x32\xb9\xd6\x17\x15\x8f\x01\xbb\x99\x69\x83\x87\x61\x70\x7f\xec\x5c\x89\xf9\xce\x60\x69\xe9\xed\x9c\xaa\x9d\x3a\x30\xdc\x58\x6c\xe1\x10\x86\x0c\xc2\x1d\xf8\x6e\xe7\xd3\xe9\x2a\x9d\x0e\xdb\x3e\x18\x03\x16\x3b\xd4\x72\x5d\xd5\x93\xf7\x93\x98\x77\xf7\x98\xbd\x6c\x34\xe7\x95\x25\x4b\x3a\x7a\x7d\xfa\x19\xcc\xf9\xcf\xc0\x53\x3f\x23\xb3\x5b\x5f\x0b\xcf\x0b\x87\xe6\xa5\x93\x0b\x21\x63\x86\x67\x09\x72\x7e\xe0\xa4\x42\x23\x6e\x32\xbd\x89\x91\x69\x7d\x55\x15\x7e\x51\x04\x6e\x5f\xa9\x12\x9d\x93\xd1\x41\xcc\x72\x6e\x5d\xd1\x8a\x1b\x52\x1c\x0f\x57\x6f\x58\x1b\x84\xb4\xdf\xb0\x66\x9a\x1d\x0e\x6e\x07\xe1\x84\x5f\xb0\x80\xef\xf8\x0a\x21\xe5\x25\xee\xdd\x88\xc1\x98\x81\x5e\x90\x6a\xb5\x6b\xb1\x6d\xbf\xcd\x56\xbc\x48\x68\x99\xbc\x85\x6e\x9f\xaa\x2a\xcb\x02\x7e\x28\xea\xf3\xe8\x0c\x84\x7d\x41\x5e\xf4\xa9\xdb\x29\xb6\xf9\x82\x0f\x8a\x2c\xbd\xa3\x2c\x6d\x30\x42\xb8\x31\x6a\x4b\x80\x87\x17\x39\x0e\x3a\xef\x9e\xdd\x97\xd8\x50\xe4\xe4\xc2\xc0\xfa\xb4\x14\x58\xd1\x0c\x2b\x0b\x56\x1a\x51\x24\x55\x4a\x5c\x0b\x37\xb3\xa9\x34\x04\xaa\xe9\xf3\x74\xfe\xb5\xe4\x57\xf8\xff\x1f\xeb\x33\x6d\xbd\xeb\xeb\x5f\xde\x77\x8c\x42\xfc\x9d\xcc\xab\x1c\xc1\xe7\xac\x5b\xa2\xa9\x9c\x78\x34\x6d\x9f\x1e\xd4\x34\xba\x9b\xbe\x1f\x5a\xa5\x96\x97\x53\x48\x13\x26\xa3\xdb\xcb\xea\x69\xa6\xc7\x3c\x63\xb9\x54\xee\x31\x94\x01\xd0\xf8\x2c\xf4\x84\xfe\xfc\xc0\x83\xe0\x40\x91\x53\x39\xce\x04\x59\xf5\x0b\x40\xf5\xd1\x8f\x17\x6e\x04\x99\x94\x09\x63\x30\x68\xff\x52\xaa\x63\xef\x12\x7c\xee\x76\xcd\x3b\x9e\x17\x99\xc0\x3a\x57\xf6\xd5\xf0\xdf\x5a\x09\x46\x59\x2e\x03\xe6\xa7\xa7\x66\xf4\x7b\x8a\xa7\x51\xcd\xce\x11\x52\x98\x9a\xc2\xc3\xbb\x23\x0d\xfb\xf2\xe0\xcb\x83\xa7\xcf\x9c\x22\x86\xb1\x2e\x6e\x08\xc7\x6b\x79\x34\x9e\x8e\xd8\x7b\xe6\x7a\xf0\x94\xfe\xfb\x25\xfd\xf7\x2b\xf6\x9e\xbd\x67\xec\x9c\x9d\xb3\xf8\xbf\xee\x3f\xec\x3d\x1b\xba\x41\x88\xba\xfa\x74\xd0\x94\x1d\x89\xb3\x49\x7d\xd5\x7a\x60\xd4\xb4\x9a\x9a\x86\x92\xc1\x44\xe7\x02\xba\xfa\xe5\xff\xf2\xf7\x40\xbe\x85\x45\xd2\x53\xe8\xd4\x1e\x74\x69\x9f\xdd\x80\x67\x3a\xe7\x57\xe8\x95\x39\x4c\x6c\xc5\x33\xf7\xf0\xbd\xaf\x86\x4f\xf7\x99\x56\xcd\xdb\xaf\xa5\x76\x32\xd0\xf7\x70\xef\xe9\xfe\x68\xa9\xcb\x5f\xae\xe8\xf2\x02\xff\x27\xd5\x0c\xbb\x46\x6f\x5f\xef\x7e\xa9\x1f\xaa\xf9\x0d\x9f\x87\x05\xef\x8f\x8c\xa9\xbc\x0e\x94\x19\x11\x92\x0f\x84\xec\x61\xfd\x4a\x0f\xce\x86\x8d\xce\x99\xb4\x23\x76\x6a\x77\x77\x3d\xdb\xac\x33\x98\x3d\xb7\xc7\x71\x0c\x3a\x0b\x03\x0f\x6b\xe3\xc9\x42\x4a\x7f\x0b\x88\xc3\x5e\x63\x23\xf7\x22\xe7\xc0\x2b\x0f\xbb\xa4\xb3\x88\xdb\xa9\x77\x5c\x03\x12\x62\x79\xd7\x2f\x6e\xdc\x90\x7d\xf8\xc1\xdd\xbd\x00\x1d\xef\xc5\xd0\x15\x69\x23\xf5\xce\xaf\xdf\x69\x00\x89\x70\xde\xf5\xcd\xd0\xf7\x8d\xf1\x2e\xc3\xde\xee\x34\xf7\xe5\xdb\x1d\x88\x80\x05\x25\x94\xc8\xb0\xe8\x64\x27\x08\x51\xbf\x8c\x23\x98\xbb\x43\x95\xd6\x79\x47\x2d\xfb\x0f\x3c\x10\x60\x78\x4d\x21\x18\x57\x2e\xbf\x49\x94\x9b\xd4\x48\x65\x75\xbb\xb0\xde\xc7\x23\x76\x88\x0b\xd8\x40\x04\xf1\x2e\xfd\xba\x75\xec\x6a\xa2\xe4\x1b\xd0\x59\x42\x24\x25\xd7\x88\x33\xa8\xfc\xf1\x48\x0e\x5f\x4d\xda\x57\x98\xd6\xd3\xc9\x8a\x64\xb2\x3a\xca\x82\x08\xae\x6e\x91\x40\xf1\x51\xbc\x7e\x22\x6a\x8c\xa7\x2b\xe0\x4c\x69\xbb\x98\xe6\x70\x3d\xa1\x85\x54\x3f\x53\x5b\x7c\xee\x2f\x8b\xf2\x23\x58\xb0\x8d\x73\x13\xc8\x64\xdb\x1c\x16\x5f\x0e\x16\x7a\x4f\x9f\x7f\xdd\xe6\x0c\xf9\xf2\xd9\xfd\x0e\x07\xfa\xef\x65\x63\x9a\x57\xce\xee\xd7\x7b\x75\x2f\xf7\x21\x0b\x60\xc5\x26\x80\x8a\xa1\x3a\x22\x3c\x0a\x07\x9a\x91\xb6\xe2\x58\x64\xa4\xc4\x0d\x65\x7e\xde\xfe\x52\x51\xa1\xa8\x17\xee\x03\x77\xfe\xf0\xca\x08\xa8\xfc\xaa\x00\x14\xc0\x0d\xa4\x57\x76\xbf\xda\xfb\x8a\x0d\xd9\x93\x7d\xb7\x1a\x14\x2e\x2b\x18\xcc\xf8\x28\x73\x47\x03\x25\x32\xdb\x99\x53\x9e\xdc\xc8\x98\x41\xe0\xa3\x5b\x38\x84\x60\x4a\x2f\x29\xaf\x99\x3b\x7d\x87\x7b\x6a\x46\x95\x7a\x41\x8f\xea\x49\x3d\x36\xa7\xea\x5c\xa7\xcd\x88\x59\x28\x23\x9b\x42\xd4\x1d\xea\x79\x88\x26\x8a\xed\xf9\x7f\xd4\x50\xef\xfb\xad\x50\x45\xd6\x7b\x16\x28\x9d\x8a\xc3\x09\x70\x08\xcc\xdb\xa2\x37\x2f\x9e\x09\x67\x4b\x6d\x46\x67\xc3\x4c\xdf\xb0\x1b\xca\x4f\x46\x42\x4d\x2c\xb3\x8b\x3b\x72\x10\x53\x9d\xa3\x3c\x0b\x22\x99\x54\x88\x20\x4a\x69\x1b\x19\x98\xf6\x57\x31\x34\xcd\x90\xfd\xa8\x95\x2e\x9f\xa1\x76\xe4\x9a\x34\xb5\x28\xbe\xfd\x71\x28\x6a\x92\xac\x4a\x23\x76\xc4\xfa\x40\x30\x4e\xbd\x39\x05\x03\xed\xd9\xc7\x5a\x09\x66\x1c\xa4\x4a\xa7\x41\x8e\x7d\xa8\x71\xcf\x38\xbd\x32\x27\x37\xa0\x5f\x2f\x39\x65\xdc\xb7\xf0\xba\xc4\x4f\x32\x8a\xd6\x7f\x5c\x99\xe9\x57\x74\xb4\x7a\xdd\x4f\xdd\x94\x9d\xba\x7e\x99\x40\x60\xf7\xa1\xfd\x00\x35\x98\xed\x17\x7b\x4b\x43\xcf\x0d\xe1\x25\x84\xe2\xfb\x5c\xa9\x71\x8b\x1f\x5c\xa7\x88\x43\x85\xa9\x00\x9d\xd7\x24\x2e\x87\x50\xb2\x0a\xad\x0e\x18\xcf\x34\x38\x18\x9c\x80\x75\x1f\x89\x94\x6e\x9c\x04\x8a\xfd\x25\xdf\xc1\x0c\xaa\x74\xeb\x64\x94\x41\x63\x91\x2d\xae\x56\xff\x02\x77\x58\x9f\x9d\xd6\x22\x3e\xf3\x11\x2f\xc6\x28\x47\xa0\x87\xc4\xb4\xd0\x96\x37\x9b\xaf\x04\x9c\x78\x30\x65\xe8\x1d\x1a\xc1\xb8\x90\x01\x43\x45\x17\xe8\x80\xa3\x03\x59\x9a\x10\x81\x94\x50\xc3\x9e\x44\xf4\xc5\x25\xea\x60\x32\x15\x25\x1e\xa9\x63\xd1\x28\xd1\x09\xb9\x1d\xec\x97\xfa\x4e\x2c\xcd\x81\x1c\x66\x6c\xe8\xef\x58\x12\xbe\x33\xae\x92\x2b\x61\xbd\xef\xb6\x84\xaa\x82\xa2\xb2\x6c\xcc\x33\xae\x12\xb7\x6a\x17\x63\xf9\x56\x63\x63\xf8\x4b\x78\x0a\xe2\xdc\x84\xd2\x11\x6c\x3a\xca\x3c\x94\xca\x58\xd7\x1a\xa6\x24\xd6\x1d\x3c\xcc\x8c\x1e\xb8\xbd\xe9\x1b\x58\x76\x1f\x40\x53\xf4\x6f\x74\x47\x93\xf8\x17\xc2\x52\x6d\x5a\xe4\x43\xa6\x71\x5e\x38\xb2\xb0\x04\xbb\x29\x1f\x46\x4c\x8c\xa6\xa0\xe2\x2e\x4c\xd9\x4e\xb3\x40\xd2\xd7\xdc\xec\x0c\xf0\xad\xdd\xcc\x51\xc1\x2a\xf9\x37\x88\x4a\x23\x7a\x2b\x95\x42\x1d\xf7\x62\xc3\xe1\x8e\xe6\x13\x9c\x02\xe4\x5b\x07\x45\xf5\xc3\xad\x9f\xda\x55\x36\xee\xe7\xde\x33\x4b\x16\x7d\x77\x17\xdb\xb2\x92\xdf\x14\xe1\x90\x65\xc2\x33\x5f\xfd\x01\x54\x7f\x01\xe7\x5c\xed\xee\xd6\xbe\x00\xd8\x0a\x28\x59\x6a\x6b\xc5\x89\xcf\x86\xb5\xc0\xf6\xbc\xb2\xc7\xac\xc8\x32\xdc\xac\xb5\xd1\xe4\x94\x5f\xab\x6b\xab\x49\x42\x0b\x4d\xbf\xc5\xca\x1f\xc6\x3f\xf2\x35\x30\xe0\x1a\x9b\x07\x84\xc2\x01\x1b\x57\x96\x4d\xe5\xb5\x93\xfc\x77\x72\x73\xa0\x2b\x67\x26\xb2\x82\x95\x22\xad\x12\xc2\x2d\x80\x63\xe9\x30\xb6\xc9\x90\x59\xda\x4b\x87\x9d\xc6\x80\xee\x20\xd5\x99\x6a\x9e\x3a\x72\x02\x1b\x04\x54\x2b\x39\x61\xe2\x5a\x94\x73\x56\x68\x63\x60\x1b\x82\xd8\xc2\xe2\x3d\x88\x13\x05\x30\x65\xb0\x1f\xa0\x57\x5e\x65\xdf\x21\x9d\x7d\x07\x6c\x5a\xdd\x10\x45\x9f\xc7\x85\xf7\xd5\xc1\xd3\x83\xa7\x1f\x36\xbf\xce\xe1\x7f\xb5\x4f\xce\xff\xf7\x74\xb2\xc2\xca\xac\xfb\xd2\x58\x39\xf7\x71\xdb\x7d\x09\xde\xb5\xaf\xf6\x23\xef\xdd\x57\x07\x5f\x1e\x3c\xdd\x73\x7d\xfd\x72\xdf\xf5\x3a\xf2\xcb\x7d\x19\xf9\xe5\xc2\x2f\xa9\x47\xc2\x34\x3c\x73\xa7\x8a\x2a\x35\x81\xe6\x94\x6c\x73\xaa\xfa\x73\x3d\x32\xd6\x87\x20\x72\x2f\xcb\x71\xd9\x35\xfd\x02\xbb\x16\x1d\x84\xd2\xb2\xbf\xe4\xba\x14\x7f\x89\xee\xbf\xd5\xa3\xd6\xde\x51\xd6\x42\xdc\x2c\x87\x04\x72\x5e\x0c\xaf\x5a\x04\xc5\xba\xa4\x03\x76\x4d\x06\xbc\x2d\xb0\x91\xf3\xe2\x1e\xed\x20\x9f\x4c\x27\xae\xd5\x17\x94\x48\x46\x4d\x51\xa2\x14\xba\x71\x73\x4a\xe8\x1b\xcf\xe3\xfa\xdf\xb1\x70\xba\x2c\x7a\xbd\x6a\x90\xc0\x7b\xd2\x1b\x1a\xab\x4b\x3e\x15\x07\xf4\xd8\x87\x42\x6b\xfa\x33\x12\xf8\x34\xb2\x62\x10\x7e\x89\xa8\x7d\x7c\x09\xb6\xcf\x97\x04\x29\xc0\x13\xa8\x5e\x84\x81\x6c\xe0\x67\x46\x75\x91\x0f\x24\xf5\xb6\x05\xd8\x5f\x97\x44\x2f\x7e\x63\x4e\x32\x6e\xac\x4c\xbe\xcf\x74\x72\x75\x61\x9d\xb9\xd3\x59\xb5\x58\xd5\x6a\x63\x4e\x15\x3b\xfc\xe5\x82\x1d\x4b\x73\x55\xb3\x44\x22\x13\x4b\xb3\x60\x90\x07\x24\x62\xc2\x8e\x60\x39\x4f\x66\xa8\xba\x92\xd7\xd9\xb3\x51\xf5\xb7\x57\xfe\xc4\x6f\x8c\xc0\xee\x8f\x5d\xf7\xdd\xd7\xa2\xbd\x08\x5e\x1b\x6e\x24\xbe\xce\xe9\xf1\x1a\x12\x75\x27\xa6\x2d\x7d\x2e\x5b\xc1\x69\xe6\xc1\xf1\x11\x03\x21\x13\xc4\x6b\x0f\x88\xcc\x4d\x9e\x32\x58\x43\x73\x5d\xb1\x1b\x8e\x06\x35\x48\xd8\x11\xbb\x94\xc5\x33\x76\x12\x31\xfe\xac\x6a\xca\x69\x1f\x01\x7d\x95\x0c\x6a\x58\x73\x98\x78\xe3\x04\x32\xd5\xf4\xb0\x13\x54\xad\xcc\x33\xb6\x23\xde\xd9\xbf\xee\x0c\xd8\xce\xbb\x89\x71\xff\x51\x76\x02\x0c\x61\xc4\x3c\xea\x74\x3c\x35\x11\x65\x6d\x3a\xe2\x0f\x96\x81\x8f\xfa\x5f\xb2\xec\xf2\xd5\xf1\xab\x67\xa0\xcb\xa7\xda\x59\x7d\xc4\xcd\xef\x61\xbc\x48\x36\x46\xc3\x00\xb9\x22\x89\xce\x8b\x52\xe7\x32\x2a\xb6\x85\x2d\xd7\x66\x07\xb0\x3e\xb2\xbd\xc0\xb0\x85\xc5\xd0\xcb\x7a\x0a\xcd\xf9\x25\x15\x7d\xa0\xee\xb2\x98\x4e\x27\x4c\x63\x6a\x40\xb3\xdc\x5f\x9a\x70\x93\x5b\x3e\xd4\x0a\x32\xce\xd7\x0b\xc6\x69\xe6\xf4\xd5\x41\x2a\xae\x0f\x4c\xca\x9f\x0e\xe0\x31\xb8\x1a\xe6\x0b\x7d\xe2\x86\xed\x3c\xdd\x19\xb1\x0b\x99\xcb\x8c\x97\x19\x51\xe1\x52\x13\xf5\x7d\xce\x50\xf0\x0d\x82\xf9\xfb\x64\x87\xed\x61\xbd\x3d\xa8\x1b\x99\xf0\xe8\x6b\x01\x6d\x14\x32\x63\xf6\x5b\x69\x97\xac\x07\xf7\x3b\xeb\xec\x82\x67\xc4\x8a\xff\x4a\x65\xad\xb3\x94\x9b\x8b\xc3\xb7\xe6\x8b\xd5\xca\x8a\x1c\x99\x13\x5d\x92\x11\x18\x6e\xf1\xa0\x3e\x52\x91\xda\xf2\xd2\x4d\xfd\xfd\x99\xa8\x3f\xd5\xf1\xc3\x7a\x00\x9a\x63\xe1\x14\xe9\x67\x7c\x7d\x6b\x90\x7c\xa0\xe4\xef\x95\x60\xa7\xc7\x5e\x88\x17\xa2\x34\xd2\x58\x27\xa2\xd2\x86\x6a\x20\x51\x5f\xd8\x3b\xcc\xf9\xbf\xb5\x62\x27\xdf\x5f\x50\xb7\xf6\x37\x70\xb0\x5b\x4a\x3a\xfe\xef\xaa\x14\x4e\x23\xea\xac\x7e\x85\x96\x16\x55\x2e\xf7\x39\x3b\xe6\x96\xa3\xe6\x85\x92\x4a\xd7\x40\x58\xa0\x54\x8d\xa1\x40\xc9\xa3\x9c\xb5\x54\x9e\xd9\xfa\xb5\x1f\xb7\x82\xce\xda\x23\x67\xbb\x9f\xbf\x79\x7d\xba\x06\xdd\x29\x81\xe3\x76\xfa\x52\xa7\x3d\x29\x50\x51\x83\xfe\xc8\x03\x60\xd2\x23\xfc\x9c\xe5\xee\x49\xec\x4c\x2b\x31\x60\xaf\x05\x4f\x99\x93\x6e\xf4\xcf\x5f\x4a\x69\xef\x8b\xf5\x54\x5f\x9d\x8f\x7e\x3f\x89\xbd\x0c\x84\x6f\xcc\x0f\xc2\x59\x84\xef\x07\x60\x94\x20\x74\x48\x07\x18\x67\x7a\xcc\x48\x58\xac\xf3\xed\xdf\xbc\x3e\xed\xed\xe5\xdf\xbc\x3e\xf5\xef\xee\xfe\xa9\x27\x9b\xf9\xda\x3d\x1a\x0f\xb5\xed\xf0\x7c\x41\xd9\xaf\xd5\xb9\x9a\x16\x67\xd1\x20\xb8\xbb\x35\x30\xea\xcb\x0e\x58\xd7\x98\x5f\x49\xd5\xba\xde\xad\x29\x6d\x80\x12\x27\xc0\x3f\x45\x41\x34\x40\x9d\x4b\x9f\xb1\xbc\xca\x2c\x20\xfc\xc0\x5a\x73\x8b\x0f\xf2\xc3\xfc\xaa\x63\x84\x76\xc9\xd8\xb1\xc0\x70\x44\xfa\xcc\xd7\x5c\x84\x5f\xac\xfe\xc1\x4b\xae\xf8\xd4\xdd\x0e\x27\x20\xcb\xf1\xcf\x68\x91\xef\xa1\xd3\x5d\x85\xaf\xf8\x35\x97\x19\x1f\xcb\x4c\x5a\xd0\xe7\xf6\x47\x5e\x9b\xc7\xbc\x7c\xe8\xf2\xda\xa4\x5f\xaf\xaa\x6d\x50\x5b\x63\x2c\x14\x80\xf2\x63\x7b\xee\xbb\x83\x1b\x27\xea\xf7\x47\x20\xf7\xe1\x46\x40\x5e\x5f\x50\x7e\x5f\x7f\x4c\xf9\x5d\x8b\x9e\x0a\xf3\xfd\xbc\x25\x5f\xd7\xb2\xee\xe4\x5a\x5a\xa9\x3b\xc1\x17\x04\xb0\xf9\xc8\xd5\x27\xe4\x4c\xef\xa0\x40\xc1\xde\x69\xf9\xfb\xae\x2a\xd4\xa7\xd9\x38\xe9\xe3\xdb\x38\x0c\x99\x0d\x69\xa6\x7b\x19\xae\xba\x39\xaf\x6b\x04\x20\x65\xfc\x6a\xa1\x54\x1c\x77\xd6\x05\xc9\x72\x0f\xb0\x0c\xbf\x77\xfb\xa9\x0d\x90\x04\x5e\x9d\xc5\x6f\x58\xc1\xfd\x8c\x8b\x6f\xcd\x0f\x0b\x1e\x52\xf0\x31\x6b\xbd\xcf\x3a\xbe\x66\x22\x8a\xd9\xa4\x7b\x2e\xbb\x6b\xe6\xf9\x45\x33\x6a\x73\x24\x8a\x19\x7b\x7e\xb1\x42\x4c\x62\x1d\x81\x7b\x6f\x83\xb1\x9c\x5d\xc3\x32\x39\x11\x56\xb6\x1a\x84\x35\x0b\xca\x5c\x2b\x69\x75\x69\xd6\x20\xe6\xfc\xa3\xfb\x51\xdc\x7c\x6b\x6e\x7d\xbe\xf6\x83\xc2\x5e\x46\x9f\x72\x96\xe8\x2c\x13\x89\xcf\xee\x87\x29\x0e\x3f\x5b\xe1\x88\xa1\x0c\x04\x33\xba\xfa\x06\x5c\x31\xe4\x74\x39\xc0\x65\x77\xf0\xfa\xe4\xf0\xf8\xe5\xc9\x28\x4f\xff\x34\xd3\x37\x43\xab\x87\x95\x11\x43\x69\xbb\xe9\x5b\x6b\xc4\xce\xe8\xc1\xd3\x6d\x67\x7d\x39\xb9\xed\xcc\x4d\x59\x0d\xe0\xfc\xc6\xd4\x10\xeb\x3e\xee\x5c\x6a\x6d\x97\x41\xd6\x27\x55\x96\xe1\xdc\xda\x52\x88\x41\xec\xdf\xbe\x27\x04\x7d\x7d\x6d\x96\x2e\x5c\xbb\x79\x1b\x43\xf4\x69\x35\xe3\x4d\xd9\x20\xdd\x75\x85\xb6\x9a\x36\x5b\x9a\x87\xba\xbd\xe6\x4c\x5c\x34\x3e\xc7\x80\x88\x9d\xb9\x79\xb9\x12\x73\x06\x30\x09\x13\x5d\x02\x65\x49\x73\x7d\x0a\x9b\xc0\xe0\x1d\x54\x46\x94\x23\x52\x38\x36\x64\xe0\xbb\xa8\x22\xf0\x22\xaf\xc5\xa4\xcf\x61\x7f\x2d\x26\xab\x46\x9d\x3e\x06\x5c\xd7\x90\x1e\xe7\xf4\x95\xca\xce\x30\x37\x16\xf1\xa4\x71\x6c\x57\x4e\x03\xe1\x5c\x6c\xc8\xb8\x77\x42\x28\xe8\x03\x45\xa7\x0b\x1b\x22\x5b\x9a\xbc\xd8\x6d\x49\x93\x64\xef\x1d\x06\xd1\xd7\xce\x8a\x15\x37\x07\x37\xba\xbc\x92\x6a\x3a\xbc\x91\x76\x36\xc4\x91\x32\x07\x80\x6e\x7f\xf0\x27\xf8\x0f\x45\x91\x0f\xd3\x94\xf2\xdf\x2a\x23\x26\x55\x86\x99\x69\x66\xc4\x78\x21\x7f\x16\xa5\x81\x2c\xcb\x2b\xa9\xd2\x01\xab\x64\xfa\x5d\xdb\x19\x63\x7d\xec\x96\xf6\xec\xf4\x8b\x63\x5d\x11\x41\xbd\x8e\x8f\xd1\xd2\xcb\xa4\x92\xa7\xda\x20\xc7\x91\x1b\xaa\xc6\x16\xe0\x69\x2e\xd5\xa6\xec\x80\xb6\xd6\x81\x54\x69\xbb\x91\x5c\x08\x40\x40\x3b\x4d\xf3\x80\x3e\xa3\x30\x76\xc8\xf9\xe1\xde\x7b\x82\x24\xe6\x94\xfd\xd3\xcc\xfd\xb9\x93\x60\xc9\xe7\xe6\xf7\x6c\x88\x4f\x19\x16\x69\x3d\xae\xdb\x44\x9e\xfb\x5c\x9f\x2f\x91\xa7\x5f\x87\xfc\x67\x48\xcf\xf9\xa4\x2b\x8e\x6d\xb0\xce\xfc\x69\xfd\x60\x6b\x1c\xea\xee\x9a\xf1\xa7\xd1\xd0\xea\xd3\x07\xf8\xf7\x8c\x07\x85\x03\x05\x0c\xa5\x92\xf7\xa7\x41\x8e\x7c\x4d\xf8\xe4\xf1\x1d\x12\xad\x14\x71\x01\xbc\x2a\x84\xba\xb0\x3c\xb9\xea\x18\xd5\xdd\x6a\x55\x7f\x30\xad\xea\x13\x25\x02\xf9\x25\x8a\x85\x77\x94\xfe\x56\x27\x7b\xe3\x26\x7f\x80\x02\x18\x89\xed\x5e\xf2\xa2\xbb\x77\xd5\xb7\xb4\xa0\x41\x85\x8f\xc9\xa1\x0a\xc5\x41\x85\x2e\x00\x59\x8b\x6a\x4f\x61\x1c\x3f\xbf\xc6\xd3\x75\x7f\xd3\x11\xd3\x5f\x0e\x4c\xd4\x60\x53\xa2\xe6\xee\x93\xb1\xb4\xb5\xac\x34\xc2\x22\xf8\x13\xc1\x01\x6b\xc5\x12\x02\x78\x00\x7d\x24\x82\x2d\x88\x74\x15\xc5\x74\x62\x7d\xd5\x68\xc0\x89\x7a\xf2\xe4\xc9\x13\xc4\xbe\xf9\x8f\xff\xf8\x0f\xa6\x4b\xe0\xdd\x4c\x64\xbe\x7c\x23\xdc\xf5\xf5\xd3\xa7\x23\xf6\x8f\xc3\x97\x2f\xa0\xa2\xa1\xb0\x06\xd9\xd8\xb0\x65\x77\x43\xe3\xc7\x66\xc0\xfe\xf7\xc5\xab\xb3\x1a\x95\xa1\xf9\x2d\x98\xe6\xe1\xf5\x9a\x1c\x18\x4f\xfe\xf6\xd7\xbf\x8e\xd8\xb1\x2c\xa1\xa2\x4b\x8a\xc0\xaf\x1e\x5c\x2d\xbc\x14\x88\xd5\x03\xa8\x29\x5e\xe3\x92\x81\xca\x90\x0a\x93\x73\x39\x9d\x59\xaa\x88\x75\x0b\x32\x93\x89\xc5\xe2\x31\x14\x6b\x9e\xbe\x1d\xe9\x33\x88\x90\x86\xb4\x3f\xe8\xdc\x80\x65\xf2\x4a\xb0\x89\xf9\xa1\xd4\x55\x51\x43\x1a\x12\xe9\x30\x15\xca\x60\x63\xf5\x5c\x19\x61\x1f\x78\xda\x6a\x27\x57\x73\x63\x6d\x43\x4b\x0b\x0a\x2b\x95\xb7\xd6\xb8\x7e\x05\x97\xa1\x18\x06\x32\x00\x1b\x7c\x97\xc1\xd7\x93\xb2\xa3\x20\x55\x3c\xca\x48\x51\xea\xff\xc1\x25\x00\xb5\xc8\x91\x78\x86\x5a\x61\x98\x49\xaa\x14\x8e\xa2\x5b\xbe\x9e\x9a\x08\xd6\xfd\xc7\xc4\xda\xb2\x4c\x7d\x95\x49\xe3\x1e\x01\xf0\x3e\x1f\x78\x72\xcd\xdb\xeb\x56\xa9\xc1\xf5\x52\xa9\xa5\x5f\x13\x94\x0a\x89\x4b\x22\xbc\x24\xf4\xe1\xba\x0d\xc4\x05\x20\xe4\x1b\xba\xd7\x8f\x52\x18\x88\x46\xbe\xb5\x11\xb6\xa2\xa1\x81\x2c\x7a\xf7\x6c\x20\x63\x84\x37\xcc\x79\x79\xe5\x0c\x57\x92\x2e\x23\x76\xee\x3a\x19\xc0\x73\x10\xd8\xf7\x1a\x03\x9b\x39\x9f\xc3\x63\x49\x71\x83\x87\xec\x8e\x46\xbb\xb8\xfd\x74\xc9\x8c\xe5\x25\xed\x25\xf7\xf9\xe3\x40\x14\x7f\xc9\x0b\x83\x08\xb7\x4e\x53\x05\xf4\x67\x0d\xb5\xeb\x76\xe6\x45\x10\xa7\xb1\xde\xa2\x80\xb3\x21\x0c\x4c\xeb\x06\x36\x1c\x01\x9c\x66\x9f\x76\xf9\x46\xc0\x53\xe7\x1d\x14\x0e\xbc\x16\x63\xaa\xe9\x42\x64\xe3\x4e\xfa\x06\x31\x20\x65\xe2\x41\x29\x18\xab\x19\x4f\x49\x70\xc6\x0a\x58\x4c\x85\xf9\x70\xf5\x08\xbc\xfa\xd0\x26\xf0\xea\xae\x53\xe0\xd5\x25\x88\x8c\x57\x63\x0d\xfb\x48\x32\x0e\x26\x1d\x60\x78\x46\x4d\xea\x29\x00\x5e\xba\x22\xda\xd6\x48\xe2\xea\xc9\x88\x15\xe3\x63\xa3\xb3\xca\xe2\x4f\xeb\x2f\xe3\xd3\x0f\x1a\xf5\xf8\xd8\x70\xe4\x85\xdb\xa2\xb3\x10\xb4\x00\x3c\x3e\xba\x1c\x8b\x78\x75\x16\x1b\x5d\x9c\x10\x7f\x20\x07\x44\xe7\x71\x0e\x06\x5b\x1f\x63\xed\x1b\x0b\x15\x77\x37\x33\x41\x29\x10\x91\xde\xe7\xa4\xa9\x93\x11\xa0\x54\x7a\x15\x0e\x81\x73\xd2\xb5\xb8\x19\x13\x23\xbb\xfb\x12\x8c\x64\x7b\x47\xa1\x3c\xde\xa7\xdd\x9d\x2a\x2b\xca\x09\x4f\xc4\x7e\xec\x63\x10\xc5\x4c\xe4\xa2\x74\x03\x45\xf7\xf9\x1a\xed\x19\x57\x29\xc1\x4e\x25\xa2\x84\x1d\x2c\xde\x59\x51\xba\x41\x3d\xba\x38\x65\x69\x29\xaf\x45\x69\xd8\xde\xf7\x00\x20\x88\x70\x53\xfb\x0f\x30\x0d\x16\x5f\x64\x1d\x1e\x10\x78\x70\x3f\xa5\x1f\xd0\x94\x97\xe1\x2a\x92\x33\xf5\x54\x79\x6c\x2c\x37\xad\x26\xf6\x1d\x8d\xdc\x86\x80\x23\x14\xa4\x2f\xb0\x37\x63\x6c\xd3\x23\xb7\x03\xc9\x54\x62\xb1\x61\x6e\x58\x29\xa6\xce\x1a\x2b\x23\x98\x3e\x84\x49\x59\x5b\x71\x43\xff\x05\x25\x75\xb0\xea\x43\xb5\x1f\x13\xb2\x2b\xf5\xb5\x4c\xbd\x3a\x84\x68\xf4\x01\x13\xae\xe0\x26\x02\x2f\xe0\xc6\xe8\x44\x82\xab\x29\x9a\x1a\xb4\x52\x41\x69\x6a\xd2\x7e\xf9\x70\x73\x1c\x26\xd3\x40\x9e\xd3\x8a\x73\x94\xf5\x72\x20\xea\x54\x9c\x57\xe3\x4c\x9a\xd9\x45\xaf\x21\x91\x55\x0d\x63\x52\xe2\x52\xa6\xca\xad\x91\x11\x23\x94\x91\x44\x11\x8f\xea\x96\x74\xda\xb6\x86\x69\xf0\xbf\x8e\x37\x85\x86\x6a\x78\x20\x9e\xf7\x5f\x9d\xd5\xfd\x20\xb0\x12\x64\x3c\x4e\xc5\x1b\x55\x34\x3e\x4f\x78\x96\x19\xd2\x6f\x03\x9f\x87\x3f\x7b\x50\x43\xf5\x00\x26\xb8\x2a\xa4\x5b\x30\xbe\xf7\x90\x82\x83\xc2\x2b\x90\xcf\xac\x7c\x31\x13\x01\x0c\x6b\xe5\x6f\x02\xe2\x66\xff\x83\x30\x42\x58\x89\x83\x8b\x6e\x8d\xb4\x1f\xdb\xf0\xcf\xc3\x0b\xff\x7c\x9a\x9a\x8a\x9a\x4e\x93\xc3\x87\x43\xa8\xd0\xc2\xd0\x46\x45\x14\xb1\xfe\xa0\xf1\x07\xd2\x47\xd2\x34\xd7\x16\x02\xc6\xfe\x1d\x5a\x62\x9f\xe8\xc7\xbb\xbb\xd8\x28\xa8\x62\xce\x14\x07\x09\x35\xa4\xf1\x4b\xa2\x2d\x45\x36\x72\xd8\xe7\xcb\x72\xad\x3e\xd3\xe1\x38\xc7\x0f\x77\x0d\x4b\x75\x52\x39\xe3\xab\x1e\xf6\x3a\xe1\xa2\x1b\x33\xdf\xe3\xa2\x0a\x4a\xf5\x8d\xba\xe1\x65\x7a\x78\xde\xaa\x36\xb7\xa9\x9c\xd5\x6d\xc5\xaa\xb7\xff\x98\xb9\xcf\xf9\x18\x90\x6e\x09\xdb\x70\x1b\xed\x5b\xd9\x44\x2c\xcd\x57\xb9\xdb\xac\x76\x42\xf6\x8e\xd1\xbc\xfb\x3a\xec\xb6\x01\xc2\x6d\x80\xb0\x71\x6d\x52\x80\xf0\x14\x03\x84\x31\xab\x6d\x43\xbc\x90\x87\xd6\x8d\xf8\xa3\x88\x31\x1d\xd7\x22\x15\x35\xf1\xc5\x7a\xde\x05\xe5\x1f\x37\x6f\xbd\xea\x22\x83\xc1\xcb\x5c\xd0\xcb\x1e\x43\x3c\x6a\x03\xe2\x49\x30\x96\x1d\xac\x42\xbc\x9a\x02\xbf\xae\x57\x43\x94\x5a\x0c\x4c\x47\x11\xee\x42\xa7\xc4\x66\x00\x34\x1b\x48\x19\x30\x08\x34\x78\xca\x97\x9b\x82\x76\x5e\xf0\x44\x80\x7c\x0b\xea\x4f\x2f\x41\x82\x8e\x0b\x80\xf5\xb4\x08\x18\x2c\x04\x18\x9d\xf3\x2e\xab\x81\xf5\xb6\x22\xdc\x55\x5b\x3c\x5d\x5b\x5a\x44\x14\xc5\x56\xfd\x42\x30\xc9\x4c\xe4\x1c\xfe\xf9\xdc\x0f\x81\x93\x8d\xce\x78\xb0\x02\x21\xe0\x44\x99\x1b\xa6\x27\x83\x46\xa6\xeb\xce\xf5\xd3\x9d\x6e\xc1\x06\xd6\x5f\x9c\x92\xf9\x7d\x74\xde\x39\xd8\xc3\x16\x07\xec\xbc\x11\xdb\x71\x7b\xa8\x26\x7c\xf4\xb8\xf7\x21\x83\x02\xce\x0f\x1c\xe1\x8d\x19\x9c\xbe\x83\xb8\x6d\x83\xb7\x83\x10\x35\x78\x00\xca\xdf\x36\x78\xfb\x18\x83\xb7\xd1\xc1\xe8\x05\xdd\x8a\x40\x6e\x1c\x12\xf0\xd1\xdc\xb1\xf0\x46\x0d\xd9\x30\x3e\x94\xeb\xe3\xb8\xba\x6c\xa6\x2e\xed\x8e\x46\xbb\xbb\x3e\xba\x4b\xeb\xbe\xb2\x93\xe1\x37\x4c\xa8\x44\xa7\x9e\xad\x76\x22\x4b\x63\x41\xdd\xab\xdd\x6d\x71\x5f\x72\xff\xac\x38\xfd\x09\xda\xee\x63\xaa\x3b\xcb\x16\x0f\x49\xf8\xfc\x13\x28\x31\xb5\xea\x12\x80\x0f\x69\x88\x02\x9e\x35\xe9\x30\xfe\x7b\xc3\x32\x99\x4b\xe2\x7a\x77\x1b\x5d\x18\x6b\xd8\x1e\x7e\x38\x4a\x8a\x6a\x40\x37\x8c\x72\x91\xeb\x72\x3e\x08\x37\xb9\x2f\x1b\xbf\xa2\x3b\xf6\x91\xef\xa4\x2a\x4b\xa1\x6c\x36\x7f\xcc\x1a\x90\x1f\xc4\x0d\x51\x80\xc2\x1c\x77\x41\x1c\xa9\xaf\xe6\xd2\xaa\x23\xbe\xe0\x36\x8f\xf8\x05\x02\x1a\xad\x19\xd4\x71\x71\xf7\xa9\x50\xd7\xec\x9a\x97\xf7\x44\x8e\x5f\x75\xf5\xa8\xf3\xa4\xf2\x5a\x1a\xdd\x3a\x2c\x1a\x35\x14\x0f\xcf\x45\x70\x42\xbb\xcd\xa6\x2b\x5b\x54\x96\x24\xba\xdf\x81\x1e\x65\x3c\xec\xbc\x05\xe5\xf0\x69\x1b\x16\xa5\xe6\x55\x70\x6b\x45\xa9\x9e\xb1\xff\xde\x7b\xfb\xc5\xfb\xe1\xfe\x77\x7b\x7b\xbf\x3e\x19\xfe\xe7\x6f\x5f\xec\xbd\x1d\xc1\x3f\xfe\xb2\xff\xdd\xfe\x7b\xff\xc7\x17\xfb\xfb\x7b\x7b\xbf\xfe\xf4\xf2\x87\xcb\xf3\x93\xdf\xe4\xfe\xfb\x5f\x55\x95\x5f\xe1\x5f\xef\xf7\x7e\x15\x27\xbf\xdd\xb1\x91\xfd\xfd\xef\xfe\xdc\xb9\xeb\x5c\xcd\x5f\x75\x14\x85\x78\x0d\x7b\x3c\x92\x9b\x2d\xf6\xb2\xfc\x16\x68\x25\xa4\xb2\x43\x5d\x0e\xb1\xe9\x67\x00\x16\xdc\xf1\x01\x7e\x79\xf5\xbd\xff\x6b\x35\xa0\x86\xdb\xf7\x4a\xfd\x9a\x37\x38\x84\x3e\x8f\x65\x0f\x65\xc6\xbe\xa5\x66\x99\x8c\x15\x79\xa1\x4b\x5e\xce\x59\x4a\xde\xcc\xf9\x0a\x04\xa2\x08\x82\xa8\x33\xa4\x30\xf4\x23\x95\xe5\x1a\x2a\x8d\x3b\x23\x0a\x89\x54\x56\x79\x4f\x78\x42\xd0\x56\x3c\x19\x37\x80\xbc\x4f\xa8\xfd\x3e\xa5\x88\x6e\xa3\x80\xc6\x98\x27\x57\x68\x41\x85\xd9\x42\xbd\x31\x2a\xad\xdf\xd9\xa1\x94\x08\xa4\xf3\x27\xc7\x3e\xe4\xb6\xe8\x54\xb8\xa9\xf4\x37\x63\xdb\x0d\x27\x3c\x46\xda\x29\x81\xb0\x66\xa4\xd2\x25\x7b\x09\x0a\xd0\x5a\x67\x9f\xf5\x82\x15\x22\xff\x2d\x5e\x38\xad\xaf\xa7\x4a\x54\xdf\x9c\x4f\x20\xb2\x1a\xec\x4d\xc2\xf5\x9a\x00\xc9\x56\x9d\x21\xd6\xd0\x2c\x60\x22\x4f\xfc\xb6\xf4\xf1\x5b\x37\x9d\xae\x55\xd4\x4d\xc1\x31\x9d\x19\xcc\x5b\x91\x09\xf0\x40\x81\x6d\x0a\xd3\x11\xa6\xf0\x32\xa2\xe6\xaf\x8c\x7b\x92\x56\xcd\x7b\xea\x07\x21\x4d\xd6\x18\xd7\x84\xe7\xd3\x6e\x5a\xd4\xee\x9b\x8b\xf0\x66\xb5\x3f\x03\x4a\x96\xbd\xf9\x69\x2a\x30\x52\xe8\x29\xa4\x6a\xeb\x09\x64\x56\x44\x7c\x3d\x9e\x92\x66\x69\xa1\x2a\x99\x35\x57\xaa\x67\x9e\x08\x2f\x5e\x29\x4a\x28\x5c\x5a\x76\xab\x57\x5d\x65\x44\x39\x9c\x56\x32\xed\x6f\xbd\x3d\x38\xb5\xa3\xa3\xb2\xd1\x97\x8a\xd1\x8b\x62\xd1\xbb\x3a\x11\x52\x36\xbb\x33\xbc\xd6\xd9\x9f\x8d\xf3\x34\x26\xc7\x68\x66\x82\xf2\xc0\x87\xe6\x85\x81\x4f\x37\xb8\x0c\xae\x24\x3a\x67\x93\x79\x42\xd0\x4e\xb2\x41\xdd\x83\xcd\xe2\x9e\x80\xa2\xaa\x61\x20\xaa\xae\x1d\x12\x6c\x2c\x26\x98\xf1\x84\xbf\x01\x4f\x01\x95\x82\xa5\x22\x13\x56\x44\x0c\xf3\x05\x72\x62\x97\x22\xd7\xd7\x44\xcc\xfa\xc6\x50\xbc\x5c\x4e\x9e\x31\xbe\xdf\x28\x38\x36\x44\x79\x2c\x44\x8a\xf5\x61\x11\xa9\x60\x59\x29\x33\x60\xe3\x7d\x9f\xcf\x4a\xf4\x97\x25\x38\xd5\x88\xdd\x0b\xfc\x58\xa5\x70\x03\x00\x20\x55\xa5\xce\x99\x51\xbc\x30\x33\x6d\xc1\x65\xc2\x0b\x9e\x48\x3b\x67\xb6\xe4\xc9\x95\xbb\x05\xe2\xa8\xf0\xb8\x01\x4b\xf6\x29\xbd\x3d\x1e\xbe\x66\xc9\x9a\x9d\x95\xba\x9a\xce\xa0\x86\x0a\xef\x4a\x32\x6e\xfc\xdb\xaf\xfc\x3d\xd9\xf0\x86\xa5\x73\xc5\x73\x99\x04\xee\x90\x52\x5f\x4b\x23\x35\x45\xba\x7c\xbb\xe7\x81\x85\x01\xa3\x67\x47\x19\x97\x39\xdb\x33\x42\xb0\x13\xbf\x24\xf0\x9b\x0b\xd4\x24\xd1\x93\x58\x36\x93\xea\x08\xf0\x91\x80\x07\xdc\x27\xb5\xe8\x0d\xa9\x0a\xa8\x0c\xb8\x9e\xaf\x7c\xe8\x7e\x98\xae\xd5\x7d\xd2\x25\x24\xbc\x79\x0a\x20\xa1\x52\x1d\x65\xc4\x1c\x9e\x9f\x9a\xd8\xbe\x25\x1a\x45\x6c\x09\xbe\xc8\xb4\x9a\xc6\xc0\x77\xf5\xca\x74\x42\x5e\x01\x1f\xe6\xb5\x4c\x2b\x9e\xa1\x78\xa7\xce\x1c\x5d\x9c\xe2\xcf\xe5\x74\x66\x87\x37\x02\xbc\x9f\x78\x0a\xd6\x7b\xc6\x3f\x54\x2e\x65\xda\x4a\x03\xc7\x81\x25\x2f\x1b\x7a\x92\x81\x73\x92\xcf\x01\x78\x97\x92\x3b\x1b\xc9\x38\x1e\xa6\x1e\x9b\x58\x35\xe2\xd0\xbd\xc3\x40\x90\xe8\x54\x22\x70\x0f\xbb\x21\x86\x95\xba\xdc\x37\x60\x7b\xac\x39\x37\xc2\xc7\xb6\x66\x7e\x04\x85\xb8\x3d\x43\xf0\xda\x14\xd9\xeb\x7a\x99\x5c\x8a\xbc\xc8\xb8\xed\x27\xb5\x64\xe7\x97\xc8\xfd\x1d\x05\x8f\xdd\x76\xe4\x2a\x1d\xf2\xcc\xad\xc8\xf3\x9f\x8f\xa8\xb2\x0d\x37\x58\x23\x7d\xed\xb2\xe6\x28\xf5\xbc\xd4\x4e\x4b\x5a\xb9\xb5\x00\x4b\x6d\x2c\x52\x10\x46\xf4\x64\xf0\x51\xdc\x28\xe4\x08\x76\x7f\x9c\xff\x7c\x34\x60\x72\x24\x46\xfe\xaf\x70\xab\x97\x86\x56\x4f\xb1\xc0\x21\x54\xd0\xc0\x7a\x86\xae\xc4\xce\xdf\xf8\xb7\xff\xfa\xd6\x75\xd2\x7d\xfb\xf7\xe1\xb7\x11\x97\xd1\xdf\xff\xe5\x84\x6b\xe9\x6e\x68\x7e\x1a\xe7\x97\x83\xdc\x73\x7f\xfd\xeb\x5c\xa7\x17\x85\x48\x46\xf8\x5a\xe6\x5f\x98\x25\xc0\x84\xb2\x4e\xd7\x3e\xd7\x90\x59\x26\x53\x5c\xe5\xf0\xec\x52\xfc\x8f\x0f\x10\x10\x5d\x2a\x09\x92\x84\x5b\xa1\xe0\x00\xf0\x85\xc6\x4a\x5b\xfc\x39\x12\xad\x42\xff\xf7\x26\x31\xf5\xa9\xd5\x1a\xb6\x39\x8a\x92\x43\xc5\xc4\x3b\x69\x00\x77\x06\xdf\x15\x86\x83\x53\xf2\xba\x3f\xd3\x5c\xb3\x6e\x84\x03\xcc\x10\x70\xaf\xba\xbe\xfd\x45\x69\xfb\x97\x30\xfd\x3e\x31\x11\x19\xcc\x19\xbf\xd6\x32\x65\x15\xf0\x66\xb9\x1d\xa8\xc0\xb3\x5d\x53\x17\x8e\xe7\x2c\x97\xc6\xf2\x2b\x31\x62\x17\xee\xcc\x8a\x33\x0c\x70\xf4\x14\x03\x16\x1a\x91\xb2\x4a\x59\x99\xc1\xb7\x75\x3b\xae\xcb\xf1\x59\x76\x3a\x61\xa6\x4a\x80\x9c\xb7\x14\x43\x7f\x3a\xd2\x5d\x4b\x32\xa6\x7e\x97\x41\x98\xec\x19\x47\xfb\xa9\x48\xe1\xa7\x48\xf5\xab\x68\x79\x2d\xe5\x55\xbb\x7e\x6a\x95\xd4\x27\x22\x0c\x26\xd0\x6b\xbb\x43\x30\xf3\x09\x40\x68\xca\x51\xc0\x40\x89\x44\x18\xc3\xcb\x39\xb2\xa1\xca\x40\xda\x48\x29\xaf\x70\x52\xe7\x5c\x55\xd0\x40\x29\x90\x5b\xb7\x4a\x60\x74\x38\x1b\x97\xfa\x4a\xa8\x50\x42\xe0\x66\xb1\x99\x50\x5d\x67\x8d\x22\xed\x34\x4b\x66\x5c\x4d\x45\x5d\x45\x9e\xf3\x14\xc6\xfe\xa7\xa0\x69\xf9\xf7\x71\x23\xc0\x27\x4e\x61\x91\x16\x86\x62\xec\xce\xa7\x10\xf6\x78\xab\x02\x0e\xee\xa0\x8e\x4b\xb8\x57\x92\x59\x2b\x99\xc8\xfa\x71\x84\x77\x77\x81\x0f\x41\xa1\x58\x63\xf2\x76\x2e\x2c\x4f\xb9\xe5\xbd\x25\x70\xbf\xe4\x81\xf5\x93\x92\x3a\x60\x39\x44\xc9\x1e\x74\xc6\x7a\x55\x52\x17\x32\xc6\x15\x00\x69\x30\xf3\xb3\x0f\xb8\x54\xd6\xad\x6b\x0a\x3a\x62\x5e\x36\xe8\x6a\x3c\xcb\xf4\x0d\x21\xd5\xf9\xd6\x50\x64\x89\x94\xa5\x15\xa8\x7d\xb5\x48\xeb\x12\x14\xef\x25\x66\xe2\x26\xba\xb7\x51\xbe\xac\x63\xff\x49\x33\x37\x7b\xa5\x82\x86\x67\x9d\x50\x56\x22\x87\xbe\x07\x82\xa0\xc1\xaf\x14\x6e\xd5\x85\x69\x80\x79\x9a\x0a\x6b\xea\xac\x4a\x3c\x4d\x9c\x88\xa4\xb3\x9c\x9c\x08\x70\xd4\xd0\xd4\x90\x1d\xbe\x5a\x53\xc4\x89\x33\x9a\x4e\x0b\x77\x7e\xad\x7d\x66\xfa\x0b\x1e\x21\xfd\xed\x4b\x9d\x76\x8f\x42\x2d\xf0\xb8\xd6\x0d\xd7\xd5\x26\x58\x79\x64\xc0\xc9\x83\x37\x40\x4c\xde\x34\x60\x32\xf0\x08\x98\xf1\xeb\xf6\xee\xd4\x5a\x33\x1d\x06\xb2\x36\x78\xdc\x10\x1e\x37\x7c\xda\xd5\x71\xdd\x3d\x6b\xd1\x5f\x1d\xb3\x17\x9b\x1d\xea\x21\x52\xe1\x44\xeb\x45\x2f\x81\x84\x05\x14\xa5\xd0\x2e\x9d\xbf\x94\x99\x11\xb2\x61\xa8\x9e\x56\x48\x27\x35\x9f\xb1\xbf\x34\x34\x2e\xd2\x6c\x83\x35\x8c\x55\x4c\x7b\xde\x3c\x1e\xd1\xc4\x7b\x38\xaf\xe6\xed\xfb\x0b\x8d\x81\xaa\xb7\xda\x6a\xf4\xd5\x52\x41\xfd\x76\xaa\x32\xf0\xf0\x87\x1a\x55\xb7\x98\x4b\x9d\x65\x9e\xbb\x1d\x2d\xe4\x85\xdc\x26\xe0\x0d\xc2\x68\xc9\x20\xb8\x21\x82\xbe\xaf\xc4\x4d\x50\xec\xb8\x41\xb8\x52\x1f\xab\x07\x57\x89\x4f\x38\x5b\xd5\x5e\xa8\xe8\x3a\x54\x73\xec\xfa\x71\x34\xb4\xe8\x5e\x60\x53\xf7\x20\x67\x01\x28\x3e\xce\x30\x23\x27\x28\x3e\xd0\x17\x9e\xdd\xf0\xb9\x81\x5d\x56\x5b\x6c\xe1\xf9\x84\xf5\x5e\x37\xfc\x5a\x4c\x3a\xf0\xc9\xc7\x57\x6f\xd1\xfc\xfe\xe2\xf9\x00\xb6\x22\x55\xfb\x24\xdd\xba\x99\x16\x14\xdc\x8b\x57\x7f\x69\x01\x90\x19\x09\x69\x51\x7d\xc4\x57\x1b\xdb\xf9\xf0\xfc\x14\x1a\xf6\x96\xdb\x14\xfe\xf0\x27\x7a\x08\x14\x8e\x85\xdb\x6f\x35\x44\x14\xac\xdd\xf8\xb7\x2b\xf2\xc6\xea\x45\xff\x13\xf0\x21\x51\xfc\xc5\xd7\x03\xbb\x03\xe1\xf0\xfc\x14\x9f\x38\x02\x4a\x5c\xae\xe6\xa4\x6b\xd9\x99\x2c\xd3\x61\xc1\x4b\x3b\x47\xe7\xc5\xa0\xf1\xb4\x50\x14\xd9\xc3\x70\xf4\x1a\x1a\xee\x42\xa1\x16\x5f\x8d\x39\x82\xe1\xf3\x81\x17\x8a\x9c\xdd\x3a\x33\x9b\x36\x22\x5d\x4b\x34\xfd\xd5\x18\x91\x98\x42\xc7\xfb\x2e\x1e\xc4\x88\xa4\xb1\x20\xfe\x54\xe7\xb2\x93\xf1\xa6\x99\xce\x82\xc7\x2c\xe8\xd0\xe4\x6f\xd2\x71\xdd\x58\xd0\xd9\xc0\xf8\x77\x2d\x0d\x98\x9c\xb8\x03\x4e\xab\x21\x55\xab\x07\xe7\x38\xe9\x7d\x3e\xef\x13\x0d\x79\xb7\x75\xd1\xfd\x19\x3f\x2b\x6e\x20\xec\x75\xb6\xa7\xb4\xc2\xfd\x8f\xf7\xee\x63\xda\xeb\x2d\xfe\x5d\xb8\x65\xc4\x7e\x99\x09\x15\x1f\x7e\xb1\x43\x7c\x10\x0e\x61\xa9\x52\x37\xf9\x70\x32\x82\x3f\xc0\x54\x49\x22\x44\xf0\x20\xc5\x74\xf1\xb5\x7c\xa2\x2e\xe7\xdc\x26\x33\x61\x98\xd1\x00\x3b\x6a\x2c\xcf\xb2\xda\x73\x43\xc3\xa5\x41\x8f\xf0\x5e\xf4\x48\xbd\x68\x14\x79\x93\x13\xab\xc8\x38\x79\x4a\x26\x95\x4a\x30\xb1\x4a\xda\xb9\xef\xc1\xf1\xa2\x2a\x05\xe6\xaa\x41\x87\x8e\x9c\xa0\xef\x36\x32\x3b\xc3\x60\x82\x80\x9d\xa3\x48\x6d\x9e\xfc\x84\xad\xe7\xa4\xe9\x98\x27\x57\x37\xbc\x4c\x0d\xd4\xaf\x73\x2b\x91\xe2\x70\xd0\x68\x76\x2f\xea\x83\x7b\x7a\x43\x53\xd8\x0f\xc6\xad\x11\x81\xca\xae\x7e\x0c\xe3\x95\xd5\x39\xb7\x32\x01\xb7\x8d\x9c\x44\x9e\xf8\x3c\x50\x40\x84\x48\x2a\x4a\x76\x38\x2b\xe8\x35\xc0\x82\x2b\xb1\xcc\xc2\xde\x68\x26\x73\xa7\x81\x71\xa0\x7e\x9e\x84\x6a\x75\x1f\x33\xf8\x50\x4f\x9d\x9a\xf9\x0b\x04\x6a\xa2\xbb\xd0\x21\xe4\x4c\x75\x03\xcd\x87\xa8\x40\x70\x87\x53\x59\xf6\x60\x41\x41\xa2\xdf\xb8\x35\xed\xfa\x1a\x2d\xd5\x81\x9b\x9e\x1b\xe1\xf4\x2e\xf3\xc1\x05\x6b\x46\xab\x7a\x24\xa7\x0a\x0b\x77\xa5\xf1\x2e\x04\xca\xc4\xde\x4b\x4b\x5d\x14\xe4\x0c\xcc\xf7\x17\x7b\x04\xb1\xb7\xf2\x5a\x18\x88\x3b\xfb\xdc\x6e\x37\x0c\x53\xa1\x44\xc9\x2d\x78\xf2\x09\x8e\x10\x76\xee\xe2\x23\x1a\x1b\x66\x84\xa0\x2c\xfb\xec\x0d\x11\xfc\x87\x85\x1b\x32\xc5\xef\xa4\x98\xa2\x67\x91\x74\xd3\xad\x46\xf9\xc1\x66\xb6\x1a\xe5\x56\xa3\x6c\x71\x6d\x35\xca\xc5\x6b\xab\x51\xc6\x57\x48\x46\xee\x57\x9b\xac\xab\x0b\xa2\xc4\x8f\x38\x95\xaa\xbe\xe1\x36\x97\xdf\xe9\x84\xbd\x16\x89\xbe\x16\x25\x1e\x22\x27\xef\x0a\xae\x9c\xae\xf4\x9c\xcb\xcc\x1d\x21\xfe\x28\xa9\xdd\x1b\xc0\xa3\xd3\x74\xb1\x47\x1e\xa5\x30\x1f\xb4\x59\x73\xea\x14\x21\x5d\xb8\xfb\x29\x90\x5f\x94\xe2\x5a\xea\xca\xf8\x84\xaf\xca\xa2\xb0\x30\x96\xf4\x99\x99\x9c\x06\xba\xbb\x90\x8e\x51\x8a\x44\x97\x69\x0d\x59\x65\x2c\xb7\x95\x69\xd6\x90\x26\xe8\xd3\xee\xcf\x9d\x19\xc6\x71\x83\x4e\xcf\x3e\xcf\x19\xcc\x98\xeb\x7d\xbf\xee\xbe\xc0\x4c\x3c\xfc\x70\x4c\xcb\xd0\x27\x07\xd6\x89\x89\x4e\xf5\xad\xac\x88\x96\x2b\x2d\xac\x7b\xcf\x61\x03\x8f\xe6\x00\xc9\xc3\x87\xa1\xd9\x61\x9d\x0b\xd8\x9a\x1f\x31\xbe\x7a\x9c\x4d\xd6\x3b\x70\x4a\x7c\x3d\xb8\xd4\xc1\xe6\xd5\x5b\xd5\x02\xfb\x24\x95\x0b\xac\xff\xea\x05\xf6\xe9\x2b\x18\x58\xa8\x28\xeb\x7f\xdf\xbf\xf6\x15\x6e\x0b\x3b\x9f\x8e\xa5\x0f\xed\xfc\x06\x94\x5a\x68\x47\x1a\xa6\x73\x69\xad\xf0\x09\x24\x61\x27\x83\xc3\x3f\xae\xf0\x21\x99\x03\xbe\x04\xcc\x12\x11\xef\x02\x87\x54\xa4\xab\x82\xc6\x79\x23\x0d\x18\x48\x5c\x39\xbb\x16\x11\x6d\x41\x76\x0c\x29\xdd\xd7\xdb\xea\x5b\x39\xd4\xbd\xdd\xad\x1c\x8a\xaf\xad\x1c\x62\xc0\xc6\x95\x41\xf1\x48\xaf\x8a\xb1\x6f\x94\xa0\x74\xf8\x58\x64\xec\xf7\x4a\x94\x73\xe6\x14\xdd\x3a\xcd\x14\xe8\xb6\x8c\x4c\x29\x51\x93\x1c\x93\x5d\xad\xcb\x0d\xd5\xf1\xc0\x71\x7a\xf2\xce\xd9\x09\x80\x80\xd0\xbb\xd4\x5f\x7c\x40\x13\xc8\x08\x67\x21\xcc\x4c\x6c\x1d\x60\x8e\x48\xc3\x5e\x70\xa6\xc2\xe1\xd9\x71\x9f\xa6\x7e\x1f\xe9\x03\xac\xbf\x14\x02\xb6\xe4\x92\xf9\xc0\x10\xe1\x50\x86\x6f\xe0\x60\x0b\x69\x1e\xc1\xd1\xc8\xae\xc4\x7c\x40\xd9\x54\xc4\xb5\xe8\x6f\xc6\xc4\xc4\x26\xe1\x4b\x37\xa0\xc0\xe6\xd5\xf3\x09\xd4\xa7\x6f\x10\xaf\xae\x04\x1f\xcd\xb6\xfc\xe0\xf6\x73\x28\xf6\x7c\xc8\xf6\x40\x04\x12\x5f\xb7\x91\x82\xe0\x6a\x05\x0e\x01\x5f\x2d\x15\x16\x28\x54\x88\x81\x84\xed\x67\x79\xb1\xbe\xdd\x53\x78\xf9\x69\xfc\x44\x83\x15\xb6\x60\xa3\x2c\xe7\x4a\xcc\x77\x0d\x61\x69\x68\x65\x66\xb2\xf0\x2c\x91\x20\x27\x69\x57\xb2\x9f\x21\xff\xcd\x37\x81\x12\xf1\x54\x0d\xd8\x99\xb6\xee\x3f\x27\x90\xd0\x8b\x31\x16\x2d\xcc\x99\xb6\xf0\xc9\x46\x0f\x37\xbe\xda\x27\x1a\x6c\x0a\xd1\x48\x08\xb1\x60\xea\x3a\xd4\xae\xfa\x34\x4f\x18\x54\xca\xe5\x09\x13\x23\x0d\x3b\x55\x4c\x97\x7e\x54\xad\x27\xbe\x32\xd4\x84\xf7\x5e\x47\xd1\xb0\x15\x6d\xd0\x64\xe8\xb2\x31\x17\x1f\x68\x2e\x04\xd6\xa4\xff\x06\xbc\xdb\x10\x89\x0c\xb9\xa9\x40\xbe\xc4\xad\x98\xca\x84\xe5\xa2\x9c\x02\xee\x4a\x32\xeb\x7b\x8a\xfb\x3a\x17\xf1\xea\xf1\x74\xc4\xab\xd7\x75\x08\x2a\xca\x0b\xc8\x3a\xfe\x34\xea\x0f\xb6\x8d\xc7\x75\xce\x0b\xb7\x04\xff\x8f\x3b\x95\x61\x15\xfc\x5f\x20\x77\x33\x23\x76\xc8\x8c\x54\xd3\x4c\x34\xbe\x23\x7f\x66\xdc\x8c\x6b\xc1\xd9\xaf\xbf\x57\xf2\x9a\x67\x02\xab\x04\xb8\x0a\xd4\x2b\x7a\xb2\xa4\x74\x0d\x88\xe1\xcd\xc9\xe5\x10\x83\xdf\xb9\x12\xf3\x9d\xc1\xd2\xb2\xdd\x39\x55\x3b\x35\x84\x53\x63\xa1\x06\xe5\x02\xc2\xb3\x3b\xf0\xdd\xce\xe7\xd1\xd3\x1e\x80\x19\xdb\xdb\x9a\x24\x97\xf3\x51\xc6\x8d\xe9\x03\x4d\x66\xa1\x20\x7c\xa1\xf5\x55\xc4\x12\x17\xd1\x3d\x75\x49\x38\x55\xa0\xf4\xee\x47\x87\x0a\xc8\xbe\xf2\x81\x7b\x18\xff\x6b\xe2\xb3\xee\x0a\x43\xb7\x12\x0a\x1c\x40\xd8\x7c\x85\x6c\x03\x51\xa1\x4e\xd3\xb9\x65\xc4\x7f\x86\x88\x88\x9e\xb0\xe7\x35\x61\x84\x34\xe0\xa2\x92\xbe\x66\x56\x69\xcb\xa4\x4a\xb2\x8a\x82\x21\xf0\x53\x70\x70\xf5\x63\xc0\xf6\x36\xbc\xbd\x2f\xec\xba\x59\xbf\xa2\x7d\x4a\xd1\x52\x21\xd4\x62\xf6\x07\xe4\xdb\x84\x6c\x0a\x1c\xed\x75\x8e\xd6\xa4\x55\xc9\x47\x93\xe8\x24\x69\xea\x97\xcf\xe5\xb8\x14\xec\x68\xc6\x95\x12\x59\x84\x22\x43\xce\x50\x6e\x2d\x4f\x66\x18\xb3\xe3\xcc\xed\xe3\x4c\xd8\x5d\x83\x04\xfd\x39\x4f\x66\x52\x05\x5c\x05\x15\xd0\x94\xea\xba\xb2\x35\x50\x03\x75\x35\x90\x7a\x64\x95\xd9\x25\x5a\x19\x5a\x77\x31\x9f\x4b\x93\x6d\xa6\x06\x28\x5f\xbc\xa7\x46\xea\xa7\x3d\x0f\x23\x8f\xe7\x32\x50\x9f\xc0\xbd\x1f\xe6\xab\xc9\x83\x43\x5b\xaa\x89\x28\x4b\x9c\xa1\xb1\xa0\x1f\x2c\x70\xcc\x8e\x88\xc4\x62\xa6\x6f\x58\xaa\xd9\x0d\xb0\xad\x5e\x3b\x05\x02\x52\x91\x8c\x57\x3d\xa2\x9e\x42\x62\x60\xa2\xf3\xa2\xd4\xb9\x34\xbe\xfc\x91\x96\xc7\xda\x00\x53\xb2\xaa\x35\xe6\x6c\x73\x16\xb3\x4a\x35\xc9\x1e\x9f\x1f\x31\xcb\xcb\xa9\xb0\xee\x19\x4c\x55\xf9\x58\x74\xc4\x85\x59\x37\x2a\x79\xaf\x2c\x20\xbb\x81\x06\xa4\x31\x6a\x1f\xe1\xf7\x60\xaf\xfd\xaf\x20\x81\x10\xd2\x14\x27\xba\xa4\x64\xcb\xf0\x25\xc1\xd0\xbb\x55\xf8\x33\x1d\x9c\x95\xb2\xa6\x23\x2a\x7c\x17\x7e\x10\x5c\x0a\xbf\xfc\x72\xd6\x0f\xac\xfb\x6e\xdd\xde\x6d\xab\xee\x46\x97\x59\x7a\x23\x53\x54\xce\x0c\xdb\x73\x37\xef\x77\x1b\x81\x35\xa2\xbc\x77\xde\xe9\x37\x37\x32\xed\x69\xf0\xa1\xa9\xe6\xa0\xfb\x3c\x6a\x37\xe8\x0c\x46\x5d\xa6\x42\x59\x27\x2c\x4b\xc3\xf6\xe0\x17\xfb\xec\x44\x62\x25\x3e\xfc\x1e\x40\x54\xf3\xb1\x54\x35\xca\x43\x3d\xa9\xee\xb8\x74\x72\xc3\x9b\xf7\x46\x58\xac\xa1\x86\x32\x64\x6d\x67\xcc\xc8\xbc\xca\x2c\x57\x42\x57\x26\x9b\x77\x5c\xda\x0f\x75\x62\x27\x99\x78\x87\x3b\xbc\xbb\xd2\x13\x9a\x6a\x2a\x3f\x90\x68\x5b\x03\xa7\x2c\x69\x3f\x75\x2a\x78\x7a\x10\x34\xa1\x00\x04\x20\xde\x89\x84\x6a\xc4\x8a\xac\x9a\xca\x56\x45\xc1\x5b\x1e\xc4\x56\xbf\xbe\x1b\x0f\x62\x4d\xf7\x56\x19\x51\x23\x97\x75\xe3\x21\xdf\x40\xda\xc2\xf5\xea\x97\x97\xab\x29\x0b\x53\x51\x08\x95\x02\x74\xfa\xf3\x7a\xff\x61\xe7\xd7\x36\xf6\x04\x59\xde\xcf\x59\xe1\xf1\xcf\x1b\xa7\x74\x94\x78\x3f\xd3\x59\x6a\x98\x78\x67\x4b\xee\x8e\x83\xdc\x09\xfe\xf0\x9b\x09\xe3\xaa\xab\x68\x7f\x2c\xc4\x5b\xec\x33\x69\xa0\xe9\x23\xd5\x40\x4d\xaf\x8c\x9c\xbb\x26\xe6\xe1\xac\x47\xaf\xf1\x71\xcf\xe4\x9c\x78\x80\x92\x74\x30\xcd\x3a\xb4\x15\x24\x9a\xf4\x94\x66\xfd\x4b\x37\x32\x4d\xb3\x82\x5a\x6f\xa1\x57\x6b\xdc\xac\x5b\x66\xcd\x87\xc5\xac\x39\x01\xb8\xa7\xee\xe0\xc7\xd4\xce\x82\xcf\x8e\x3e\x24\xb5\xf5\x2e\x3e\x3a\xda\x51\xd1\x99\x0c\x4c\x39\xd4\x10\xc1\x26\x30\xe3\x66\xa3\x2e\x8e\xa8\x94\x6a\x27\xcd\xd7\xcd\x3b\xc8\x2d\x37\xc2\x76\xf1\x24\x37\x15\xcc\xba\x3d\x27\x72\xe2\x95\x4f\x5f\x21\x7b\x27\x14\x7a\x7a\x08\x24\x36\xfc\x3b\xe9\xa2\xaa\x71\xa7\xd3\x42\xfd\xb8\x7b\x70\x64\x11\x32\xcb\xb0\x8d\xd4\xcd\x76\xc2\x6d\x47\x42\xfa\x0e\xa7\x31\xf5\xf6\xcd\x9b\xd3\xe3\x3e\x87\xd0\xb5\xe7\xb5\x55\xf8\x77\x73\x18\x69\x95\x02\x80\xae\xfc\xbd\x8a\x0d\x6d\x80\x6e\x0c\x03\x47\xf7\xaf\x63\x74\xa6\x89\xa8\xc3\x04\xc7\xd2\x5c\x75\x07\x38\x5f\x6a\xb2\xb9\xdd\x7f\x38\x3a\x61\xf4\xe9\x9d\xbc\xf3\xf7\x71\xcf\x77\x45\xc5\x9e\x26\xa2\x0e\xdc\xa5\xd2\x5c\xad\x01\x1c\xbd\xab\x0d\x5c\xa4\x67\xed\xea\x38\x37\x33\xd2\xb0\x68\xe1\x79\x18\xd5\x08\xdf\x77\xae\x2b\x76\x43\x30\x82\x64\x21\x5e\xca\xe2\x19\x3b\x51\xa6\x2a\x45\x9d\xa1\xb5\xd8\x94\xd3\xb7\xee\x6c\x2f\x02\x52\xa3\x79\xd6\x5b\x54\xa2\xef\x95\xfa\x58\xc2\x1c\x05\x2f\x2d\x18\x72\xfd\x2c\xa4\xd0\x9c\x97\xd3\xd1\x07\xea\x2e\x2b\xe9\x74\xe2\x8b\x2f\x06\x84\x29\x16\x80\xd3\xfd\x4d\x6e\xed\x44\x20\xa3\xf1\x6a\x79\x1e\x80\x7d\xd9\x41\x2a\xae\x0f\x4c\xca\x9f\x0e\xe0\x31\xbe\x64\xb0\xd9\x27\x6e\xd8\xce\xd3\x9d\x11\xbb\x90\xb9\xcc\x78\x99\xcd\x1b\x04\x67\xf5\x7d\xee\xd8\xf5\x0d\x42\x36\xcb\x93\x1d\xb6\xa7\x4b\x68\x39\xe1\x8a\x65\xc2\x63\x2e\xd0\xae\x9e\xa3\xdd\xb1\xbf\x19\x22\x92\x6d\x4c\xa4\x08\xa5\x65\x4f\x6b\x2d\xf5\x3a\x15\x9d\xf7\x0d\xd0\xda\xe3\xfa\xc0\x93\xca\x9d\x82\x23\xf6\x86\x8e\x2f\xd2\x0b\x70\x31\xc0\x66\xf6\x77\x6c\xd6\x64\x6d\x9e\x3f\xa4\x95\x67\x63\x39\x74\xb7\x69\x03\xdd\xd6\x7b\x32\x95\xf6\xb5\x28\x74\x0f\x3a\x1c\x36\xb4\x10\x5f\x90\xd6\x7d\xa0\x8d\x04\x7a\x1a\x6e\x19\x47\x91\x94\x54\x19\x77\x46\x1d\x46\x17\x46\xec\xf8\xe4\xfc\xf5\xc9\xd1\xe1\xe5\xc9\xf1\x33\xf6\x03\xb5\x24\x63\x3b\x60\xc4\x2e\x63\xdc\xe9\xa8\xa2\x8d\xc0\x7d\xc3\xb3\x06\x24\x62\xb9\xaa\x89\x33\x00\x87\x93\x2b\x76\xaa\xa4\xad\x29\xc3\xb0\x2e\x20\xd3\x8a\x32\xfd\xdd\xaf\x29\xba\x31\x95\x98\x8f\xaa\xa8\x31\xf7\x75\xb3\x35\xd8\xa1\x48\xb0\x13\xba\xd2\xca\x41\xb2\x66\xe5\xaf\x9e\x9e\x75\x18\xaa\x9e\x0b\xa7\x1f\x1b\x2b\xf0\x20\x79\x18\x08\x8c\x16\xd7\x9f\xe3\x61\x1b\x68\x1f\x3d\xb0\xae\x2e\x1b\xac\x8c\xa3\xd1\xee\x88\xb9\x63\x7c\x77\xb4\xeb\x55\xbe\x6c\x89\x3a\x34\x34\x1a\xe3\x97\x37\x17\xfc\x88\xb1\x57\xbe\x6c\x12\xc0\xa7\x56\xb3\x90\x22\xfe\x62\xc4\x39\xb9\xb0\x6d\x7c\xe9\x7e\x35\x8e\x1f\x4a\x80\xe7\x53\x79\x2d\x14\xbe\xd8\xfa\x24\xb5\xef\x6a\x2f\xd3\x18\xbf\x39\x59\xca\xaf\x5f\xac\xef\xdd\x50\xe2\xf4\xf4\x66\x24\xbe\xe8\xbd\x12\x9d\xe7\x88\xd0\x3d\x0b\x60\x32\x35\x1e\x4c\x90\x8e\x6b\xb1\xf2\x11\x97\x7c\xd2\x6a\x63\x2f\x9c\x0c\xbe\xa9\x05\xab\x3e\x7c\x4c\xe5\xcd\xaa\x36\xa7\xee\xcf\x63\x46\xc0\xf8\xc6\x83\xac\xd2\x31\x7b\x10\x1e\x7e\xf0\xfa\xe4\xf0\xf8\xe5\xc9\x28\x4f\x1f\xa0\x90\x16\x2a\x2d\xb4\x54\xd6\xb4\xb5\xf0\xdb\xf1\xa1\x77\x15\xef\xa1\xdb\xfd\xe8\x70\xa1\x39\xbf\x7f\xfc\x07\x11\xcb\x41\x2a\x2c\x97\x99\x89\x56\x97\xd5\x85\xce\xf4\x74\x35\x01\xda\x3d\x96\xcd\x9f\x10\x21\x77\xc8\x87\x6e\x3d\xae\xcf\xd8\x6d\xcf\xa3\xbc\x68\xe7\x22\x6f\xb2\x1b\xc8\x7a\xb4\x82\xdd\x08\x74\xc7\x8f\x60\xc0\x3e\xa3\x19\xb1\x34\x8a\xe8\xce\x01\xf1\xe6\x49\x28\x6a\x56\x87\x88\x5d\xfd\xae\xf6\xc5\x7a\x06\xbf\xad\x69\xe1\x24\x79\x5b\x1a\xff\xe6\xa8\xfb\x96\x9a\x07\x48\x51\x8a\x61\x80\xcd\x06\x7a\x6f\x5d\x46\x6a\x59\x7c\x9e\x78\x4f\xb0\xf7\x1b\xe3\x5d\xd9\x7c\xd1\x23\x5c\x6b\xf2\xc1\x11\x8f\x58\x84\x59\x36\xaf\xa9\x51\xc8\x1b\xc6\xa7\x08\x87\x5d\x52\x40\xae\x28\xe5\xb5\xcc\xc4\x14\x68\x8f\xa4\x9a\x46\x30\x4e\x31\xf0\x13\xd1\x20\x35\x83\x53\x2f\xdd\x5f\x11\xf5\x1e\xac\xac\xb3\x57\x97\xc0\xa0\x05\x29\x15\x9d\x0d\x4e\xf7\x40\xd8\xf3\xc3\xe1\x10\x5c\x7f\x7b\xff\xe3\x2c\x9f\x34\xdb\x67\xbf\x08\x7a\x8e\x06\x8a\xaf\x12\x68\xee\x67\x3a\xf0\x2d\x41\x5f\xeb\x91\x85\x05\x8d\x69\x7c\x74\xd7\x81\xbb\xd3\x69\xd4\x78\x94\x37\xee\x97\x02\x20\xbb\xeb\x3c\x83\x87\x68\x25\xad\xe9\x00\xed\x59\xda\xfb\x60\xd3\xaa\x3d\x12\xd2\x07\xfc\xb9\xc0\x99\x99\xe7\x99\x54\x57\x35\x46\xfc\x44\xbb\x75\x8c\xe5\xcc\x52\x5d\xf9\x5d\x53\x0a\x9e\xdd\x7e\x62\xb4\x59\xa3\x6b\x3b\x2d\x6c\x6f\xf1\x08\x88\x17\x38\x69\xf1\xa3\x17\x5e\x94\x00\x16\x8b\xfa\x9d\x9d\x07\x3d\x62\xd2\x24\x46\x76\x17\xef\xd0\x4c\x43\xb6\x2b\x76\x7a\x71\x74\x71\xfa\x59\xa3\x7e\xb7\x1d\xae\xd0\xbb\x07\x6d\x3d\xc8\xdf\xdb\x65\x55\x0d\x59\x56\xb5\xfd\x25\xba\x5e\xce\x75\x69\x79\xb6\x06\xc1\x99\xcc\x78\x71\x58\xd9\xd9\xb1\x34\x80\xd6\xd8\x8f\xfa\xb7\xd4\x6a\x54\xaf\x88\x3c\x74\x9e\x70\x43\xfa\xe5\x4b\xf7\x1d\xfd\x78\x78\xce\x78\xe5\xd6\xa3\x25\x8a\xa1\xb5\x25\xcb\xf9\xb7\xb8\xc0\x1a\xe8\x5e\x47\x86\xda\xfc\xc8\xb8\xf8\xbb\x36\x69\x54\x3e\x5f\xd5\xdb\x36\x1e\x0d\x27\x17\x4a\xfd\x47\x12\x83\x96\x4a\x5a\xc9\xad\x2e\x7b\x8b\x0d\x36\x5a\x0c\x0e\xc3\xca\x58\x9d\xd3\x2e\x3a\xf5\x77\x40\x42\x16\xe8\x6f\x4b\x3f\xaa\xbd\x89\x60\x7d\xc2\x98\x9f\x2a\x67\x2b\xf2\x44\x2c\x94\xd9\x0c\x80\xfa\x07\xdb\x96\xe1\x9e\x6f\xc9\x89\x0e\x28\xf6\xd9\xdf\x9f\x35\xc8\x31\x97\x18\x8c\xbd\x17\xb3\xa6\xc7\x5d\x9b\x57\x5a\xfe\xde\x8f\x68\x93\xbf\xab\x85\x78\x02\x0e\xd1\x7f\x55\x3c\xc3\xa1\x3d\x5b\xa7\xf3\xbd\x39\xa5\xfd\xbc\x71\x73\x95\xd0\xcb\xd7\x4b\xe2\x2c\x78\xdb\x2a\x83\x18\xfd\x38\x22\xb6\xe4\xca\xb8\x75\xd2\xf4\x67\xec\x52\x02\xc4\x2e\xdb\xb3\x49\xb1\xbf\xb6\x91\xea\xab\x1c\x36\xab\x54\xac\xac\xe2\xbb\x5f\xe2\xd2\x78\x11\xca\x61\xbb\xbd\xe6\xda\x93\x1c\x60\xb7\xf7\xe3\xb7\xa5\xb6\xc2\x3a\x8a\xc7\x0b\x15\x44\xf6\x42\x1a\xeb\x09\x84\xe1\x03\x69\x88\x6b\x0d\x6c\x81\x73\xa6\x4b\x26\x8b\x7f\xf2\x34\x2d\x9f\xa1\x1e\x41\xb6\x2a\xfc\xdb\x04\x38\x7c\xae\x42\xb6\xcd\x9e\x9d\x17\x44\xe2\x71\x79\x74\xce\x90\x28\xfc\x9b\xbf\x3d\x01\xbb\xe0\xab\x2f\xff\xf6\xa4\xe3\x42\x7c\xa8\x55\x85\xac\x6f\x9f\x68\xef\x99\x15\x8f\xa4\x8a\xa4\x51\x2d\xe2\xc6\x02\xb4\xdd\x0b\x2c\xce\x70\xe7\x24\x09\x4d\xdc\x08\x6e\x55\x86\xd3\xbb\x4f\x9d\x78\x5b\x75\xf1\x07\xaa\xba\x60\xa1\x1a\x1f\x05\x6b\x2f\x0b\x39\x6e\x10\x60\x75\x96\x05\x38\xca\xee\xf3\x87\x22\xbb\x5b\x8e\x6e\xdb\x95\xdc\x5c\xc1\x71\x8a\x9f\xa7\xce\xaf\xcb\x53\x8f\xcf\x2e\xfe\xf9\xe2\xf0\xfb\x93\x17\xf0\xae\x94\x15\xe8\x96\x27\x59\x42\x6d\x72\xd6\xef\xbe\xdc\xdb\x3b\xb7\xda\x0e\x69\x1f\x09\x06\x6a\x21\xb5\x40\xb1\xb3\xe7\x17\xf7\xcd\x2a\xe8\x6a\xce\xaa\x49\x87\xd1\x7b\x68\x71\x0d\x60\x5a\x17\xe5\x7a\x2a\xe7\x7b\x0e\x8a\x44\xb0\xf7\x0d\x3f\x8a\x5b\x43\xf8\x8e\x9d\x5d\x1d\x2d\xd7\x06\xdb\x38\x5d\xef\xc3\xf1\x6f\x37\x62\x38\x8a\xbd\x47\xbe\x3f\xeb\x68\x77\xd3\x21\xcb\xbe\x60\x1d\x76\xb1\x2d\xaf\x3e\x3a\x11\x86\x67\x47\xe9\x4e\x55\x77\x9e\x0a\x13\xd8\x98\x1f\xc1\x6a\x2d\x56\x51\x0f\x76\x3f\x1d\x56\x36\x4b\x1c\xdc\x9e\x7a\x29\xca\x2a\x68\xd4\x75\xdf\x46\xe0\xe9\x33\x32\x39\x39\xc2\x4c\xc1\x93\x5e\x09\xe1\xeb\x8f\xf0\x13\x80\xde\x7b\x88\x07\x0c\x74\x7c\x4d\xe5\x65\xe1\xd9\xfd\x6c\xc7\xd0\xdc\x22\xd2\xca\xbd\x56\x89\xa7\x2f\x2f\xb4\x47\xd2\x89\x21\x59\x36\x72\x09\xb1\x8d\x3b\x87\xc2\x31\xf4\x4b\x4b\x77\xc3\x3a\x5d\x0d\xc5\x4c\x5b\xad\x7a\xae\xa1\x5d\xd5\x68\x53\xb0\x9d\xc3\x1d\x47\x58\xe9\x9e\x89\x32\x92\xb7\x58\x41\x14\xc2\xea\xce\xf2\xf0\x47\xb7\x56\x3e\xc0\xde\x0c\xaf\x3f\x3c\x49\x54\xa4\xa7\xc7\x6b\x10\x42\x8f\x0d\xec\xe8\xbe\x61\xc2\xb5\x25\xca\xa6\x3d\x55\xee\xbb\x86\xfc\x98\x9f\x1e\x93\xb9\xe0\xcb\xf2\x0d\x6d\x2b\x76\xfb\xbe\x5a\x8b\x2a\xa5\x4b\x7b\xa3\xcb\xbe\xe0\xe3\x9a\xcd\x2d\x64\x61\xd2\x77\x4b\x60\x1c\x8f\x53\x8a\xe0\x5b\x3e\x78\x49\x72\x01\x92\x64\x81\x06\xf5\x36\x89\xf2\x29\x04\xca\xc3\x11\x24\x9f\x46\x71\xf9\xb4\x48\x5c\x6b\x33\x7f\xfd\xf6\xe8\x65\xb0\x7c\x63\xe4\x06\x75\x0b\xa5\x96\xbb\x1c\xdc\xcd\x91\xe4\x59\x8b\x9c\x2d\xb5\x93\x43\xed\xc4\x49\x53\xc4\xfa\x96\x30\x38\x88\xb4\x8d\x59\xe6\x66\x56\xab\x98\xf0\x91\xc0\xba\x06\x0c\x39\x13\x73\x5e\x10\x69\x7e\xaa\x6f\xd4\x0d\x2f\x53\x76\x78\x7e\xfa\xf9\xe5\x6a\xe7\x4a\x50\xdc\x0f\x5d\xb8\x05\x9a\xb5\xa0\x75\x7b\x90\x81\x0f\x49\x42\xee\x8f\xb1\xb4\x06\x53\xf9\x21\x19\xdf\xc6\xde\x28\x77\x4e\x85\x4c\x16\x27\xe9\x9c\x54\xa3\x96\x22\xb5\x4a\x31\x9d\x58\x9e\x79\x22\x66\x61\x6f\x84\x50\xec\xc9\x93\x27\x18\xa0\x78\xf2\x1f\xff\xf1\x1f\x0c\x58\x37\x53\x91\xc8\x7c\xf9\x46\xb8\xeb\xeb\xa7\x4f\x47\xec\x1f\x87\x2f\x5f\x30\x9e\x80\x2d\x87\xc8\xb7\xd8\x32\xcc\x67\xfc\x63\x33\x60\xff\xfb\xe2\xd5\x99\x3f\xbe\xcc\xc2\xb7\xb0\x5c\xc2\xeb\x8d\xd8\x71\x94\x7b\x1f\x07\x0f\xb8\x9d\xc1\x68\x28\x6d\x19\x9f\x4c\x70\xc1\x81\xe4\x96\xc6\x0b\x13\x8f\x3d\x27\xa7\x33\xcf\x44\xef\x96\x5a\x06\x45\x01\xd2\x75\x11\x02\x36\x1e\xc7\x11\x6b\x1c\xa0\xad\x70\x88\x40\x57\x06\x2c\x93\x57\x82\x4d\x0c\xf0\xd1\xd7\xc4\x29\xa5\x30\xce\x00\x4b\xb8\x72\xad\x63\x63\xf5\xcc\x18\xd1\x11\x1b\x73\xdd\x99\x13\x1d\x99\xcb\x9b\x21\x64\xda\xf3\x9e\x42\x8c\xb8\x01\x7d\x8d\x16\x8a\x0c\x37\x0b\x0f\x35\x93\xa1\xf1\xb6\xe7\xe1\x7d\x70\x51\x11\xfa\x61\x2d\x19\x79\xa6\xd5\x34\x5e\x83\xb5\xf6\xe1\x93\x29\xe7\x85\x68\x3b\x18\x3d\x11\xea\xf4\x43\x4f\x87\xc2\xfd\x25\x2f\xba\x31\x81\x34\x73\x74\x7d\x9b\x0d\x1c\x4a\x3e\xd6\x95\xf5\x39\x7b\xf4\x3d\xc0\xb7\x59\xed\x87\xbe\x53\x17\x7a\x63\x29\xea\x8f\xf7\xaf\x27\xd2\xad\x66\xce\x1c\x9c\xda\x4d\x95\x75\xc0\x04\x4f\x66\xec\x4a\xcc\x87\x78\x02\x14\x1c\xd0\x23\x60\xb4\x8f\xdd\x18\x37\x68\xf8\x83\xe7\x39\x75\xd6\x24\x4d\x85\x4f\xb0\x8c\xf4\x03\x8f\x3e\xe1\x0d\x2e\x43\x7a\x39\x51\x59\xa9\xc8\x43\xe9\xb9\x2b\x13\xad\x2c\xf1\x62\x06\xee\x2a\x48\x18\x5d\x00\x24\x70\x12\x46\xa4\xee\x67\xe6\x43\x4f\xae\xb3\x4a\xdd\x89\x42\xfa\x47\xa5\x96\x7e\x0d\x78\xee\x90\xd3\x6b\x04\x21\x23\x71\xcf\x89\x18\x65\xa6\xce\x64\x02\x15\x47\xee\x76\xba\xd7\x8f\x52\x18\x88\x06\x60\x82\x11\xb6\xa2\xa1\x81\x3c\x61\xf7\x6c\x61\x0c\x93\xf0\x86\x39\x2f\xaf\x84\x07\x1a\xe6\xd9\x88\x9d\xbb\x4e\x06\xb4\x79\xa4\x12\xbc\xc6\x02\x11\x27\x63\x62\x24\x08\xf7\x90\xdd\xd1\x68\x17\x8f\xca\x15\xb8\x10\x9d\x57\x4d\x9f\x2c\x72\xbd\xb1\xc7\x35\x96\xf2\x4b\x5e\x18\x64\xd3\x73\xa6\x05\x30\x56\x6a\xc0\x6d\xb1\x33\xaf\x4c\xf0\x8e\x10\xe2\xf1\xd5\x33\x8d\x59\xbf\x4c\xa8\xfd\xf1\xa0\x76\x88\xb5\x37\xaf\xbe\xf9\x4f\x7b\x64\x3f\xbd\x8d\xfb\x94\xd6\x10\x49\x92\xbe\x18\x19\x7b\xa7\xdc\xcc\x7b\x20\x36\xf3\x57\x33\x74\x04\xfa\x6d\x03\x4b\xfa\x4e\xb6\x08\x41\xa9\x67\xe2\x41\x19\x1f\xa7\x13\x10\xa9\xab\xb1\x6e\x62\xbb\xcc\x9f\x30\x6e\x04\xd6\x6f\x75\x74\x65\xd9\xf3\xd7\xa7\xa0\xa9\xef\x6e\x96\x2c\x5e\x5d\x92\x68\x16\xaf\xa6\x23\x23\x82\x95\x08\x47\x6d\x5c\x7d\x0c\x53\x65\x35\xb0\x75\xd6\xc2\x61\xc4\x5e\xd2\x51\x8c\x8b\x9c\x8f\x8d\xce\x2a\x1b\x90\x28\x56\x9c\xd3\xd0\xa8\xe7\xf6\x44\xd0\x26\x7f\x5b\x74\x6a\x83\xbe\x82\x47\x59\x3f\x07\x38\x5e\x3d\x0a\x9f\xae\x09\xb2\x78\xfd\xc1\xd2\x64\xf1\xea\x71\x16\xbc\xba\xd8\xf3\x4c\xf8\x66\x03\x7a\xa7\xaf\x88\x6c\x68\xb7\x90\x23\x6b\x0d\xaa\xce\x5e\x51\xc5\x1a\xca\xb6\x08\xd8\xf5\xd5\xdd\xab\x4b\xef\x45\x0e\xc6\xc3\xf3\xd3\x1e\xad\xd2\xa8\xd5\x5b\xec\xd2\xf8\x8e\xad\x65\x7a\x97\xab\x31\xc0\xa7\x68\x99\x3a\x95\xde\x3b\x90\x8e\xeb\x11\xa5\x90\x9e\x13\xca\x7f\x00\xd3\x66\xe9\xc5\x9f\xbb\xc3\x28\x2e\xe6\x6a\x32\x74\xa0\x33\xb8\x3e\xb6\x22\x56\x0f\x9f\xc3\x03\x22\xee\xf1\x9b\x41\x1b\x6a\xbc\xc0\xe8\x77\xa8\xd8\x59\xbc\x9a\xa7\xe8\x6b\x3f\x88\xec\x42\x64\xee\xd0\x63\x0b\x2e\x9b\x42\xa7\xcf\x90\xf3\x9b\x2b\xa5\x2d\xac\x1b\x33\x60\x19\xf0\x91\x0f\xd0\x15\xe3\x34\xd0\x28\xfb\xab\x8c\x82\xa6\x3d\xeb\x9c\xbd\x2d\x1e\xd6\xfb\x02\x62\xb0\x88\x60\xec\xce\xfb\x59\x49\xec\x13\xac\x26\x77\xd5\xaa\x4a\x9f\xb4\xfc\x8d\x75\x45\xed\xfb\x45\x64\x92\x99\xc8\x39\xf2\x91\xf8\x01\x72\xf2\xfa\xa6\x94\xd6\x0a\x44\x1d\x17\x65\x6e\x98\x9e\x0c\x1a\x71\xe3\x9d\xeb\xa7\x3b\x7d\xe9\xb3\xec\x53\x18\xd4\xcc\xef\xd0\xb6\x30\x60\xb7\x5d\xcd\xb8\x41\xc3\xb8\x70\xbb\x13\xac\xe9\x0c\x08\x92\xd4\x82\xc3\xd2\x29\x11\xd7\x38\xfe\x1b\x3d\x74\x9f\xce\x17\xd1\xd6\x07\x31\x08\x8a\xe9\xd6\x07\xb1\xf5\x41\xf4\xd1\xe2\x27\xf3\x41\x44\x07\xb7\x17\xa6\x2b\xfc\x11\x71\x21\x9e\x77\x4a\xd4\x50\x16\x11\x4c\xb4\x5b\xf2\xde\x1d\xa1\xcb\x66\xac\x60\x77\x34\xda\xdd\xf5\x4e\x0a\xda\x1f\x95\x9d\x0c\xbf\x61\x42\x25\x3a\xc5\x45\xe5\xda\x2f\x8d\x05\xa5\xb6\xb6\xca\xe3\xbe\xe4\xfe\x59\x71\xbc\x01\xda\xee\x77\x49\xf4\x28\xa1\x7c\x4a\xca\xf3\x4f\xaa\x82\xd5\x8a\x57\x80\x01\xa3\x01\x0c\x68\x89\xa4\x81\xd5\x29\x32\x99\xcc\x25\xe1\x13\x3a\x71\x21\x8c\x35\x6c\x0f\x3f\x1c\x25\x45\x35\xa0\x1b\x46\xb9\xc8\x75\x39\x1f\x84\x9b\xdc\x97\x8d\x5f\xd1\x1d\xfb\xa0\xb5\x25\x55\x59\x0a\x65\xb3\xf9\x1f\x57\x7f\xf3\x43\xbc\xc1\xea\x5b\x58\x15\x5d\xea\x3e\x56\x5d\xcd\x65\x59\x93\x08\x80\xf7\x2e\x8c\x36\x9c\x43\x54\x81\x31\xa8\x9d\x3f\xee\x53\xa1\xae\xd9\x35\x2f\x5b\x57\x60\xac\xba\x3e\x89\xc6\x96\xca\x6b\x69\x74\xeb\x1a\xb6\x95\x4d\xc6\x83\x77\x41\x87\x32\xfa\x88\x75\x65\x8b\xca\xd2\xe9\xe2\xf7\xb6\x87\xec\x0b\x7b\x7a\x41\xf1\x7d\xba\xd3\x63\xe7\x0a\x6e\xad\x28\xd5\x33\xf6\xdf\x7b\x6f\xbf\x78\x3f\xdc\xff\x6e\x6f\xef\xd7\x27\xc3\xff\xfc\xed\x8b\xbd\xb7\x23\xf8\xc7\x5f\xf6\xbf\xdb\x7f\xef\xff\xf8\x62\x7f\x7f\x6f\xef\xd7\x9f\x5e\xfe\x70\x79\x7e\xf2\x9b\xdc\x7f\xff\xab\xaa\xf2\x2b\xfc\xeb\xfd\xde\xaf\xe2\xe4\xb7\x3b\x36\xb2\xbf\xff\xdd\x9f\x7b\x7c\x09\xae\xe6\xaf\x7a\x13\xc1\x78\x0d\x3f\x89\x1a\xd1\x6c\xbb\xe7\xa5\xcb\xd8\xbb\x61\xed\xd1\x1e\x4a\x65\x87\xba\x1c\xe2\x43\x9e\x31\x5b\x56\x7d\x89\xae\xfa\xf8\xfb\x74\x32\xa6\x56\x62\x6a\x04\x4c\x6f\xd8\x6c\xa0\x10\xc1\xc4\xd4\x1e\x3d\xc3\xc4\x63\xbb\xda\x29\x4c\x5f\x6e\xfd\xc1\x77\xb9\x3e\x61\xa6\x12\xe1\xd9\xfc\xc1\xd3\x94\x2e\x88\x4d\x79\x9b\xa3\xb4\x74\x6d\x73\x94\x96\xaf\x6d\x8e\xd2\x3d\xaf\x6d\x8e\x92\xbf\xb6\x39\x4a\x5b\xff\x60\xf7\xeb\x0f\xee\x1f\xdc\xe6\x28\xdd\xf7\xda\xe6\x28\xb5\xbe\x1e\x50\x8e\x12\x2a\xf9\xab\x32\x95\x48\xcd\xaf\xd3\x94\x36\x36\x4b\xc9\xb8\xf5\x90\x88\xc3\x24\xd1\x95\xb2\x97\xfa\x4a\x74\x0c\xe4\x2e\xd8\xa4\x4b\xad\x03\x24\xe2\x2d\x36\xea\xf2\xcd\x1b\x69\xb0\xf6\xa5\x8f\xf6\xa0\x3f\xf6\xa7\x39\xf2\x2a\x95\xce\x46\xed\x79\xb3\xf8\x66\x63\x58\x6c\x95\x8a\xb4\xfe\x82\x44\x9a\x75\xf3\x3d\x62\x87\xac\x14\x89\x2c\xa4\x3b\x00\x00\x2b\x08\x3e\xc7\xed\x13\x58\x9c\xa5\x35\x22\x9b\x10\x93\xad\xaa\xcb\x9c\xcb\xc8\xfe\xa4\x13\x65\xe5\x63\x50\x87\xd0\x9e\x6b\x94\x99\x99\xae\xb2\x94\x95\xe2\x7f\xbc\xf2\x41\xbd\xb9\x8c\x5b\x88\x5d\xaa\xf0\x2a\xf5\x63\xa9\x71\x5e\x48\x02\x15\xdb\x24\x31\x28\xde\x15\xb2\x84\xcd\x76\x21\x12\xad\xd2\xbe\x3d\x24\x4b\xed\xd7\xba\x02\xc4\x85\x44\xca\xd2\x0a\x6f\x80\x72\x4c\x9e\xc9\x54\xda\x79\xc8\xe7\xc0\x6d\xef\xd4\x56\xe4\x0e\xa6\x85\x60\xea\x89\x60\xbc\x28\x4a\xcd\x93\x99\x30\xd1\xd3\x50\x09\x25\xa0\x8c\x50\xe5\x99\x55\x53\xa9\x50\x0f\x85\xdf\x38\x65\x25\x9b\xb3\x52\x5b\x9f\x9a\x76\xcb\x03\x2f\xa3\xc6\xe0\xe7\xa8\x71\xd8\x72\x0e\xf9\x6b\x3a\x6e\x02\x7b\x25\x27\xf1\x1f\x86\xe9\x2c\xf5\xd0\xac\xdf\x3c\x71\x8a\x7f\x42\xab\xd8\x1d\x02\x00\x9a\x69\x35\xcb\x9c\xf2\xe4\x0e\x86\xdb\x7f\xfc\xe5\x5f\xd9\x4c\x57\xa5\x19\xc5\x60\x7f\x4f\xe1\x33\xf4\x70\x78\xc3\xc1\xb2\x4c\x70\x63\xd9\xd3\x27\x2c\x97\xaa\x72\x27\x7e\x4f\x0b\xaf\x2f\x5d\x37\xd2\x72\xff\xf6\xd7\x8e\xad\xf5\xa3\xdf\xde\xaa\xd9\x16\xc8\x98\x47\xea\x2d\xed\x71\x04\xf4\x40\xd6\xcc\x05\x65\x97\x8e\xa4\x78\x16\x95\xd5\x6b\xde\xf9\xbf\x57\x7a\x3c\xb7\xdd\x21\x6c\xa8\x9d\x26\x76\xcd\x7f\xd1\x87\x77\x81\x8a\xad\x91\x62\x5b\x74\x65\xed\x1c\xdf\x53\x69\x6c\x2b\x86\xef\x1a\xf3\xa6\xc5\x8f\xbb\x1e\xe6\x53\x67\x1f\xf7\x52\x49\x0f\x2d\x79\x8b\xce\x7b\xa4\x93\x44\x18\x10\x45\x1e\x14\x0e\x9c\xbb\x78\x6f\xcb\x87\x6e\x28\xda\xcc\x2a\x10\x19\xbf\xf8\x7b\xe0\x2a\xed\x34\x58\x5d\x54\x7e\xbf\xb0\x7b\x1a\x2d\x6c\xac\x29\x23\x8c\x54\x53\xa4\x16\xcd\xab\xcc\xca\x22\xab\x47\xee\xb5\xff\x01\x1d\xc0\x71\xb4\x80\x47\xee\x69\x8e\xa0\x57\x88\x7e\x0e\x91\x95\xbd\xd0\x96\x50\x16\x19\x32\x4b\x77\x8e\x17\xbc\xe4\x61\xf8\x13\x9d\xe7\xdc\xec\x53\xe0\x81\x43\x16\x0c\xd1\x00\xb9\x5f\xf1\xac\xee\x71\x94\x75\xb0\xae\x85\x6b\x85\xe2\xaa\x75\xf8\xaf\x09\x38\x0f\x4d\x31\x7d\x13\x12\xed\x91\xe4\x7e\x61\xc5\x92\x42\xfc\x3d\x4f\xae\x84\x4a\xd9\x1b\xe3\x07\x2e\x9d\x2b\x9e\x13\x7e\x7c\x51\x6a\x64\x51\x17\xe9\xc2\xef\xcd\x80\xdc\x8e\x08\x7d\xe2\x01\xac\x50\xdf\x5a\xd7\x28\x56\xa6\x27\xf0\x60\xd7\xd0\xc7\xe4\x9d\x41\x97\x6e\x29\xaf\x13\xe1\x75\x47\xf7\xbb\x75\xbd\xfc\x75\x6b\xb4\x3a\xb6\x1a\x3a\x8a\x68\x4c\x71\x17\xc2\x91\x1e\x22\x97\x00\x13\xcf\x33\x27\xe2\xe6\x01\xf3\x67\x61\x81\x8d\xe7\xe0\xf7\x5a\x0b\xf2\x58\x39\xee\x8e\x29\xb5\x5b\x8e\xd3\xa6\x30\x7b\xcd\x53\x6d\xd8\xf7\x99\x4e\xae\xd8\xb1\x00\xa3\xe1\x53\x92\xef\x97\xe3\xf4\x61\x13\x67\xe6\x7c\xda\x2e\x63\x64\xc8\x72\xad\xa4\xd5\x65\x1b\x79\xbc\x41\x40\x81\x5b\x2a\xc3\xbb\x20\xa6\xbb\x7d\xf6\x58\x88\x0c\xdd\x92\xef\x67\xe9\x40\x53\xc1\x75\x02\x92\x07\x3f\x02\xa1\xda\x5a\x8e\xfc\x69\xa6\x6f\x86\x56\x0f\x2b\x23\x86\xb2\x75\x22\x54\xe7\x81\xba\x12\x73\xc8\x2a\xeb\x65\xa8\xa8\xb1\x86\xe5\x6e\x35\xf8\xd9\xe1\x73\xa7\xdf\xbd\xfe\xfe\xf8\x8d\x11\xe5\x28\xb6\x56\x0e\x84\x4d\x0e\x12\x51\xcc\x0e\xa8\x85\x07\x3f\xac\x5e\x6c\xf6\x33\xae\xbe\x35\x54\x04\x12\x9d\x65\x04\x30\xa6\x27\xec\x48\x14\xb3\xf0\xb8\xcd\x18\xb7\x87\xcc\x29\x57\x68\xdd\x0f\xdd\xd4\xae\x6b\xa9\x29\x36\xe0\x13\x94\x1a\xd1\xe2\x2f\xc7\xf7\x23\xf2\xde\xc4\xe5\xfe\x19\xd9\x59\xda\x50\xf1\x6d\xc4\xf0\x6e\x0e\xa5\xdf\x6e\x83\xd3\x2f\xae\x1f\x6a\x12\xf6\xf9\xec\xd4\x86\xd8\x3e\x9d\xa0\x31\x9a\x8a\x94\xe9\x6b\x51\x96\x32\x15\x86\x05\xb9\x1d\xfb\xa0\x64\xb6\x19\x23\xbf\xe5\x0e\x7c\x58\x09\x07\x9b\xe3\x7e\xd8\x05\xff\x43\x43\x88\xc3\x27\x4b\x42\x9c\xa7\xb9\x54\x9b\xb1\xda\x5b\x8e\x9b\x49\x78\x26\x4e\x5f\x75\xb6\xd6\xa9\x9d\xa6\xc1\x7e\x41\x1f\x46\x9c\x02\x1f\xc1\xd9\xff\x29\xac\x5d\xa6\x74\xda\x2e\x80\xb6\x66\xb3\x7b\xca\xad\xb8\x69\xa9\x08\x0d\x6b\x91\xdf\xf6\xf7\x60\x9e\x3d\x6c\xb3\x7d\x23\x98\x42\xa2\x5d\x8e\x90\xff\xeb\x52\xb2\x68\x3d\xf5\x13\x48\xc2\xb6\x62\x52\xb6\x45\x2a\x36\xbf\x67\x0f\xcf\x4f\xd9\x0f\x78\xfb\xfa\x58\x50\x4a\x6d\xd1\xe4\x39\xd6\x39\x97\xfd\x10\xa0\x2f\x36\xba\xc8\x87\x15\x0f\xc2\x79\xb8\x97\xd1\xcd\x4e\x29\xaa\xe1\x86\xab\x52\xa4\x8c\xfc\x29\x8f\x8c\xe2\x61\x49\x9d\x7e\x1c\x14\x0f\x9f\x8a\x25\x3b\x72\xcd\xfb\xfa\x9d\x5a\x8b\xf6\xcb\x09\x94\x88\x90\xeb\xc4\x8c\x50\x46\x42\x7a\x43\x94\x81\x07\xaa\x36\xa4\xa5\x87\x62\x1d\x54\xbb\x07\xec\x85\x9e\x4a\xe5\xa5\x98\xa6\xac\x9a\x09\x97\x59\xb7\xe1\xdc\xea\xc9\x7f\x30\x3d\xd9\x98\xec\x44\xf1\x71\xd6\x3e\x65\xb2\xb9\x09\x42\x73\xec\x79\xc6\xa7\x4c\xc0\x1f\x07\xa9\x34\xee\xbf\xec\xe2\xe2\x05\x04\x83\x2b\xe5\xed\x4b\x08\x73\xd2\xd9\x12\x4a\xa3\x51\xc8\xac\x4f\x2e\xa0\x10\xef\x8d\xc1\x23\x6a\x8f\x49\x95\xba\x57\x17\xa6\x91\x94\x4c\x77\x20\x57\x4a\xa8\xbb\xc3\xd4\xc7\xb1\x60\x97\x33\x99\x5c\x9d\x47\xf1\x5f\x5d\xba\xcf\x54\xf4\x51\x43\x49\x59\xfc\x6e\x5d\xa7\x11\xbd\xd6\x79\x5f\x0e\xb5\xa8\x3d\x7f\x52\x7b\x71\x7a\x41\x23\x08\xdf\x71\x63\x74\x22\xeb\xfc\x03\xf0\x44\xd7\xc7\x77\x0a\xc7\xf7\xfa\x46\x05\x14\xce\x7e\x06\x04\xf5\xdc\x15\x5a\x8b\x5f\x51\x74\x07\x37\xb1\x96\x22\x95\x1f\xb7\xb5\x0d\x02\xae\xf1\xde\x28\x4d\xeb\xe6\x96\x29\x4d\xbd\x99\xb9\x10\x22\xf7\x05\xaf\xb4\x80\xbc\xc9\x40\x1c\xda\xcb\x4b\x28\x50\x9b\x12\x99\xc9\x5a\x86\xae\x7d\x69\xfa\x2a\xf7\xdf\x42\x7e\x10\x7e\x46\x41\x73\x90\x3d\x85\x2e\xaa\x0c\x33\x6b\xbb\x33\xbb\xfa\x18\x23\x3e\x67\x0d\x41\xf4\x4d\x63\x76\xda\x8d\xcb\xf3\xee\x5f\xaf\xf8\x38\xf8\x9d\x22\xd3\xe2\xc9\xdf\xfe\xfa\xd7\x87\xce\xf8\xd4\xcd\x71\xb7\x6e\xca\xa7\x4e\xa1\xb7\x15\xd8\x0c\xa7\x5b\x6c\x86\x2d\x36\x43\xf3\x5a\x7b\x7c\xf8\xf3\xa3\x2f\xf4\x52\xdd\xd6\x47\x65\x5b\x57\x7c\x85\x8e\x55\x71\xfd\x54\xc4\x75\x46\x50\xf8\x1c\xb8\x09\x3d\xd5\x88\x75\xc7\x48\xd8\x22\x23\xfc\xb1\x90\x11\xfa\xab\x11\xeb\x0b\x05\xa1\x7b\x6d\xd8\x1f\x07\xf1\xa0\xb3\xd8\xe8\x5a\x57\xdf\xb9\x9a\xbe\x2f\xd2\x8f\xbe\xbc\xfb\xbd\x79\x18\x76\xeb\xf6\x56\xfa\x5b\x3c\xc4\x9b\x47\xd3\xdf\xdd\x35\x11\x58\xbe\xd5\x4e\xba\xac\xd1\x74\x66\x9d\x3d\x0f\xd8\x15\xdd\xea\xec\x5e\xe5\xc5\x7b\x75\xb1\x90\x20\x10\x3e\xde\xfc\xbc\x80\x6d\x80\xbc\x5b\x9a\xfa\xe3\x0a\x8f\x3e\x52\x06\xfc\x4f\x15\x1e\x35\x0d\xd4\x5c\xef\x75\x04\x01\x09\x2a\x9c\x1e\xc7\xcc\x34\xb5\x58\x38\x3c\x3f\x65\x49\x29\x00\xda\x81\x67\x66\xc4\x56\x68\x78\x3e\x80\x44\x1a\xa1\xd7\xec\xb8\xb5\x22\x2f\x6c\xd7\x95\xb7\x8d\x8e\xfe\xc1\xa2\xa3\x9f\x3c\x4a\x31\xab\x72\xae\x86\x4e\x5a\x40\x7c\xb4\x91\x77\xb2\x70\x1e\x8e\x18\xc9\x05\x54\x2b\xc0\x17\x0a\x25\xcd\x95\x92\xbf\x57\xa2\x76\x57\x04\xad\x63\x03\x82\x3b\xd0\x8f\x9e\xc7\x0e\x35\xaa\x05\x29\x92\xe8\xa5\x22\x2e\x1a\x90\x30\x8e\x5e\x60\x44\x6a\x59\xc3\xf5\x66\x67\x02\xb5\xb7\x73\x00\x49\xa8\xef\x6a\xda\x87\x68\x20\xf2\x2c\xd3\x37\xf8\xec\x58\x1f\x71\xf3\xe7\xfa\x42\xb8\x24\x63\xc1\x72\x59\x96\xba\xa4\x30\x52\xdc\x1d\x4c\x1f\x72\x76\xa6\x28\xd1\x60\x2b\x29\xe9\xe3\x42\x58\x9a\x6a\x58\x2a\x56\x33\xae\xb0\x80\xd3\xfd\xdb\x67\x5c\xc3\xb3\xbd\xbc\x1b\x8b\x19\xbf\x96\xba\x2a\xf1\xd7\x56\xb3\x1d\xfa\x0a\xce\xde\xb9\xae\x82\xef\xbc\x82\x0a\xad\xf0\x76\x66\xc5\x38\x9d\xd5\x5f\x82\x81\x9b\x6a\xef\x8e\x1c\x8a\x77\xd2\xd8\xe5\x77\xf1\x43\xe4\x29\x27\xd6\xb1\xf2\xae\x4d\xe1\x0e\xd8\x9f\x5b\xd7\xde\x36\xd7\x5b\xdc\x5a\x53\x53\xbd\xbe\x80\xaf\x3e\xa6\xa7\x12\x62\x0d\x96\xcc\xfb\x72\xb8\x87\x97\xc3\x8a\x6f\xd9\x92\xeb\x6a\x23\x15\xe5\xad\x92\xfc\xc1\x2b\x64\x59\x64\x32\x99\x9f\x1e\xf7\x9b\xb9\x81\x6d\xfa\xe3\xcf\x84\xac\x0d\xf7\x39\xfb\x9e\x1b\x91\xb2\x97\x5c\xf1\x29\x7a\x5d\xf6\x2e\xce\xbf\x7f\xb9\xef\x56\x11\x78\x75\x4e\x8f\x57\xa6\x76\x5c\xc4\x8d\x9f\xad\xab\xce\x9d\x2d\x0e\x5d\x6f\x6a\xc3\x52\xab\x2d\x87\x6f\x6d\x10\x00\x2c\xe8\x04\x5d\xe8\xd3\x56\xa8\x03\xe7\x8b\x20\x51\x98\xbe\xe1\xd1\xdf\xcc\xa2\xa8\xbe\xce\xd3\xab\x4f\x39\x00\x91\xdf\xfc\x43\x6f\x79\xb7\x18\xd8\x1d\xe2\x5c\x4d\x36\x12\x5b\x72\x2b\xa6\xf3\x63\x51\x64\x7a\xee\x16\xc0\x79\xe4\xc6\xc7\x5b\xc7\xa8\x36\x94\x63\x9e\xb0\xb2\xca\x04\x72\x0b\x2d\xc2\xae\x29\x21\xd2\x5a\xd2\x49\x65\x2c\x07\xd0\x35\x6c\xff\x83\x3d\xba\xf3\x61\x75\xd7\x63\x69\x88\xfd\xfc\xe8\x5d\x4d\x88\x4a\xb7\x4b\x3e\xf8\x93\xbb\x1f\x4c\xf0\xf8\x8f\xaf\xd9\xfb\xc4\x35\xef\x1c\xc1\x6c\xb2\x03\xc2\x2e\x7f\x5d\x65\xee\xf0\xc9\xd2\x05\x8a\x57\xd0\xd3\x68\x8e\x11\xed\x02\x64\x82\xeb\xfd\x80\x8d\x2b\xa7\xc4\x09\xd3\xf0\x71\x2f\x43\x7d\xde\xcc\x30\xa4\xed\x7e\xc4\x78\x51\x64\x12\x53\x98\x75\x49\x71\xe9\xc8\xa1\xb9\x7c\xdb\x5d\x44\xcb\x3d\x75\x99\xfb\xe9\x2e\x43\x76\x2d\xca\xf1\x5d\x70\x2a\xee\xab\x96\xf0\x42\x42\x1c\xe7\xce\x5a\x4c\x63\xe2\x0e\xcf\x4f\xf1\xd7\xab\x1c\xc7\xfe\x4b\x9c\x41\x9a\x1b\x1f\xde\x20\xce\x20\xb4\x5c\x02\xd2\xd2\xe1\xf9\x29\x42\x7b\x11\xd8\x52\xed\xfe\x70\x76\x02\xc7\x24\xc7\x1a\xe1\x91\x4f\x5d\x8b\x96\x69\x15\x1e\x2a\x54\x95\x0b\x04\x68\xaa\xc9\xc6\x9c\xf1\xa8\xe6\x75\xeb\xb5\xf7\xc4\xd9\x3a\xce\xf4\xd9\xd9\x89\x15\x61\x2c\x7d\x28\xa3\xfe\x80\x30\xd9\xf9\x4b\xe3\x2e\x27\x39\xea\x0e\xdf\xf5\xf8\xb9\x7f\x96\xc0\x3d\xb3\x02\xee\x7d\x9e\x29\xad\x5e\xd3\x50\xbd\x79\xfd\xa2\xdd\x42\x38\x6b\xb6\x41\xa0\x3e\x02\xf0\x0b\x0b\x5e\xda\xff\x8f\xbd\xe7\xe9\x6d\xdc\x56\xfe\xde\x4f\x41\xf8\x92\x4d\x10\x7b\xf1\x43\xdb\xdf\xa1\xb7\x3c\x27\xc5\x0b\x9a\x3f\x0b\x3b\x4d\x2f\x3d\x94\x91\x18\x9b\x88\x44\xfa\x91\x92\x13\x6f\xd1\xef\xfe\xc0\xe1\x90\x92\x6c\x89\xa2\x62\x67\x9b\x3c\xd4\x97\xdd\x48\xe4\x88\x1c\x0e\x87\xf3\x9f\x9c\x66\xa4\x54\x99\x73\x2b\xda\x1c\x01\x0c\xc5\x5b\xd2\x75\xad\xf0\xd1\x84\x90\x13\xbb\xfa\xb8\x38\x76\x8f\xdb\x0b\x7c\xd1\x14\x5c\x66\xd9\x29\x79\xe4\x70\x65\x7b\xc1\x56\xa4\xee\xd6\x9a\x73\x91\x18\x75\x50\x8c\xfd\x8d\x3c\x30\x22\xa7\x24\xfa\x8d\x0e\x5e\x53\x90\x99\x59\x96\x42\x31\x4c\xf8\x84\xd9\xf4\x09\x98\x2c\x8c\x16\x3b\xcd\x4a\x5d\x30\x35\x93\xe6\x40\xa9\x85\xed\x40\x61\x10\x5a\x7f\xfd\x2f\x2e\x52\x88\xd3\x9a\xc1\xe1\x93\x50\x41\x18\x07\x63\x90\x01\x09\xfe\x77\x43\x2c\x15\x51\x7e\xd2\x65\xb2\x34\x53\x1a\xad\x64\xaa\x47\x86\x15\x8d\xac\xc9\x50\x8f\x8e\xcd\x5f\xdb\x73\xb0\x51\x38\xb5\x7e\x9f\xe9\x8a\x8f\x8e\x4f\x09\x20\x08\x1c\x80\xb2\x58\x7e\x5c\x3a\x74\x73\x05\x1d\xfd\x55\x54\x38\xab\x43\x00\x1a\x14\x95\xab\xef\x79\xc9\x0b\xe6\xaf\x57\xb7\x96\x26\x5f\xe9\x66\x9b\xe1\x13\x72\x26\x08\xcb\x57\x05\x58\xaf\x49\xce\xa8\x73\x89\xb3\x35\x53\x9b\x62\x89\x95\x40\x1c\x03\xf9\xf0\x48\xdf\x0f\xe1\x5b\x77\xd7\x57\x44\x0e\x3b\x6c\x07\xb9\x47\x27\x47\xdb\x8c\xb4\x3a\x11\x3e\x2c\x2a\xe1\x88\x7e\x15\x1a\xef\x4d\xcf\x26\x0a\xed\x23\xcb\x2d\x3d\xff\xb8\xba\x42\xc7\x8a\xc5\xd5\x2f\x5c\xa4\xda\xdf\xa6\x88\x71\xdf\x88\xef\x56\x24\xc3\x08\x3f\x22\x82\x77\x45\xe0\x58\xb1\x35\x00\xde\x49\xfd\x5d\xa0\x82\x00\x50\x75\xb8\x96\x69\xfb\xd6\x69\xac\xef\x65\xad\xb1\x0f\x36\xa8\xec\x2e\x08\x0b\xc5\xdd\xcd\xaa\x55\x27\x08\x2f\x47\x00\xf5\x5d\x23\xa9\x0c\x0e\xc0\x27\x6b\x6f\xc0\x9a\x64\xeb\x9c\x93\xc7\x8c\x2e\x2a\x32\x02\xae\x67\x05\xad\xe9\xfc\xde\x4d\x41\x13\xde\x2e\xf2\xf6\xca\xc4\x7d\x52\xf0\xb8\xc2\x52\x67\x0b\xf3\x91\xd6\x97\xfd\xa2\xb0\x07\xde\x4d\x4d\x31\xce\xc6\x22\x68\xc8\xeb\xc2\xbf\xb3\xd9\xd1\x1a\x25\xb8\x82\x6d\x4e\x31\x85\xf8\x29\x90\x43\xe6\xf7\x0d\x32\xe9\x19\x6f\x07\xd1\x3e\xb1\xcd\xb3\x54\xed\xb5\xd8\x5f\x4d\x5f\xc1\x2f\x66\xf4\x81\x65\xfd\x1b\xe4\x9a\xae\xcc\xb4\xab\x60\x55\xab\xbd\xa3\xaf\xd3\xea\x0f\x36\xae\xcc\xc5\xf2\x49\xb5\xa0\x82\x7f\xb5\x11\xbe\x89\xd9\xc7\x52\x99\x3f\x3f\x59\x7f\x89\xd5\xfd\x33\x96\x14\xc7\x48\x7f\xad\x7c\xaf\x87\x40\x69\x9a\x72\x2b\x3d\x7c\xe9\xa1\xa5\x30\x12\xb8\x78\x7a\x0b\x9c\x07\x36\x56\x3f\xed\x87\x1d\xae\x11\xbc\xb9\x54\x81\x58\xac\x60\xff\x9c\x72\xbc\x99\xf7\xdd\x61\x85\xe5\x94\xbf\x76\x5a\xf6\xb7\x07\x5e\x73\x5a\x94\x8a\x17\xad\x07\x52\xb8\x23\x17\xbf\x94\x0f\x0c\x7d\xcc\x83\xbb\x0b\x08\x35\x3c\xfb\x72\x79\xd8\xe5\x68\xec\x70\xb0\x04\xe0\x00\x8d\xdc\x42\x4a\x41\xf3\x07\xbe\x28\x65\xa9\xb3\x4d\xdd\xb0\x49\xc1\x45\x3e\x21\xe4\xd2\x5a\x76\xc4\x51\x41\xa8\x90\x62\x93\x63\x53\x91\x64\x65\xca\x1a\x10\xc1\x93\xb8\x96\x3c\x25\xb4\x2c\x64\x4e\x0b\x9e\x90\x44\x32\x95\x80\xd7\xb1\x0e\xa9\xd4\x8c\xd0\x8e\xbe\x49\xa9\x0b\x99\x93\x9c\x2a\xbd\xa4\x59\xd6\xb5\xc6\x07\x38\xd5\x42\xe5\xcb\xc7\x30\xff\xce\x97\x6b\x3b\xea\x57\xd2\x77\x4f\xb5\xf6\x08\xfa\x36\x83\xdb\x0b\xc0\xba\x9b\x4a\x23\x60\x60\x9d\x80\xd6\x0a\x48\x3d\x0b\xd3\x87\x9d\xd0\xce\xed\x9d\x57\x80\x1b\x06\xfb\x42\xa0\x2f\x4b\x2f\x73\xba\x88\x10\x24\xaf\x8c\x76\x40\xc5\xc6\x75\xb3\xc5\x3a\xf5\x29\x91\x0a\x23\x4f\xfc\xdd\xea\xf8\xca\x17\x7c\x55\xe4\x16\x5c\x7a\x52\x61\x08\x38\x52\x29\x24\x06\x30\xf5\x28\x55\x6e\xe4\x3a\xae\xc8\x63\x29\xc0\xd0\xa6\x31\x62\x1c\x54\x12\xb4\xd5\xd0\x4c\x4b\xbf\x03\xc1\x47\x28\xdc\x20\x08\xd5\xe4\x99\x65\xd9\x84\x9c\x65\x19\x56\x11\xad\xd5\x8b\xa8\x72\xbe\xab\xb8\x84\x87\x0d\x49\xf9\x82\xe9\x82\x7c\x9a\xff\xfb\xec\x18\x4e\x6d\xb0\x63\x6c\x48\x41\x5d\xca\x5b\xd3\x3e\x03\xe7\x7f\x5a\x82\x9c\x90\xd0\x82\x66\x72\x61\x5d\xf3\x60\xeb\x15\x29\x59\x65\x74\x03\x57\x04\xac\xa8\x82\xa8\xd5\xc4\xda\x68\x88\x2a\x05\x14\x47\xfe\xa6\x27\x4e\x3f\x2b\x08\xd5\x2f\x1e\x03\x4d\xbe\x72\xab\xf7\x54\x89\x7d\xdb\xa3\x4c\xb1\x55\x46\x3b\xac\x0a\x0d\x8a\xbe\x6b\x24\x34\x1b\x31\x17\x54\x58\x29\x98\x87\x31\x21\x73\x4b\x3b\x39\x2d\x12\xeb\x17\xfd\x23\x67\x05\x4d\x69\x41\x27\x46\x17\xfc\xa3\x99\x5d\x27\xb3\xd4\x00\xea\x5e\xe8\x8e\x31\x5b\x79\xb1\xfd\x52\xfd\xe6\x2e\x34\x42\xad\x6f\x0e\xf2\xb9\xdb\x8f\x41\x33\xc6\x9e\xfc\x09\xa6\x7f\xf1\x62\x54\xb1\xa0\x1f\xae\x31\xd6\xed\x4e\x4d\x2b\x43\xd6\x9c\x09\x52\x6b\xce\xa0\xd4\xe4\x1d\xde\xa6\xe4\x9e\x80\x09\xf5\xec\xe6\xbc\xdb\xdc\xd5\x6f\x32\xe8\x31\x11\x34\x9d\x0b\x81\xe1\x39\x03\x33\xbe\x69\x7a\x18\x5c\x4a\x0d\x24\x21\xda\x04\x15\xea\x2a\xca\xb8\xc6\x76\xc1\x9a\xe9\x93\xb6\x5f\xb7\x7d\x24\xca\xc5\x13\xe3\xd8\xe9\xcb\x56\x1b\xfb\xc1\x76\x36\x8a\xf3\xf3\xf4\x66\x94\x75\x65\x8c\x59\xcc\x43\x82\x89\x33\x91\x7a\x64\xc7\xfa\xc5\x22\xed\x3b\x6e\xaa\x03\x06\xea\x97\xb2\x11\xbc\xf4\xc4\x36\x47\x1a\x33\x67\xa4\xd0\x4b\xbe\xb2\x29\x8f\xe8\x86\xc0\xd5\x25\xf7\x34\xe3\xa9\x07\x61\xa9\xfa\x52\x9c\x92\x1b\x59\x98\x7f\x2e\x5e\xb8\x2e\xac\xfa\x79\x2e\x99\xbe\x91\x05\x3c\x39\xc8\x54\xed\x10\x06\x4c\x14\x15\x60\x6b\xc9\x86\x7d\x55\x53\x93\xdd\x84\x2e\x91\xed\x39\xa4\x70\x4d\x2e\x85\x91\x08\x70\x46\x3e\x15\x58\x23\x08\x97\xc7\x22\xa4\x18\x83\x8d\xbb\x15\x06\x22\x42\xaa\x06\x1e\x02\xe0\x10\x94\x0d\x22\x84\x37\x5c\x3b\x26\xee\xcf\x6c\xea\xcc\x6e\x3c\x21\x39\x53\x0b\xf0\xda\x24\x3d\x5e\x8b\x58\x53\x64\x94\x01\xb2\x77\xad\x80\x65\x5e\x75\x1a\x2e\x76\x16\xa9\xd6\xde\xb2\xa5\xdc\x5a\x33\xfe\x34\xdc\x07\x30\xf5\x17\xe4\x83\xeb\x09\x39\x73\x57\xd5\xd4\xdf\xa1\xf7\xaa\x0e\xc6\x40\xe0\x9a\x18\x56\xb2\xa6\x19\xb3\x95\xfa\xa9\xf0\x39\x5b\xf2\x71\x87\xb1\x9f\x62\x5e\xb8\xd9\xb3\x5e\x64\x1a\x3d\xb1\xcd\xe8\x74\x67\x69\x47\x97\x62\x54\x25\xee\x35\x16\xd3\x33\x51\x90\xb6\x46\xf0\x6e\xf4\xfa\xb3\x20\xc8\x2c\xe3\xcd\x2b\xbd\xeb\xa6\x9f\x78\xbb\x0b\xbb\x55\xd8\xf8\xa4\x8f\x0d\x0a\xc1\x6d\xac\x48\x2e\x15\x98\x33\xcd\xd3\x7a\x89\x10\x23\xaa\x3e\xf1\xd5\xaa\xaa\xa8\x52\xae\x16\x8a\xa6\x8c\x2c\x14\x5d\x2d\x87\x8a\x25\x56\xb6\x69\x03\xff\x61\x04\xdd\x0e\xe4\x07\x34\xba\x60\xbf\x67\xf6\xb0\x94\xf2\x09\xd2\xe9\x80\x10\xde\xd0\xfe\xf0\x9b\xfd\xd6\x79\xf5\xcc\xa9\x92\x9a\xa4\xac\xa0\x3c\x83\x78\x90\xdb\xab\x6b\x8c\x18\x71\xe7\xb8\x1b\x65\x7b\xf0\xc5\x01\x14\x00\x9a\x62\x24\xd3\x8c\xad\x39\x7b\x46\xab\x44\x57\xac\xc7\x98\x2c\x98\x80\x00\x87\x40\x20\xd0\x98\x68\x9e\xb2\x0b\x48\xde\xed\x06\xb4\x87\xe1\xbc\x63\xcc\x7d\x9b\x37\xcc\xc1\x7b\xb9\x77\xc4\x29\xeb\xd5\xdf\x2f\x52\x05\x8a\x09\xc5\xe5\x12\xc7\xe5\x09\x63\x34\xfa\x4f\xe4\x87\x1f\xbe\xef\x6c\x94\xd3\x17\x9e\x97\xf9\x4f\xe4\xff\x7f\xfc\xf1\xfb\x1f\xbb\x9b\x71\x61\x9b\xfd\x5f\xf7\xfc\x70\xb7\x4d\x67\xe7\xef\x00\xdf\xa9\x8f\xc8\x0b\x3b\xe5\x22\x40\x3d\x52\x9e\x95\x0a\x63\x41\x23\x55\x84\x9f\xeb\x7d\xc0\xa1\x52\x25\x4f\x50\x07\xd1\x05\x8c\x61\x20\xd9\x23\x17\x4c\xc3\x25\x30\xa5\x50\x2c\x91\x0b\xc1\xbf\xb2\xd4\xdd\x01\x03\x81\x1d\x50\x2d\xde\x91\x38\x61\x22\xb5\x77\x71\x9a\x33\x6f\x49\x45\x9a\x85\x1c\xfe\x11\x33\xad\xef\xe0\xbd\x50\x06\x27\xcf\x20\x84\x5d\x57\x3d\xb6\xd0\x05\x37\x8a\xa2\xfb\xc9\x9e\x68\x16\x6d\x7b\xcd\xd4\x32\xc6\x79\x40\xb1\x6e\x19\xe3\x8e\xde\x67\x55\x56\x78\xf6\x9f\x92\xa9\x0d\x24\x8a\x54\x82\x7d\x2d\x98\xec\xae\xaa\x43\xe0\xa6\x81\x12\x95\x2d\x04\xb3\xa5\x0b\x57\x42\x4c\x15\xee\xb1\xf5\x6d\xe8\xc3\xac\xfb\xdc\x39\x92\xc8\x19\x11\x65\x96\x75\x35\x15\x32\xe4\x72\xaa\xe3\xae\x47\x95\x8c\xd3\xf1\x62\xcd\x02\x2d\x98\xfe\xa6\xc6\x81\xfa\xc4\x0f\x24\xca\xbf\x6f\x73\x41\x7d\xc2\x51\x71\xa1\xf1\x31\xa1\x71\xe5\x6e\x22\xcc\x08\xf6\x37\x24\x68\x34\xb2\x48\xcd\x5b\x1a\x16\xec\x6f\x50\x7c\x4e\x9c\x91\xa1\x65\xe8\xef\xce\xd4\xf0\x8a\xc9\xc7\x98\x1d\x5a\xa6\xfe\x8f\xf1\x61\x07\xe1\xb1\xd1\x50\x03\x22\xa1\x22\x57\x32\xc2\x28\x61\x7f\xff\x98\x26\x06\x9d\x44\x11\x8c\x79\x98\x99\x22\x7a\x55\x15\xe3\x62\x2d\x6d\xb1\xe8\x41\x32\xdc\x6c\xa7\xe3\x96\x28\xf7\x0c\x9c\x15\x65\x39\x2f\xfc\xd6\x45\x5a\xa3\xd0\x92\x52\xf7\x1b\xbb\xc3\x33\x08\xe7\x8f\x1c\x44\x07\x69\xce\xbc\xcc\xd8\x6f\xbc\x58\xde\xba\xe2\xf0\x48\xd5\x45\xb9\xca\x60\xb2\xb5\x17\x86\x84\x66\x95\x64\x78\x69\xaf\x23\x63\x89\xcc\x73\x26\x52\x1b\x44\x94\xd3\x27\x46\xaa\x2b\x2f\x8d\x8c\x07\x62\x30\x80\x63\x2f\x2b\x2a\x2a\x39\x71\x6d\x78\x79\x88\xa2\x22\xe9\x29\xf6\xac\x8d\x4e\xcc\x08\x27\x64\xd4\x32\x2a\x1a\x89\x17\xe4\x81\x65\x12\x52\xb9\x6d\xa4\xa8\x8d\x65\x76\xb9\x0c\x86\x25\xe3\x53\x3c\xf5\xb0\x70\x24\x13\x8b\xaa\x1e\x95\xce\xe0\x72\x5a\xe4\xc0\x52\xb0\x09\x99\xa1\x08\x13\x27\x15\xc5\xb0\xd3\x48\x56\x1a\x7d\x20\x56\xb5\x18\x06\x63\xd6\xf5\xab\xe3\x76\xed\x9e\xc5\x60\xd7\x35\xfe\x5f\xc6\xaf\xbf\xb8\x61\x18\x7a\x9b\x5b\xba\x3a\x15\x3c\x6e\xb7\x98\x57\x62\xaf\x3e\x06\x53\xdd\x98\x4c\x67\x17\x67\x77\x17\xa7\xe4\xd7\x2f\xe7\xf0\xef\xf9\xc5\xd5\x85\xf9\x77\x7a\x7b\x73\x73\x31\xbd\x33\x72\xc4\x89\x2d\x41\x6f\xd4\x38\x83\x5d\x73\x1e\xc9\x26\xb7\xa0\x62\x43\x1e\xcb\xc2\xb0\x83\xea\x63\x8d\x51\x50\x6b\x03\xa0\x69\x6a\x54\xc6\x0f\xb7\x86\xed\x08\xdf\x36\x9b\xd4\xef\xde\xb0\x55\xfb\x31\xe1\xaa\x5f\x4c\x8a\x26\x92\xe8\xac\x83\xc6\x90\x47\xaf\x4c\x37\xf8\x5d\x90\x9f\xa5\x22\x78\x59\x19\xdc\x5e\x99\xea\x23\x4c\xea\x30\xff\x9f\xd8\x47\x9f\x33\xb9\x38\xf2\xb9\x1e\x8c\x64\x72\x41\x74\xf9\xe0\x73\x70\xe0\x34\x85\xd6\x27\xae\x59\x23\x75\xe1\xd4\x27\xe2\xd4\x7a\x79\xe0\x8d\x3e\xf5\x06\x75\xb8\x9f\xe1\x86\xb1\x46\x4b\xf3\x60\x1b\xe0\xc9\xe7\xf6\x11\x38\xc1\x89\xab\xad\x1e\xbf\x0b\x43\xae\xcf\x3c\x4b\x13\xaa\xd2\x1d\x9a\x85\xc3\xcd\x2e\x39\x60\xcf\x96\xdd\xb5\xb7\x41\x57\xc0\xb1\x58\x86\x5c\x33\x95\xd1\x95\x8d\x10\x87\xba\xc7\x10\x7a\x04\x1f\x39\x67\x2b\x06\x79\x50\xee\xb6\x72\x26\x92\x4c\x42\x5d\x0e\x7b\x32\x9e\x36\xa7\x6e\x43\x91\x5c\xf1\x42\x97\x8d\xe7\x77\xc8\xe8\xdd\xb2\x39\x08\x33\x1e\x44\xbd\x36\x30\xb9\xb3\xb8\x8b\xcf\xdb\xb0\x4a\xa3\x97\x7c\x19\x19\x61\x96\xd9\xe8\x94\x8c\x7c\xfd\x92\x14\xa5\xe4\xd1\xc9\xa8\x6a\x50\xcf\x53\x02\x21\x19\x5d\x42\x63\xf8\x4e\x3d\x23\x12\x16\xd8\x39\xae\xfc\xa7\xab\x1a\x34\xe6\x68\x43\x23\x16\x8c\xa1\x09\x68\xd2\x18\xc8\xce\x57\xab\x14\xbb\xde\x2f\x9a\xe1\xd7\xba\x17\x90\xd2\x6e\x53\xf5\x10\x39\x8a\x99\xd5\x70\x01\x69\xf3\x06\xf1\x78\xc7\x5b\xbd\x48\x0e\x57\x64\x45\x95\x51\x45\x5c\xcb\xe6\x35\x67\x27\xbd\x97\x9c\x45\x10\x41\xcd\xbf\x12\x29\xb5\xcf\x7d\x8f\x69\x46\xb5\x6e\xb1\xbc\x02\x23\x30\x80\x09\xb3\x90\x09\x75\xce\x27\xa8\x61\xbd\xa4\xeb\x40\x91\x83\x88\x41\x17\x54\x2d\x58\x11\xf6\x8c\x50\xb1\xb9\x0d\x96\x45\x1b\x47\x17\x62\x1d\xc7\xed\xa6\x97\x71\x55\x84\x6b\xcc\x45\x31\x96\x6a\x6c\xbb\xfc\x44\x0a\x55\x76\xf9\xb8\x0a\x9e\x33\x59\x16\x73\x96\x48\xd1\x9e\xd1\x80\xed\x0e\xe6\xea\x19\x90\xe6\x81\xde\xc6\x33\x27\x46\xd4\x0b\x19\x3a\xc5\xac\x92\x31\x9c\x87\xb1\x59\x8a\xe5\xf6\xea\x7a\x9f\xc5\x26\x90\x0a\x1d\x5e\xc9\x7b\x64\xfb\x62\xe1\x47\x8a\x23\x0f\x76\xbb\x2e\x8b\xe1\x9d\xa6\xde\x73\x15\x6e\x8d\xc8\x08\x97\xd3\xe8\x9c\xbf\x2e\x68\x51\xee\x50\x43\x63\x6d\x90\x59\xce\x6d\x4a\x19\xca\xf4\x73\xe8\x57\x37\xf2\xed\xd6\x10\xb0\x75\x49\xa0\x9d\x0b\x56\x9c\x10\xec\x68\xf6\x67\xa1\x28\xb7\x0a\x24\x4d\x8a\x12\x72\x93\x69\x81\x81\x8d\x58\x44\xe7\xbb\xb6\x69\xb4\xaa\x8c\x21\x35\x31\x61\xaa\xd0\x57\x54\x17\xbf\xae\x52\xda\x91\xbd\xb4\x15\xb0\xa8\x0b\xd8\x30\x56\xb0\x7e\x16\x2c\x35\x1c\x1e\x51\x60\xe1\x91\x67\xc3\x7a\x4b\x0b\x71\xa8\x27\xbf\xda\x40\xa6\xfb\xd8\x7c\xaa\x7d\xd4\x33\x69\x70\x72\xd6\xca\x80\x9a\xa1\x1a\x7d\xa3\x35\xc7\x89\x02\x68\x44\xb0\x97\x36\x8d\x7b\xff\x11\x67\x8c\x8a\xf6\x70\xf9\x2d\x8a\x82\x76\xc3\x69\x08\x3f\x40\x9e\x97\xdc\x88\xac\x36\xcb\x4b\x13\x27\x42\xa5\x2c\x63\x1d\xc9\x5e\x7b\x86\x92\xe2\x17\xce\xf1\x03\x51\x61\x4e\x5f\x9a\x7d\xbc\x41\x1f\x85\x70\x4c\x9e\xa8\x84\x65\x94\x1e\xbc\xd6\xb4\x3d\x2b\x10\x5f\x1e\x32\x99\x3c\xd9\xa2\x62\x90\xcf\xcf\xbf\x32\xe5\xe2\xce\xab\x0b\xc5\xf0\x96\xab\x85\xbb\xc1\xd3\xe1\xcd\x5d\x69\x04\x50\x0c\x6c\x83\x40\x0f\x5f\xaa\xca\xb2\x58\x0a\xcc\x9e\xfb\x36\xa1\xab\x4e\x51\x81\x78\xfd\x86\xe7\x60\x57\x67\xb1\xf5\x47\xa0\xe6\x21\xaa\x8c\x34\xc7\xec\x96\xcf\xbf\x74\x67\x82\x1c\x34\x1c\x35\x94\x8f\x62\x5b\x00\xfa\x44\x12\x2c\x57\x13\xcc\x5c\x89\xb5\x7c\xf5\x64\xa8\x90\x78\x21\xdd\x0f\x39\x06\xda\x41\x83\x0b\x0f\xee\xed\xeb\x4c\x03\xa8\x7e\x43\x7c\x78\xb1\xc5\x56\x07\x79\x99\xc4\x90\xa2\x98\xcd\xe2\x21\x5e\xed\xc0\x24\x4f\xeb\x89\x7f\x94\xaa\x53\x81\x39\xdc\xe0\xc3\xf9\x4c\xbd\x80\x8c\xf4\xd9\x1d\xbb\xb6\x9b\xbc\x63\xb8\x97\xef\x72\x4a\x28\x59\x72\x5d\x48\x85\xae\x35\xb8\x90\x4c\x51\xb8\x30\xb5\x3d\x06\xec\x30\xd1\x70\x53\x3f\x04\x42\x57\x2b\x46\xfd\x5d\x45\x78\x36\xc1\x65\x43\x8a\x25\x52\xa5\xad\x03\x73\xda\x7d\xab\x2c\xd5\xfa\xf9\x03\xe4\x66\x66\x54\x17\x77\x7e\x0c\x46\x40\x88\xe4\xc6\x4d\xf1\x07\xa7\x58\xcd\xc6\x95\x73\x91\xa2\x7a\x29\x09\x15\xd6\xaa\xb1\x9f\x0c\xde\x2f\x64\x54\x73\xb3\xd2\xdc\xab\xe6\xf5\xec\x25\xb7\xda\x14\xbf\xcd\xc8\x73\xa6\x75\x30\xd1\x68\x2b\x48\x03\xea\x02\x13\x5f\x17\x18\xbb\xbb\xc3\xde\x0a\x08\x36\x1c\xd3\x55\xee\xda\x74\x93\x1a\x01\x31\xc1\x1a\x14\xfc\xb6\xda\x6b\xc9\x56\x4b\xaa\x63\x27\xe3\x77\x91\x0f\xf1\x8d\xde\x0e\x91\xa3\x51\x8c\xea\x50\xaa\xe4\x16\x6e\x1f\x14\x67\x8f\x64\x4a\x73\x96\x4d\xa9\x3e\x24\x72\x81\x03\x4c\x08\x9b\x2c\x26\xe4\x68\x56\xf3\xb6\xde\xc8\xe2\x3a\x74\x6f\x43\x4f\x75\x80\x98\x1d\xfd\xa6\x7b\x79\x6f\x25\xa1\x7f\xe7\xee\xb9\x67\xf7\x1e\x61\x60\x87\xbe\x8b\xbd\x19\xce\xf7\xed\xda\x8f\xcd\x9d\x58\x2a\xb0\xf8\x25\xaf\xdd\x91\x3d\xc9\x8c\x5d\xbb\xf0\x3d\xef\xbf\x9e\x29\x79\x10\xf3\x56\x93\xc9\xce\xec\xee\x1a\x9a\x2b\x98\xfd\xeb\x01\x76\x50\xf2\xdb\x8c\x74\x3a\xbf\x3f\xa4\xd8\xf2\xf7\x26\xdb\xe3\x02\x76\xbe\x0f\xc8\xe5\xe3\xf0\x29\xbc\x6f\x22\x7f\x0a\x8e\x16\x43\x01\xdf\x32\x00\xe3\xdc\x7d\x15\x6d\x1d\xbe\x5a\x2f\xfc\xf5\x88\xb7\xa2\x61\x9b\x06\x7d\x7c\x82\xfb\xe7\xd8\xda\x5e\xfa\x08\x09\x1f\x8c\x08\xa6\xcd\xa6\x38\x0e\x7c\x3e\x52\xa1\x8a\x53\xa6\xfa\x15\xdd\x5e\x25\x96\xf4\x2f\xad\x6b\x14\x5a\x60\xfb\x8b\xd5\xd9\x22\x74\xe2\x01\xca\x5a\xbf\xc6\x33\x00\x58\xaf\xf8\x37\x10\x5e\xbb\x01\x77\xfb\xb7\x55\x1d\xd8\x74\x99\x01\x93\xb6\x8e\xe1\xc4\x70\xe0\x04\x6a\x46\x5b\xde\x8d\xec\xa9\x69\xbf\x9d\x6d\xf3\x40\x08\x37\x6c\x52\xf8\xa1\xa6\x55\x96\xfc\x70\x38\xef\xad\xa0\x11\x0d\xef\x1d\x94\x03\xe9\x25\xa0\xb7\x2d\x54\x60\x7f\x7d\x54\xf7\xf7\xd3\x5b\x4c\x41\xa6\x20\x8d\xbd\x51\x65\x16\xcd\xd4\x9a\xa5\x0d\x4f\x1d\xd6\x6e\x6f\x3e\xab\xf9\x6d\x2b\xf8\x88\x76\xf2\xe7\x5f\xdf\xfd\x37\x00\x00\xff\xff\x61\xf0\xd9\xb1\x48\xda\x07\x00") func operatorsCoreosCom_clusterserviceversionsYamlBytes() ([]byte, error) { return bindataRead( @@ -125,7 +125,7 @@ func operatorsCoreosCom_clusterserviceversionsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_installplansYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4b\x93\xdb\x36\x12\xbe\xcf\xaf\xe8\x9a\x1c\x9c\x54\x59\x9a\x24\x7b\x49\xe9\xe6\x9d\x6c\xb6\x66\x37\x0f\x97\x67\xe2\x4b\x36\x87\x16\xd9\x12\x91\x01\x01\x04\x0f\xc9\xda\x54\xfe\xfb\x56\x03\x7c\x4a\x24\x45\x8d\x27\x8e\x6b\x2b\xbc\xd8\x43\x36\x80\x7e\xf7\xd7\x00\x84\x46\xbc\x25\xeb\x84\x56\x2b\x40\x23\xe8\x9d\x27\xc5\x7f\xb9\xe5\xe3\x57\x6e\x29\xf4\xcd\xee\x8b\xab\x47\xa1\xf2\x15\xdc\x06\xe7\x75\xf9\x86\x9c\x0e\x36\xa3\xaf\x69\x23\x94\xf0\x42\xab\xab\x92\x3c\xe6\xe8\x71\x75\x05\x80\x4a\x69\x8f\xfc\xda\xf1\x9f\x00\x99\x56\xde\x6a\x29\xc9\x2e\xb6\xa4\x96\x8f\x61\x4d\xeb\x20\x64\x4e\x36\x4e\x5e\x2f\xbd\xfb\x7c\xf9\xd5\xf2\xf3\x2b\x80\xcc\x52\x1c\xfe\x20\x4a\x72\x1e\x4b\xb3\x02\x15\xa4\xbc\x02\x50\x58\xd2\x0a\x84\x72\x1e\xa5\x34\x12\x95\x5b\x6a\x43\x16\xbd\xb6\x6e\x99\x69\x4b\x9a\xff\x29\xaf\x9c\xa1\x8c\xd7\xde\x5a\x1d\xcc\x0a\x06\x69\xd2\x6c\x35\x8b\xe8\x69\xab\xad\xa8\xff\x06\x58\x80\x96\x65\xfc\x7f\x12\xfd\x2e\x2d\xfa\x5a\xa2\x8a\x6f\xa5\x70\xfe\xdf\xc7\x5f\xbe\x15\xce\xc7\xaf\x46\x06\x8b\xb2\xcf\x6a\xfc\xe0\x0a\x6d\xfd\xf7\xed\xc2\xbc\x90\x30\xe9\x93\x50\xdb\x20\xd1\xf6\x46\x5d\x01\xb8\x4c\x1b\x5a\x41\x1c\x64\x30\xa3\xfc\x0a\xa0\x52\x5a\x35\xc9\x02\x30\xcf\xa3\x21\x50\xbe\xb6\x42\x79\xb2\xb7\x5a\x86\x52\x35\x8b\x30\x4d\x4e\x2e\xb3\xc2\xf8\xa8\xec\x87\x82\x60\x23\xac\xf3\x70\x7b\xff\x16\x84\x02\x5f\x50\x94\x09\xf4\x06\x32\x19\x9c\x27\x7b\x4f\x76\x27\x32\xaa\x7c\x23\xae\xdf\x4c\x07\xf0\x8b\xd3\xea\x35\xfa\x62\x05\x4b\x56\xf7\x72\x7c\xd0\x4f\x9f\xff\xdc\x19\x97\x6c\x78\x7b\xff\xb6\xf3\xce\x1f\x58\x42\xe7\xad\x50\xdb\x29\x8e\xd1\x18\xab\x77\x28\xa1\xd4\x39\x4d\xf0\x52\xd3\x9d\x2c\xfb\xea\xf4\xc3\xc8\xda\xc3\x53\x46\xe5\x0f\x4d\xd9\xfb\x90\xa6\x5c\x6b\x2d\xa9\xf2\x96\x9a\x78\xf7\x05\x4a\x53\xe0\x17\xd5\x4b\x97\x15\x54\x62\x6b\x24\x6d\x48\xbd\x7a\x7d\xf7\xf6\x6f\xf7\x47\x1f\xa0\xaf\x8b\x8e\xcb\x41\xce\x51\x48\x2e\x1a\xb0\x72\x9c\x18\x3d\x6c\x48\x04\x47\xd1\xa2\x6d\x04\x9c\xb0\xa9\xd7\xbf\x50\xe6\x3b\xaf\x2d\xfd\x1a\x84\xa5\xbc\xbb\x3a\x6b\xa4\x8e\xf1\xa3\xd7\xac\x9d\xce\x2b\x63\x79\x2d\xdf\x89\xa4\xf4\x74\x92\x4c\xef\xfd\x91\x64\x2f\x58\xfc\x44\xd7\x93\xac\x72\x78\xca\x2b\x9d\xb1\x50\xbe\x10\x0e\x2c\x19\x4b\x8e\x94\x6f\x85\x56\x95\x4c\x4b\x60\x67\x24\xeb\x38\xea\x82\xcc\x39\x11\xed\xc8\x7a\xb0\x94\xe9\xad\x12\xff\x6d\x66\x73\xe0\x75\x8a\x00\xf4\xe4\x3c\xc4\x10\x52\x28\x61\x87\x32\xd0\x4b\x40\x95\x43\x89\x07\xb0\xc4\xf3\x42\x50\x9d\x19\x22\x89\x5b\xc2\x77\xda\xb2\x01\x36\x7a\x05\x85\xf7\xc6\xad\x6e\x6e\xb6\xc2\xd7\x29\x34\xd3\x65\x19\x94\xf0\x87\x9b\x98\x0d\xc5\x3a\xb0\x35\x6e\x72\xda\x91\xbc\x71\x62\xbb\x40\x9b\x15\xc2\x53\xe6\x83\xa5\x1b\x34\x62\x11\x99\x55\x31\x8d\x2e\xcb\xfc\x13\x5b\x25\x5d\xf7\xe2\x48\x7d\x83\xfe\x0b\x75\xde\x9a\xd4\x35\xe7\x2f\x10\x8e\xdd\x24\x0e\x4f\xb2\xb4\x2a\xe5\x57\xac\x95\x37\xff\xb8\x7f\x80\x9a\x81\xa4\xf6\xa4\xe1\x96\xd4\xb5\xca\x66\x45\x09\xb5\x21\x9b\x28\x37\x56\x97\x71\x16\x52\xb9\xd1\x42\xf9\xf8\x47\x26\x05\x29\x0f\x2e\xac\x4b\xe1\x5d\xf4\x39\x72\x9e\xed\xb0\x84\xdb\x58\x41\x60\x4d\x10\x4c\x8e\x9e\xf2\x25\xdc\x29\xb8\xc5\x92\xe4\x2d\x3a\xfa\xc3\x55\xcd\x1a\x75\x0b\x56\xdf\x7c\x65\x77\x0b\xe0\xe9\x80\x93\x18\x03\xa8\x4b\xd4\xa8\x75\x3a\x31\x7e\x6f\x28\x6b\xa2\xa1\x89\xe9\x57\xc6\x48\x91\x25\xb7\x6f\xbc\x83\x1d\x79\xdd\x24\x82\x5e\x56\x9a\x64\x67\x2c\xec\x21\x95\x97\xd3\xb4\xd9\xff\x74\xb2\x10\x7f\x9a\x55\x46\x60\x22\x67\x40\xcc\x1b\x69\xe9\xd3\x2f\x47\xfa\xaa\x53\x3b\x3b\x34\x7b\x58\x70\x64\xdb\x82\x61\xb4\x14\xd9\x01\x36\xda\x72\x7e\xe8\xe8\x76\x09\x77\x1e\xca\xe0\xa2\xbf\x69\x45\xac\xd9\xeb\x57\xc1\xeb\x12\xbd\xc8\xae\x41\x5b\xb8\xfe\x0e\x55\x40\x79\xbd\x1c\x60\x61\xd4\x21\x5a\xde\x87\x54\x3a\x5c\x23\xda\x67\x5c\x75\xe3\x73\xa1\xb5\x78\x18\xf8\x2a\x3c\x95\x83\xc3\xce\x70\xbf\x25\xc5\x45\x63\x20\x63\xb7\x43\x39\x51\x6e\xc9\x9e\x7c\x4f\xde\x38\x3e\x6e\x64\xc9\x34\xac\x41\x3a\x17\x8d\x77\x1e\x7d\x38\x91\xb3\xe7\x22\xd7\xdd\x98\x8a\xe4\x9d\x04\x56\x15\xd0\x8d\xb6\x65\x8a\x29\x5c\xeb\x90\x92\x55\x9a\x9a\x3d\xc3\x79\x32\xae\x09\x15\x0e\xb6\x4c\x97\x46\x92\xef\xd7\xde\x25\xfc\x47\x41\xb5\x02\xa7\x43\x6f\x51\xc8\x38\x15\x66\x3e\xa0\x8c\x33\x52\x55\xa1\x0f\xce\x53\xb9\xbc\x7e\x9e\x48\xcd\xd0\xa3\xd4\xdb\xfb\x94\x0d\x06\x08\x4c\x81\x8e\x2e\x89\x3f\xef\x49\x05\xce\xc2\x95\x33\xbe\xca\x32\x1d\x94\x7f\x43\x9b\xf3\x21\x39\x3e\x16\x2c\x6d\xc8\x92\xca\xaa\xfa\xee\x12\x01\x60\xa2\x00\x5f\xa0\xe7\x48\x0e\x2e\xa9\x39\xd7\x09\x07\xe7\x0d\x94\xa9\x15\x3e\x1e\x95\x83\xca\x3b\x27\x2f\x4c\x62\x95\x61\x31\x5f\xdf\xd5\xf8\x24\xc1\x12\xaa\xa5\xf3\x43\xcc\xc1\xb9\x28\xe0\x67\x23\x48\xe6\x11\x7f\xce\xe1\xe0\xc5\x5d\xa5\xd0\x58\xc5\xbd\x06\x04\x23\x28\xa3\x1e\x1c\x8a\x0a\x23\xcc\xab\x97\x5c\xf0\x2c\x55\xdf\x5e\xa6\x5a\x5d\xc1\x80\x16\x2e\x79\x14\x0a\x90\x71\x81\xc8\xe1\x5f\xf7\x3f\x7c\x7f\xf3\x4f\x9d\x78\x63\x4b\x91\x73\xc9\x93\x4b\x52\xfe\x25\xb8\x90\x15\x80\x8e\x59\x63\xf7\x64\xff\xa7\x65\x89\x4a\x6c\xc8\xf9\x65\x35\x1b\x59\xf7\xd3\x97\x3f\x2f\xe1\x1b\x6d\x81\xde\x21\x07\xcf\x4b\x10\x49\x6b\x0d\xa8\xa8\x5c\x23\xa6\x72\x16\xa6\x19\x0b\x7b\xe1\x8b\xc8\x92\xd1\x79\xc5\xf4\x3e\x32\xeb\xf1\x91\xf3\x77\x62\x36\x70\x2f\xf3\x48\x2b\xb8\x4e\xad\x49\xb3\xf4\x6f\x0c\xc3\x7f\xbf\x86\x4f\xf7\x05\x59\x82\x6b\xfe\xf3\x3a\x2d\xd8\x60\x40\x7e\x57\xdb\xb1\x5d\x38\x3a\xa4\xb7\x62\xbb\xa5\x18\xf9\x0c\x68\x18\x34\x7c\xc6\x15\x42\x6c\x40\xe9\x0e\x71\x9c\x82\xf5\x69\x28\x13\x1b\x41\xf9\x09\x23\x3f\x7d\xf9\xf3\x35\x7c\xda\x97\x0b\x84\xca\xe9\x1d\x7c\x99\xda\x31\xe1\x58\xc6\xcf\x96\xf0\x10\x2d\x73\x50\x1e\xdf\xf1\x9c\x59\xa1\x1d\x29\xd0\x4a\x1e\x98\xe3\x02\x77\x04\x4e\x97\x04\x7b\x92\x72\x91\x50\x42\x0e\x7b\x3c\xb0\x0c\xb5\x2a\xd9\xaa\x08\x06\xad\x3f\x42\xc8\x0f\x3f\x7c\xfd\xc3\x2a\xad\xc6\x66\xdb\x2a\x5e\x82\xd1\xd7\x46\x30\xfe\x65\xe0\x9b\x50\x5c\xb4\x39\x33\x12\x92\x91\x38\xf5\x15\xa8\xb6\x54\x37\x8f\x9b\xc0\x78\x6a\x79\x8c\x98\x66\x7b\xfc\x10\x5c\x1d\x76\xf6\x08\x5b\x8f\x03\xed\x4f\x04\x85\xb3\x45\x8c\x3d\xe0\x2c\x11\xbf\xef\xf8\xe0\xa4\x88\x8f\x61\x4d\x56\x91\xa7\x28\x65\xae\x33\xc7\x02\x66\x64\xbc\xbb\xd1\x3b\x4e\xaa\xb4\xbf\xd9\x6b\xfb\x28\xd4\x76\xc1\x4e\xb6\x48\x96\x77\x37\x71\xf7\xe3\xe6\x93\xf8\xcf\x7b\x49\x34\x5a\xaa\x87\xc5\x8a\xe4\x1f\x42\x36\x5e\xc7\xdd\x3c\x59\xb4\x1a\x52\x5f\x52\x09\x5e\xdc\xa7\x80\xcf\x8e\x47\x73\xb8\xec\x0b\x91\x15\x75\xd3\xda\xc9\x70\x25\xe6\x29\x05\xa2\x3a\xfc\xe1\x6e\xcc\x0a\x0c\x96\xd7\x3e\x2c\xaa\x7d\xb9\x05\xaa\x9c\xff\xef\x84\xf3\xfc\xfe\xc9\x1a\x0b\x62\x66\x00\xff\x78\xf7\xf5\x87\x71\xee\x20\x9e\x18\xad\xeb\xa0\x72\x49\xdf\x6a\xfd\x18\xcc\x20\x48\xe8\x09\xf4\xf7\x2e\x75\xdd\x7f\x54\x5d\x9a\x50\x0b\x63\xf5\xd6\x72\xad\xec\x74\xb9\x60\x82\x4c\xe9\x35\x28\x83\xd9\x23\x6e\xa9\x5a\x34\x96\x11\xee\x8d\xab\x72\x54\xb5\x02\xe3\x30\xe7\x09\xb8\x7f\x94\xfb\xb4\x1b\x50\xf1\x39\xc2\x66\x5d\x17\x99\xc7\x88\x60\x2b\xbe\xcf\xf3\x7b\x16\x98\x4d\x61\xdb\xf4\x1c\x21\xdc\x37\xb4\x19\x25\x14\x39\xfb\xfd\x46\x0c\xb4\x27\x35\x89\x41\x5f\x8c\x7e\xb4\x64\x24\x0e\x81\x68\x98\x01\x21\xe1\x84\xcf\x31\xba\x23\x6b\xdc\x1e\x0d\xab\x2d\x52\x27\x8c\x4a\xcb\x3d\xb2\xf8\xa6\xb2\x02\x8b\x04\x7b\x74\x31\x03\xc9\x1d\xe5\x71\x03\x66\x0c\x87\xce\xb0\xc8\x3c\x69\x61\x16\x6c\x1e\x90\xf7\x09\xe0\xb9\xcb\xf8\x44\x3a\x4a\xcf\x59\x20\x3d\xc0\xd3\x5f\x70\xfa\x2f\x38\xfd\x91\xc3\xe9\x8b\x62\x60\x0a\x5a\x0f\xb9\xff\xc7\x0a\xb0\x2f\x12\x7a\x0a\x6c\x0f\x09\xfd\x91\x40\xee\x8b\x65\x9c\x84\xdf\x63\x82\x7e\x24\x20\xfc\x22\x61\x67\x02\xf2\x21\x91\xff\x9f\x61\xf9\x45\x3a\x9c\x80\xe8\x43\x7a\xfb\x28\x80\xfa\x6c\x01\x33\xad\xd2\x29\xf8\x04\x4a\xe9\x63\xad\x66\xc0\xf1\x3e\x30\x33\x8d\xb2\xb7\x4f\xdb\x85\xc9\xe7\xe0\xd4\x18\x24\x4f\xcf\x04\x30\xef\x4e\x72\x06\x93\x9d\xc7\xca\xe9\x59\x54\xdb\xd7\x67\x88\x78\xcd\x09\x92\x79\x08\x10\x40\xa2\xf3\x0f\x16\x95\x13\xf5\x0d\x8e\x69\xfa\x23\x8b\x7c\x8b\xdc\x76\x88\xb2\xe9\x32\x92\x7d\xc0\x37\x53\x56\x80\x36\x1e\xd5\x54\xfb\xf2\x8c\x69\x94\xf6\xc5\x58\xd3\xd1\x3e\x33\xa3\x84\x9f\x74\x0e\xb0\x82\x1c\x3d\x2d\x98\xa3\xb3\x62\xff\x18\x0f\x2b\x9f\x4d\x64\xc6\xf0\xc6\xea\x35\xe5\x7f\x9a\x54\x25\x39\x87\xdb\xcb\xc4\x79\x05\x45\x28\x51\x81\x25\xcc\x71\x2d\xa9\x9e\x84\xd1\x58\x3c\xad\x54\x5b\xc8\xc9\xa3\x90\xae\x73\xc2\xd2\xda\xf7\xd9\x84\xb5\x84\xee\x5c\x95\x80\xd3\x2b\x26\x69\x58\x3c\x28\xec\xd9\xe3\x85\x8b\x46\xfe\x23\x38\x1d\x3e\xb9\x9a\xe4\xf4\xbe\x39\x91\xea\x31\xf9\xb2\x3e\xc1\x7c\xb0\x81\x5e\xc2\x37\x28\x1d\xbd\x84\x1f\xd5\xa3\xd2\xfb\xe7\xe3\x37\x12\x5e\xa4\xd7\x83\x89\x5c\x35\x7c\x3e\x03\x2b\x6d\x77\x3f\x33\xd9\xdf\x35\x03\xea\x1d\x9a\xaa\x43\x5f\x04\x25\x7e\x0d\xfd\x46\xa5\x39\x64\xfa\xf4\xb8\x85\xb9\xbd\x7f\x1b\x9d\x23\xb5\xdb\x2e\x35\x32\x75\x6b\x77\x7b\xff\xd6\x7d\x76\xa6\x36\x4c\x4a\x65\x26\x1b\xd5\x9e\x3c\xdc\xd3\x1e\xb5\x5a\x52\x67\x9d\xab\x3f\xed\xb6\x8c\x09\x52\x2e\xe1\xce\xbf\x70\xcc\x83\xc8\x50\xca\x03\x77\x2d\xa2\xe4\xc0\x6c\x50\xcf\xb9\xaa\x36\xcd\xf9\x8c\x02\x71\x12\x6c\xb4\xd9\x50\xe6\xc5\x8e\x3a\xc3\x6b\x45\xa7\x0d\x27\xca\x2b\x39\xde\x8b\xb9\x7a\x2b\x67\x26\x6b\x6f\x2a\xf2\xda\x51\xba\xf6\x6f\xb5\x5a\x4d\x9a\x7a\xcd\xe8\x34\x8a\x60\xa3\x83\xca\x01\x7d\x34\xcf\x13\x79\xee\x9f\xe1\x7e\xb8\x03\xff\x69\xfc\xf4\x3c\x9b\x8d\x9d\x13\xf8\x06\x7d\x4d\x81\xaf\x36\xc9\xd1\x3b\xca\x42\xe7\x8e\x57\xf7\x0e\xc7\xd3\xf6\x1a\xcf\xbb\xec\x25\x68\x66\x56\xfa\x9c\x5b\x7f\xe7\xe2\x89\x67\x5d\xf4\x6c\xb9\x9f\x15\x69\xd3\x55\x77\x18\x7f\xbf\x49\x45\x37\x6e\x75\x66\x58\x92\xcc\xd0\x51\x7e\x5c\x8b\x13\x18\x9f\x53\x80\x67\x30\x7a\xae\xe8\xce\x98\x62\xba\x0e\x9e\x75\xfb\x58\x15\x13\xd5\xba\xbe\x05\xd1\xb4\x1b\x3d\xff\xe6\x7c\x82\x90\x91\x8d\x45\x26\x5d\xa2\x43\xd6\xd5\xbe\xd0\x4f\xce\x8c\x13\xd6\xee\xb1\xfe\x5d\x8d\xdf\x78\xc1\x88\xed\x16\x27\xd8\xae\xaa\x7f\x2d\xb6\xa3\xbc\x77\x95\x26\x16\xc9\x12\x0f\xf1\x6a\x5a\x69\xb4\xf5\x98\x0e\x38\x82\xca\xc9\x3a\x8f\x2a\xe7\xb1\xfb\xe2\x10\xd5\x60\x58\xe6\x02\x1d\x08\xef\x20\xf5\xc5\xbe\x32\xd8\xc5\x77\xb0\xe2\x7d\x97\xb3\x42\x76\x94\xfd\x9a\x07\x34\x10\xa1\xb7\x78\xaa\xab\x3d\xc3\x4c\x5a\x61\x9a\x31\x89\x13\x17\xab\xde\x37\xcf\xde\x7b\x32\xc7\x79\xb5\x23\x84\x8a\x70\x7c\x27\xf2\x74\x19\x89\x0c\x08\xf5\x3c\x49\xf5\xfc\x01\x4e\x3a\x98\x18\x0f\xab\x45\xb3\x4b\x33\x4a\x30\xd1\xd1\x9e\x4f\xea\xda\xa4\x9b\xf2\xe7\x62\x7f\xec\x6e\x5e\x7a\x1a\x29\xde\x33\x5d\x8e\xdf\x94\x4b\xcf\x89\x55\xeb\x5f\x5f\x4c\x58\xb7\x73\x57\x37\xde\x06\xf5\xb6\x42\x52\x87\x59\x36\x86\xb9\x5b\x10\x73\x36\x20\x16\xe9\x47\x18\x93\x14\x8f\x42\x9d\xde\x1f\xed\x12\x30\x00\x9b\x24\x68\x2f\x0e\xce\x24\x8b\x1b\x93\x93\xb4\xd5\xa1\xd4\x7b\x9e\x89\xa5\x5f\xa0\x7c\x98\x4d\xfc\x99\x13\xd5\x47\x48\xcf\x32\xd9\xf9\x5d\xf6\x99\x13\xb5\xa6\x79\xe6\xe9\x66\xec\x8f\xcf\x9c\x73\x37\x67\xe3\xf9\x19\xa0\xc7\x49\xc8\x57\xdd\xfe\x44\x4d\x32\x68\xbd\xc8\x82\x44\xdb\xc6\x7e\x4c\xf2\x27\xbf\x5b\xba\x98\x67\xe7\xd1\xfa\x31\x14\x7a\xbc\x29\x91\x28\x6b\x4e\xe3\xae\xd6\xbe\x20\xd5\x1c\xfe\xa5\x9f\x81\xc1\x9a\xb6\x5c\x3c\x8d\x91\x87\xfa\x37\x06\xed\x0d\x76\x29\x9c\x8f\xf8\xa1\xc5\x02\x73\xaf\x42\x8c\xaa\x7d\x0c\x02\x3b\xb2\x3b\xca\x57\xe0\x6d\x68\x5e\x79\x6d\x19\x17\xf5\xde\x85\x75\xc3\x5f\xab\x86\xca\x8e\xf0\xdb\xef\x57\xff\x0b\x00\x00\xff\xff\xae\xb2\xfa\x2c\x43\x37\x00\x00") +var _operatorsCoreosCom_installplansYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4b\x93\x1b\xb7\x11\xbe\xef\xaf\xe8\x5a\x1f\x64\x57\x89\x5c\xdb\xb9\x24\xbc\x29\xeb\x38\xb5\x89\x1f\x2a\xed\x5a\x17\xc7\x87\xe6\x4c\x93\x03\x2f\x06\x80\xf1\x20\xc5\xb8\xfc\xdf\x53\x0d\xcc\x93\x9c\x19\x0e\x57\x6b\x59\x95\xf2\x5c\xa4\x9d\x69\x00\xfd\xee\xaf\x01\x10\x8d\x78\x4b\xd6\x09\xad\x56\x80\x46\xd0\x3b\x4f\x8a\xff\x72\xcb\xc7\xbf\xba\xa5\xd0\x37\xbb\x2f\xae\x1e\x85\xca\x57\x70\x1b\x9c\xd7\xe5\x1b\x72\x3a\xd8\x8c\xbe\xa2\x8d\x50\xc2\x0b\xad\xae\x4a\xf2\x98\xa3\xc7\xd5\x15\x00\x2a\xa5\x3d\xf2\x6b\xc7\x7f\x02\x64\x5a\x79\xab\xa5\x24\xbb\xd8\x92\x5a\x3e\x86\x35\xad\x83\x90\x39\xd9\x38\x79\xbd\xf4\xee\xf3\xe5\xdf\x96\x9f\x5f\x01\x64\x96\xe2\xf0\x07\x51\x92\xf3\x58\x9a\x15\xa8\x20\xe5\x15\x80\xc2\x92\x56\x20\x94\xf3\x28\xa5\x91\xa8\xdc\x52\x1b\xb2\xe8\xb5\x75\xcb\x4c\x5b\xd2\xfc\x4f\x79\xe5\x0c\x65\xbc\xf6\xd6\xea\x60\x56\x30\x48\x93\x66\xab\x59\x44\x4f\x5b\x6d\x45\xfd\x37\xc0\x02\xb4\x2c\xe3\xff\x93\xe8\x77\x69\xd1\xd7\x12\x55\x7c\x2b\x85\xf3\xff\x3e\xfe\xf2\x8d\x70\x3e\x7e\x35\x32\x58\x94\x7d\x56\xe3\x07\x57\x68\xeb\xbf\x6b\x17\xe6\x85\x84\x49\x9f\x84\xda\x06\x89\xb6\x37\xea\x0a\xc0\x65\xda\xd0\x0a\xe2\x20\x83\x19\xe5\x57\x00\x95\xd2\xaa\x49\x16\x80\x79\x1e\x0d\x81\xf2\xb5\x15\xca\x93\xbd\xd5\x32\x94\xaa\x59\x84\x69\x72\x72\x99\x15\xc6\x47\x65\x3f\x14\x04\x1b\x61\x9d\x87\xdb\xfb\xb7\x20\x14\xf8\x82\xa2\x4c\xa0\x37\x90\xc9\xe0\x3c\xd9\x7b\xb2\x3b\x91\x51\xe5\x1b\x71\xfd\x66\x3a\x80\x9f\x9d\x56\xaf\xd1\x17\x2b\x58\xb2\xba\x97\xe3\x83\x7e\xfc\xfc\xa7\xce\xb8\x64\xc3\xdb\xfb\xb7\x9d\x77\xfe\xc0\x12\x3a\x6f\x85\xda\x4e\x71\x8c\xc6\x58\xbd\x43\x09\xa5\xce\x69\x82\x97\x9a\xee\x64\xd9\x57\xa7\x1f\x46\xd6\x1e\x9e\x32\x2a\x7f\x68\xca\xde\x87\x34\xe5\x5a\x6b\x49\x95\xb7\xd4\xc4\xbb\x2f\x50\x9a\x02\xbf\xa8\x5e\xba\xac\xa0\x12\x5b\x23\x69\x43\xea\xd5\xeb\xbb\xb7\x7f\xb9\x3f\xfa\x00\x7d\x5d\x74\x5c\x0e\x72\x8e\x42\x72\xd1\x80\x95\xe3\xc4\xe8\x61\x43\x22\x38\x8a\x16\x6d\x23\xe0\x84\x4d\xbd\xfe\x99\x32\xdf\x79\x6d\xe9\x97\x20\x2c\xe5\xdd\xd5\x59\x23\x75\x8c\x1f\xbd\x66\xed\x74\x5e\x19\xcb\x6b\xf9\x4e\x24\xa5\xa7\x93\x64\x7a\xef\x8f\x24\x7b\xc1\xe2\x27\xba\x9e\x64\x95\xc3\x53\x5e\xe9\x8c\x85\xf2\x85\x70\x60\xc9\x58\x72\xa4\x7c\x2b\xb4\xaa\x64\x5a\x02\x3b\x23\x59\xc7\x51\x17\x64\xce\x89\x68\x47\xd6\x83\xa5\x4c\x6f\x95\xf8\x6f\x33\x9b\x03\xaf\x53\x04\xa0\x27\xe7\x21\x86\x90\x42\x09\x3b\x94\x81\x5e\x02\xaa\x1c\x4a\x3c\x80\x25\x9e\x17\x82\xea\xcc\x10\x49\xdc\x12\xbe\xd5\x96\x0d\xb0\xd1\x2b\x28\xbc\x37\x6e\x75\x73\xb3\x15\xbe\x4e\xa1\x99\x2e\xcb\xa0\x84\x3f\xdc\xc4\x6c\x28\xd6\x81\xad\x71\x93\xd3\x8e\xe4\x8d\x13\xdb\x05\xda\xac\x10\x9e\x32\x1f\x2c\xdd\xa0\x11\x8b\xc8\xac\x8a\x69\x74\x59\xe6\x9f\xd8\x2a\xe9\xba\x17\x47\xea\x1b\xf4\x5f\xa8\xf3\xd6\xa4\xae\x39\x7f\x81\x70\xec\x26\x71\x78\x92\xa5\x55\x29\xbf\x62\xad\xbc\xf9\xc7\xfd\x03\xd4\x0c\x24\xb5\x27\x0d\xb7\xa4\xae\x55\x36\x2b\x4a\xa8\x0d\xd9\x44\xb9\xb1\xba\x8c\xb3\x90\xca\x8d\x16\xca\xc7\x3f\x32\x29\x48\x79\x70\x61\x5d\x0a\xef\xa2\xcf\x91\xf3\x6c\x87\x25\xdc\xc6\x0a\x02\x6b\x82\x60\x72\xf4\x94\x2f\xe1\x4e\xc1\x2d\x96\x24\x6f\xd1\xd1\xef\xae\x6a\xd6\xa8\x5b\xb0\xfa\xe6\x2b\xbb\x5b\x00\x4f\x07\x9c\xc4\x18\x40\x5d\xa2\x46\xad\xd3\x89\xf1\x7b\x43\x59\x13\x0d\x4d\x4c\xbf\x32\x46\x8a\x2c\xb9\x7d\xe3\x1d\xec\xc8\xeb\x26\x11\xf4\xb2\xd2\x24\x3b\x63\x61\x0f\xa9\xbc\x9c\xa6\xcd\xfe\xa7\x93\x85\xf8\xd3\xac\x32\x02\x13\x39\x03\x62\xde\x48\x4b\x9f\x7e\x39\xd2\x57\x9d\xda\xd9\xa1\xd9\xc3\x82\x23\xdb\x16\x0c\xa3\xa5\xc8\x0e\xb0\xd1\x96\xf3\x43\x47\xb7\x4b\xb8\xf3\x50\x06\x17\xfd\x4d\x2b\x62\xcd\x5e\xbf\x0a\x5e\x97\xe8\x45\x76\x0d\xda\xc2\xf5\xb7\xa8\x02\xca\xeb\xe5\x00\x0b\xa3\x0e\xd1\xf2\x3e\xa4\xd2\xe1\x1a\xd1\x3e\xe3\xaa\x1b\x9f\x0b\xad\xc5\xc3\xc0\x57\xe1\xa9\x1c\x1c\x76\x86\xfb\x2d\x29\x2e\x1a\x03\x19\xbb\x1d\xca\x89\x72\x4b\xf6\xe4\x7b\xf2\xc6\xf1\x71\x23\x4b\xa6\x61\x0d\xd2\xb9\x68\xbc\xf3\xe8\xc3\x89\x9c\x3d\x17\xb9\xee\xc6\x54\x24\xef\x24\xb0\xaa\x80\x6e\xb4\x2d\x53\x4c\xe1\x5a\x87\x94\xac\xd2\xd4\xec\x19\xce\x93\x71\x4d\xa8\x70\xb0\x65\xba\x34\x92\x7c\xbf\xf6\x2e\xe1\x3f\x0a\xaa\x15\x38\x1d\x7a\x8b\x42\xc6\xa9\x30\xf3\x01\x65\x9c\x91\xaa\x0a\x7d\x70\x9e\xca\xe5\xf5\xf3\x44\x6a\x86\x1e\xa5\xde\xde\xa7\x6c\x30\x40\x60\x0a\x74\x74\x49\xfc\x79\x4f\x2a\x70\x16\xae\x9c\xf1\x55\x96\xe9\xa0\xfc\x1b\xda\x9c\x0f\xc9\xf1\xb1\x60\x69\x43\x96\x54\x56\xd5\x77\x97\x08\x00\x13\x05\xf8\x02\x3d\x47\x72\x70\x49\xcd\xb9\x4e\x38\x38\x6f\xa0\x4c\xad\xf0\xf1\xa8\x1c\x54\xde\x39\x79\x61\x12\xab\x0c\x8b\xf9\xfa\xae\xc6\x27\x09\x96\x50\x2d\x9d\x1f\x62\x0e\xce\x45\x01\x3f\x1b\x41\x32\x8f\xf8\x73\x0e\x07\x2f\xee\x2a\x85\xc6\x2a\xee\x35\x20\x18\x41\x19\xf5\xe0\x50\x54\x18\x61\x5e\xbd\xe4\x82\x67\xa9\xfa\xf6\x32\xd5\xea\x0a\x06\xb4\x70\xc9\xa3\x50\x80\x8c\x0b\x44\x0e\xff\xba\xff\xfe\xbb\x9b\x7f\xea\xc4\x1b\x5b\x8a\x9c\x4b\x9e\x5c\x92\xf2\x2f\xc1\x85\xac\x00\x74\xcc\x1a\xbb\x27\xfb\x3f\x2d\x4b\x54\x62\x43\xce\x2f\xab\xd9\xc8\xba\x1f\xbf\xfc\x69\x09\x5f\x6b\x0b\xf4\x0e\x39\x78\x5e\x82\x48\x5a\x6b\x40\x45\xe5\x1a\x31\x95\xb3\x30\xcd\x58\xd8\x0b\x5f\x44\x96\x8c\xce\x2b\xa6\xf7\x91\x59\x8f\x8f\x9c\xbf\x13\xb3\x81\x7b\x99\x47\x5a\xc1\x75\x6a\x4d\x9a\xa5\x7f\x65\x18\xfe\xdb\x35\x7c\xba\x2f\xc8\x12\x5c\xf3\x9f\xd7\x69\xc1\x06\x03\xf2\xbb\xda\x8e\xed\xc2\xd1\x21\xbd\x15\xdb\x2d\xc5\xc8\x67\x40\xc3\xa0\xe1\x33\xae\x10\x62\x03\x4a\x77\x88\xe3\x14\xac\x4f\x43\x99\xd8\x08\xca\x4f\x18\xf9\xf1\xcb\x9f\xae\xe1\xd3\xbe\x5c\x20\x54\x4e\xef\xe0\xcb\xd4\x8e\x09\xc7\x32\x7e\xb6\x84\x87\x68\x99\x83\xf2\xf8\x8e\xe7\xcc\x0a\xed\x48\x81\x56\xf2\xc0\x1c\x17\xb8\x23\x70\xba\x24\xd8\x93\x94\x8b\x84\x12\x72\xd8\xe3\x81\x65\xa8\x55\xc9\x56\x45\x30\x68\xfd\x11\x42\x7e\xf8\xfe\xab\xef\x57\x69\x35\x36\xdb\x56\xf1\x12\x8c\xbe\x36\x82\xf1\x2f\x03\xdf\x84\xe2\xa2\xcd\x99\x91\x90\x8c\xc4\xa9\xaf\x40\xb5\xa5\xba\x79\xdc\x04\xc6\x53\xcb\x63\xc4\x34\xdb\xe3\x87\xe0\xea\xb0\xb3\x47\xd8\x7a\x1c\x68\x7f\x20\x28\x9c\x2d\x62\xec\x01\x67\x89\xf8\x5d\xc7\x07\x27\x45\x7c\x0c\x6b\xb2\x8a\x3c\x45\x29\x73\x9d\x39\x16\x30\x23\xe3\xdd\x8d\xde\x71\x52\xa5\xfd\xcd\x5e\xdb\x47\xa1\xb6\x0b\x76\xb2\x45\xb2\xbc\xbb\x89\xbb\x1f\x37\x9f\xc4\x7f\xde\x4b\xa2\xd1\x52\x3d\x2c\x56\x24\xff\x10\xb2\xf1\x3a\xee\xe6\xc9\xa2\xd5\x90\xfa\x92\x4a\xf0\xe2\x3e\x05\x7c\x76\x3c\x9a\xc3\x65\x5f\x88\xac\xa8\x9b\xd6\x4e\x86\x2b\x31\x4f\x29\x10\xd5\xe1\x77\x77\x63\x56\x60\xb0\xbc\xf6\x61\x51\xed\xcb\x2d\x50\xe5\xfc\x7f\x27\x9c\xe7\xf7\x4f\xd6\x58\x10\x33\x03\xf8\x87\xbb\xaf\x3e\x8c\x73\x07\xf1\xc4\x68\x5d\x07\x95\x4b\xfa\x46\xeb\xc7\x60\x06\x41\x42\x4f\xa0\xbf\x77\xa9\xeb\xfe\xa3\xea\xd2\x84\x5a\x18\xab\xb7\x96\x6b\x65\xa7\xcb\x05\x13\x64\x4a\xaf\x41\x19\xcc\x1e\x71\x4b\xd5\xa2\xb1\x8c\x70\x6f\x5c\x95\xa3\xaa\x15\x18\x87\x39\x4f\xc0\xfd\xa3\xdc\xa7\xdd\x80\x8a\xcf\x11\x36\xeb\xba\xc8\x3c\x46\x04\x5b\xf1\x7d\x9e\xdf\xb3\xc0\x6c\x0a\xdb\xa6\xe7\x08\xe1\xbe\xa1\xcd\x28\xa1\xc8\xd9\xef\x37\x62\xa0\x3d\xa9\x49\x0c\xfa\x62\xf4\xa3\x25\x23\x71\x08\x44\xc3\x0c\x08\x09\x27\x7c\x8e\xd1\x1d\x59\xe3\xf6\x68\x58\x6d\x91\x3a\x61\x54\x5a\xee\x91\xc5\x37\x95\x15\x58\x24\xd8\xa3\x8b\x19\x48\xee\x28\x8f\x1b\x30\x63\x38\x74\x86\x45\xe6\x49\x0b\xb3\x60\xf3\x80\xbc\x4f\x00\xcf\x5d\xc6\x27\xd2\x51\x7a\xce\x02\xe9\x01\x9e\xfe\x84\xd3\x7f\xc2\xe9\x8f\x1c\x4e\x5f\x14\x03\x53\xd0\x7a\xc8\xfd\x3f\x56\x80\x7d\x91\xd0\x53\x60\x7b\x48\xe8\x8f\x04\x72\x5f\x2c\xe3\x24\xfc\x1e\x13\xf4\x23\x01\xe1\x17\x09\x3b\x13\x90\x0f\x89\xfc\xff\x0c\xcb\x2f\xd2\xe1\x04\x44\x1f\xd2\xdb\x47\x01\xd4\x67\x0b\x98\x69\x95\x4e\xc1\x27\x50\x4a\x1f\x6b\x35\x03\x8e\xf7\x81\x99\x69\x94\xbd\x7d\xda\x2e\x4c\x3e\x07\xa7\xc6\x20\x79\x7a\x26\x80\x79\x77\x92\x33\x98\xec\x3c\x56\x4e\xcf\xa2\xda\xbe\x3e\x43\xc4\x6b\x4e\x90\xcc\x43\x80\x00\x12\x9d\x7f\xb0\xa8\x9c\xa8\x6f\x70\x4c\xd3\x1f\x59\xe4\x1b\xe4\xb6\x43\x94\x4d\x97\x91\xec\x03\xbe\x99\xb2\x02\xb4\xf1\xa8\xa6\xda\x97\x67\x4c\xa3\xb4\x2f\xc6\x9a\x8e\xf6\x99\x19\x25\xfc\xa4\x73\x80\x15\xe4\xe8\x69\xc1\x1c\x9d\x15\xfb\x87\x78\x58\xf9\x6c\x22\x33\x86\x37\x56\xaf\x29\xff\xc3\xa4\x2a\xc9\x39\xdc\x5e\x26\xce\x2b\x28\x42\x89\x0a\x2c\x61\x8e\x6b\x49\xf5\x24\x8c\xc6\xe2\x69\xa5\xda\x42\x4e\x1e\x85\x74\x9d\x13\x96\xd6\xbe\xcf\x26\xac\x25\x74\xe7\xaa\x04\x9c\x5e\x31\x49\xc3\xe2\x41\x61\xcf\x1e\x2f\x5c\x34\xf2\xef\xc1\xe9\xf0\xc9\xd5\x24\xa7\xf7\xcd\x89\x54\x8f\xc9\x97\xf5\x09\xe6\x83\x0d\xf4\x12\xbe\x46\xe9\xe8\x25\xfc\xa0\x1e\x95\xde\x3f\x1f\xbf\x91\xf0\x22\xbd\x1e\x4c\xe4\xaa\xe1\xf3\x19\x58\x69\xbb\xfb\x99\xc9\xfe\xae\x19\x50\xef\xd0\x54\x1d\xfa\x22\x28\xf1\x4b\xe8\x37\x2a\xcd\x21\xd3\xa7\xc7\x2d\xcc\xed\xfd\xdb\xe8\x1c\xa9\xdd\x76\xa9\x91\xa9\x5b\xbb\xdb\xfb\xb7\xee\xb3\x33\xb5\x61\x52\x2a\x33\xd9\xa8\xf6\xe4\xe1\x9e\xf6\xa8\xd5\x92\x3a\xeb\x5c\xfd\x69\xb7\x65\x4c\x90\x72\x09\x77\xfe\x85\x63\x1e\x44\x86\x52\x1e\xb8\x6b\x11\x25\x07\x66\x83\x7a\xce\x55\xb5\x69\xce\x67\x14\x88\x93\x60\xa3\xcd\x86\x32\x2f\x76\xd4\x19\x5e\x2b\x3a\x6d\x38\x51\x5e\xc9\xf1\x5e\xcc\xd5\x5b\x39\x33\x59\x7b\x53\x91\xd7\x8e\xd2\xb5\x7f\xab\xd5\x6a\xd2\xd4\x6b\x46\xa7\x51\x04\x1b\x1d\x54\x0e\xe8\xa3\x79\x9e\xc8\x73\xff\x0c\xf7\xc3\x1d\xf8\x4f\xe3\xa7\xe7\xd9\x6c\xec\x9c\xc0\x37\xe8\x6b\x0a\x7c\xb5\x49\x8e\xde\x51\x16\x3a\x77\xbc\xba\x77\x38\x9e\xb6\xd7\x78\xde\x65\x2f\x41\x33\xb3\xd2\xe7\xdc\xfa\x3b\x17\x4f\x3c\xeb\xa2\x67\xcb\xfd\xac\x48\x9b\xae\xba\xc3\xf8\xfb\x4d\x2a\xba\x71\xab\x33\xc3\x92\x64\x86\x8e\xf2\xe3\x5a\x9c\xc0\xf8\x9c\x02\x3c\x83\xd1\x73\x45\x77\xc6\x14\xd3\x75\xf0\xac\xdb\xc7\xaa\x98\xa8\xd6\xf5\x2d\x88\xa6\xdd\xe8\xf9\x37\xe7\x13\x84\x8c\x6c\x2c\x32\xe9\x12\x1d\xb2\xae\xf6\x85\x7e\x72\x66\x9c\xb0\x76\x8f\xf5\x6f\x6b\xfc\xc6\x0b\x46\x6c\xb7\x38\xc1\x76\x55\xfd\x6b\xb1\x1d\xe5\xbd\xab\x34\xb1\x48\x96\x78\x88\x57\xd3\x4a\xa3\xad\xc7\x74\xc0\x11\x54\x4e\xd6\x79\x54\x39\x8f\xdd\x17\x87\xa8\x06\xc3\x32\x17\xe8\x40\x78\x07\xa9\x2f\xf6\x95\xc1\x2e\xbe\x83\x15\xef\xbb\x9c\x15\xb2\xa3\xec\xd7\x3c\xa0\x81\x08\xbd\xc5\x53\x5d\xed\x19\x66\xd2\x0a\xd3\x8c\x49\x9c\xb8\x58\xf5\xbe\x79\xf6\xde\x93\x39\xce\xab\x1d\x21\x54\x84\xe3\x3b\x91\xa7\xcb\x48\x64\x40\xa8\xe7\x49\xaa\xe7\x0f\x70\xd2\xc1\xc4\x78\x58\x2d\x9a\x5d\x9a\x51\x82\x89\x8e\xf6\x7c\x52\xd7\x26\xdd\x94\x3f\x17\xfb\x63\x77\xf3\xd2\xd3\x48\xf1\x9e\xe9\x72\xfc\xa6\x5c\x7a\x4e\xac\x5a\xff\xfa\x62\xc2\xba\x9d\xbb\xba\xf1\x36\xa8\xb7\x15\x92\x3a\xcc\xb2\x31\xcc\xdd\x82\x98\xb3\x01\xb1\x48\x3f\xc2\x98\xa4\x78\x14\xea\xf4\xfe\x68\x97\x80\x01\xd8\x24\x41\x7b\x71\x70\x26\x59\xdc\x98\x9c\xa4\xad\x0e\xa5\xde\xf3\x4c\x2c\xfd\x02\xe5\xc3\x6c\xe2\xcf\x9c\xa8\x3e\x42\x7a\x96\xc9\xce\xef\xb2\xcf\x9c\xa8\x35\xcd\x33\x4f\x37\x63\x7f\x7c\xe6\x9c\xbb\x39\x1b\xcf\xcf\x00\x3d\x4e\x42\xbe\xea\xf6\x27\x6a\x92\x41\xeb\x45\x16\x24\xda\x36\xf6\x63\x92\x3f\xf9\xdd\xd2\xc5\x3c\x3b\x8f\xd6\x8f\xa1\xd0\xe3\x4d\x89\x44\x59\x73\x1a\x77\xb5\xf6\x05\xa9\xe6\xf0\x2f\xfd\x0c\x0c\xd6\xb4\xe5\xe2\x69\x8c\x3c\xd4\xbf\x31\x68\x6f\xb0\x4b\xe1\x7c\xc4\x0f\x2d\x16\x98\x7b\x15\x62\x54\xed\x63\x10\xd8\x91\xdd\x51\xbe\x02\x6f\x43\xf3\xca\x6b\xcb\xb8\xa8\xf7\x2e\xac\x1b\xfe\x5a\x35\x54\x76\x84\x5f\x7f\xbb\xfa\x5f\x00\x00\x00\xff\xff\xa9\xc5\x05\x0b\x43\x37\x00\x00") func operatorsCoreosCom_installplansYamlBytes() ([]byte, error) { return bindataRead( @@ -145,7 +145,7 @@ func operatorsCoreosCom_installplansYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_olmconfigsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x6f\x6f\xdb\x46\xd2\x7f\xef\x4f\x31\xd0\xf3\x00\xb1\x73\x12\x15\x27\x87\x5c\x4a\x20\x08\x02\xe5\x5c\x04\x89\xaf\x41\xec\xcb\x01\x67\xf9\xae\x43\x72\x44\x6d\x43\xee\xb2\xbb\xb3\xb6\xd5\xa2\xdf\xfd\x30\xbb\x24\x45\xc9\xa2\x63\xa0\xad\xde\x58\x9a\x9d\x9d\x9d\xbf\xbf\x99\x31\x36\xea\x0b\x59\xa7\x8c\x4e\x01\x1b\x45\x77\x4c\x5a\x7e\xb9\xe4\xeb\x2b\x97\x28\x33\xbf\x39\x3d\xfa\xaa\x74\x91\xc2\xc2\x3b\x36\xf5\x67\x72\xc6\xdb\x9c\xde\xd1\x4a\x69\xc5\xca\xe8\xa3\x9a\x18\x0b\x64\x4c\x8f\x00\x50\x6b\xc3\x28\x64\x27\x3f\x01\x72\xa3\xd9\x9a\xaa\x22\x3b\x2b\x49\x27\x5f\x7d\x46\x99\x57\x55\x41\x36\x08\xef\x9e\xbe\x79\x96\xbc\x4a\x9e\x1d\x01\xe4\x96\xc2\xf5\x4b\x55\x93\x63\xac\x9b\x14\xb4\xaf\xaa\x23\x00\x8d\x35\xa5\x60\xaa\x3a\x37\x7a\xa5\x4a\x97\x98\x86\x2c\xb2\xb1\x2e\xc9\x8d\x25\x23\x7f\xea\x23\xd7\x50\x2e\x2f\x97\xd6\xf8\x26\x85\x83\x3c\x51\x56\xa7\x20\x32\x95\xc6\xaa\xee\x37\xc0\x4c\x1e\x09\xdf\xa3\xe1\x3f\x7c\x3c\x5f\x84\x27\x03\xad\x52\x8e\x3f\xec\xd2\x3f\x2a\xc7\xe1\xac\xa9\xbc\xc5\x6a\xa8\x64\x20\x3b\xa5\x4b\x5f\xa1\x1d\x1c\x1c\x01\xb8\xdc\x34\x94\xc2\xa2\xf2\x8e\xc9\x1e\x01\xb4\xce\x68\xf5\x98\xb5\x06\xdf\x9c\xb6\x6a\xb9\x7c\x4d\x35\x76\x4a\x82\x98\xa6\xdf\x7e\x7a\xff\xe5\xc5\xc5\xde\x01\x40\x41\x2e\xb7\xaa\xe1\xe0\xda\x5e\x4d\x50\x0e\x10\x6c\x1b\x40\xf9\xd2\x18\xed\x54\x56\x11\xac\x8c\x85\xa8\x98\xb7\x4a\x97\x72\x27\x19\xc8\xe3\x8d\x68\x6a\xb2\x9f\x28\xe7\x01\xd9\xd2\xcf\x5e\x59\x2a\x86\x4f\x8b\xe2\x5d\x42\x0c\xc8\x8d\x95\x48\xf0\xc0\xcb\xf1\x33\x48\xbf\x1d\xfa\x9e\x0d\x4f\xc4\xd0\xc8\x07\x85\x64\x1e\x39\xe0\x35\x75\x2e\xa3\xa2\xf5\x0e\x98\x15\xf0\x5a\x39\xb0\xd4\x58\x72\xa4\x63\x2e\x0a\x19\x75\x6b\x40\x02\x17\x64\xe5\x22\xb8\xb5\xf1\x55\x21\x86\xdf\x90\x65\xb0\x94\x9b\x52\xab\x5f\x7a\x69\x0e\xd8\x84\x67\x2a\x64\x72\x0c\x4a\x33\x59\x8d\x15\xdc\x60\xe5\x69\x0a\xa8\x0b\xa8\x71\x03\x96\x44\x2e\x78\x3d\x90\x10\x58\x5c\x02\xe7\xc6\x12\x28\xbd\x32\x29\xac\x99\x1b\x97\xce\xe7\xa5\xe2\xae\xb8\x72\x53\xd7\x5e\x2b\xde\xcc\x43\x9d\xa8\xcc\x4b\xae\xce\x0b\xba\xa1\x6a\xee\x54\x39\x43\x9b\xaf\x15\x53\xce\xde\xd2\x1c\x1b\x35\x0b\xca\xea\x50\x60\x49\x5d\xfc\x5f\x17\x4d\xf7\x64\xcf\x7d\x31\x64\x8e\x25\x9c\x3b\x47\x21\xa7\x1f\xf4\xb5\x64\x77\xcc\x95\x78\x3d\xda\xb2\x75\xa9\x90\xc4\x2b\x9f\xff\x7e\x71\xb9\x4d\xa7\xe0\xf6\xe8\xe1\x2d\xab\xdb\x3a\x5b\x1c\xa5\xf4\x8a\x6c\xe4\x5c\x59\x53\x07\x29\xa4\x8b\xc6\x28\xcd\xe1\x47\x5e\x29\xd2\x0c\xce\x67\xb5\x62\x17\x12\x8c\x1c\x4b\x1c\x12\x58\x04\x6c\x81\x8c\xc0\x37\x05\x32\x15\x09\xbc\xd7\xb0\xc0\x9a\xaa\x05\x3a\xfa\xd3\x5d\x2d\x1e\x75\x33\x71\xdf\xe3\x9d\x3d\x84\xc6\xfb\x17\xee\x15\x14\x40\x07\x5f\xa3\xd1\xe9\xab\xf9\xa2\xa1\x5c\xa2\x24\x6e\x93\x5b\xa1\x86\x51\x0f\xca\xbd\x0b\x4d\xf2\xd8\xc7\xc7\xcb\x54\x3e\x2b\x42\x71\xcd\x81\x93\x3d\x15\xcf\x5a\xc6\x80\xfd\xa8\x74\xd4\x51\x70\x53\xea\xb0\x83\x19\x14\xdc\xf9\xe1\xe3\x79\x2f\x77\x5f\xcd\x6f\xa8\xfa\x2d\x75\x83\x5a\xca\xc9\x33\x0b\xd3\x28\x2a\x16\x17\x5f\x46\xd8\xf6\xf4\x7f\xb7\x7f\x4b\xdc\xec\x1d\x15\x02\x07\xad\x48\xd1\xfc\x89\x83\x49\x64\x82\xc5\xc5\x97\x49\x67\x48\x08\x44\xdf\x77\x40\x69\xc7\x58\x55\x54\x00\x76\x39\x1e\x00\x3f\xe2\xff\x14\x6e\xd7\x64\x09\x70\x97\x5c\xf4\x02\xe4\x6d\xa3\xa5\xbc\x90\x61\x8d\x0e\x32\x22\x3d\x10\xaa\x74\x08\x7a\xcb\xfd\xbd\x74\xbd\xc8\xcb\x68\x4b\x62\x07\x58\x55\xb1\xdd\x35\x98\x0b\x20\xfd\x6b\x4d\x1a\x2c\x91\x16\x33\x8a\x69\x08\xc1\xad\xaa\x2a\x81\x3f\xe9\xbd\x14\x94\x1c\x18\xe6\x26\xc1\x22\xc2\x7c\x3d\xa6\xe4\xa1\xd0\x6d\xc3\x97\x19\x53\x11\xea\xdd\x3c\x67\x64\x7f\x2f\x1c\x23\x99\x1e\x78\xfb\x5c\x8f\xbf\xfe\xec\x6c\xcf\x8d\x2e\xd4\x60\x8e\x39\x24\x14\xad\xc5\xcd\x81\x53\xc5\x54\x8f\x65\xe4\xd0\xc2\xc9\xa2\x7b\x64\x5b\x2a\x05\x31\xaa\x2a\xda\x27\x71\x47\xa9\x6d\x8e\x7d\x8d\x20\xf7\xd6\x06\x80\x64\x09\x54\xd7\xec\xde\x7e\x7a\x0f\xdd\x5c\x96\xc0\x6c\x36\x83\x4b\x21\x3b\xb6\x3e\x67\xf1\x9b\x34\x2e\x5d\x50\x11\xa4\x16\xca\x86\x6e\xe5\x44\xb8\xf8\x30\x98\xd1\x65\xe7\x4a\x51\x55\x40\x83\xbc\x86\x24\xba\x3a\xd9\xba\x22\x01\x38\x93\x54\xb8\xc3\xba\xa9\x68\x1a\xdc\x00\x67\xc6\xb4\x11\x8a\x0f\xfe\x0a\xf3\x39\x7c\xee\x3b\x40\x90\x6a\x32\x47\xf6\x26\xce\x85\xa1\x19\xc3\xca\x98\x27\x6e\xd7\x9e\x44\x2e\x7e\xd0\xe6\x56\x1f\x7a\x3a\xbc\x85\x96\x52\x58\x4e\xde\xde\xa0\xaa\x24\x7f\x97\x93\x29\x2c\x27\x9f\xac\x29\x2d\x39\x19\xb3\x84\x20\x6d\x79\x39\x79\x47\xa5\xc5\x82\x8a\xe5\x44\xc4\xfe\xa5\x41\xce\xd7\xe7\x64\x4b\xfa\x40\x9b\xd7\x41\x58\x4f\xbe\x60\x2b\x43\xe0\xe6\x75\x2d\xe7\x81\x2e\x68\x75\xb9\x69\xe8\x75\x8d\x4d\x4f\x38\xc7\xa6\xbf\xdc\x87\xce\xc1\xd5\xb5\xc0\xfc\xcd\x69\xb2\x0d\xe7\x8f\x3f\x39\xa3\xd3\xe5\x64\xab\xff\xd4\xd4\x92\x16\x0d\x6f\x96\x13\xd8\x79\x35\x5d\x4e\xc2\xbb\x1d\xbd\x53\x32\x5d\x4e\xe4\x25\x21\x5b\xc3\x26\xf3\xab\x74\x39\xc9\x36\x4c\x6e\x7a\x3a\xb5\xd4\x4c\xa5\xaa\x5f\x6f\x5f\x58\x4e\x7e\x84\xa5\x16\x65\x0d\xaf\xc9\xc6\x48\x3a\xf8\x6d\x72\x30\x11\xbf\x81\xac\x63\xc3\xdd\xf6\x33\x83\x0a\x1d\x5f\x5a\xd4\x4e\x75\x03\xfb\x28\x6b\x4d\xce\x61\x39\x7e\x6e\x09\x9d\xd1\xa3\xc7\x31\x1b\x46\x8f\xc5\x96\x83\x87\xdf\xea\x0f\x70\xc0\x86\x31\xce\xbd\xda\xbd\x7f\xb1\x03\x28\x39\x01\x16\x42\xa8\xd8\x3e\x27\xb8\xe7\x96\x42\x94\xf1\x47\xea\xbb\x85\x33\x36\x80\x3a\xc4\x2d\x69\x8b\x37\xce\xa6\x19\x49\x83\xd0\x41\x94\xd7\x05\xd9\x6a\x23\xe3\xd7\x56\x6a\xbe\x46\x5d\xca\x2c\x04\xef\x57\x11\xf8\x95\x03\x99\x93\xbe\x4a\x21\x4d\xe5\xa2\x06\xef\xba\x99\x2d\xe8\xd5\x4b\x14\xe0\x88\x05\xdf\x8a\x09\x63\x5f\x9e\x53\xc3\x52\x5d\x63\xb0\xfe\xc0\xc0\x33\xfc\xac\x8c\xad\x91\x53\x90\x61\x6d\xc6\xe3\xe9\xd1\x26\xc7\x23\x1d\xdf\x72\xc7\x01\x75\xed\x6b\x94\x6e\x86\x45\x68\xca\xfd\x99\x2e\x54\x8e\x61\x50\xed\xf0\x14\x33\xe3\x23\xc2\x6d\xe3\xd0\xba\x5a\x26\xd3\x8c\x04\x09\x43\x7d\xb6\x66\xfd\x4e\xe3\x6b\xbc\xfb\x48\xba\xe4\x75\x0a\x2f\x9e\xff\xed\xe5\xab\x11\xc6\x08\x8c\x54\x7c\x4f\x5a\x5a\xe9\x81\x3d\x68\xc4\x0d\xf7\x2f\x0e\xa6\xee\x60\x67\xd2\x0d\x9f\x49\xb9\xe5\x89\xa3\xc1\x4e\x5e\xde\xa2\x03\x47\x0c\x19\xca\x88\xe3\x1b\xf1\x8b\xa0\x7c\x98\x31\x74\x4e\x53\x50\xab\xc3\xc2\x54\x0f\xe0\xd5\x06\x4e\x9f\x4f\x21\x6b\x5d\x7c\x1f\xbe\xaf\xee\xae\x93\x03\x2a\x2b\x07\xdf\x4d\xf7\xf4\x91\x81\xc7\x87\x8e\x27\x89\x03\xb7\x8a\xd7\x61\x57\x95\xa6\xd5\xee\x63\x07\xda\x20\xf5\xfa\x7e\x2b\x70\xd2\x0c\xcb\xb0\x70\x1f\xfe\x74\x69\xab\x34\xbf\xfc\xeb\x78\x7c\x95\x56\xb5\xaf\x53\x78\x36\xc2\x12\x21\xed\x91\xd1\x8c\xcc\xdb\x29\x00\x05\xba\x4a\x8b\x75\x8d\xac\x72\x50\x85\xec\x21\x2b\x45\x76\x98\xda\x62\x74\x7b\x51\xfa\xfa\x8e\x17\x9f\xb8\x16\x87\x06\xc9\xfe\xc9\x9a\xc2\xe7\xb2\x8b\x99\x55\x58\x19\xd4\x4a\xe5\x43\x80\x92\x05\x27\x54\x43\x5c\xb1\x81\xee\xc4\xe9\xfd\x32\x1b\xf7\x5d\x42\xad\x74\xe9\xda\x27\x65\x93\x13\x00\x89\x5d\xf7\x76\x4d\xa1\xf5\x84\xd5\xbc\xbd\x63\x83\x56\x4e\x15\x64\x65\x06\x86\xd2\xa3\x45\xcd\x44\x85\xc0\x8f\x94\x60\xcb\x3b\x80\x3c\xdc\xae\x75\x5d\x35\xc6\x52\x8d\x60\x25\x2a\xb6\xab\x60\xa8\xd8\x3f\xae\x54\x4f\x9f\x3d\x7f\x30\xe4\x3d\xdf\x28\x53\x83\xcc\x64\x75\x0a\xff\xb9\x7a\x3b\xfb\x37\xce\x7e\xb9\x3e\x6e\xbf\x3c\x9b\x7d\xf7\xdf\x69\x7a\xfd\x74\xf0\xf3\xfa\xe4\xcd\xff\x8f\x48\x3a\x3c\x20\x8f\xa4\x4f\xdb\x44\xba\x21\xb1\x8b\xe8\x34\x74\x18\xb3\x82\x4b\xeb\x69\x0a\x67\x58\x39\x9a\xc2\x3f\x75\x68\x0d\xbf\xd3\x69\xa4\x7d\x3d\xae\x9d\x74\xe5\x89\xbc\x7a\x78\xf8\xe8\x59\x82\x4a\x0f\xf3\xb4\xea\x3e\xb4\x61\x3c\xce\x49\x61\x6c\x8b\x0b\x68\x87\x34\x83\x7f\x1f\x40\x40\x3c\x19\x4b\x93\x76\xbc\x4d\x72\x53\xcf\x07\xff\x5e\x90\xb9\xfa\x1c\xf5\x06\xb6\xb0\x16\x87\xd2\xfd\x4c\x77\x2c\xd8\x84\xb9\x35\xce\xf5\x6b\x89\x83\x4a\x7d\x25\xe8\x27\xd7\x08\x96\x19\xe5\x18\x06\x71\x9b\x29\xb6\x68\x37\x83\xbd\x03\x72\xd4\xe1\xbf\x1d\x8e\x56\xbe\x82\x63\x47\x04\x89\x36\x05\xdd\x47\xd7\x93\x88\xa1\x98\xa9\x4a\xf1\x26\xac\xa9\x24\x7b\x76\xa5\xda\xf9\xbf\x6e\x8c\x65\xd4\x1c\xcb\xcd\x52\x49\x77\xa0\x18\x6a\x99\x37\x29\xac\x56\xc7\x85\x76\xa7\xa7\xcf\x5f\x5c\xf8\xac\x30\x35\x2a\x7d\x56\xf3\xfc\xe4\xcd\xf1\xcf\x1e\x2b\x41\x9e\xe2\x1f\x58\xd3\x59\xcd\x27\x7f\x5c\x5b\x3c\x7d\xf9\x88\x2a\x3a\xbe\x8a\xb5\x72\x7d\x7c\x35\x6b\xbf\x3d\xed\x48\x27\x6f\x8e\x97\xc9\x83\xe7\x27\x4f\xc5\x86\x41\x05\x5e\x5f\xcd\xb6\xe5\x97\x5c\x3f\x3d\x79\x33\x38\x3b\xe9\x8a\x31\xf6\xa9\x14\xd8\xfa\x6e\x68\x71\x6c\xac\x0c\x29\x3b\x34\x9f\xf5\xe1\xdd\x26\x61\x5b\xb9\xf0\xeb\x6f\x47\xff\x0b\x00\x00\xff\xff\x65\x57\xc7\x70\x5d\x17\x00\x00") +var _operatorsCoreosCom_olmconfigsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x6f\x6f\xdb\x46\xd2\x7f\xef\x4f\x31\xd0\xf3\x00\xb1\x73\x12\x15\x27\x87\x5c\x43\x20\x08\x02\xe5\x5c\x04\x89\xaf\x41\xec\xcb\x01\x67\xf9\xae\x43\x72\x44\x6d\x43\xee\xb2\xbb\xb3\xb6\xd5\xa2\xdf\xfd\x30\xbb\x24\x45\xc9\xa2\x63\xa0\xad\xde\x58\x9a\x9d\x9d\x9d\xbf\xbf\x99\x31\x36\xea\x0b\x59\xa7\x8c\x4e\x01\x1b\x45\x77\x4c\x5a\x7e\xb9\xe4\xeb\x77\x2e\x51\x66\x7e\x73\x7a\xf4\x55\xe9\x22\x85\x85\x77\x6c\xea\xcf\xe4\x8c\xb7\x39\xbd\xa3\x95\xd2\x8a\x95\xd1\x47\x35\x31\x16\xc8\x98\x1e\x01\xa0\xd6\x86\x51\xc8\x4e\x7e\x02\xe4\x46\xb3\x35\x55\x45\x76\x56\x92\x4e\xbe\xfa\x8c\x32\xaf\xaa\x82\x6c\x10\xde\x3d\x7d\xf3\x2c\x79\x95\x3c\x3b\x02\xc8\x2d\x85\xeb\x97\xaa\x26\xc7\x58\x37\x29\x68\x5f\x55\x47\x00\x1a\x6b\x4a\xc1\x54\x75\x6e\xf4\x4a\x95\x2e\x31\x0d\x59\x64\x63\x5d\x92\x1b\x4b\x46\xfe\xd4\x47\xae\xa1\x5c\x5e\x2e\xad\xf1\x4d\x0a\x07\x79\xa2\xac\x4e\x41\x64\x2a\x8d\x55\xdd\x6f\x80\x99\x3c\x12\xbe\x47\xc3\x7f\xf8\x78\xbe\x08\x4f\x06\x5a\xa5\x1c\x7f\xd8\xa5\x7f\x54\x8e\xc3\x59\x53\x79\x8b\xd5\x50\xc9\x40\x76\x4a\x97\xbe\x42\x3b\x38\x38\x02\x70\xb9\x69\x28\x85\x45\xe5\x1d\x93\x3d\x02\x68\x9d\xd1\xea\x31\x6b\x0d\xbe\x39\x6d\xd5\x72\xf9\x9a\x6a\xec\x94\x04\x31\x4d\xbf\xfd\xf4\xfe\xcb\x8b\x8b\xbd\x03\x80\x82\x5c\x6e\x55\xc3\xc1\xb5\xbd\x9a\xa0\x1c\x20\xd8\x36\x80\xf2\xa5\x31\xda\xa9\xac\x22\x58\x19\x0b\x51\x31\x6f\x95\x2e\xe5\x4e\x32\x90\xc7\x1b\xd1\xd4\x64\x3f\x51\xce\x03\xb2\xa5\x9f\xbd\xb2\x54\x0c\x9f\x16\xc5\xbb\x84\x18\x90\x1b\x2b\x91\xe0\x81\x97\xe3\x67\x90\x7e\x3b\xf4\x3d\x1b\x9e\x88\xa1\x91\x0f\x0a\xc9\x3c\x72\xc0\x6b\xea\x5c\x46\x45\xeb\x1d\x30\x2b\xe0\xb5\x72\x60\xa9\xb1\xe4\x48\xc7\x5c\x14\x32\xea\xd6\x80\x04\x2e\xc8\xca\x45\x70\x6b\xe3\xab\x42\x0c\xbf\x21\xcb\x60\x29\x37\xa5\x56\xbf\xf4\xd2\x1c\xb0\x09\xcf\x54\xc8\xe4\x18\x94\x66\xb2\x1a\x2b\xb8\xc1\xca\xd3\x14\x50\x17\x50\xe3\x06\x2c\x89\x5c\xf0\x7a\x20\x21\xb0\xb8\x04\xce\x8d\x25\x50\x7a\x65\x52\x58\x33\x37\x2e\x9d\xcf\x4b\xc5\x5d\x71\xe5\xa6\xae\xbd\x56\xbc\x99\x87\x3a\x51\x99\x97\x5c\x9d\x17\x74\x43\xd5\xdc\xa9\x72\x86\x36\x5f\x2b\xa6\x9c\xbd\xa5\x39\x36\x6a\x16\x94\xd5\xa1\xc0\x92\xba\xf8\xbf\x2e\x9a\xee\xc9\x9e\xfb\x62\xc8\x1c\x4b\x38\x77\x8e\x42\x4e\x3f\xe8\x6b\xc9\xee\x98\x2b\xf1\x7a\xb4\x65\xeb\x52\x21\x89\x57\x3e\xff\xfd\xe2\x72\x9b\x4e\xc1\xed\xd1\xc3\x5b\x56\xb7\x75\xb6\x38\x4a\xe9\x15\xd9\xc8\xb9\xb2\xa6\x0e\x52\x48\x17\x8d\x51\x9a\xc3\x8f\xbc\x52\xa4\x19\x9c\xcf\x6a\xc5\x2e\x24\x18\x39\x96\x38\x24\xb0\x08\xd8\x02\x19\x81\x6f\x0a\x64\x2a\x12\x78\xaf\x61\x81\x35\x55\x0b\x74\xf4\xa7\xbb\x5a\x3c\xea\x66\xe2\xbe\xc7\x3b\x7b\x08\x8d\xf7\x2f\xdc\x2b\x28\x80\x0e\xbe\x46\xa3\xd3\x57\xf3\x45\x43\xb9\x44\x49\xdc\x26\xb7\x42\x0d\xa3\x1e\x94\x7b\x17\x9a\xe4\xb1\x8f\x8f\x97\xa9\x7c\x56\x84\xe2\x9a\x03\x27\x7b\x2a\x9e\xb5\x8c\x01\xfb\x51\xe9\xa8\xa3\xe0\xa6\xd4\x61\x07\x33\x28\xb8\xf3\xc3\xc7\xf3\x5e\xee\xbe\x9a\xdf\x50\xf5\x5b\xea\x06\xb5\x94\x93\x67\x16\xa6\x51\x54\x2c\x2e\xbe\x8c\xb0\xed\xe9\xff\x6e\xff\x96\xb8\xd9\x3b\x2a\x04\x0e\x5a\x91\xa2\xf9\x13\x07\x93\xc8\x04\x8b\x8b\x2f\x93\xce\x90\x10\x88\xbe\xef\x80\xd2\x8e\xb1\xaa\xa8\x00\xec\x72\x3c\x00\x7e\xc4\xff\x29\xdc\xae\xc9\x12\xe0\x2e\xb9\xe8\x05\xc8\xdb\x46\x4b\x79\x21\xc3\x1a\x1d\x64\x44\x7a\x20\x54\xe9\x10\xf4\x96\xfb\x7b\xe9\x7a\x91\x97\xd1\x96\xc4\x0e\xb0\xaa\x62\xbb\x6b\x30\x17\x40\xfa\xd7\x9a\x34\x58\x22\x2d\x66\x14\xd3\x10\x82\x5b\x55\x55\x02\x7f\xd2\x7b\x29\x28\x39\x30\xcc\x4d\x82\x45\x84\xf9\x7a\x4c\xc9\x43\xa1\xdb\x86\x2f\x33\xa6\x22\xd4\xbb\x79\xce\xc8\xfe\x5e\x38\x46\x32\x3d\xf0\xf6\xb9\x1e\x7f\xfd\xd9\xd9\x9e\x1b\x5d\xa8\xc1\x1c\x73\x48\x28\x5a\x8b\x9b\x03\xa7\x8a\xa9\x1e\xcb\xc8\xa1\x85\x93\x45\xf7\xc8\xb6\x54\x0a\x62\x54\x55\xb4\x4f\xe2\x8e\x52\xdb\x1c\xfb\x1a\x41\xee\xad\x0d\x00\xc9\x12\xa8\xae\xd9\xbd\xfd\xf4\x1e\xba\xb9\x2c\x81\xd9\x6c\x06\x97\x42\x76\x6c\x7d\xce\xe2\x37\x69\x5c\xba\xa0\x22\x48\x2d\x94\x0d\xdd\xca\x89\x70\xf1\x61\x30\xa3\xcb\xce\x95\xa2\xaa\x80\x06\x79\x0d\x49\x74\x75\xb2\x75\x45\x02\x70\x26\xa9\x70\x87\x75\x53\xd1\x14\x96\x3a\x78\x02\xce\x8c\x69\x83\x14\xdf\xfc\x15\xe6\x73\xf8\xdc\x37\x81\x20\xd8\x64\x8e\xec\x4d\x1c\x0d\x43\x3f\x86\x95\x31\x4f\xdc\xae\x49\x89\x5c\xfc\xa0\xcd\xad\x3e\xf4\x7a\x78\x0b\x2d\xa5\xb0\x9c\xbc\xbd\x41\x55\x49\x0a\x2f\x27\x53\x58\x4e\x3e\x59\x53\x5a\x72\x32\x69\x09\x41\x3a\xf3\x72\xf2\x8e\x4a\x8b\x05\x15\xcb\x89\x88\xfd\x4b\x83\x9c\xaf\xcf\xc9\x96\xf4\x81\x36\xaf\x83\xb0\x9e\x7c\xc1\x56\xe6\xc0\xcd\xeb\x5a\xce\x03\x5d\x00\xeb\x72\xd3\xd0\xeb\x1a\x9b\x9e\x70\x8e\x4d\x7f\xb9\x8f\x9e\x83\xab\x6b\x41\xfa\x9b\xd3\x64\x1b\xd1\x1f\x7f\x72\x46\xa7\xcb\xc9\x56\xff\xa9\xa9\x25\x33\x1a\xde\x2c\x27\xb0\xf3\x6a\xba\x9c\x84\x77\x3b\x7a\xa7\x64\xba\x9c\xc8\x4b\x42\xb6\x86\x4d\xe6\x57\xe9\x72\x92\x6d\x98\xdc\xf4\x74\x6a\xa9\x99\x4a\x61\xbf\xde\xbe\xb0\x9c\xfc\x28\x31\x99\xcf\xc1\xf0\x9a\x6c\x0c\xa6\x83\xdf\x26\x07\x73\xf1\x1b\xe0\x3a\x36\xdf\x6d\x3f\x33\xa8\xd0\xf1\xa5\x45\xed\x54\x37\xb3\x8f\xb2\xd6\xe4\x1c\x96\xe3\xe7\x96\xd0\x19\x3d\x7a\x1c\xb3\x61\xf4\x58\x6c\x39\x78\xf8\xad\x16\x01\x07\x6c\x18\xe3\xdc\x2b\xdf\xfb\x17\x3b\x8c\x92\x13\x60\x21\x84\xa2\xed\x73\x82\x7b\x6e\xa9\x45\x99\x80\xa4\xc4\x5b\x44\x63\x03\xa8\x43\xdc\x92\xb6\x7e\xe3\x78\x9a\x91\xf4\x08\x1d\x44\x79\x5d\x90\xad\x36\x32\x81\x6d\xa5\xe6\x6b\xd4\xa5\x8c\x43\xf0\x7e\x15\xb1\x5f\x39\x90\x51\xe9\xab\x14\xd2\x54\x2e\x6a\xf0\xae\x1b\xdb\x82\x5e\xbd\x44\xc1\x8e\x58\xf3\xad\x98\x30\xf9\xe5\x39\x35\x2c\xd5\x35\x86\xec\x0f\xcc\x3c\xc3\xcf\xca\xd8\x1a\x39\x05\x99\xd7\x66\x3c\x9e\x1e\x6d\x72\x3c\xd2\xf1\x2d\x77\x9c\x51\xd7\xbe\x46\x69\x68\x58\x84\xbe\xdc\x9f\xe9\x42\xe5\x18\x66\xd5\x0e\x52\x31\x33\x3e\x82\xdc\x36\x0e\xad\xab\x65\x38\xcd\x48\xc0\x30\xd4\x67\x6b\xd6\xef\x34\xbe\xc6\xbb\x8f\xa4\x4b\x5e\xa7\xf0\xe2\xf9\xdf\x5e\x7e\x37\xc2\x18\x81\x91\x8a\xef\x49\x4b\x37\x3d\xb0\x0a\x8d\xb8\xe1\xfe\xc5\xc1\xe0\x1d\xec\x4c\xba\xf9\x33\x29\xb7\x3c\x71\x3a\xd8\xc9\xcb\x5b\x74\xe0\x88\x21\x43\x99\x72\x7c\x23\x7e\x11\xa0\x0f\x63\x86\xce\x69\x0a\x6a\x75\x58\x98\xea\x01\xbc\xda\xc0\xe9\xf3\x29\x64\xad\x8b\xef\xc3\xf7\xd5\xdd\x75\x72\x40\x65\xe5\xe0\xd5\x74\x4f\x1f\x99\x79\x7c\x68\x7a\x92\x38\x70\xab\x78\x1d\xd6\x55\xe9\x5b\xed\x4a\x76\xa0\x13\x52\xaf\xef\xb7\x02\x27\xfd\xb0\x0c\x3b\xf7\xe1\x4f\x97\xb6\x4a\xf3\xcb\xbf\x8e\xc7\x57\x69\x55\xfb\x3a\x85\x67\x23\x2c\x11\xd2\x1e\x19\xcd\xc8\xbc\x1d\x04\x50\xa0\xab\xb4\x58\xd7\xc8\x2a\x07\x55\xc8\x2a\xb2\x52\x64\x87\xa9\x2d\x46\xb7\x17\xa5\xb5\xef\x78\xf1\x89\x6b\x71\x68\x90\xec\x9f\xac\x29\x7c\x2e\xeb\x98\x59\x85\xad\x41\xad\x54\x3e\x04\x28\xd9\x71\x42\x35\xc4\x2d\x1b\xe8\x4e\x9c\xde\xef\xb3\x71\xe5\x25\xd4\x4a\x97\xae\x7d\x52\x96\x39\x01\x90\xd8\x75\x6f\xd7\x14\x5a\x4f\xd8\xce\xdb\x3b\x36\x68\xe5\x54\x41\x56\xc6\x60\x28\x3d\x5a\xd4\x4c\x54\x08\xfc\x48\x09\xb6\xbc\x03\xc8\xc3\xed\x66\xd7\x55\x63\x2c\xd5\x08\x56\xa2\x62\xbb\x0d\x86\x8a\xfd\xe3\x4a\xf5\xf4\xd9\xf3\x07\x43\xde\xf3\x8d\x32\x35\xc8\x4c\x56\xa7\xf0\x9f\xab\xb7\xb3\x7f\xe3\xec\x97\xeb\xe3\xf6\xcb\xb3\xd9\xab\xff\x4e\xd3\xeb\xa7\x83\x9f\xd7\x27\x6f\xfe\x7f\x44\xd2\xe1\x19\x79\x24\x7d\xda\x26\xd2\xcd\x89\x5d\x44\xa7\xa1\xc3\x98\x15\x5c\x5a\x4f\x53\x38\xc3\xca\xd1\x14\xfe\xa9\x43\x6b\xf8\x9d\x4e\x23\xed\xeb\x71\xed\xa4\x2b\x4f\xe4\xd5\xc3\xc3\x47\xcf\x12\x54\x7a\x98\xa7\x55\xf7\xa1\x25\xe3\x71\x4e\x0a\x63\x5b\xdc\x41\x3b\xa4\x19\xfc\x07\x01\x02\xe2\xc9\x58\x9a\xb4\x13\x6e\x92\x9b\x7a\x3e\xf8\x0f\x83\x8c\xd6\xe7\xa8\x37\xb0\x85\xb5\x38\x94\xee\x67\xba\x63\xc1\x26\xcc\xad\x71\xae\xdf\x4c\x1c\x54\xea\x2b\x41\x3f\xb9\x46\xb0\xcc\x28\xc7\x30\x8b\xdb\x4c\xb1\x45\xbb\x19\xac\x1e\x90\xa3\x0e\xff\xf0\x70\xb4\xf2\x15\x1c\x3b\x22\x48\xb4\x29\xe8\x3e\xba\x9e\x44\x0c\xc5\x4c\x55\x8a\x37\x61\x53\x25\x59\xb5\x2b\xd5\xae\x00\x75\x63\x2c\xa3\xe6\x58\x6e\x96\x4a\xba\x03\xc5\x50\xcb\xbc\x49\x61\xbb\x3a\x2e\xb4\x3b\x3d\x7d\xfe\xe2\xc2\x67\x85\xa9\x51\xe9\xb3\x9a\xe7\x27\x6f\x8e\x7f\xf6\x58\x09\xf2\x14\xff\xc0\x9a\xce\x6a\x3e\xf9\xe3\xda\xe2\xe9\xcb\x47\x54\xd1\xf1\x55\xac\x95\xeb\xe3\xab\x59\xfb\xed\x69\x47\x3a\x79\x73\xbc\x4c\x1e\x3c\x3f\x79\x2a\x36\x0c\x2a\xf0\xfa\x6a\xb6\x2d\xbf\xe4\xfa\xe9\xc9\x9b\xc1\xd9\x49\x57\x8c\xb1\x4f\xa5\xc0\xd6\x77\x43\x8b\x63\x63\x65\x48\xd9\xa1\xf9\xac\x0f\xef\x36\x09\xdb\xca\x85\x5f\x7f\x3b\xfa\x5f\x00\x00\x00\xff\xff\x1e\x16\x84\x1b\x60\x17\x00\x00") func operatorsCoreosCom_olmconfigsYamlBytes() ([]byte, error) { return bindataRead( @@ -165,7 +165,7 @@ func operatorsCoreosCom_olmconfigsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorconditionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\xdd\x6f\x1b\xb9\x11\x7f\xf7\x5f\x31\x50\x0b\xc4\x4e\xa5\x55\x9c\x2b\xae\x39\x01\x41\x10\xe4\x9a\x22\x48\x7c\x09\x62\xf7\x1e\x6a\xb9\xcd\xec\x72\x24\xf1\xb2\x4b\xee\x91\x5c\xd9\xba\xc3\xfd\xef\xc5\x90\xfb\x25\x69\xa5\xf8\x90\x34\x68\x0b\xf2\xc5\x12\x3f\x86\xc3\xf9\xfe\xd1\x14\x96\xf2\x47\x32\x56\x6a\x35\x03\x2c\x25\xdd\x39\x52\xfc\xcd\x26\x1f\x9f\xd8\x44\xea\xe9\xfa\xfc\xe4\xa3\x54\x62\x06\x2f\x2a\xeb\x74\xf1\x9e\xac\xae\x4c\x46\xdf\xd3\x42\x2a\xe9\xa4\x56\x27\x05\x39\x14\xe8\x70\x76\x02\x80\x4a\x69\x87\xdc\x6d\xf9\x2b\x40\xa6\x95\x33\x3a\xcf\xc9\x4c\x96\xa4\x92\x8f\x55\x4a\x69\x25\x73\x41\xc6\x13\x6f\xb6\x5e\x3f\x4a\x9e\x24\x8f\x4e\x00\x32\x43\x7e\xf9\x95\x2c\xc8\x3a\x2c\xca\x19\xa8\x2a\xcf\x4f\x00\x14\x16\x34\x03\x5d\x92\x41\xa7\x4d\xa6\x95\xf0\xdb\xdb\xa4\xe9\xb2\x49\xa6\x0d\x69\xfe\x53\x9c\xd8\x92\x32\xe6\x60\x69\x74\x55\x76\xcb\xb6\xe6\x04\x9a\x0d\xa3\xe8\x68\xa9\x8d\x6c\xbe\x03\x4c\x40\xe7\x85\xff\x1c\x04\xf0\xb6\xa6\xf1\xa2\xd9\xda\x8f\xe5\xd2\xba\xd7\xc3\xe3\x6f\xa4\x75\x7e\x4e\x99\x57\x06\xf3\x21\xe6\xfd\xb0\x5d\x69\xe3\x7e\xe8\x58\xe1\xad\xb3\xad\x4d\xac\x54\xcb\x2a\x47\x33\x40\xe2\x04\xc0\x66\xba\xa4\x19\x78\x0a\x25\x66\x24\x4e\x00\x6a\xc9\xd6\x14\x27\xb5\xf4\xd6\xe7\xf5\x06\x36\x5b\x51\x81\xcd\x76\xc0\x64\xd5\xf3\x77\xaf\x7e\xfc\xe6\x72\x67\x00\x40\x90\xcd\x8c\x2c\x9d\xd7\xd3\xde\x19\x41\x5a\xc0\xda\x36\xa0\x31\x0e\xd0\x0b\x70\x9b\x92\xe0\xc3\xde\xfc\x0f\x70\xbb\x92\xd9\x8a\x97\x55\x96\x04\x38\xcd\x47\x5d\xd3\x06\xa4\x5a\x68\x53\x78\xe5\x73\xef\xdb\x37\x17\x80\xa9\xae\x1c\xb8\x15\x81\x75\xe8\x3c\x59\x54\xad\x08\x92\x1e\x93\xbc\xdb\x0c\x74\xfa\x13\x65\xae\xd7\x6d\xe8\xe7\x4a\x1a\x12\xfd\xf3\xb0\x34\x1a\x93\xed\x75\x97\x86\xe9\xba\x9e\xfe\x43\xeb\x39\xc8\x56\xff\x8e\x60\x1e\xb0\xf4\xc2\x3c\x10\xec\x1b\x64\x3d\xe3\xb5\x1e\x48\xd4\x22\xf7\xa2\x59\x49\x0b\x86\x4a\x43\x96\x54\xf0\x96\xe6\x68\xfe\x00\x09\x5c\x92\xe1\x85\x6c\x19\x55\x2e\x82\x84\x8c\x03\x43\x99\x5e\x2a\xf9\x4b\x4b\xcd\xb2\xa4\x78\x9b\x1c\x1d\x59\x07\x52\x39\x32\x0a\x73\x58\x63\x5e\xd1\x18\x50\x09\x28\x70\x03\x86\x98\x2e\x54\xaa\x47\xc1\x4f\xb1\x09\x5c\x68\x43\x5e\xf8\x33\x58\x39\x57\xda\xd9\x74\xba\x94\xae\x71\xff\x4c\x17\x45\xa5\xa4\xdb\x4c\xbd\x27\xcb\xb4\x62\x2f\x9a\x0a\x5a\x53\x3e\xb5\x72\x39\x41\x93\xad\xa4\xa3\xcc\x55\x86\xa6\x58\xca\x89\x67\x56\x05\xd7\x2c\xc4\x1f\x4c\x6d\x13\xf6\xc1\x8e\xf8\x82\xca\xac\x33\x52\x2d\xb7\x86\xbc\xb7\x1d\x95\x35\xfb\x5b\x30\xbc\xb0\x3c\x9c\xa5\x13\x29\x77\xb1\x54\xde\xff\xf5\xf2\x0a\x1a\x06\x82\xd8\x83\x84\xbb\xa9\xb6\x13\x36\x0b\x4a\xaa\x05\x99\x30\x73\x61\x74\xe1\xa9\x90\x12\xa5\x96\x2a\x18\x62\x96\x4b\x52\x0e\x6c\x95\x16\xd2\x59\x6f\x60\x64\x1d\xeb\x21\x81\x17\x3e\xfa\x41\x4a\x50\x95\x02\x1d\x89\x04\x5e\x29\x78\x81\x05\xe5\x2f\xd0\xd2\x7f\x5c\xd4\x2c\x51\x3b\x61\xf1\xdd\x5f\xd8\xfd\xe0\xbd\xbf\x60\xcf\xa1\x00\x9a\xc0\x7a\x50\x3b\x7b\x2e\x7f\x59\x52\x06\x98\xe7\xfa\x96\x35\x96\xe5\x95\x75\x64\x00\x45\x21\xd5\x01\xf7\x3f\xee\xf7\x75\x74\x18\x43\xa9\x1d\x9f\x1e\xf3\x7c\x03\x7a\x4d\xc6\x48\xc1\x9a\x0f\x6b\x0c\x95\xda\x38\x12\x90\x6e\x3c\xa5\xa1\xa8\x71\xf4\xa0\x87\x43\x42\x38\x72\x99\xeb\x4d\xc1\x16\xb4\x3f\xd8\x50\x45\x63\x70\x33\x30\x2a\x1d\x15\x83\xcb\x8e\x28\x8a\x5b\x7d\xc8\x21\x7e\x3e\x63\xcb\x2d\xed\x8d\xba\xc8\xce\x56\x88\x52\x59\x10\xe4\x50\xe6\x16\x16\xda\x80\x56\x04\xc8\x36\xe0\x42\x24\x23\xc8\x2a\x63\xbc\x4b\x34\xaa\xf2\xde\xf3\xfc\xdd\xab\x36\x1d\x24\x30\x99\x4c\xe0\x8a\xbb\xad\x33\x55\xe6\xd8\x77\x39\x54\x29\x41\xc2\x53\x15\xd2\xf8\xf8\x64\x99\x38\xeb\xda\x1f\x03\x30\x18\xc1\x42\x52\x2e\xa0\x44\xb7\x82\x84\x77\xa9\x38\x7d\xb7\xe9\x1f\xe0\xa5\x36\x40\x77\x58\x94\x39\x8d\x43\xde\x79\xa9\xf5\xa5\x9f\x58\x6f\xf8\x2b\x4c\xa7\xf0\xbe\xf5\xf9\x60\x10\xa9\x25\xb3\x0e\xb5\x8a\xb7\x30\x58\x68\xfd\xc0\x6e\x9f\x27\xe1\x85\xaf\x95\xbe\x55\x43\x5b\xfb\xbd\xd0\xd0\x0c\xe6\xa3\xe7\x6b\x94\x39\xa6\x39\xcd\x47\x63\x98\x8f\xde\x19\xbd\x34\x64\x39\x71\x73\x07\x07\xe2\xf9\xe8\x7b\x5a\x1a\x14\x24\xe6\x23\x26\xfb\xa7\x12\x5d\xb6\xba\x20\xb3\xa4\xd7\xb4\x79\xea\x89\xb5\xdd\x97\xce\x70\x41\xb2\x79\x5a\xf0\xb8\xef\xe7\x4a\xe3\x6a\x53\xd2\xd3\x02\xcb\xb6\xe3\x02\xcb\x76\x71\xab\x3a\x0b\xd7\x37\xec\xd8\xeb\xf3\xa4\x53\xe7\x87\x9f\xac\x56\xb3\xf9\xa8\xe3\x7f\xac\x0b\x36\x8b\xd2\x6d\xe6\x23\xd8\xda\x75\x36\x1f\xf9\x7d\x9b\xfe\x86\xc9\xd9\x7c\xc4\x3b\x71\xb7\xd1\x4e\xa7\xd5\x62\x36\x1f\xa5\x1b\x47\x76\x7c\x3e\x36\x54\x8e\xb9\xcc\x78\xda\xed\x30\x1f\x7d\x80\xb9\x62\x66\xb5\x5b\x91\x09\x9a\xb4\xf0\xdb\xe8\x88\xed\x0f\xba\x62\x68\xc3\xe9\xbc\x6b\x9c\xd8\xad\xc5\x25\x1d\x1c\x37\x84\xb6\xae\xa9\x86\x86\x83\x8a\x0f\x0e\x33\x83\x83\x83\xc7\x22\x45\x68\x39\x5a\x77\x65\x50\x59\xd9\x54\xb7\x87\x66\xee\x38\xe4\xfe\x42\xf6\x9e\x90\xf3\xad\x03\xc7\x1d\xde\x0d\x5b\x45\xbb\x76\x36\x7b\x17\x67\x31\x76\xda\x70\x34\x8e\x9d\xa8\xbc\x32\x92\xda\x23\x43\x89\x91\x12\xdc\xae\x48\x79\x52\x95\x12\x64\xf2\x0d\xc7\xd2\x8e\x6a\xb6\x42\xb5\xe4\x94\x06\xaf\xd8\xc5\xd1\x3b\x31\xa7\xbb\x8f\xec\x1d\x63\x5e\xa8\xa0\xb2\x4d\xea\xf5\x7c\xb5\x14\x39\x1a\x04\x2f\xae\xc9\xf8\xec\x9d\x65\x54\x3a\x76\x99\xdd\x98\xdc\xb5\xa3\xe1\xb0\x69\x21\x71\xcc\x80\x73\xee\x84\x37\x3e\x30\xb3\x36\x8e\x7b\x0a\xbe\x9e\x1d\xea\x8c\x55\x55\xa0\x62\xeb\x11\xcc\x6f\x37\xa6\x84\xcc\xd0\xd7\x1b\x4d\x90\xec\x72\x57\xa7\x87\x5a\xd4\x5c\x60\xa4\xc4\xe1\xcd\x3b\x5d\x7d\xac\xcf\x3c\x7c\x81\x77\x6f\x48\x2d\xdd\x6a\x06\xdf\x3c\xfe\xcb\xb7\x4f\x0e\x4c\x0c\xd1\x8e\xc4\xdf\x48\x71\x1e\x1c\x28\x67\x0f\x88\x61\x7f\x61\xaf\x78\xf2\xe7\x4c\x9a\x1a\x22\x59\x76\x73\xbc\x85\x6c\xdb\xe5\x2d\x5a\xb0\xe4\x20\x45\x2e\xfc\xab\x92\xe5\xc2\xa1\x5b\x2a\xeb\x50\x65\x34\x06\xb9\x18\x26\x26\xdb\xa8\x9c\x6f\xe0\xfc\xf1\x18\xd2\x5a\xc4\xfb\x31\xf9\xfa\xee\x26\x19\x60\x59\x5a\xf8\x6e\xbc\xc3\x0f\x57\x83\x95\x4f\x63\x6c\x38\x70\x2b\xdd\x8a\x8b\x45\x9f\xdb\xea\xb2\x7a\x20\xb7\x51\xcb\xef\xa7\x14\xc7\x19\x6e\x49\xe6\x93\x66\x2b\x95\xfb\xf6\xcf\x87\xf5\x2b\x95\x2c\xaa\x62\x06\x8f\x0e\x4c\x09\x21\xed\x9e\xda\x0c\x93\xbb\xd4\x8e\x1c\xba\x96\x06\x0b\xae\xbc\x32\x90\x82\x0b\xaa\x85\x24\xd3\x37\x6d\x3e\x74\xbd\x90\x93\xf5\x96\x14\x1f\xd8\x3a\x0e\xf5\x8c\xfd\x9d\xd1\xa2\xca\xb8\xa4\xd6\x0b\x5f\x2f\xca\x85\xcc\xfa\x01\x8a\xeb\x54\xef\x0d\x01\x29\x01\xdd\xb1\xd0\x5b\x4c\x12\x60\x0b\xa1\x92\x6a\x69\xeb\x2d\xb9\x20\xe7\x00\x12\x52\xe9\xed\x8a\x7c\x3e\xf1\x08\xab\x5e\x63\x3c\x57\x56\x0a\x32\x24\x00\x61\x59\xa1\x41\xe5\x88\x04\x87\x1f\x76\xc1\x7a\x6e\x2f\xe4\x61\x57\x9d\x37\xde\x18\x5c\x35\x04\x2b\x66\xb1\xae\xe8\xbd\xc7\x7e\x39\x57\x3d\x7f\xf4\xf8\xa8\xca\xdb\x79\x07\x27\x95\xe8\x18\xeb\xcd\xe0\x9f\xd7\xcf\x27\xff\xc0\xc9\x2f\x37\xa7\xf5\x87\x47\x93\xef\xfe\x35\x9e\xdd\x3c\xec\x7d\xbd\x39\x7b\xf6\xc7\x03\x94\x82\x07\xdd\xd3\x7c\xea\x24\xd2\x54\x7e\x8d\x46\xc7\x3e\xc3\xe8\x05\x5c\x19\x46\x9d\x2f\x31\xb7\x34\x86\xbf\x2b\x9f\x1a\x3e\x53\x68\xa4\xaa\xe2\x30\x77\x9c\x95\x47\xbc\xeb\x70\x45\xd1\x4e\xf1\x2c\x1d\x9f\x53\xb3\x7b\x60\x8e\xe7\xf5\x7e\x42\xf2\xb5\x98\x5e\xf4\x23\x4d\x0f\x05\x82\x8f\x78\x5c\x6b\x26\x75\xcd\x9a\x64\xba\x98\xf6\x50\x22\x17\xcb\x17\xa8\x36\xd0\x85\xb5\x50\x69\xee\x5a\xba\x65\xf8\x03\x98\x19\x6d\x6d\x0b\x73\x2d\xe4\xf2\x23\x41\x5b\x8e\x86\x60\x99\x52\x86\xbe\xba\x36\xa9\x74\x06\xcd\xa6\xe3\xce\x42\x86\xca\x83\x56\x4b\x8b\x2a\x87\x53\x4b\x04\x89\xd2\x82\xf6\xa3\xeb\x59\x88\xa1\x98\xca\x5c\xba\x0d\x47\x49\x41\x99\x56\x8b\x5c\xd6\x45\x7d\xc1\xa0\x0b\x95\x0b\xee\x66\x68\x49\x77\x20\x1d\x14\x5c\x44\x92\xe5\x29\xa7\x42\xd9\xf3\xf3\xc7\xdf\x5c\x56\xa9\xd0\x05\x4a\xf5\xb2\x70\xd3\xb3\x67\xa7\x3f\x57\x98\x73\xe4\x11\x3f\x60\x41\x2f\x0b\x77\xf6\xe5\xd2\xe2\xf9\xb7\xf7\xf0\xa2\xd3\xeb\xe0\x2b\x37\xa7\xd7\x93\xfa\xd3\xc3\xa6\xeb\xec\xd9\xe9\x3c\x39\x3a\x7e\xf6\x90\xcf\xd0\xf3\xc0\x9b\xeb\x49\xe7\x7e\xc9\xcd\xc3\xb3\x67\xbd\xb1\xb3\x7d\x67\xe4\x8c\x25\x33\x7a\x9e\x65\xba\xfa\x6a\x98\x72\xd8\xf7\x3f\x81\xe6\x43\x08\x68\xf0\xfc\x36\x2c\x1f\xc0\xf2\xd2\xd9\x3a\x7d\x06\xd8\x1e\x2c\xa3\x0e\x24\x1c\x60\x9d\x41\x99\x07\xb3\xca\x5c\x85\x79\x0f\xf3\x83\xdd\x58\x47\xc5\x17\x82\xec\x9d\x19\x47\xf8\x1c\xe1\x73\x84\xcf\x7b\x6d\x32\x00\x36\x23\xd2\x8e\x48\xbb\x6b\x11\x69\x47\xa4\x1d\x91\xf6\xbd\xb4\x19\x91\x76\x44\xda\xdb\x2d\x22\xed\x7a\x4e\x44\xda\x11\x69\x7f\x6d\xa4\x1d\xf2\xd4\x0c\x9c\xa9\x9a\xa2\xc5\x3a\x6d\xb8\x48\x81\x05\x9b\x6c\xd3\x59\xa5\xad\x7e\x3b\x2b\xac\x5d\x17\x7e\xfd\x6d\xfb\x39\xcd\xe3\xf8\x9c\x26\x3e\xa7\x89\xcf\x69\xe2\x73\x9a\xa6\x7d\xed\xe7\x34\xdb\xd7\x6f\xe1\xcd\xcb\xd6\x75\x9b\xb7\xd9\xd2\xe8\xb5\x14\x64\x77\x1e\xdf\xf8\x3a\x7c\x27\xcb\x14\xa8\xaa\xfe\x83\x1a\xfa\x3a\xcf\x69\xe2\xdd\x5c\xbc\x9b\x8b\x77\x73\xf1\x6e\xae\xd7\xe2\xdd\x5c\xdb\xe2\xdd\x5c\xbc\x9b\x8b\x77\x73\xf1\x6e\x2e\xde\xcd\xed\xb6\x78\x37\x17\x5a\xbc\x9b\x8b\x77\x73\x03\xed\x7f\xe3\x6e\xae\x6f\x41\xf1\x57\x15\x11\x7a\x46\xe8\xf9\x5f\x06\x3d\x23\x9e\x8c\x78\x32\xe2\xc9\x81\x16\xf1\x64\xc4\x93\x11\x4f\x46\x3c\xb9\xd7\x22\x9e\xac\xe7\x44\x3c\x19\xf1\x64\xfc\x55\xc5\xef\xfc\x55\xc5\xdb\x37\x17\xbd\x97\x1c\xe1\x85\x47\xcf\xb2\x56\xb8\x26\x48\x89\x54\x5b\x46\xc4\xff\xc2\x46\x28\x1c\xa1\x70\xfc\x2f\x2c\x44\xd4\x1c\x51\x73\x44\xcd\x11\x35\xef\x2a\x2e\xa2\xe6\x88\x9a\xb7\x55\x19\x51\xf3\xef\x17\x5a\x44\xcd\x11\x35\x0f\xa8\xe2\xff\x03\x35\x1f\xfb\x85\x44\xbf\xef\x53\x3f\x90\xf8\x77\x00\x00\x00\xff\xff\x79\xf0\xdc\xa4\x52\x56\x00\x00") +var _operatorsCoreosCom_operatorconditionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x5f\x6f\x1b\xb9\x11\x7f\xf7\xa7\x18\xa8\x05\x62\xa7\xd2\x2a\x4e\x8a\xf4\x22\x20\x08\x82\x5c\x53\x04\x89\x2f\x41\xec\xde\x43\x2d\xb7\x99\x5d\x8e\x24\x9e\x77\xc9\x3d\x92\x2b\x5b\x77\xb8\xef\x5e\x0c\xb9\xff\x64\xad\x14\x1f\x92\x06\x6d\x41\xbe\x58\x22\x87\x43\x72\xfe\xff\x68\x0a\x4b\xf9\x23\x19\x2b\xb5\x9a\x01\x96\x92\x6e\x1d\x29\xfe\x66\x93\xeb\xef\x6c\x22\xf5\x74\x7d\x7a\x74\x2d\x95\x98\xc1\xab\xca\x3a\x5d\x7c\x24\xab\x2b\x93\xd1\xf7\xb4\x90\x4a\x3a\xa9\xd5\x51\x41\x0e\x05\x3a\x9c\x1d\x01\xa0\x52\xda\x21\x77\x5b\xfe\x0a\x90\x69\xe5\x8c\xce\x73\x32\x93\x25\xa9\xe4\xba\x4a\x29\xad\x64\x2e\xc8\x78\xe6\xcd\xd2\xeb\x47\xc9\xb3\xe4\xd1\x11\x40\x66\xc8\x4f\xbf\x90\x05\x59\x87\x45\x39\x03\x55\xe5\xf9\x11\x80\xc2\x82\x66\xa0\x4b\x32\xe8\xb4\xc9\xb4\x12\x7e\x79\x9b\x34\x5d\x36\xc9\xb4\x21\xcd\x7f\x8a\x23\x5b\x52\xc6\x3b\x58\x1a\x5d\x95\xdd\xb4\x2d\x9a\xc0\xb3\xd9\x28\x3a\x5a\x6a\x23\x9b\xef\x00\x13\xd0\x79\xe1\x3f\x07\x01\xbc\xaf\x79\xbc\x6a\x96\xf6\x63\xb9\xb4\xee\xed\xf0\xf8\x3b\x69\x9d\xa7\x29\xf3\xca\x60\x3e\xb4\x79\x3f\x6c\x57\xda\xb8\x1f\xba\xad\xf0\xd2\xd9\xd6\x22\x56\xaa\x65\x95\xa3\x19\x60\x71\x04\x60\x33\x5d\xd2\x0c\x3c\x87\x12\x33\x12\x47\x00\xb5\x64\x6b\x8e\x93\x5a\x7a\xeb\xd3\x7a\x01\x9b\xad\xa8\xc0\x66\x39\x60\xb6\xea\xe5\x87\x37\x3f\x3e\x39\xbf\x33\x00\x20\xc8\x66\x46\x96\xce\xeb\x69\xe7\x8c\x20\x2d\x60\x6d\x1b\xd0\x18\x07\xe8\x05\xb8\x4d\x49\xf0\x69\x87\xfe\x13\xdc\xac\x64\xb6\xe2\x69\x95\x25\x01\x4e\xf3\x51\xd7\xb4\x01\xa9\x16\xda\x14\x5e\xf9\xdc\xfb\xfe\xdd\x19\x60\xaa\x2b\x07\x6e\x45\x60\x1d\x3a\xcf\x16\x55\x2b\x82\xa4\xb7\x49\x5e\x6d\x06\x3a\xfd\x89\x32\xd7\xeb\x36\xf4\x73\x25\x0d\x89\xfe\x79\x58\x1a\x8d\xc9\xf6\xba\x4b\xc3\x7c\x5d\x4f\xff\xa1\xf5\x1c\x64\xab\xff\x8e\x60\x1e\xb0\xf4\x02\x1d\x08\xf6\x0d\xb2\x7e\xe3\xb5\x1e\x48\xd4\x22\xf7\xa2\x59\x49\x0b\x86\x4a\x43\x96\x54\xf0\x96\xe6\x68\xfe\x00\x09\x9c\x93\xe1\x89\x6c\x19\x55\x2e\x82\x84\x8c\x03\x43\x99\x5e\x2a\xf9\x4b\xcb\xcd\xb2\xa4\x78\x99\x1c\x1d\x59\x07\x52\x39\x32\x0a\x73\x58\x63\x5e\xd1\x18\x50\x09\x28\x70\x03\x86\x98\x2f\x54\xaa\xc7\xc1\x93\xd8\x04\xce\xb4\x21\x2f\xfc\x19\xac\x9c\x2b\xed\x6c\x3a\x5d\x4a\xd7\xb8\x7f\xa6\x8b\xa2\x52\xd2\x6d\xa6\xde\x93\x65\x5a\xb1\x17\x4d\x05\xad\x29\x9f\x5a\xb9\x9c\xa0\xc9\x56\xd2\x51\xe6\x2a\x43\x53\x2c\xe5\xc4\x6f\x56\x05\xd7\x2c\xc4\x1f\x4c\x6d\x13\xf6\xc1\x1d\xf1\x05\x95\x59\x67\xa4\x5a\x6e\x0d\x79\x6f\x3b\x28\x6b\xf6\xb7\x60\x78\x61\x7a\x38\x4b\x27\x52\xee\x62\xa9\x7c\xfc\xeb\xf9\x05\x34\x1b\x08\x62\x0f\x12\xee\x48\x6d\x27\x6c\x16\x94\x54\x0b\x32\x81\x72\x61\x74\xe1\xb9\x90\x12\xa5\x96\x2a\x18\x62\x96\x4b\x52\x0e\x6c\x95\x16\xd2\x59\x6f\x60\x64\x1d\xeb\x21\x81\x57\x3e\xfa\x41\x4a\x50\x95\x02\x1d\x89\x04\xde\x28\x78\x85\x05\xe5\xaf\xd0\xd2\x7f\x5c\xd4\x2c\x51\x3b\x61\xf1\xdd\x5f\xd8\xfd\xe0\xbd\x3b\x61\xc7\xa1\x00\x9a\xc0\xba\x57\x3b\x3b\x2e\x7f\x5e\x52\x06\x98\xe7\xfa\x86\x35\x96\xe5\x95\x75\x64\x00\x45\x21\xd5\x1e\xf7\x3f\xec\xf7\x75\x74\x18\x43\xa9\x1d\x9f\x1e\xf3\x7c\x03\x7a\x4d\xc6\x48\xc1\x9a\x0f\x73\x0c\x95\xda\x38\x12\x90\x6e\x3c\xa7\xa1\xa8\x71\xf0\xa0\xfb\x43\x42\x38\x72\x99\xeb\x4d\xc1\x16\xb4\x3b\xd8\x70\x45\x63\x70\x33\x30\x2a\x1d\x15\x83\xd3\x0e\x28\x8a\x5b\x7d\xc8\xa1\xfd\x7c\xc1\x92\x5b\xda\x1b\x75\x91\x9d\xad\x10\xa5\xb2\x20\xc8\xa1\xcc\x2d\x2c\xb4\x01\xad\x08\x90\x6d\xc0\x85\x48\x46\x90\x55\xc6\x78\x97\x68\x54\xe5\xbd\xe7\xe5\x87\x37\x6d\x3a\x48\x60\x32\x99\xc0\x05\x77\x5b\x67\xaa\xcc\xb1\xef\x72\xa8\x52\x82\x84\xe7\x2a\xa4\xf1\xf1\xc9\x32\x73\xd6\xb5\x3f\x06\x60\x30\x82\x85\xa4\x5c\x40\x89\x6e\x05\x09\xaf\x52\x71\xfa\x6e\xd3\x3f\xc0\x6b\x6d\x80\x6e\xb1\x28\x73\x1a\xc3\x5c\x85\xd4\xf3\x5a\xeb\x73\x4f\x5b\xaf\xf9\x2b\x4c\xa7\xf0\xb1\x75\xfb\x60\x13\xa9\x25\xb3\x0e\xe5\x8a\x37\x32\x58\x68\xfd\xc0\x6e\x1f\x29\xe1\x89\x6f\x95\xbe\x51\x43\xab\xfb\xb5\xd0\xd0\x0c\xe6\xa3\x97\x6b\x94\x39\xa6\x39\xcd\x47\x63\x98\x8f\x3e\x18\xbd\x34\x64\x39\x77\x73\x07\xc7\xe2\xf9\xe8\x7b\x5a\x1a\x14\x24\xe6\x23\x66\xfb\xa7\x12\x5d\xb6\x3a\x23\xb3\xa4\xb7\xb4\x79\xee\x99\xb5\xdd\xe7\xce\x70\x4d\xb2\x79\x5e\xf0\xb8\xef\xe7\x62\xe3\x62\x53\xd2\xf3\x02\xcb\xb6\xe3\x0c\xcb\x76\x72\xab\x3d\x0b\x97\x57\xec\xdb\xeb\xd3\xa4\xd3\xe8\xa7\x9f\xac\x56\xb3\xf9\xa8\xdb\xff\x58\x17\x6c\x19\xa5\xdb\xcc\x47\xb0\xb5\xea\x6c\x3e\xf2\xeb\x36\xfd\xcd\x26\x67\xf3\x11\xaf\xc4\xdd\x46\x3b\x9d\x56\x8b\xd9\x7c\x94\x6e\x1c\xd9\xf1\xe9\xd8\x50\x39\xe6\x4a\xe3\x79\xb7\xc2\x7c\xf4\x89\x75\x32\x9d\x82\x76\x2b\x32\x41\x99\x16\x7e\x1b\x1d\x30\xff\x41\x6f\x0c\x6d\x38\xa3\x77\x8d\x73\xbb\xb5\xb8\xa4\xbd\xe3\x86\xd0\xd6\x65\xd5\xd0\x70\x50\xf1\xde\x61\xde\xe0\xe0\xe0\xa1\x60\x11\x5a\x8e\xd6\x5d\x18\x54\x56\x36\x05\xee\x3e\xca\x3b\x3e\xb9\x3b\x91\x1d\x28\xa4\x7d\xeb\xc0\x71\x87\xf7\xc4\x56\xd1\xae\xa5\x66\x07\xe3\x44\xc6\x7e\x1b\x8e\xc6\xe1\x13\x95\x57\x46\x52\x3b\x65\xa8\x32\x52\x82\x9b\x15\x29\xcf\xaa\x52\x82\x4c\xbe\xe1\x70\xda\x71\xcd\x56\xa8\x96\x9c\xd5\xe0\x0d\x7b\x39\x7a\x3f\xe6\x8c\x77\xcd\xde\x31\xe6\x89\x0a\x2a\xdb\x64\x5f\xbf\xaf\x96\x23\x07\x84\xe0\xc8\x35\x1b\x9f\xc0\xb3\x8c\x4a\xc7\x2e\x73\x37\x2c\x77\xed\x60\x44\x6c\x5a\xc8\x1d\x33\xe0\xb4\x3b\xe1\x85\xf7\x50\xd6\xc6\x71\x4f\xc1\xd7\xd4\xa1\xd4\x58\x55\x05\x2a\xb6\x1e\xc1\xfb\xed\xc6\x94\x90\x19\xfa\x92\xa3\x89\x93\x5d\xfa\xea\xf4\x50\x8b\x9a\x6b\x8c\x94\x38\xc2\x79\xa7\xab\x8f\xf5\x85\x87\x2f\xf0\xf6\x1d\xa9\xa5\x5b\xcd\xe0\xc9\xe3\xbf\x3c\xfd\x6e\x0f\x61\x88\x76\x24\xfe\x46\x8a\x53\xe1\x40\x45\xbb\x47\x0c\xbb\x13\x7b\xf5\x93\x3f\x67\xd2\x94\x11\xc9\xb2\xa3\xf1\x16\xb2\x6d\x97\x37\x68\xc1\x92\x83\x14\xb9\xf6\xaf\x4a\x96\x0b\x47\x6f\xa9\xac\x43\x95\xd1\x18\xe4\x62\x98\x99\x6c\xa3\x72\xbe\x81\xd3\xc7\x63\x48\x6b\x11\xef\xc6\xe4\xcb\xdb\xab\x64\x60\xcb\xd2\xc2\xb3\xf1\x9d\xfd\x70\x41\x58\xf9\x4c\xc6\x86\x03\x37\xd2\xad\xb8\x5e\xf4\xe9\xad\xae\xac\x07\xd2\x1b\xb5\xfb\xfd\x9c\xe2\x38\xc9\x2d\xc9\x7c\xd6\x6c\xa5\x72\x4f\xff\xbc\x5f\xbf\x52\xc9\xa2\x2a\x66\xf0\x68\x0f\x49\x08\x69\xf7\xd4\x66\x20\xee\xb2\x3b\x72\xe8\x5a\x1a\x2c\xb8\xf8\xca\x40\x0a\xae\xa9\x16\x92\x4c\xdf\xb4\xf9\xd0\xf5\x44\xce\xd7\x5b\x52\x7c\x60\xeb\x38\xd4\x33\xf6\x0f\x46\x8b\x2a\xe3\xaa\x5a\x2f\x7c\xc9\x28\x17\x32\xeb\x07\x28\x2e\x55\xbd\x37\x04\xb0\x04\x74\xcb\x42\x6f\x61\x49\x40\x2e\x84\x4a\xaa\xa5\xad\x97\xe4\x9a\x9c\x03\x48\x48\xa5\x37\x2b\xf2\xf9\xc4\x83\xac\x7a\x8e\xf1\xbb\xb2\x52\x90\x21\x01\x08\xcb\x0a\x0d\x2a\x47\x24\x38\xfc\xb0\x0b\xd6\xb4\xbd\x90\x87\x5d\x81\xde\x78\x63\x70\xd5\x10\xac\x78\x8b\x75\x51\xef\x3d\xf6\xeb\xb9\xea\xe9\xa3\xc7\x07\x55\xde\xd2\xed\x25\x2a\xd1\x31\xdc\x9b\xc1\x3f\x2f\x5f\x4e\xfe\x81\x93\x5f\xae\x8e\xeb\x0f\x8f\x26\xcf\xfe\x35\x9e\x5d\x3d\xec\x7d\xbd\x3a\x79\xf1\xc7\x3d\x9c\x82\x07\xdd\xd3\x7c\xea\x24\xd2\x14\x7f\x8d\x46\xc7\x3e\xc3\xe8\x05\x5c\x18\x06\x9e\xaf\x31\xb7\x34\x86\xbf\x2b\x9f\x1a\xbe\x50\x68\xa4\xaa\x62\xff\xee\x38\x2b\x8f\x78\xd5\xe1\x8a\xa2\x25\xf1\x5b\x3a\x4c\x53\x6f\x77\x0f\x8d\xdf\xeb\xfd\x84\xe4\x6b\x31\xbd\xe8\x47\x9a\x1e\x10\x04\x1f\xf1\xb8\xd6\x4c\xea\xb2\x35\xc9\x74\x31\xed\x01\x45\xae\x97\xcf\x50\x6d\xa0\x0b\x6b\xa1\xd2\xbc\x6b\xe9\x96\x11\x10\x60\x66\xb4\xb5\x2d\xd2\xb5\x90\xcb\x6b\x82\xb6\x1c\x0d\xc1\x32\xa5\x0c\x7d\x81\x6d\x52\xe9\x0c\x9a\x4d\xb7\x3b\x0b\x19\x2a\x8f\x5b\x2d\x2d\xaa\x1c\x8e\x2d\x11\x24\x4a\x0b\xda\x8d\xae\x27\x21\x86\x62\x2a\x73\xe9\x36\x1c\x25\x05\x65\x5a\x2d\x72\x59\xd7\xf5\x05\xe3\x2e\x54\x2e\xb8\x9b\xa1\x25\xdd\x82\x74\x50\x70\x11\x49\x96\x49\x8e\x85\xb2\xa7\xa7\x8f\x9f\x9c\x57\xa9\xd0\x05\x4a\xf5\xba\x70\xd3\x93\x17\xc7\x3f\x57\x98\x73\xe4\x11\x3f\x60\x41\xaf\x0b\x77\xf2\xf5\xd2\xe2\xe9\xd3\x7b\x78\xd1\xf1\x65\xf0\x95\xab\xe3\xcb\x49\xfd\xe9\x61\xd3\x75\xf2\xe2\x78\x9e\x1c\x1c\x3f\x79\xc8\x67\xe8\x79\xe0\xd5\xe5\xa4\x73\xbf\xe4\xea\xe1\xc9\x8b\xde\xd8\xc9\xae\x33\x72\xc6\x92\x19\xbd\xcc\x32\x5d\x7d\x33\x58\x39\xec\xfb\x9f\x01\xf4\x21\x04\x34\x90\x7e\x1b\x99\x0f\xc0\x79\xe9\x6c\x9d\x3e\x03\x72\x0f\x96\x51\x07\x12\x0e\xb0\xce\xa0\xcc\x83\x59\x65\xae\xc2\xbc\x07\xfb\xc1\x6e\xac\xa3\xe2\x2b\xa1\xf6\xce\x8c\x23\x82\x8e\x08\x3a\x22\xe8\xa1\x36\x19\xc0\x9b\x11\x6c\x47\xb0\xdd\xb5\x08\xb6\x23\xd8\x8e\x60\xfb\x5e\xda\x8c\x60\x3b\x82\xed\xed\x16\xc1\x76\x4d\x13\xc1\x76\x04\xdb\xdf\x1a\x6c\x87\x3c\x35\x03\x67\xaa\xa6\x68\xb1\x4e\x1b\x2e\x52\x60\xc1\x26\xdb\x74\x56\x69\xab\xdf\xce\x0a\x6b\xd7\x85\x5f\x7f\xdb\x7e\x54\xf3\x38\x3e\xaa\x89\x8f\x6a\xe2\xa3\x9a\xf8\xa8\xa6\x69\xdf\xfa\x51\xcd\xf6\x0d\x5c\x78\xf9\xb2\x75\xe3\xe6\x6d\xb6\x34\x7a\x2d\x05\xd9\x3b\x4f\x70\x7c\x1d\x7e\x27\xcb\x14\xa8\xaa\xfe\xb3\x1a\xfa\x36\x8f\x6a\xe2\xf5\x5c\xbc\x9e\x8b\xd7\x73\xf1\x7a\x6e\xbb\xc5\xeb\xb9\xb6\xc5\xeb\xb9\x78\x3d\x17\xaf\xe7\xe2\xf5\x5c\xbc\x9e\xbb\xdb\xe2\xf5\x5c\x68\xf1\x7a\x2e\x5e\xcf\x0d\xb4\xff\x8d\xeb\xb9\xbe\x05\xc5\x9f\x57\x44\xf4\x19\xd1\xe7\x7f\x1f\xfa\x8c\x90\x32\x42\xca\x08\x29\x07\x5a\x84\x94\x11\x52\x46\x48\x19\x21\xe5\x4e\x8b\x90\xb2\xa6\x89\x90\x32\x42\xca\xf8\xf3\x8a\xdf\xf9\xf3\x8a\xf7\xef\xce\x7a\xef\x39\xc2\x3b\x8f\x9e\x65\xad\x70\x4d\x90\x12\xa9\xb6\x8c\x88\xff\x8b\x8d\x68\x38\xa2\xe1\xf8\xbf\xd8\xba\x45\xe0\x1c\x81\x73\x04\xce\x11\x38\x6f\x29\x2e\x02\xe7\x08\x9c\xb7\x55\x19\x81\xf3\xef\x17\x5a\x04\xce\x11\x38\x0f\xa8\xe2\xff\x03\x38\x1f\xfa\xa9\x44\xbf\xef\x73\xbf\x94\xf8\x77\x00\x00\x00\xff\xff\x0a\x10\x91\x5e\x61\x56\x00\x00") func operatorsCoreosCom_operatorconditionsYamlBytes() ([]byte, error) { return bindataRead( @@ -185,7 +185,7 @@ func operatorsCoreosCom_operatorconditionsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorgroupsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x79\x6f\x23\x37\x96\xff\xbf\x3f\xc5\x83\x66\x81\xb6\xb3\x3a\xda\x9d\x45\x36\x23\x20\x08\x8c\xee\x74\xe0\x4d\xb7\xdb\x68\xbb\xb3\xc0\x5a\xde\x1d\xaa\xea\x55\x89\x63\x16\x59\x43\xb2\x24\x6b\x82\x7c\xf7\xc5\x7b\x64\x1d\xba\xe5\x1c\xb3\x93\x85\xea\x1f\x5b\x3c\xdf\xc1\xf7\x7b\x07\x29\x4a\xf9\x23\x5a\x27\x8d\x1e\x83\x28\x25\x3e\x79\xd4\xf4\xcb\x0d\x1f\xbf\x76\x43\x69\x46\xf3\x8b\x17\x8f\x52\xa7\x63\x78\x53\x39\x6f\x8a\x4f\xe8\x4c\x65\x13\x7c\x8b\x99\xd4\xd2\x4b\xa3\x5f\x14\xe8\x45\x2a\xbc\x18\xbf\x00\x10\x5a\x1b\x2f\xa8\xd9\xd1\x4f\x80\xc4\x68\x6f\x8d\x52\x68\x07\x39\xea\xe1\x63\x35\xc5\x69\x25\x55\x8a\x96\x17\xaf\xb7\x9e\xbf\x1a\x7e\x3d\x7c\xf5\x02\x20\xb1\xc8\xd3\xef\x64\x81\xce\x8b\xa2\x1c\x83\xae\x94\x7a\x01\xa0\x45\x81\x63\x30\x25\x5a\xe1\x8d\xcd\xad\xa9\x4a\x37\xac\x7f\xba\x61\x62\x2c\x1a\xfa\x53\xbc\x70\x25\x26\xb4\x3b\x8f\x69\xa7\xac\x8c\x09\xeb\xd5\x44\x0a\x8f\xb9\xb1\xb2\xfe\x0d\x30\x00\xa3\x0a\xfe\x3f\x30\xff\x31\xae\xf1\x3d\x2d\xc9\xed\x4a\x3a\xff\xc3\x66\xdf\x7b\xe9\x3c\xf7\x97\xaa\xb2\x42\xad\x13\xcc\x5d\x6e\x66\xac\xbf\x6e\xb7\xe7\xed\xf2\xd0\x25\x75\x5e\x29\x61\xd7\xe6\xbd\x00\x70\x89\x29\x71\x0c\x3c\xad\x14\x09\xa6\x2f\x00\xa2\xf8\xe2\x32\x83\x28\xa2\xf9\x45\x5c\xd5\x25\x33\x2c\x44\xbd\x07\xd0\x92\xfa\xf2\xe6\xea\xc7\x2f\x6f\xd7\x3a\x00\x52\x74\x89\x95\xa5\x67\x65\xac\x30\x04\xd2\x81\x9f\x21\x54\x5a\x7a\x30\x19\x14\x95\xf2\xd2\xa3\x16\x3a\x59\x42\x66\x2c\x7c\x7c\xff\x01\x0a\xa1\x45\x8e\x69\x47\xd4\x70\xe5\x49\xf7\xce\x5b\x21\x75\x58\x41\x6a\xe7\x85\x52\xac\x5e\x5a\xa9\x19\x0c\x52\x83\xf4\x2e\x68\x84\x78\x03\x6f\x40\x00\xa9\x51\x66\x12\x53\x70\xc8\x5b\x7b\x61\x73\xf4\xed\x30\x37\xec\x70\xe0\x97\x24\x1e\x33\xfd\x2b\x26\xbe\xd3\x6c\xf1\x6f\x95\xb4\x98\x76\x99\x25\x51\xd5\x87\xb6\xd3\x5c\x5a\xa2\xc8\x77\x4e\x41\xf8\x3a\x26\xb2\xd2\xbe\x26\xb5\x97\x24\xda\x30\x0e\x52\xb2\x0e\x0c\x6c\x47\x25\x11\x1b\x2c\x76\xe6\x64\x26\x1d\x58\x2c\x2d\x3a\xd4\xbe\x91\x88\xd0\x91\x81\x21\xdc\xa2\xa5\x89\x74\x56\x2a\x95\x92\x28\xe7\x68\x3d\x58\x4c\x4c\xae\xe5\xdf\x9b\xd5\x1c\xc9\x8a\xb6\x51\xc2\xa3\xf3\x20\xb5\x47\xab\x85\x82\xb9\x50\x15\xf6\x41\xe8\x14\x0a\xb1\x04\x8b\xb4\x2e\x54\xba\xb3\x02\x0f\x71\x43\xf8\x60\x2c\x69\x27\x33\x63\x98\x79\x5f\xba\xf1\x68\x94\x4b\x5f\x03\x40\x62\x8a\x82\x94\xbf\x1c\xb1\x2d\xcb\x69\x45\x3a\x1b\xa5\x38\x47\x35\x72\x32\x1f\x08\x9b\xcc\xa4\xc7\xc4\x57\x16\x47\xa2\x94\x03\x26\x56\x33\x08\x0c\x8b\xf4\x4f\x36\x42\x86\x7b\xb9\x26\xbe\xa0\x32\xe7\xad\xd4\xf9\x4a\x17\xdb\xdc\x5e\x59\x93\xe5\xd1\xc9\x14\x71\x7a\xe0\xa5\x15\x29\x35\x91\x54\x3e\x7d\x77\x7b\x07\x35\x01\x41\xec\x41\xc2\xed\x50\xd7\x0a\x9b\x04\x25\x75\x86\x36\x8c\xcc\xac\x29\x78\x15\xd4\x69\x69\xa4\xf6\xfc\x23\x51\x12\xb5\x07\x57\x4d\x0b\x3a\xb4\x74\xc0\xd0\x79\xd2\xc3\x10\xde\x30\xfe\xc1\x14\xa1\x2a\x53\xe1\x31\x1d\xc2\x95\x86\x37\xa2\x40\xf5\x46\x38\xfc\xdd\x45\x4d\x12\x75\x03\x12\xdf\xf1\xc2\xee\xc2\xf7\xe6\x84\x0d\x83\x02\xa8\xe1\x75\xa7\x76\x56\xf0\xe3\xb6\xc4\xa4\xc6\x10\x9a\xc9\x98\x21\xf4\x1a\xc8\xd4\x2a\x1a\x1e\x4b\x04\x6d\x99\x89\x4a\xf9\x75\x4a\x00\xaa\x32\xb7\x22\xc5\x5b\x6f\x09\xd6\x97\x63\x78\x1b\x46\xae\x0d\xdc\x65\xee\xcc\x22\x2a\x4c\xbc\xb1\x9b\x3d\x6b\xac\xde\xc6\x81\x71\x46\x60\x73\x85\xb5\x97\x6e\x3f\x6e\x1d\xc1\xe9\x21\x6a\xe9\x2b\x84\x4f\x66\xdf\x3d\xd1\x99\xee\xb8\x84\x03\xd4\xaf\x4f\x0a\x16\x45\x9e\x8d\xd0\x48\x89\x29\xaa\x46\x14\x35\x92\x16\xc1\x64\xee\x66\xb8\xd2\x02\xc2\x22\x5c\x5e\xbf\xc5\x74\x1b\x73\x2d\x83\xc2\x5a\xb1\xdc\x31\x42\x7a\x2c\x76\x12\xbe\x46\xfa\xe5\x1e\xf2\x22\x30\xd4\x3d\x7e\x26\xd8\x17\x79\xf6\x44\x01\xf4\xfa\x20\xe0\x11\x97\x01\x1f\x09\x76\xa3\xca\xc2\x60\x8b\x8c\xa6\xac\xcc\x47\x5c\xf2\xa0\x08\x96\x3b\xa9\x3b\xa0\xbf\xf0\x6d\xf7\x46\xab\xdf\x80\xb6\xdc\xdb\x5f\x13\xbb\x73\xd0\xa1\xc3\x12\xbe\x47\x5c\xee\xeb\x5e\x13\x38\xc9\x21\x9a\x71\x90\x3c\x35\xb0\xb4\xd8\xb2\x6b\x61\x8b\xb2\x54\x12\x19\x0d\xf7\xae\xbd\x13\x8e\x56\xbf\x9a\xd5\x67\x10\xda\xa8\xb2\x45\xf8\xa0\xec\x97\x2e\x28\x96\x4e\xfa\x4c\x96\x31\xc8\x08\xa1\x45\xed\x0a\x7f\x14\x4a\x76\xc2\x18\x3e\xd5\x57\xba\x0f\xd7\xc6\xd3\x9f\xef\x9e\x24\x41\x3d\x9d\x87\xb7\x06\xdd\xb5\xf1\xdc\xf2\x9b\xb0\x1a\x48\x78\x06\xa3\x61\x02\x1f\x76\x1d\xec\x8a\x38\xe9\xfa\x43\x0a\xc3\x32\xd6\x4f\x23\x14\xe9\xc8\x23\x19\x5b\x73\xc4\x11\x4a\x58\x28\x2c\x51\x54\x8e\x1d\x98\x36\x7a\x80\x45\xe9\x97\x5b\xd7\x88\x82\x30\x76\x45\x0e\x7b\x96\x8b\x4b\xdd\x91\x5f\x0d\x3d\x21\x02\x52\x14\xca\x42\x5a\x31\xd1\xec\xcd\x09\xb4\x65\x02\x05\xda\x1c\xa1\x24\x84\x3a\x46\xbc\xfb\x70\x25\x7c\x07\xd0\xe5\x48\x5d\x31\x64\xbe\x27\x03\x78\x06\xc4\x86\xf1\x01\x96\x0a\x51\x92\x9a\x7e\x22\xf4\x61\x49\xfd\x0c\xa5\x90\x14\x31\x5f\x72\xf4\xaf\x70\xa5\x4f\x6a\x96\x69\x77\x19\x5a\x41\x3a\x20\x28\x99\x0b\x45\x78\x47\x27\x59\x03\xaa\x80\x7e\x14\xa4\xaf\x01\x7b\x1f\x16\x33\xe3\x02\x98\x65\x12\x15\xc7\x4e\xbd\x47\x5c\xf6\xfa\x1b\xaa\xed\x5d\xe9\x5e\xc0\xc5\x0d\x65\x36\x20\x6a\xb4\x5a\x42\x8f\xfb\x7a\xbf\xdc\x17\xec\x05\x4b\x91\xa6\x9c\x5e\x0a\x75\x73\x04\x9a\xed\xd5\x9b\x43\x3b\x97\x09\x5e\x26\x89\xa9\x34\x27\x5e\x47\xf8\xf5\xf5\x29\x35\xf8\x89\xb4\x90\x7a\x25\x37\xe1\x91\x20\xc2\x50\x58\xcc\x64\x32\x83\x85\x54\x8a\xc3\x40\x87\x29\xa9\x27\xc5\x52\x99\x65\x23\xe7\x33\x77\x1e\x34\x4b\xf1\x68\x2d\x7b\xce\xf4\x76\x87\x06\xbb\x98\xa3\xf4\x21\xb9\xb1\x66\x2e\x53\x4c\x2f\x6f\xae\xb6\x4a\x69\x95\x39\x9e\x02\x1e\x95\x72\x9c\xbe\x51\xcc\xea\x4d\x8c\x59\xb7\x86\x30\x65\x67\xfd\x4e\x92\xbf\x93\xd8\xa9\x31\x0a\xc5\x66\x7f\x08\x85\x9a\x24\xf6\x30\xad\x77\x6b\x13\x22\xdc\xe1\x53\xa9\x64\x22\x7d\x8d\xdf\x6d\x6c\xc5\xf9\x10\x4f\x62\xe0\x92\x1c\x0d\x38\xf4\xfd\x36\x56\x93\x0e\x64\xae\x8d\xdd\x7e\x3e\xf7\xe3\xc9\x1e\x14\x39\x80\x1d\x4f\x83\xc7\x6a\x8a\x56\xa3\x47\x37\xa0\x18\x6b\x10\x27\xe0\xa6\x09\xac\x87\xb0\x87\xa4\xd4\xfb\xbc\x3a\x61\x25\x01\x8d\x8b\xd5\xd8\x1a\xb2\xf6\x95\xe4\x9b\x46\x35\x12\x64\x7b\xb6\xc8\x46\x9c\x54\xd6\xa2\xf6\x6a\x09\x7e\x61\xc0\x55\x65\x69\xac\xc7\x74\x7d\x49\x32\x4d\x98\xe8\x3a\xd0\x1e\xf3\xa1\x62\x13\x60\xa0\x10\x4a\x99\x05\x24\xaa\x72\x1e\x6d\xb4\xac\x98\x29\xb3\xba\x0a\x33\xc7\x3a\x8d\x0d\x2e\x81\x9c\x41\x39\x13\x0e\xdb\x1c\xcc\x55\x49\x82\x98\x62\x1a\x3a\xa2\x2b\xc1\x2c\xc3\xc4\xcb\x39\xaa\x25\x14\x28\xb8\xd2\x20\x7c\xbb\x3f\x9d\xec\xb0\x7d\xcb\xf0\xda\x8e\x1a\x9f\x7c\x9d\xa4\x83\xe4\x24\x7c\xb5\x52\x61\x1b\x76\x67\xc2\x41\x26\xa4\xa2\xbc\x6e\xa2\xe1\x0e\x93\xd9\x8d\xc5\xb9\xc4\xc5\x67\xed\x44\x86\xef\x84\x54\xef\x8c\x5d\x08\x9b\x76\x64\xf0\x7b\xb0\x4f\x54\x35\x7d\x81\xa4\x5a\x2e\x97\x0d\x70\xaa\x65\xbf\xa5\x22\x47\x4d\x02\x20\x7e\x17\x35\x83\x37\x8a\x24\xb6\x98\xa1\x26\xd7\x5b\x4d\x9b\x13\x05\x16\x33\xb4\xa8\xc9\x9e\x44\xbd\x7e\x67\x52\xe3\x1e\x12\xe1\x85\x32\x39\x4b\x66\x8a\xa8\xeb\xbc\x17\x16\xd2\xcf\x40\xf0\x66\xb5\xf4\x32\x0e\xaf\x11\x90\x42\x05\x62\x31\xda\x6e\xa7\x68\x34\xd1\xf0\x9f\x97\x9f\xae\xaf\xae\xbf\x1f\xb3\x57\xd9\x27\xe1\xcd\x73\x2d\x1d\x54\x3c\xaa\x53\xf5\x70\x95\xf2\x74\xc4\x2b\x8d\x4f\x25\x26\x44\xda\x14\x67\x62\x2e\xc9\x06\x6c\xac\x87\xcc\xd1\x8a\xa9\x42\xa0\x34\x18\x94\x71\xb4\x8e\x42\xe7\x60\x69\x2a\x98\x89\x39\x42\x8a\x58\x42\xa5\x53\xb4\xce\x0b\x9d\x12\xf5\x26\x8b\x91\xef\x2a\x13\x30\x45\xea\xad\x2b\x62\x1b\xd6\xd5\x7b\x2e\xc0\xb7\x99\xee\x8e\x44\x96\x3e\xd4\x55\xb1\x1d\x95\x06\x7b\x66\x51\xef\x3e\x11\xaf\xa6\xfd\x5e\xf8\x6a\x03\xfa\xf6\x24\xfe\x3c\xbe\x49\xfd\xc3\xaf\x6d\xc9\xff\xa7\xe7\xe7\xfe\xbb\xf3\xa8\x01\x28\xe1\xfc\xe7\x70\x0a\x9f\x91\xf1\x27\x46\x07\xb3\x39\xec\x92\xde\x34\x43\xd7\x63\xef\x6d\x9e\xb3\x5d\xf8\x37\x75\x36\xab\xf0\xdf\x90\xd4\x86\x68\x29\x7a\x21\x55\x90\xb8\xd1\x08\x82\x42\x16\x5f\x53\x19\x81\x9d\xd5\x82\x4d\x45\xf2\xf2\xe6\x0a\x1a\x6d\xc0\x60\x30\x08\x20\xeb\xbc\xad\x12\xf6\xa3\x52\x7b\xd4\x04\x42\xb4\x6a\x2a\x2d\x97\x14\x1d\x2d\xde\xca\x21\x66\x84\x21\xcc\x2c\x85\x9f\xc1\x30\x28\x7f\xd8\x11\x05\xc0\x3b\x63\x01\x9f\x44\x51\x2a\xec\xb3\x18\xe0\x9d\x31\xf1\xcc\x84\x0d\x7f\x82\xd1\x08\x3e\xb5\x49\x1c\x07\xaa\x53\x8a\xb7\x42\x0e\xc7\x15\x53\xc8\x8c\x21\x29\x77\xf9\x19\xd2\xc4\x1f\xb4\x59\xe8\x6d\x5b\xf3\x5e\xc2\xe2\x18\x26\xbd\xcb\xb9\x90\x8a\x4c\x7f\xd2\xeb\xc3\xa4\x77\x63\x4d\xce\x21\xb3\xce\x27\x31\x06\x9e\xf4\xde\x22\xc3\x4c\x3a\xe9\xd1\xb2\xff\xca\x19\xc9\x07\x4a\x4e\x7e\xc0\xe5\x37\xbc\x58\xd3\x5c\xbb\xdf\x6f\x42\xf2\x42\xed\xe4\xe8\xef\x96\x25\x7e\x43\x51\x7b\xdd\xf0\x41\x94\xcd\xe4\xce\x69\xba\x7f\x28\xd0\x8b\xf9\xc5\xb0\x55\xe7\x5f\xfe\xea\x8c\x1e\x4f\x7a\x2d\xfd\x7d\x53\xd0\xb1\x28\xfd\x72\xd2\x83\x95\x5d\xc7\x93\x1e\xef\x5b\xb7\xd7\x44\x8e\x27\x3d\xda\x89\x9a\xad\xf1\x66\x5a\x65\xe3\x49\x6f\xba\xf4\xe8\xfa\x17\x7d\x8b\x65\x9f\xc0\xe9\x9b\x76\x87\x49\xef\x2f\x04\xc4\xa3\x11\x18\x3f\x43\x1b\x34\xe9\xe0\xe7\x6d\xc8\x75\x44\x28\x7f\xa8\xe6\x11\x2c\xf6\xce\x0a\xed\x64\x7d\xf3\xb3\x73\x68\x81\xce\x89\x7c\x77\xbf\x45\xe1\xb6\x86\xa5\xa1\x3b\x9c\x86\x9d\xdd\xc4\xcb\xd6\xce\xc3\x05\x95\x4d\x1e\x8e\x2c\x64\x6d\x4e\x6c\xcb\x2c\xce\x83\xa7\x06\xb6\xd8\xe6\x4c\xf8\x66\x34\x19\x22\x05\x01\x64\xdf\x11\x60\x39\x15\x64\xbd\xc5\x08\x29\x5e\x20\x4c\x31\xf8\xf9\x70\x95\x93\xa2\x55\x4b\x72\x53\xed\xaa\xc9\x4c\xe8\x9c\x02\x9b\x90\xee\x0b\xb6\x77\x0a\x9f\x1e\xc9\x90\x38\x4d\xd4\x50\xb9\xba\xb0\xce\x74\x35\x2b\x12\x70\x04\x83\x8f\xcb\x30\x32\x26\x09\x96\x9e\xac\xeb\x50\xd5\xec\x40\x6d\x24\x33\xb6\x10\x7e\x4c\xee\x19\x07\x7e\xf7\xf1\x88\x87\xe3\x48\xc1\xc7\xd1\x21\x2b\x9f\x55\x85\xa0\xa8\x47\xa4\x1c\x08\x34\x7d\x3a\x95\x89\xe0\x60\xa5\xc6\x53\x31\x35\x55\x40\xb8\x56\x0f\x51\xd4\x14\x71\x4c\x91\xd3\x13\xb2\xcf\xc8\xd6\xaf\x64\xbe\x10\x4f\xef\x51\xe7\x7e\x36\x86\x2f\x5f\xff\xfb\x57\x5f\xef\x18\x18\x80\x11\xd3\xef\x43\x98\xb7\xe5\xb2\x6a\x87\x18\x36\x27\x76\x0b\x67\xc4\xe7\xb0\xbe\x21\x18\xe6\xed\x98\xa6\xf2\xd7\x9e\xa0\x85\xe0\x44\x0b\xa6\xc2\x71\x8a\x40\x72\x21\x94\xe7\xb8\x51\x27\xd8\xa7\xe8\x7a\xeb\x62\xd2\x75\x32\x8d\x8b\xd7\x7d\x98\x46\x11\x6f\xc2\xf7\xfd\xd3\xc3\x70\x0b\xc9\xd2\xc1\x9f\xfb\x6b\xf4\x50\x6e\x5d\xb1\xc7\xe3\xb4\x96\x23\x52\x8b\xc1\x0d\xc6\x70\x7b\x8b\x1b\xc4\x86\xde\x43\x8a\x23\x67\x98\xe3\xee\x2a\x6c\x7d\x6c\xa5\xf6\x5f\xfd\xdb\x6e\xfd\x4a\x2d\x8b\xaa\x18\xc3\xab\x1d\x43\x02\xa4\x1d\xa9\xcd\x30\xb8\x8d\x02\x04\x41\x57\x6e\x45\x51\x70\xca\x2f\x53\xd4\x5e\x66\x12\x6d\xf7\x68\x87\xc4\x83\x27\xd6\x31\x7a\x23\xc5\x97\x2e\xe2\x50\xe7\xb0\xdf\x58\x93\x56\x09\x5a\xf6\xc0\xb1\x12\x92\x74\x01\x6a\x59\x62\xb0\x86\x90\x86\x42\x13\x7a\xd7\xd5\x24\x0a\xcf\x51\x68\xa9\x73\x17\xb7\x94\x2e\x00\x48\xf0\xba\x8b\x19\xb2\xeb\x59\xa9\x40\x31\x55\x4e\xa6\x68\x31\x05\x01\x79\x25\xac\xd0\x1e\x31\x25\xf8\x09\x55\xa8\x70\x0b\xd8\x42\x9e\x68\xef\xde\x6a\x6b\x0c\xa6\x1a\xc0\x8a\x48\x8c\xf7\x75\xa1\x3e\xf9\x9b\x99\xea\xc5\xab\xd7\x7b\x55\xde\x8c\xdb\x5d\xc3\x17\xde\xa3\xd5\x63\xf8\xef\xfb\xcb\xc1\x7f\x89\xc1\xdf\x1f\xce\xe2\x3f\xaf\x06\x7f\xfe\x9f\xfe\xf8\xe1\x8b\xce\xcf\x87\xf3\x6f\xff\x65\xc7\x4a\xdb\xc3\xf6\x1d\xc7\x27\x3a\x91\x3a\x48\xac\x35\xda\x67\x0f\x63\x32\xb8\xb3\x15\xf6\xe1\x9d\x50\x0e\xfb\xf0\x59\xb3\x6b\xf8\x95\x42\xdb\x9d\xb9\x84\x6f\x00\x3d\xda\x75\x7b\xf0\xd1\x0c\x61\x92\xf6\x8f\x89\xe4\xee\xab\x48\x1e\x27\x24\x0e\xdb\x4c\xd6\x45\x9a\xce\x1d\x2f\x30\xe2\x51\x58\x3a\x8c\xe1\xed\x30\x31\xc5\xa8\x73\x07\x4c\x71\xf5\x07\xa1\x97\xd0\xc2\x5a\x08\x4a\xd7\x4f\xba\xf3\x84\x4d\x22\xb1\x94\x91\x36\xb7\xe8\xa0\xe4\x23\x42\x13\xb9\x06\xb0\x9c\x62\x22\x38\x10\xb7\x53\xe9\xad\xb0\xcb\x4e\xde\x01\x89\xd0\xb1\x16\x99\x55\x0a\xce\x1c\x22\x0c\xb5\x49\x71\x13\x5d\xcf\x03\x86\x8a\xa9\x54\xd2\x2f\x43\xe1\x32\x31\x3a\x53\x32\xc6\xff\x45\x69\xac\x17\xda\xd7\x45\xdf\x1c\x9f\x40\xfa\x50\x6f\x0e\xc5\xb9\xb3\x54\xbb\x8b\x8b\xd7\x5f\xde\x56\xd3\xd4\x14\x42\xea\x77\x85\x1f\x9d\x7f\x7b\xf6\xb7\x4a\x28\xae\x98\x5e\x8b\x02\xdf\x15\xfe\xfc\xb7\x73\x8b\x17\x5f\x1d\x61\x45\x67\xf7\xc1\x56\x1e\xce\xee\x07\xf1\xbf\x2f\xea\xa6\xf3\x6f\xcf\x26\xc3\xbd\xfd\xe7\x5f\x10\x0f\x1d\x0b\x7c\xb8\x1f\xb4\xe6\x37\x7c\xf8\xe2\xfc\xdb\x4e\xdf\xf9\xa6\x31\x76\xb2\xd2\x83\x09\xe6\xfb\x76\x6c\x88\x4e\x7c\xfd\x18\xaa\xb6\xcc\xd5\xd0\x70\x3d\xe5\x8c\x56\x4c\xfe\x38\x2e\xf3\xec\xaa\xf2\x31\x41\x97\x3e\xbe\x8a\xbb\x5a\xbf\xed\x94\x4d\x36\xae\xc6\x1b\x0f\xb4\xc2\xd4\x3f\x6b\x9d\x76\xf5\x66\xe1\x13\x66\xcf\xbc\x58\xf8\x84\x59\xb7\xd4\x16\x04\xb3\x7a\x9f\x10\x9f\xab\x34\x17\x0e\xbf\xc3\xdb\x81\xdd\x0f\x9c\xb6\xb2\x40\xc1\x7e\x5d\x2f\x8d\xe7\x31\xf2\xb0\xf3\x22\xf4\xa0\x49\xb3\x3f\xbe\x11\x7e\x76\x14\x05\x2f\xaf\xa2\xd8\xf8\xd6\x90\xef\x71\x4b\x89\x09\xae\xbc\xa1\xe2\x38\x0e\x45\x1a\x1b\x29\xf0\xb1\x18\xfb\xfa\x21\xe2\x88\x77\xa5\xed\x1b\x2b\x0a\x9a\x40\x10\x10\xcb\x14\xfe\xe3\xf6\xe3\xf5\xe8\x7b\x13\x63\x05\xca\x66\x5c\xb0\x2d\xbe\xe5\xea\x83\xab\x92\x19\x08\x47\xa4\x51\x7e\x7b\xcb\xa5\x87\x42\x68\x99\xa1\xf3\xc3\xb8\x1a\x5a\x77\xff\xfa\x61\xb8\x5a\xee\x90\xf1\x42\xb5\x7e\x89\x14\x0f\x00\xdb\x06\x31\xd3\xcc\xe5\xa0\x95\x49\x2a\x4d\x1a\x89\x5e\x30\xb1\x5e\x3c\x22\x98\x48\x6c\x85\xec\x14\xc6\xd0\xa3\x63\xd2\xd9\xfa\x27\x32\xac\x9f\x7b\x70\xb6\xe0\x92\x7e\x8f\x7e\xf6\xc2\x86\xcd\xc3\x31\x6a\xeb\x78\xfc\xb8\x71\x88\xef\xad\xcc\x73\x0e\xb7\xb8\x6e\x3b\x47\xed\xcf\xd9\xbf\x65\xa0\x4d\x67\xb0\x8e\xf7\x63\xed\xad\xd8\x3a\x21\xf7\xaf\x1f\x7a\x70\xb6\xca\x17\x85\xa0\xf8\x04\xaf\x9b\x9b\xb0\xd2\xa4\xe7\x75\xd6\xba\xd4\x5e\x3c\x71\x62\x30\x33\x0e\x75\xb8\x48\xf0\x26\x54\x63\x9d\xa1\xe4\x13\x95\x1a\x84\x00\x33\x85\x45\x28\xc0\xd5\xa2\x0c\x97\xc9\xa5\xb0\x7e\xed\x59\xdd\xdd\xc7\xb7\x1f\xc7\x61\x37\x52\x5b\xae\xeb\x2c\x37\x93\x5a\xa8\x58\xd6\x6e\xe2\x43\x22\xa4\x0a\x4a\xf2\x26\xa6\xb6\x75\x45\x37\xab\x7c\x65\x71\xb8\xfe\xcc\xea\xe8\x13\xbf\xed\x8d\xdb\xf6\xc3\xce\x6f\xdd\xd6\x0d\xed\xff\xf0\x25\xd9\xd1\x2c\xea\x1d\x37\xad\x9b\x2c\x5e\x77\xce\xe0\x5e\x16\x5b\x68\x26\x2e\x53\x93\x38\x62\x30\xc1\xd2\xbb\x91\x99\x13\x74\xe2\x62\xb4\x30\xf6\x51\xea\x7c\x40\x87\x6c\x10\x34\xef\x46\xec\x62\x46\x7f\xe2\x3f\xbf\x8a\x23\xf6\x53\xc7\xb3\x15\x1e\xb4\xfe\x03\x78\x63\xf7\x39\xfa\xc5\xac\xd5\xf1\xe5\x73\x3c\xc1\xcb\xdb\x3a\xf9\x5b\x9b\x4d\xe6\x12\x2e\xc2\xe3\x4b\xd7\x0e\xc2\x15\x22\x0d\x10\x28\xf4\xf2\x77\x3f\xc6\x24\x40\xce\xf1\x93\xe5\x20\x3e\x45\x1f\x08\x9d\x0e\x9a\xf8\x3a\x59\xfe\x62\x89\x55\xf2\x48\x03\xfe\x7c\xf5\xf6\x1f\x73\xb8\x2b\xf9\x2c\x6b\x0d\x55\x94\x31\x78\x5b\xd5\xd1\x9d\xf3\xc6\x8a\x1c\x57\xdb\xaa\x69\x93\x7c\xb4\x0c\xc7\xbc\x12\x7e\xfa\x99\x9b\xda\xc7\xe7\x42\x95\x33\xf1\xba\x9e\x7b\x7a\x82\x7e\x7a\x82\x7e\x7a\x82\x7e\x7a\x82\xbe\x57\xd8\x7f\xd4\x27\xe8\xa7\x27\xe4\xa7\x27\xe4\xa7\x27\xe4\xbb\xbb\x4f\x4f\xc8\x4f\x4f\xc8\x4f\x4f\xc8\xd7\xbf\xd3\x13\xf2\xd3\x13\xf2\xd3\x13\xf2\xd3\x13\xf2\x2d\xdf\x4e\x35\xfd\xff\x7e\x7c\x79\xba\x1c\xfb\x63\x5c\x8e\x9d\xae\xbb\x4e\xd7\x5d\xa7\xeb\xae\xd3\x75\xd7\x2f\x38\xf1\xa7\xeb\xae\xd3\x75\xd7\xe9\xba\xeb\x74\xdd\xf5\x4f\x7a\xdd\x95\x09\xe5\x8e\xbe\xef\xfa\xdf\x00\x00\x00\xff\xff\x25\xf1\x04\x48\x34\x4b\x00\x00") +var _operatorsCoreosCom_operatorgroupsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x79\x6f\x23\x37\x96\xff\xbf\x3f\xc5\x83\x66\x81\xb6\xb3\x3a\xda\x9d\x45\x76\x22\x20\x08\x8c\xee\x74\xe0\x4d\xb7\xdb\x68\xbb\xb3\xc0\x5a\xde\x1d\xaa\xea\x55\x89\x63\x16\x59\x43\xb2\x24\x6b\x82\x7c\xf7\xc5\x7b\x64\x1d\xba\xe5\x1c\xb3\x93\x85\xea\x1f\x5b\x3c\xdf\xc1\xf7\x7b\x07\x29\x4a\xf9\x23\x5a\x27\x8d\x1e\x83\x28\x25\x3e\x79\xd4\xf4\xcb\x0d\x1f\xff\xec\x86\xd2\x8c\xe6\x17\x2f\x1e\xa5\x4e\xc7\xf0\xa6\x72\xde\x14\x9f\xd0\x99\xca\x26\xf8\x16\x33\xa9\xa5\x97\x46\xbf\x28\xd0\x8b\x54\x78\x31\x7e\x01\x20\xb4\x36\x5e\x50\xb3\xa3\x9f\x00\x89\xd1\xde\x1a\xa5\xd0\x0e\x72\xd4\xc3\xc7\x6a\x8a\xd3\x4a\xaa\x14\x2d\x2f\x5e\x6f\x3d\x7f\x35\xfc\x7a\xf8\xea\x05\x40\x62\x91\xa7\xdf\xc9\x02\x9d\x17\x45\x39\x06\x5d\x29\xf5\x02\x40\x8b\x02\xc7\x60\x4a\xb4\xc2\x1b\x9b\x5b\x53\x95\x6e\x58\xff\x74\xc3\xc4\x58\x34\xf4\xa7\x78\xe1\x4a\x4c\x68\x77\x1e\xd3\x4e\x59\x19\x13\xd6\xab\x89\x14\x1e\x73\x63\x65\xfd\x1b\x60\x00\x46\x15\xfc\x7f\x60\xfe\x63\x5c\xe3\x7b\x5a\x92\xdb\x95\x74\xfe\x87\xcd\xbe\xf7\xd2\x79\xee\x2f\x55\x65\x85\x5a\x27\x98\xbb\xdc\xcc\x58\x7f\xdd\x6e\xcf\xdb\xe5\xa1\x4b\xea\xbc\x52\xc2\xae\xcd\x7b\x01\xe0\x12\x53\xe2\x18\x78\x5a\x29\x12\x4c\x5f\x00\x44\xf1\xc5\x65\x06\x51\x44\xf3\x8b\xb8\xaa\x4b\x66\x58\x88\x7a\x0f\xa0\x25\xf5\xe5\xcd\xd5\x8f\x5f\xde\xae\x75\x00\xa4\xe8\x12\x2b\x4b\xcf\xca\x58\x61\x08\xa4\x03\x3f\x43\xa8\xb4\xf4\x60\x32\x28\x2a\xe5\xa5\x47\x2d\x74\xb2\x84\xcc\x58\xf8\xf8\xfe\x03\x14\x42\x8b\x1c\xd3\x8e\xa8\xe1\xca\x93\xee\x9d\xb7\x42\xea\xb0\x82\xd4\xce\x0b\xa5\x58\xbd\xb4\x52\x33\x18\xa4\x06\xe9\x5d\xd0\x08\xf1\x06\xde\x80\x00\x52\xa3\xcc\x24\xa6\xe0\x90\xb7\xf6\xc2\xe6\xe8\xdb\x61\x6e\xd8\xe1\xc0\x2f\x49\x3c\x66\xfa\x57\x4c\x7c\xa7\xd9\xe2\xdf\x2a\x69\x31\xed\x32\x4b\xa2\xaa\x0f\x6d\xa7\xb9\xb4\x44\x91\xef\x9c\x82\xf0\x75\x4c\x64\xa5\x7d\x4d\x6a\x2f\x49\xb4\x61\x1c\xa4\x64\x1d\x18\xd8\x8e\x4a\x22\x36\x58\xec\xcc\xc9\x4c\x3a\xb0\x58\x5a\x74\xa8\x7d\x23\x11\xa1\x23\x03\x43\xb8\x45\x4b\x13\xe9\xac\x54\x2a\x25\x51\xce\xd1\x7a\xb0\x98\x98\x5c\xcb\xbf\x37\xab\x39\x92\x15\x6d\xa3\x84\x47\xe7\x41\x6a\x8f\x56\x0b\x05\x73\xa1\x2a\xec\x83\xd0\x29\x14\x62\x09\x16\x69\x5d\xa8\x74\x67\x05\x1e\xe2\x86\xf0\xc1\x58\xd2\x4e\x66\xc6\x30\xf3\xbe\x74\xe3\xd1\x28\x97\xbe\x06\x80\xc4\x14\x05\x29\x7f\x39\x62\x5b\x96\xd3\x8a\x74\x36\x4a\x71\x8e\x6a\xe4\x64\x3e\x10\x36\x99\x49\x8f\x89\xaf\x2c\x8e\x44\x29\x07\x4c\xac\x66\x10\x18\x16\xe9\x9f\x6c\x84\x0c\xf7\x72\x4d\x7c\x41\x65\xce\x5b\xa9\xf3\x95\x2e\xb6\xb9\xbd\xb2\x26\xcb\xa3\x93\x29\xe2\xf4\xc0\x4b\x2b\x52\x6a\x22\xa9\x7c\xfa\xee\xf6\x0e\x6a\x02\x82\xd8\x83\x84\xdb\xa1\xae\x15\x36\x09\x4a\xea\x0c\x6d\x18\x99\x59\x53\xf0\x2a\xa8\xd3\xd2\x48\xed\xf9\x47\xa2\x24\x6a\x0f\xae\x9a\x16\x74\x68\xe9\x80\xa1\xf3\xa4\x87\x21\xbc\x61\xfc\x83\x29\x42\x55\xa6\xc2\x63\x3a\x84\x2b\x0d\x6f\x44\x81\xea\x8d\x70\xf8\xbb\x8b\x9a\x24\xea\x06\x24\xbe\xe3\x85\xdd\x85\xef\xcd\x09\x1b\x06\x05\x50\xc3\xeb\x4e\xed\xac\xe0\xc7\x6d\x89\x49\x8d\x21\x34\x93\x31\x43\xe8\x35\x90\xa9\x55\x34\x3c\x96\x08\xda\x32\x13\x95\xf2\xeb\x94\x00\x54\x65\x6e\x45\x8a\xb7\xde\x12\xac\x2f\xc7\xf0\x36\x8c\x5c\x1b\xb8\xcb\xdc\x99\x45\x54\x98\x78\x63\x37\x7b\xd6\x58\xbd\x8d\x03\xe3\x8c\xc0\xe6\x0a\x6b\x2f\xdd\x7e\xdc\x3a\x82\xd3\x43\xd4\xd2\x57\x08\x9f\xcc\xbe\x7b\xa2\x33\xdd\x71\x09\x07\xa8\x5f\x9f\x14\x2c\x8a\x3c\x1b\xa1\x91\x12\x53\x54\x8d\x28\x6a\x24\x2d\x82\xc9\xdc\xcd\x70\xa5\x05\x84\x45\xb8\xbc\x7e\x8b\xe9\x36\xe6\x5a\x06\x85\xb5\x62\xb9\x63\x84\xf4\x58\xec\x24\x7c\x8d\xf4\xcb\x3d\xe4\x45\x60\xa8\x7b\xfc\x4c\xb0\x2f\xf2\xec\x89\x02\xe8\xf5\x41\xc0\x23\x2e\x03\x3e\x12\xec\x46\x95\x85\xc1\x16\x19\x4d\x59\x99\x8f\xb8\xe4\x41\x11\x2c\x77\x52\x77\x40\x7f\xe1\xdb\xee\x8d\x56\xbf\x01\x6d\xb9\xb7\xbf\x26\x76\xe7\xa0\x43\x87\x25\x7c\x8f\xb8\xdc\xd7\xbd\x26\x70\x92\x43\x34\xe3\x20\x79\x6a\x60\x69\xb1\x65\xd7\xc2\x16\x65\xa9\x24\x32\x1a\xee\x5d\x7b\x27\x1c\xad\x7e\x35\xab\xcf\x20\xb4\x51\x65\x8b\xf0\x41\xd9\x2f\x5d\x50\x2c\x9d\xf4\x99\x2c\x63\x90\x11\x42\x8b\xda\x15\xfe\x28\x94\xec\x84\x31\x7c\xaa\xaf\x74\x1f\xae\x8d\xa7\x3f\xdf\x3d\x49\x82\x7a\x3a\x0f\x6f\x0d\xba\x6b\xe3\xb9\xe5\x37\x61\x35\x90\xf0\x0c\x46\xc3\x04\x3e\xec\x3a\xd8\x15\x71\xd2\xf5\x87\x14\x86\x65\xac\x9f\x46\x28\xd2\x91\x47\x32\xb6\xe6\x88\x23\x94\xb0\x50\x58\xa2\xa8\x1c\x3b\x30\x6d\xf4\x00\x8b\xd2\x2f\xb7\xae\x11\x05\x61\xec\x8a\x1c\xf6\x2c\x17\x97\xba\x23\xbf\x1a\x7a\x42\x04\xa4\x28\x94\x85\xb4\x62\xa2\xd9\x9b\x13\x68\xcb\x04\x0a\xb4\x39\x42\x49\x08\x75\x8c\x78\xf7\xe1\x4a\xf8\x0e\xa0\xcb\x91\xba\x62\xc8\x7c\x4f\x06\xf0\x0c\x88\x0d\xe3\x03\x2c\x15\xa2\x24\x35\xfd\x44\xe8\xc3\x92\xfa\x19\x4a\x21\x29\x62\xbe\xe4\xe8\x5f\xe1\x4a\x9f\xd4\x2c\xd3\xee\x32\xb4\x82\x74\x40\x50\x32\x17\x8a\xf0\x8e\x4e\xb2\x06\x54\x01\xfd\x28\x48\x5f\x03\xf6\x3e\x2c\x66\xc6\x05\x30\xcb\x24\x2a\x8e\x9d\x7a\x8f\xb8\xec\xf5\x37\x54\xdb\xbb\xd2\xbd\x80\x8b\x1b\xca\x6c\x40\xd4\x68\xb5\x84\x1e\xf7\xf5\x7e\xb9\x2f\xd8\x0b\x96\x22\x4d\x39\xbd\x14\xea\xe6\x08\x34\xdb\xab\x37\x87\x76\x2e\x13\xbc\x4c\x12\x53\x69\x4e\xbc\x8e\xf0\xeb\xeb\x53\x6a\xf0\x13\x69\x21\xf5\x4a\x6e\xc2\x23\x41\x84\xa1\xb0\x98\xc9\x64\x06\x0b\xa9\x14\x87\x81\x0e\x53\x52\x4f\x8a\xa5\x32\xcb\x46\xce\x67\xee\x3c\x68\x96\xe2\xd1\x5a\xf6\x9c\xe9\xed\x0e\x0d\x76\x31\x47\xe9\x43\x72\x63\xcd\x5c\xa6\x98\x5e\xde\x5c\x6d\x95\xd2\x2a\x73\x3c\x05\x3c\x2a\xe5\x38\x7d\xa3\x98\xd5\x9b\x18\xb3\x6e\x0d\x61\xca\xce\xfa\x9d\x24\x7f\x27\xb1\x53\x63\x14\x8a\xcd\xfe\x10\x0a\x35\x49\xec\x61\x5a\xef\xd6\x26\x44\xb8\xc3\xa7\x52\xc9\x44\xfa\x1a\xbf\xdb\xd8\x8a\xf3\x21\x9e\xc4\xc0\x25\x39\x1a\x70\xe8\xfb\x6d\xac\x26\x1d\xc8\x5c\x1b\xbb\xfd\x7c\xee\xc7\x93\x3d\x28\x72\x00\x3b\x9e\x06\x8f\xd5\x14\xad\x46\x8f\x6e\x40\x31\xd6\x20\x4e\xc0\x4d\x13\x58\x0f\x61\x0f\x49\xa9\xf7\x79\x75\xc2\x4a\x02\x1a\x17\xab\xb1\x35\x64\xed\x2b\xc9\x37\x8d\x6a\x24\xc8\xf6\x6c\x91\x8d\x38\xa9\xac\x45\xed\xd5\x12\xfc\xc2\x80\xab\xca\xd2\x58\x8f\xe9\xfa\x92\x64\x9a\x30\xd1\x75\xa0\x3d\xe6\x43\xc5\x26\xc0\x40\x21\x94\x32\x0b\x48\x54\xe5\x3c\xda\x68\x59\x31\x53\x66\x75\x15\x66\x8e\x75\x1a\x1b\x5c\x02\x39\x83\x72\x26\x1c\xb6\x39\x98\xab\x92\x04\x31\xc5\x34\x74\x44\x57\x82\x59\x86\x89\x97\x73\x54\x4b\x28\x50\x70\xa5\x41\xf8\x76\x7f\x3a\xd9\x61\xfb\x96\xe1\xb5\x1d\x35\x3e\xf9\x3a\x49\x07\xc9\x49\xf8\x6a\xa5\xc2\x36\xec\xce\x84\x83\x4c\x48\x45\x79\xdd\x44\xc3\x1d\x26\xb3\x1b\x8b\x73\x89\x8b\xcf\xda\x89\x0c\xdf\x09\xa9\xde\x19\xbb\x10\x36\xed\xc8\xe0\xf7\x60\x9f\xa8\x6a\xfa\x02\x49\xb5\x5c\x2e\x1b\xe0\x54\xcb\x7e\x4b\x45\x8e\x9a\x04\x40\xfc\x2e\x6a\x06\x6f\x14\x49\x6c\x31\x43\x4d\xae\xb7\x9a\x36\x27\x0a\x2c\x66\x68\x51\x93\x3d\x89\x7a\xfd\xce\xa4\xc6\x3d\x24\xc2\x0b\x65\x72\x96\xcc\x14\x51\xd7\x79\x2f\x2c\xa4\x9f\x81\xe0\xcd\x6a\xe9\x65\x1c\x5e\x23\x20\x85\x0a\xc4\x62\xb4\xdd\x4e\xd1\x68\xa2\xe1\x3f\x2f\x3f\x5d\x5f\x5d\x7f\x3f\x66\xaf\xb2\x4f\xc2\x9b\xe7\x5a\x3a\xa8\x78\x54\xa7\xea\xe1\x2a\xe5\xe9\x88\x57\x1a\x9f\x4a\x4c\x88\xb4\x29\xce\xc4\x5c\x92\x0d\xd8\x58\x0f\x99\xa3\x15\x53\x85\x40\x69\x30\x28\xe3\x68\x1d\x85\xce\xc1\xd2\x54\x30\x13\x73\x84\x14\xb1\x84\x4a\xa7\x68\x9d\x17\x3a\x25\xea\x4d\x16\x23\xdf\x55\x26\x60\x8a\xd4\x5b\x57\xc4\x36\xac\xab\xf7\x5c\x80\x6f\x33\xdd\x1d\x89\x2c\x7d\xa8\xab\x62\x3b\x2a\x0d\xf6\xcc\xa2\xde\x7d\x22\x5e\x4d\xfb\xbd\xf0\xd5\x06\xf4\xed\x49\xfc\x79\x7c\x93\xfa\x87\x5f\xdb\x92\xff\x4f\xcf\xcf\xfd\x77\xe7\x51\x03\x50\xc2\xf9\xcf\xe1\x14\x3e\x23\xe3\x4f\x8c\x0e\x66\x73\xd8\x25\xbd\x69\x86\xae\xc7\xde\xdb\x3c\x67\xbb\xf0\x6f\xea\x6c\x56\xe1\xbf\x21\xa9\x0d\xd1\x52\xf4\x42\xaa\x20\x71\xa3\x11\x04\x85\x2c\xbe\xa6\x32\x02\x3b\xab\x05\x9b\x8a\xe4\xe5\xcd\x15\x34\xda\x80\xc1\x60\x10\x40\xd6\x79\x5b\x25\xec\x47\xa5\xf6\xa8\x09\x84\x68\xd5\x54\x5a\x2e\x29\x3a\x5a\xbc\x95\x43\xcc\x08\x43\x98\x59\x0a\x3f\x83\x61\x50\xfe\xb0\x23\x0a\x80\x77\xc6\x02\x3e\x89\xa2\x54\xd8\x27\xbb\x27\x49\xc0\x3b\x63\xe2\xb1\x09\x7b\xfe\x04\xa3\x11\x7c\x6a\xf3\x38\x8e\x55\xa7\x14\x72\x85\x34\x8e\x8b\xa6\x90\x19\x43\x82\xee\xb2\x34\xa4\x89\x3f\x68\xb3\xd0\xdb\x76\xe7\xbd\x84\xc5\x31\x4c\x7a\x97\x73\x21\x15\x59\xff\xa4\xd7\x87\x49\xef\xc6\x9a\x9c\xa3\x66\x9d\x4f\x62\x18\x3c\xe9\xbd\x45\x46\x9a\x74\xd2\xa3\x65\xff\x95\x93\x92\x0f\x94\x9f\xfc\x80\xcb\x6f\x78\xb1\xa6\xb9\xf6\xc0\xdf\x84\xfc\x85\xda\xc9\xd7\xdf\x2d\x4b\xfc\x86\x02\xf7\xba\xe1\x83\x28\x9b\xc9\x9d\x03\x75\xff\x50\xa0\x17\xf3\x8b\x61\xab\xd1\xbf\xfc\xd5\x19\x3d\x9e\xf4\x5a\xfa\xfb\xa6\xa0\x93\x51\xfa\xe5\xa4\x07\x2b\xbb\x8e\x27\x3d\xde\xb7\x6e\xaf\x89\x1c\x4f\x7a\xb4\x13\x35\x5b\xe3\xcd\xb4\xca\xc6\x93\xde\x74\xe9\xd1\xf5\x2f\xfa\x16\xcb\x3e\xe1\xd3\x37\xed\x0e\x93\xde\x5f\x48\x27\xa3\x11\x18\x3f\x43\x1b\x94\xe9\xe0\xe7\x6d\xe0\x75\x44\x34\x7f\xa8\xec\x11\x8c\xf6\xce\x0a\xed\x64\x7d\xf9\xb3\x73\x68\x81\xce\x89\x7c\x77\xbf\x45\xe1\xb6\x46\xa6\xa1\x3b\x9c\x86\x9d\xdd\xc4\xcb\xd6\xce\xc3\x35\x95\x4d\x1e\x8e\xac\x65\x6d\x4e\x6c\x2b\x2d\xce\x83\xa7\x06\x36\xda\xe6\x4c\xf8\x66\x34\xd9\x22\xc5\x01\x64\xe2\x11\x63\x39\x1b\x64\xbd\xc5\x20\x29\xde\x21\x4c\x31\xb8\xfa\x70\x9b\x93\xa2\x55\x4b\xf2\x54\xed\xaa\xc9\x4c\xe8\x9c\x62\x9b\x90\xf1\x0b\x36\x79\x8a\xa0\x1e\xc9\x90\x38\x53\xd4\x50\xb9\xba\xb6\xce\x74\x35\x2b\x12\x76\x04\x9b\x8f\xcb\x30\x38\x26\x09\x96\x9e\xac\xeb\x50\xe1\xec\x40\x79\x24\x33\xb6\x10\x7e\x4c\x1e\x1a\x07\x7e\xf7\xf1\x88\x87\xe3\x48\xc1\xc7\xd1\x21\x31\x9f\x55\x85\xa0\xc0\x47\xa4\x1c\x0b\x34\x7d\x3a\x95\x89\xe0\x78\xa5\x86\x54\x31\x35\x55\x00\xb9\x56\x0f\x51\xd4\x14\x74\x4c\x91\x33\x14\xb2\xcf\xc8\xd6\xaf\x64\xbe\x10\x4f\xef\x51\xe7\x7e\x36\x86\x2f\x5f\xff\xfb\x57\x7f\xde\x31\x30\x00\x23\xa6\xdf\x87\x48\x6f\xcb\x7d\xd5\x0e\x31\x6c\x4e\xec\xd6\xce\x88\xcf\x61\x7d\x49\x30\xcc\xdb\x31\x4d\xf1\xaf\x3d\x41\x0b\xc1\xb9\x16\x4c\x85\xe3\x2c\x81\xe4\x42\x40\xcf\xa1\xa3\x4e\xb0\x4f\x01\xf6\xd6\xc5\xa4\xeb\x24\x1b\x17\xaf\xfb\x30\x8d\x22\xde\x84\xef\xfb\xa7\x87\xe1\x16\x92\xa5\x83\xaf\xfb\x6b\xf4\x50\x7a\x5d\xb1\xd3\xe3\xcc\x96\x83\x52\x8b\xc1\x13\xc6\x88\x7b\x8b\x27\xc4\x86\xde\x43\x8a\x23\x7f\x98\xe3\xee\x42\x6c\x7d\x6c\xa5\xf6\x5f\xfd\xdb\x6e\xfd\x4a\x2d\x8b\xaa\x18\xc3\xab\x1d\x43\x02\xa4\x1d\xa9\xcd\x30\xb8\x0d\x04\x04\x41\x57\x6e\x45\x51\x70\xd6\x2f\x53\xd4\x5e\x66\x12\x6d\xf7\x68\x87\xdc\x83\x27\xd6\x61\x7a\x23\xc5\x97\x2e\xe2\x50\xe7\xb0\xdf\x58\x93\x56\x09\x5a\xf6\xc0\xb1\x18\x92\x74\x01\x6a\x59\x62\xb0\x86\x90\x89\x42\x13\x7d\xd7\x05\x25\x8a\xd0\x51\x68\xa9\x73\x17\xb7\x94\x2e\x00\x48\xf0\xba\x8b\x19\xb2\xeb\x59\x29\x42\x31\x55\x4e\xa6\x68\x31\x05\x01\x79\x25\xac\xd0\x1e\x31\x25\xf8\x09\x85\xa8\x70\x11\xd8\x42\x9e\x68\xaf\xdf\x6a\x6b\x0c\xa6\x1a\xc0\x8a\x48\x8c\x57\x76\xa1\x44\xf9\x9b\x99\xea\xc5\xab\xd7\x7b\x55\xde\x8c\xdb\x5d\xc6\x17\xde\xa3\xd5\x63\xf8\xef\xfb\xcb\xc1\x7f\x89\xc1\xdf\x1f\xce\xe2\x3f\xaf\x06\x5f\xff\x4f\x7f\xfc\xf0\x45\xe7\xe7\xc3\xf9\xb7\xff\xb2\x63\xa5\xed\x91\xfb\x8e\xe3\x13\x9d\x48\x1d\x27\xd6\x1a\xed\xb3\x87\x31\x19\xdc\xd9\x0a\xfb\xf0\x4e\x28\x87\x7d\xf8\xac\xd9\x35\xfc\x4a\xa1\xed\x4e\x5e\xc2\x37\x80\x1e\xed\xba\x3d\xf8\x68\x86\x30\x49\xfb\xc7\x44\x72\xf7\x15\x25\x8f\x13\x12\x87\x6d\x26\xeb\x22\x4d\xe7\x9a\x17\x18\xf1\x28\x2c\x1d\xc6\x08\x77\x98\x98\x62\xd4\xb9\x06\xa6\xd0\xfa\x83\xd0\x4b\x68\x61\x2d\x04\xa5\xeb\x27\xdd\x79\xc2\x26\x91\x58\x4a\x4a\x9b\x8b\x74\x50\xf2\x11\xa1\x89\x5c\x03\x58\x4e\x31\x11\x1c\x8b\xdb\xa9\xf4\x56\xd8\x65\x27\xf5\x80\x44\xe8\x58\x8e\xcc\x2a\x05\x67\x0e\x11\x86\xda\xa4\xb8\x89\xae\xe7\x01\x43\xc5\x54\x2a\xe9\x97\xa1\x76\x99\x18\x9d\x29\x19\x53\x80\xa2\x34\xd6\x0b\xed\xeb\xba\x6f\x8e\x4f\x20\x7d\x28\x39\x87\xfa\xdc\x59\xaa\xdd\xc5\xc5\xeb\x2f\x6f\xab\x69\x6a\x0a\x21\xf5\xbb\xc2\x8f\xce\xbf\x3d\xfb\x5b\x25\x14\x17\x4d\xaf\x45\x81\xef\x0a\x7f\xfe\xdb\xb9\xc5\x8b\xaf\x8e\xb0\xa2\xb3\xfb\x60\x2b\x0f\x67\xf7\x83\xf8\xdf\x17\x75\xd3\xf9\xb7\x67\x93\xe1\xde\xfe\xf3\x2f\x88\x87\x8e\x05\x3e\xdc\x0f\x5a\xf3\x1b\x3e\x7c\x71\xfe\x6d\xa7\xef\x7c\xd3\x18\x3b\x89\xe9\xc1\x1c\xf3\x7d\x3b\x36\x44\x27\xbe\x7e\x0f\x55\x5b\xe6\x6a\x68\xb8\x9e\x75\x46\x2b\x26\x7f\x1c\x97\x79\x76\x61\xf9\x98\xa0\x4b\x1f\x5f\xc8\x5d\x2d\xe1\x76\x2a\x27\x1b\xb7\xe3\x8d\x07\x5a\x61\xea\x9f\xb5\x54\xbb\x7a\xb9\xf0\x09\xb3\x67\xde\x2d\x7c\xc2\xac\x5b\x6d\x0b\x82\x59\xbd\x52\x88\x2f\x56\x9a\x3b\x87\xdf\xe1\xf9\xc0\xee\x37\x4e\x5b\x59\xa0\x60\xbf\x2e\x99\xc6\xf3\x18\x79\xd8\x79\x17\x7a\xd0\xa4\xd9\x1f\xdf\x08\x3f\x3b\x8a\x82\x97\x57\x51\x6c\x7c\x71\xc8\x57\xb9\xa5\xc4\x04\x57\x9e\x51\x71\x1c\x87\x22\x8d\x8d\x14\xf8\x58\x8c\x7d\xfd\x10\x71\xc4\xeb\xd2\xf6\x99\x15\x05\x4d\x20\x08\x88\x65\x0a\xff\x71\xfb\xf1\x7a\xf4\xbd\x89\xb1\x02\x65\x33\x2e\xd8\x16\x5f\x74\xf5\xc1\x55\xc9\x0c\x84\x23\xd2\x28\xbf\xbd\xe5\xd2\x43\x21\xb4\xcc\xd0\xf9\x61\x5c\x0d\xad\xbb\x7f\xfd\x30\x5c\xad\x78\xc8\x78\xa7\x5a\x3f\x46\x8a\x07\x80\x6d\x83\x98\x69\xe6\x72\xd0\xca\x24\x95\x26\x8d\x44\x2f\x98\x58\x2f\x1e\x11\x4c\x24\xb6\x42\x76\x0a\x63\xe8\xd1\x31\xe9\x6c\xfd\x13\x19\xd6\xcf\x3d\x38\x5b\x70\x55\xbf\x47\x3f\x7b\x61\xc3\xe6\xed\x18\xb5\x75\x3c\x7e\xdc\x38\xc4\xf7\x56\xe6\x39\x87\x5b\x5c\xba\x9d\xa3\xf6\xe7\xec\xdf\x32\xd0\xa6\x33\x58\xc7\x2b\xb2\xf6\x62\x6c\x9d\x90\xfb\xd7\x0f\x3d\x38\x5b\xe5\x8b\x42\x50\x7c\x82\xd7\xcd\x65\x58\x69\xd2\xf3\x3a\x6b\x5d\x6a\x2f\x9e\x38\x31\x98\x19\x87\x3a\xdc\x25\x78\x13\x0a\xb2\xce\x50\xf2\x89\x4a\x0d\x42\x80\x99\xc2\x22\xd4\xe0\x6a\x51\x86\xfb\xe4\x52\x58\xbf\xf6\xb2\xee\xee\xe3\xdb\x8f\xe3\xb0\x1b\xa9\x2d\xd7\x75\x96\x9b\x49\x2d\x54\xac\x6c\x37\xf1\x21\x11\x52\x05\x25\x79\x13\x53\xdb\xba\xa8\x9b\x55\xbe\xb2\x38\x5c\x7f\x69\x75\xf4\x89\xdf\xf6\xcc\x6d\xfb\x61\xe7\xe7\x6e\xeb\x86\xf6\x7f\xf8\x98\xec\x68\x16\xf5\x8e\xcb\xd6\x4d\x16\xaf\x3b\x67\x70\x2f\x8b\x2d\x34\x13\x97\xa9\x49\x1c\x31\x98\x60\xe9\xdd\xc8\xcc\x09\x3a\x71\x31\x5a\x18\xfb\x28\x75\x3e\xa0\x43\x36\x08\x9a\x77\x23\x76\x31\xa3\x3f\xf1\x9f\x5f\xc5\x11\xfb\xa9\xe3\xd9\x0a\x6f\x5a\xff\x01\xbc\xb1\xfb\x1c\xfd\x62\xd6\xea\xf8\xf2\x39\x9e\xe0\xe5\x6d\x9d\xfc\xad\xcd\x26\x73\x09\x77\xe1\xf1\xb1\x6b\x07\xe1\x0a\x91\x06\x08\x14\x7a\xf9\xbb\x1f\x63\x12\x20\xe7\xf8\xc9\x72\x10\x5f\xa3\x0f\x84\x4e\x07\x4d\x7c\x9d\x2c\x7f\xb1\xc4\x2a\x79\xa4\x01\x7f\xbe\x7a\xfb\x8f\x39\xdc\x95\x7c\x96\xb5\x86\x2a\xca\x18\xbc\xad\xea\xe8\xce\x79\x63\x45\x8e\xab\x6d\xd5\xb4\x49\x3e\x5a\x86\x63\x5e\x09\x3f\xfd\xcc\x4d\xed\xfb\x73\xa1\xca\x99\x78\x5d\xcf\x3d\xbd\x42\x3f\xbd\x42\x3f\xbd\x42\x3f\xbd\x42\xdf\x2b\xec\x3f\xea\x2b\xf4\xd3\x2b\xf2\xd3\x2b\xf2\xd3\x2b\xf2\xdd\xdd\xa7\x57\xe4\xa7\x57\xe4\xa7\x57\xe4\xeb\xdf\xe9\x15\xf9\xe9\x15\xf9\xe9\x15\xf9\xe9\x15\xf9\x96\x6f\xa7\x9a\xfe\x7f\xbf\xbf\x3c\x5d\x8e\xfd\x31\x2e\xc7\x4e\xd7\x5d\xa7\xeb\xae\xd3\x75\xd7\xe9\xba\xeb\x17\x9c\xf8\xd3\x75\xd7\xe9\xba\xeb\x74\xdd\x75\xba\xee\xfa\x27\xbd\xee\xca\x84\x72\x47\xdf\x77\xfd\x6f\x00\x00\x00\xff\xff\x43\xb0\x74\xb5\x37\x4b\x00\x00") func operatorsCoreosCom_operatorgroupsYamlBytes() ([]byte, error) { return bindataRead( @@ -205,7 +205,7 @@ func operatorsCoreosCom_operatorgroupsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\xcd\x72\xe3\x36\x12\xbe\xfb\x29\xba\x94\x83\x93\x2a\xfd\x24\xb3\x97\x94\x6e\x2e\x7b\xb2\xe5\xdd\xac\x67\x6a\xec\x99\x4b\x2a\x87\x16\xd9\x12\xb1\x02\x01\x06\x0d\x4a\xd6\x4e\xcd\xbb\x6f\x35\x00\x4a\xa4\x24\x4b\xd4\xac\x27\x1b\x5c\x24\x82\x40\xa3\x7f\xbf\xee\x06\xb1\x52\x9f\xc8\xb1\xb2\x66\x0a\x58\x29\x7a\xf6\x64\xe4\x89\xc7\xcb\x9f\x79\xac\xec\x64\xf5\xd3\xd5\x52\x99\x7c\x0a\xb7\x35\x7b\x5b\x7e\x20\xb6\xb5\xcb\xe8\x8e\xe6\xca\x28\xaf\xac\xb9\x2a\xc9\x63\x8e\x1e\xa7\x57\x00\x68\x8c\xf5\x28\xd3\x2c\x8f\x00\x99\x35\xde\x59\xad\xc9\x8d\x16\x64\xc6\xcb\x7a\x46\xb3\x5a\xe9\x9c\x5c\x20\xde\x1c\xbd\xfa\x71\xfc\xf3\xf8\xc7\x2b\x80\xcc\x51\xd8\xfe\xa4\x4a\x62\x8f\x65\x35\x05\x53\x6b\x7d\x05\x60\xb0\xa4\x29\xd8\x8a\x1c\x7a\xeb\x78\xbc\xfb\x97\x59\x47\x56\x7e\xca\x2b\xae\x28\x93\x83\x17\xce\xd6\x55\x7b\x75\x6b\x4d\x24\xd5\xf0\x87\x9e\x16\xd6\xa9\xe6\x19\x60\x04\x56\x97\xe1\x7f\x94\xfb\x5d\xa2\x11\xa6\xb4\x62\xff\xcf\xce\xf4\xaf\x8a\x7d\x78\x55\xe9\xda\xa1\x6e\x9d\x19\x66\x59\x99\x45\xad\xd1\xed\xe6\xaf\x00\x38\xb3\x15\x4d\xe1\x56\xd7\xec\x49\x26\x92\x1e\x12\x0f\xa3\x24\xeb\xea\xa7\xc4\x12\x67\x05\x95\xd8\x30\x08\x42\xca\xdc\xbc\xbf\xff\xf4\xb7\xc7\xbd\x17\x00\x39\x71\xe6\x54\xe5\x83\x56\x1b\x1e\xc1\x51\xe5\x88\xc9\x78\x06\x84\x2c\x1e\xbb\x65\x68\xdc\xda\xee\x37\xc2\x98\x9d\xfd\x9b\x32\xdf\x9a\xae\x9c\x2c\xf6\x2d\x2d\xc5\xd1\xf2\x9e\xce\xfc\x1e\x1f\xd7\xc2\x6c\x5c\x07\xb9\x38\x0e\x31\xf8\x82\x1a\xb1\x29\x4f\x12\x82\x9d\x83\x2f\x14\xef\xf8\x0d\xbe\x20\xd3\x68\x12\x57\x63\x78\x24\x27\x1b\x81\x0b\x5b\xeb\x5c\x3c\x6c\x45\xce\x83\xa3\xcc\x2e\x8c\xfa\xcf\x96\x1a\x83\xb7\xe1\x18\x8d\x9e\xd8\x83\x32\x9e\x9c\x41\x0d\x2b\xd4\x35\x0d\x01\x4d\x0e\x25\x6e\xc0\x91\xd0\x85\xda\xb4\x28\x84\x25\x3c\x86\x7f\x59\x47\xa0\xcc\xdc\x4e\xa1\xf0\xbe\xe2\xe9\x64\xb2\x50\xbe\x89\x8d\xcc\x96\x65\x6d\x94\xdf\x4c\x82\x9b\xab\x59\x2d\x76\x9f\xe4\xb4\x22\x3d\x61\xb5\x18\xa1\xcb\x0a\xe5\x29\xf3\xb5\xa3\x09\x56\x6a\x14\x98\x35\x21\x3e\xc6\x65\xfe\x9d\x4b\xd1\xc4\xd7\x7b\xea\x8b\x76\x60\xef\x94\x59\x74\x5e\x05\x9f\x3c\xa9\x6b\x71\x4f\x50\x62\xe8\xb8\x3d\xca\xb2\x53\xa9\x4c\x89\x56\x3e\xbc\x7d\x7c\x82\x86\x81\xa8\xf6\xa8\xe1\x96\xb7\xec\x94\x2d\x8a\x52\x66\x4e\x2e\xae\x9c\x3b\x5b\x06\x2a\x64\xf2\xca\x2a\xe3\xc3\x43\xa6\x15\x19\x0f\x5c\xcf\x4a\xe5\xc5\x8a\x7f\xd4\xc4\x5e\xec\x30\x86\xdb\x00\x0d\x30\x23\xa8\xab\x1c\x3d\xe5\x63\xb8\x37\x70\x8b\x25\xe9\x5b\x64\xfa\xe6\xaa\x16\x8d\xf2\x48\xd4\xd7\x5f\xd9\x6d\x64\x3b\xdc\x70\x10\x25\x00\x0d\xfc\xbc\x68\x9d\x26\x22\x1f\x2b\xca\x3a\xa1\x90\x13\x2b\x27\xae\xeb\xd1\x93\x38\x7c\x07\x76\xfa\x1c\xed\xd1\xd7\xdc\xef\xf0\xb0\xb4\x73\xbc\x9d\xb1\x18\xba\x75\x3e\x9a\x1d\x7c\x48\xa4\x88\x41\x33\x5b\x56\xd6\x88\x63\xf4\xe5\xea\x65\xe8\x80\x90\x1c\x1a\x7a\x87\xef\xf6\x78\xbf\xdd\x2e\x4d\xf3\x33\xe2\xad\xf7\x8a\x0c\xe8\x23\x39\xa6\x28\xd0\x11\x70\xeb\xc1\xad\x0c\x71\x5b\xb1\xc5\x31\x9e\x04\x9c\x35\xce\x48\x3f\x92\xa6\xec\xd0\x3c\xe7\x24\x96\xd1\xd9\x7f\x7c\xc9\x9e\xf0\xbf\xb6\x77\xc4\xd8\x0e\x44\xe0\x8f\x9a\xdc\x06\xec\x8a\x9c\x84\x3b\x79\x31\xdc\x4e\x29\x35\x53\x2e\x18\xc8\x61\x67\x47\x2d\xd7\x27\x8c\xd9\x53\x4d\x7d\x44\x95\x51\xa2\xcf\x8a\xb7\xcf\x02\x29\xad\x1c\xd7\x43\xea\xfd\x8d\x49\x70\xc5\x41\xcc\xa8\x00\x6e\x94\x92\x8c\x56\x46\xd4\x7a\x2a\xa8\x33\x03\xe8\x08\x6e\x1e\xee\x28\x3f\xe6\x0f\x5d\x81\xd1\x39\xdc\x9c\x58\xa5\x3c\x95\x27\x85\xd8\x13\xe3\xe6\x04\xab\x09\xa7\x9b\x37\xc9\x8b\x8d\x47\x65\x38\xe5\xa0\x21\x20\x2c\x69\x13\xd3\x95\x64\xc1\x26\x28\xc3\x62\x47\x21\xb9\x05\xdb\x2e\x69\x13\x16\xa5\xdc\x75\x92\xc3\x1e\xb6\x8d\xe3\x74\x30\xec\xc6\x48\x8e\x3f\xbb\xc6\x1e\x07\xb5\xee\xe8\xe3\x54\x71\x2c\x69\x73\x6e\xc9\x9e\x31\x44\x47\x8a\x53\x55\x20\x56\x91\x89\xa0\x49\x99\xda\x1a\x02\xab\x4a\x2b\x0a\x89\xeb\x2c\xfd\x17\xb3\xc7\xe1\x68\xc4\xbf\x90\x69\x7b\xb4\x8c\x5b\xd2\xe6\x9a\xa3\x03\x48\x74\x14\xaa\x92\x58\xdf\xc2\x40\x53\xc1\x7c\x42\xad\xf2\x5d\x51\x1a\x22\xe1\xde\x0c\xe1\xc1\x7a\xf9\x79\xfb\xac\x24\x43\x8b\xdf\xdc\x59\xe2\x07\xeb\xc3\xcc\xab\x8a\x1d\x59\xb9\x50\xe8\xb8\x29\x04\x88\x89\x31\x29\x52\xb5\x4b\x1a\x1e\xc3\xfd\xbc\x83\x6a\xb2\xfa\xde\x80\x75\x8d\x74\xa1\xc8\x8c\x84\x22\x89\xb2\xe6\x50\x83\x18\x6b\x46\x54\x56\x7e\x73\x94\x46\x52\x8a\x75\x1d\x9d\x9c\x20\x97\x48\x3d\x49\x69\x14\xdf\xc4\x22\x56\x63\x46\x39\xe4\x75\x60\x3a\x14\x64\xd2\x6e\xa8\x0c\x4a\x72\x0b\x82\x4a\x10\xae\xaf\xaa\xcf\xe1\x52\x1c\x3d\xd0\xa9\x4d\xf4\x8c\xfd\x02\x04\x87\xec\x73\x21\x6c\xc7\x3d\x11\xde\x4a\xac\xc4\x74\x9f\x05\xc5\x82\xf6\xbe\x40\x85\xca\xf1\x18\x6e\x42\x7b\xa4\xa9\xf3\x4e\x99\xa0\xe7\x36\x19\xa1\xa0\x18\x04\x8a\x56\xa8\x05\x37\xc5\xd3\x0d\x90\x8e\x28\x6a\xe7\x07\xc9\x62\x08\xeb\x42\x6a\x01\x89\xef\xb9\x22\x1d\x4a\xe2\xc1\x92\x36\x83\xe1\x81\xb9\x07\xf7\x66\x10\xf1\xf5\xc0\xc0\x5b\x30\xb6\x46\x6f\x60\x10\xde\x0d\xfe\xb7\xfc\x72\x16\x74\x31\xcf\x43\x63\x8d\xfa\x7d\x4f\x24\x3c\x6b\x4b\x47\xf3\x17\x49\x74\x8c\xf7\x81\xe6\x51\x98\x56\x39\x31\x27\x47\x26\x14\x59\xf6\xc5\x1a\x62\x57\x75\x0c\x13\x8a\x52\x0e\x6b\xe5\x8b\x6e\xed\xf2\x92\x76\xce\x7b\xf8\x19\xbf\xee\x0a\xa1\xb2\xe2\x43\xc3\x76\xf4\xc1\xad\x14\x11\x23\x1b\x6e\x87\x40\xc6\xa9\xac\x68\x98\x95\x22\x37\x16\xd2\x62\xf9\x68\x86\x13\x99\xb4\x97\x41\xfb\xa5\xb3\x97\x3b\xe9\x13\x82\xde\xbc\xbf\x6f\x7a\xe8\xd8\x3a\x53\x23\xe8\x19\x00\xef\x09\xde\x3b\x1d\x5c\xc0\xd4\xed\x76\x53\x3b\x5f\xb5\xfa\xf0\x6d\x8b\x11\x5a\xc6\xc6\x83\xfa\x30\x7c\x1e\x02\x7b\xc1\xdf\x71\x76\x77\xdc\xb6\x99\xc5\x15\x2a\x8d\x33\xdd\xb4\x48\x31\xd9\xa6\x06\x69\xcb\xfc\x75\x74\x1b\x3a\x87\xe5\xbd\xcb\xae\xfe\x85\x97\x94\x55\xd1\x65\x7b\x2c\x94\xf3\xcf\x2c\xeb\x5f\x7d\x49\x27\xc3\xfe\xc9\xa1\x61\xd5\x5c\xd9\xf5\xc9\x3c\x7b\xad\x0d\x7b\xf0\xaa\xa4\xe4\x0d\x8d\x31\xfc\x96\x2c\xe5\xf1\xb6\xc1\x1a\x6a\x62\x33\xa0\xbf\xf5\x05\xbd\x08\x28\xed\x71\x41\xa5\x22\x63\x6e\x5d\x89\x7e\x0a\x39\x7a\x1a\x09\x67\xbd\xd4\xf0\x31\x5c\x6a\xbc\xaa\x0a\xd6\xc8\x62\x8d\x19\xe5\x7f\x05\x21\x4b\x62\xc6\xc5\xe5\xd2\xdd\x40\x51\x97\x28\xd1\x85\x79\x88\xa3\x44\x08\x94\xc9\x55\x86\xe1\x3a\x2a\x27\x8f\x4a\x33\xe0\xcc\xd6\x31\xfa\x76\xe6\x7f\x75\x0b\x3b\x42\x3e\x87\xb2\x47\xe4\x88\x29\x5f\xb6\x8a\xf2\xba\xa6\xba\xe6\xe0\x03\xdf\x92\xeb\xe3\xd7\x3b\x67\xb9\x4e\x57\x3d\x5b\xb0\x4d\x0c\x0f\x43\x34\xd9\x39\x3c\xb9\x9a\x86\xf0\x0b\x6a\xa6\x21\x7c\x34\x4b\x63\xd7\xaf\xcf\x7b\x58\x7c\xb1\xbe\x37\x55\xe0\x70\xcb\xf3\x2b\xb2\x15\x0a\xc2\xf7\xe8\x8b\x0b\xd2\xda\xf5\x7d\xaa\x85\x42\x2d\x1f\xaa\x88\x4a\x51\x46\x9d\xcb\x69\x50\x86\x3d\x61\x9e\x26\xc9\x78\xe5\x28\xbd\x1b\xc6\x9b\xd3\xd4\xc1\xec\x2e\xaf\xa5\xbe\x04\x94\xb2\x53\xe5\xf0\x8f\xc7\x77\x0f\x93\xbf\xdb\x54\xb2\x62\x96\x11\xa7\xd4\x22\x75\xe6\x10\xb8\xce\x0a\x40\x6e\xae\x0b\x1f\x43\xd2\x29\xd1\xa8\x39\xb1\x1f\x27\x6a\xe4\xf8\xb7\x37\xbf\x8f\xe1\x17\xeb\x80\x9e\xb1\xac\x34\x0d\x41\xa5\x36\xa7\xb9\xe2\x6d\x95\x47\x41\x98\xed\xde\x50\x09\x05\x96\x2a\x9b\x27\xa6\xd7\x81\x59\x8f\x4b\x02\x9b\x98\xad\x09\xb4\x5a\xd2\x14\x06\x5c\x51\xd6\x3a\xfa\xb3\xc1\x92\xbe\x0c\xe0\xfb\x75\x41\x8e\x60\x20\x8f\x83\x78\xe0\xb6\x84\x94\xb9\x96\x53\xa6\x83\x63\x1f\xee\xd4\x62\x41\x8e\x62\x31\x4e\x2b\x32\xfe\x07\xe9\xc4\xd4\x1c\x8c\x6d\x2d\x0e\x24\x44\x9f\x15\x65\x6a\xae\x28\x3f\x60\xe4\xb7\x37\xbf\x0f\xe0\xfb\xae\x5c\x82\x3a\xf4\x0c\x6f\x62\x97\xa1\x58\x64\xfc\x21\x35\x6e\xbc\x31\x1e\x9f\x85\x66\x26\xad\x83\x89\x35\xbf\xb7\x50\xe0\x8a\x80\x6d\x49\xb0\x26\xad\x47\xf1\xde\x34\x87\x75\x6c\x49\x1b\x55\xc6\x16\xaf\x42\xe7\xf7\xbe\x57\x3c\xbd\xbb\x7b\x37\x8d\xa7\x89\xd9\x16\x46\x8e\x30\xd6\xc3\x5c\x19\xd4\xa9\xef\x50\xbc\x6b\x53\xb8\x8e\x46\xf2\x16\xb2\x02\x4d\xc0\xca\xa0\x8d\x79\xed\x6b\x47\xe3\xfd\xfb\xeb\xaf\x8a\x81\x63\x1f\x12\x4e\xb9\x7f\xf8\xac\xb0\x5f\x64\xfe\x1f\x2f\xed\xbf\x4a\xe8\xf0\x5d\xed\x02\xa1\x1f\x5a\x7e\x7a\x52\xe8\x65\x3d\x23\x67\xc8\x53\x90\x3b\xb7\x19\x8b\xc8\x19\x55\x9e\x27\x76\x45\x6e\xa5\x68\x3d\x59\x5b\xb7\x54\x66\x31\x12\x47\x1c\x45\xef\xe0\x49\xf8\x16\x39\xf9\x2e\xfc\xbc\x9a\x8c\x5c\x61\x76\xb1\xa0\x61\xd3\x9f\x21\xad\x9c\xc3\x93\x57\x11\xb6\x69\xe4\x2e\xef\x9d\xae\x1f\x23\x70\x64\xfb\x34\x24\xec\xd6\x85\xca\x8a\xe6\x53\x64\x0b\x29\x4b\xcc\x23\x94\xa2\xd9\x7c\x73\xe7\x17\x95\xd6\x4e\xce\xde\x8c\xd2\x67\xf4\x11\x9a\x5c\xfe\xb3\x62\x2f\xf3\xaf\xa2\xc3\x5a\x5d\x04\x04\x1f\xef\xef\xfe\x9c\x90\xa8\xd5\x57\x44\x7d\xfc\x8c\x35\x05\xef\xea\xa6\xa6\x65\x6f\x9d\x54\xae\x9d\xb9\x7a\xb6\xbd\xb1\xd8\x09\x9f\x8a\x2c\xf8\xfc\xe5\xea\xbf\x01\x00\x00\xff\xff\x7e\x2b\xf8\xdd\x18\x21\x00\x00") +var _operatorsCoreosCom_operatorsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x5f\x73\xe3\xb6\x11\x7f\xf7\xa7\xd8\x51\x1e\x9c\xcc\xe8\x4f\x72\x7d\x69\xf5\xe6\xb1\x2f\x1d\xb7\xa9\xef\xe6\xec\xbb\x97\x4c\x1e\x56\xe4\x4a\x44\x05\x02\x0c\x16\x94\xac\xde\xdc\x77\xef\x2c\x00\x4a\xa4\x24\x4b\xd4\xd5\x97\x06\x2f\x12\x41\x60\xb1\x7f\x7f\xbb\x0b\x62\xa5\x3e\x91\x63\x65\xcd\x14\xb0\x52\xf4\xec\xc9\xc8\x13\x8f\x97\x7f\xe5\xb1\xb2\x93\xd5\x4f\x57\x4b\x65\xf2\x29\xdc\xd6\xec\x6d\xf9\x81\xd8\xd6\x2e\xa3\x3b\x9a\x2b\xa3\xbc\xb2\xe6\xaa\x24\x8f\x39\x7a\x9c\x5e\x01\xa0\x31\xd6\xa3\x4c\xb3\x3c\x02\x64\xd6\x78\x67\xb5\x26\x37\x5a\x90\x19\x2f\xeb\x19\xcd\x6a\xa5\x73\x72\x81\x78\x73\xf4\xea\xc7\xf1\xdf\xc6\x3f\x5e\x01\x64\x8e\xc2\xf6\x27\x55\x12\x7b\x2c\xab\x29\x98\x5a\xeb\x2b\x00\x83\x25\x4d\xc1\x56\xe4\xd0\x5b\xc7\xe3\xdd\xbf\xcc\x3a\xb2\xf2\x53\x5e\x71\x45\x99\x1c\xbc\x70\xb6\xae\xda\xab\x5b\x6b\x22\xa9\x86\x3f\xf4\xb4\xb0\x4e\x35\xcf\x00\x23\xb0\xba\x0c\xff\xa3\xdc\xef\x12\x8d\x30\xa5\x15\xfb\x7f\x76\xa6\x7f\x51\xec\xc3\xab\x4a\xd7\x0e\x75\xeb\xcc\x30\xcb\xca\x2c\x6a\x8d\x6e\x37\x7f\x05\xc0\x99\xad\x68\x0a\xb7\xba\x66\x4f\x32\x91\xf4\x90\x78\x18\x25\x59\x57\x3f\x25\x96\x38\x2b\xa8\xc4\x86\x41\x10\x52\xe6\xe6\xfd\xfd\xa7\xbf\x3c\xee\xbd\x00\xc8\x89\x33\xa7\x2a\x1f\xb4\xda\xf0\x08\x8e\x2a\x47\x4c\xc6\x33\x20\x64\xf1\xd8\x2d\x43\xe3\xd6\x76\xbf\x11\xc6\xec\xec\xdf\x94\xf9\xd6\x74\xe5\x64\xb1\x6f\x69\x29\x8e\x96\xf7\x74\xe6\xf7\xf8\xb8\x16\x66\xe3\x3a\xc8\xc5\x71\x88\xc1\x17\xd4\x88\x4d\x79\x92\x10\xec\x1c\x7c\xa1\x78\xc7\x6f\xf0\x05\x99\x46\x93\xb8\x1a\xc3\x23\x39\xd9\x08\x5c\xd8\x5a\xe7\xe2\x61\x2b\x72\x1e\x1c\x65\x76\x61\xd4\x7f\xb6\xd4\x18\xbc\x0d\xc7\x68\xf4\xc4\x1e\x94\xf1\xe4\x0c\x6a\x58\xa1\xae\x69\x08\x68\x72\x28\x71\x03\x8e\x84\x2e\xd4\xa6\x45\x21\x2c\xe1\x31\xfc\xcb\x3a\x02\x65\xe6\x76\x0a\x85\xf7\x15\x4f\x27\x93\x85\xf2\x4d\x6c\x64\xb6\x2c\x6b\xa3\xfc\x66\x12\xdc\x5c\xcd\x6a\xb1\xfb\x24\xa7\x15\xe9\x09\xab\xc5\x08\x5d\x56\x28\x4f\x99\xaf\x1d\x4d\xb0\x52\xa3\xc0\xac\x09\xf1\x31\x2e\xf3\xef\x5c\x8a\x26\xbe\xde\x53\x5f\xb4\x03\x7b\xa7\xcc\xa2\xf3\x2a\xf8\xe4\x49\x5d\x8b\x7b\x82\x12\x43\xc7\xed\x51\x96\x9d\x4a\x65\x4a\xb4\xf2\xe1\xed\xe3\x13\x34\x0c\x44\xb5\x47\x0d\xb7\xbc\x65\xa7\x6c\x51\x94\x32\x73\x72\x71\xe5\xdc\xd9\x32\x50\x21\x93\x57\x56\x19\x1f\x1e\x32\xad\xc8\x78\xe0\x7a\x56\x2a\x2f\x56\xfc\xbd\x26\xf6\x62\x87\x31\xdc\x06\x68\x80\x19\x41\x5d\xe5\xe8\x29\x1f\xc3\xbd\x81\x5b\x2c\x49\xdf\x22\xd3\x37\x57\xb5\x68\x94\x47\xa2\xbe\xfe\xca\x6e\x23\xdb\xe1\x86\x83\x28\x01\x68\xe0\xe7\x45\xeb\x34\x11\xf9\x58\x51\xd6\x09\x85\x9c\x58\x39\x71\x5d\x8f\x9e\xc4\xe1\x3b\xb0\xd3\xe7\x68\x8f\xbe\xe6\x7e\x87\x87\xa5\x9d\xe3\xed\x8c\xc5\xd0\xad\xf3\xd1\xec\xe0\x43\x22\x45\x0c\x9a\xd9\xb2\xb2\x46\x1c\xa3\x2f\x57\x2f\x43\x07\x84\xe4\xd0\xd0\x3b\x7c\xb7\xc7\xfb\xed\x76\x69\x9a\x9f\x11\x6f\xbd\x57\x64\x40\x1f\xc9\x31\x45\x81\x8e\x80\x5b\x0f\x6e\x65\x88\xdb\x8a\x2d\x8e\xf1\x24\xe0\xac\x71\x46\xfa\x91\x34\x65\x87\xe6\x39\x27\xb1\x8c\xce\xfe\xe3\x4b\xf6\x84\xff\xa5\xbd\x23\xc6\x76\x20\x02\xbf\xd7\xe4\x36\x60\x57\xe4\x24\xdc\xc9\x8b\xe1\x76\x4a\xa9\x99\x72\xc1\x40\x0e\x3b\x3b\x6a\xb9\x3e\x61\xcc\x9e\x6a\xea\x23\xaa\x8c\x12\x7d\x56\xbc\x7d\x16\x48\x69\xe5\xb8\x1e\x52\xef\x6f\x4c\x82\x2b\x0e\x62\x46\x05\x70\xa3\x94\x64\xb4\x32\xa2\xd6\x53\x41\x9d\x19\x40\x47\x70\xf3\x70\x47\xf9\x31\x7f\xe8\x0a\x8c\xce\xe1\xe6\xc4\x2a\xe5\xa9\x3c\x29\xc4\x9e\x18\x37\x27\x58\x4d\x38\xdd\xbc\x49\x5e\x6c\x3c\x2a\xc3\x29\x07\x0d\x01\x61\x49\x9b\x98\xae\x24\x0b\x36\x41\x19\x16\x3b\x0a\xc9\x2d\xd8\x76\x49\x9b\xb0\x28\xe5\xae\x93\x1c\xf6\xb0\x6d\x1c\xa7\x83\x61\x37\x46\x72\xfc\xd9\x35\xf6\x38\xa8\x75\x47\x1f\xa7\x8a\x63\x49\x9b\x73\x4b\xf6\x8c\x21\x3a\x52\x9c\xaa\x02\xb1\x8a\x4c\x04\x4d\xca\xd4\xd6\x10\x58\x55\x5a\x51\x48\x5c\x67\xe9\xbf\x98\x3d\x0e\x47\x23\xfe\x85\x4c\xdb\xa3\x65\xdc\x92\x36\xd7\x1c\x1d\x40\xa2\xa3\x50\x95\xc4\xfa\x16\x06\x9a\x0a\xe6\x13\x6a\x95\xef\x8a\xd2\x10\x09\xf7\x66\x08\x0f\xd6\xcb\xcf\xdb\x67\x25\x19\x5a\xfc\xe6\xce\x12\x3f\x58\x1f\x66\x5e\x55\xec\xc8\xca\x85\x42\xc7\x4d\x21\x40\x4c\x8c\x49\x91\xaa\x5d\xd2\xf0\x18\xee\xe7\x1d\x54\x93\xd5\xf7\x06\xac\x6b\xa4\x0b\x45\x66\x24\x14\x49\x94\x35\x87\x1a\xc4\x58\x33\xa2\xb2\xf2\x9b\xa3\x34\x92\x52\xac\xeb\xe8\xe4\x04\xb9\x44\xea\x49\x4a\xa3\xf8\x26\x16\xb1\x1a\x33\xca\x21\xaf\x03\xd3\xa1\x20\x93\x76\x43\x65\x50\x92\x5b\x10\x54\x82\x70\x7d\x55\x7d\x0e\x97\xe2\xe8\x81\x4e\x6d\xa2\x67\xec\x17\x20\x38\x64\x9f\x0b\x61\x3b\xee\x89\xf0\x56\x62\x25\xa6\xfb\x2c\x28\x16\xb4\xf7\x05\x2a\x54\x8e\xc7\x70\x13\xda\x23\x4d\x9d\x77\xca\x04\x3d\xb7\xc9\x08\x05\xc5\x20\x50\xb4\x42\x2d\xb8\x29\x9e\x6e\x80\x74\x44\x51\x3b\x3f\x48\x16\x43\x58\x17\x52\x0b\x48\x7c\xcf\x15\xe9\x50\x12\x0f\x96\xb4\x19\x0c\x0f\xcc\x3d\xb8\x37\x83\x88\xaf\x07\x06\xde\x82\xb1\x35\x7a\x03\x83\xf0\x6e\xf0\xbf\xe5\x97\xb3\xa0\x8b\x79\x1e\x1a\x6b\xd4\xef\x7b\x22\xe1\x59\x5b\x3a\x9a\xbf\x48\xa2\x63\xbc\x0f\x34\x8f\xc2\xb4\xca\x89\x39\x39\x32\xa1\xc8\xb2\x2f\xd6\x10\xbb\xaa\x63\x98\x50\x94\x72\x58\x2b\x5f\x74\x6b\x97\x97\xb4\x73\xde\xc3\xcf\xf8\x75\x57\x08\x95\x15\x1f\x1a\xb6\xa3\x0f\x6e\xa5\x88\x18\xd9\x70\x3b\x04\x32\x4e\x65\x45\xc3\xac\x14\xb9\xb1\x90\x16\xcb\x47\x33\x9c\xc8\xa4\xbd\x0c\xda\x2f\x9d\xbd\xdc\x49\x9f\x10\xf4\xe6\xfd\x7d\xd3\x43\xc7\xd6\x99\x1a\x41\xcf\x00\x78\x4f\xf0\xde\xe9\xe0\x02\xa6\x6e\xb7\x9b\xda\xf9\xaa\xd5\x87\x6f\x5b\x8c\xd0\x32\x36\x1e\xd4\x87\xe1\xf3\x10\xd8\x0b\xfe\x8e\xb3\xbb\xe3\xb6\xcd\x2c\xae\x50\x69\x9c\xe9\xa6\x45\x8a\xc9\x36\x35\x48\x5b\xe6\xaf\xa3\xdb\xd0\x39\x2c\xef\x5d\x76\xf5\x2f\xbc\xa4\xac\x8a\x2e\xdb\x63\xa1\x9c\x7f\x66\x59\xff\xea\x4b\x3a\x19\xf6\x4f\x0e\x0d\xab\xe6\xca\xae\x4f\xe6\xd9\x6b\x6d\xd8\x83\x57\x25\x25\x6f\x68\x8c\xe1\xb7\x64\x29\x8f\xb7\x0d\xd6\x50\x13\x9b\x01\xfd\xad\x2f\xe8\x45\x40\x69\x8f\x0b\x2a\x15\x19\x73\xeb\x4a\xf4\x53\xc8\xd1\xd3\x48\x38\xeb\xa5\x86\x8f\xe1\x52\xe3\x55\x55\xb0\x46\x16\x6b\xcc\x28\xff\x33\x08\x59\x12\x33\x2e\x2e\x97\xee\x06\x8a\xba\x44\x89\x2e\xcc\x43\x1c\x25\x42\xa0\x4c\xae\x32\x0c\xd7\x51\x39\x79\x54\x9a\x01\x67\xb6\x8e\xd1\xb7\x33\xff\xab\x5b\xd8\x11\xf2\x39\x94\x3d\x22\x47\x4c\xf9\xb2\x55\x94\xd7\x35\xd5\x35\x07\x1f\xf8\x96\x5c\x1f\xbf\xde\x39\xcb\x75\xba\xea\xd9\x82\x6d\x62\x78\x18\xa2\xc9\xce\xe1\xc9\xd5\x34\x84\x9f\x51\x33\x0d\xe1\xa3\x59\x1a\xbb\x7e\x7d\xde\xc3\xe2\x8b\xf5\xbd\xa9\x02\x87\x5b\x9e\x5f\x91\xad\x50\x10\xbe\x47\x5f\x5c\x90\xd6\xae\xef\x53\x2d\x14\x6a\xf9\x50\x45\x54\x8a\x32\xea\x5c\x4e\x83\x32\xec\x09\xf3\x34\x49\xc6\x2b\x47\xe9\xdd\x30\xde\x9c\xa6\x0e\x66\x77\x79\x2d\xf5\x25\xa0\x94\x9d\x2a\x87\x7f\x3c\xbe\x7b\x98\xfc\xdd\xa6\x92\x15\xb3\x8c\x38\xa5\x16\xa9\x33\x87\xc0\x75\x56\x00\x72\x73\x5d\xf8\x18\x92\x4e\x89\x46\xcd\x89\xfd\x38\x51\x23\xc7\xbf\xbe\xf9\x6d\x0c\x3f\x5b\x07\xf4\x8c\x65\xa5\x69\x08\x2a\xb5\x39\xcd\x15\x6f\xab\x3c\x0a\xc2\x6c\xf7\x86\x4a\x28\xb0\x54\xd9\x3c\x31\xbd\x0e\xcc\x7a\x5c\x12\xd8\xc4\x6c\x4d\xa0\xd5\x92\xa6\x30\xe0\x8a\xb2\xd6\xd1\x9f\x0d\x96\xf4\x65\x00\xdf\xaf\x0b\x72\x04\x03\x79\x1c\xc4\x03\xb7\x25\xa4\xcc\xb5\x9c\x32\x1d\x1c\xfb\x70\xa7\x16\x0b\x72\x14\x8b\x71\x5a\x91\xf1\x3f\x48\x27\xa6\xe6\x60\x6c\x6b\x71\x20\x21\xfa\xac\x28\x53\x73\x45\xf9\x01\x23\xbf\xbe\xf9\x6d\x00\xdf\x77\xe5\x12\xd4\xa1\x67\x78\x13\xbb\x0c\xc5\x22\xe3\x0f\xa9\x71\xe3\x8d\xf1\xf8\x2c\x34\x33\x69\x1d\x4c\xac\xf9\xbd\x85\x02\x57\x04\x6c\x4b\x82\x35\x69\x3d\x8a\xf7\xa6\x39\xac\x63\x4b\xda\xa8\x32\xb6\x78\x15\x3a\xbf\xf7\xbd\xe2\xe9\xdd\xdd\xbb\x69\x3c\x4d\xcc\xb6\x30\x72\x84\xb1\x1e\xe6\xca\xa0\x4e\x7d\x87\xe2\x5d\x9b\xc2\x75\x34\x92\xb7\x90\x15\x68\x02\x56\x06\x6d\xcc\x6b\x5f\x3b\x1a\xef\xdf\x5f\x7f\x55\x0c\x1c\xfb\x90\x70\xca\xfd\xc3\x67\x85\xfd\x22\xf3\xff\x78\x69\xff\x55\x42\x87\xef\x6a\x17\x08\xfd\xd0\xf2\xd3\x93\x42\x2f\xeb\x19\x39\x43\x9e\x82\xdc\xb9\xcd\x58\x44\xce\xa8\xf2\x3c\xb1\x2b\x72\x2b\x45\xeb\xc9\xda\xba\xa5\x32\x8b\x91\x38\xe2\x28\x7a\x07\x4f\xc2\xb7\xc8\xc9\x77\xe1\xe7\xd5\x64\xe4\x0a\xb3\x8b\x05\x0d\x9b\xfe\x08\x69\xe5\x1c\x9e\xbc\x8a\xb0\x4d\x23\x77\x79\xef\x74\xfd\x18\x81\x23\xdb\xa7\x21\x61\xb7\x2e\x54\x56\x34\x9f\x22\x5b\x48\x59\x62\x1e\xa1\x14\xcd\xe6\x9b\x3b\xbf\xa8\xb4\x76\x72\xf6\x66\x94\x3e\xa3\x8f\xd0\xe4\xf2\x9f\x15\x7b\x99\x7f\x15\x1d\xd6\xea\x22\x20\xf8\x78\x7f\xf7\xc7\x84\x44\xad\xbe\x22\xea\xe3\x67\xac\x29\x78\x57\x37\x35\x2d\x7b\xeb\xa4\x72\xed\xcc\xd5\xb3\xed\x8d\xc5\x4e\xf8\x54\x64\xc1\xe7\x2f\x57\xff\x0d\x00\x00\xff\xff\x08\x9c\x4f\xa3\x18\x21\x00\x00") func operatorsCoreosCom_operatorsYamlBytes() ([]byte, error) { return bindataRead( @@ -225,7 +225,7 @@ func operatorsCoreosCom_operatorsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_subscriptionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x7b\x73\xe3\xb8\x95\x38\xfa\xff\x7c\x0a\x94\x93\x2a\xdb\x59\x49\xee\xce\xe6\x97\xe4\xf6\xa6\xb2\xe5\xb1\xdd\x13\xff\xa6\xbb\xc7\xdb\x76\xcf\xd4\xde\x6c\xee\x06\x22\x21\x09\x31\x09\x70\x00\x50\x6e\xe5\xf1\xdd\x6f\xe1\x1c\x00\x04\xa9\x17\x29\xc9\x8f\x9e\x21\xff\x98\x69\x53\x00\x08\x1c\x1c\x9c\x17\xce\x83\x16\xfc\x7b\xa6\x34\x97\xe2\x0d\xa1\x05\x67\x9f\x0d\x13\xf6\x2f\x3d\xba\xff\xbd\x1e\x71\x79\x36\x7f\xfd\xd5\x3d\x17\xe9\x1b\x72\x51\x6a\x23\xf3\x8f\x4c\xcb\x52\x25\xec\x92\x4d\xb8\xe0\x86\x4b\xf1\x55\xce\x0c\x4d\xa9\xa1\x6f\xbe\x22\x84\x0a\x21\x0d\xb5\xaf\xb5\xfd\x93\x90\x44\x0a\xa3\x64\x96\x31\x35\x9c\x32\x31\xba\x2f\xc7\x6c\x5c\xf2\x2c\x65\x0a\x06\xf7\x9f\x9e\xbf\x1a\xfd\x7e\xf4\xea\x2b\x42\x12\xc5\xa0\xfb\x1d\xcf\x99\x36\x34\x2f\xde\x10\x51\x66\xd9\x57\x84\x08\x9a\xb3\x37\x44\x97\x63\x9d\x28\x5e\xc0\x27\x46\xb2\x60\x8a\x1a\xa9\xf4\x28\x91\x8a\x49\xfb\xbf\xfc\x2b\x5d\xb0\xc4\x7e\x7c\xaa\x64\x59\xbc\x21\x2b\xdb\xe0\x70\x7e\x8e\xd4\xb0\xa9\x54\xdc\xff\x4d\xc8\x90\xc8\x2c\x87\x7f\xe3\xda\x6f\xa3\xaf\xc2\xeb\x8c\x6b\xf3\xed\xd2\x4f\xef\xb8\x36\xf0\x73\x91\x95\x8a\x66\x8d\xd9\xc2\x2f\x7a\x26\x95\xf9\x50\x7d\xdb\x7e\x4b\x97\xe3\xf8\xdf\xae\x21\x17\xd3\x32\xa3\xaa\x3e\xc8\x57\x84\xe8\x44\x16\xec\x0d\x81\x31\x0a\x9a\xb0\xf4\x2b\x42\x1c\x1c\xdd\x98\x43\x42\xd3\x14\xf6\x86\x66\x37\x8a\x0b\xc3\xd4\x85\xcc\xca\x5c\x84\x6f\xda\x36\x29\x0b\xa3\xbe\x21\x77\x33\x46\x0a\x9a\xdc\xd3\x29\xf3\xdf\x1b\xb3\x94\x18\x19\x3a\x10\xf2\x37\x2d\xc5\x0d\x35\xb3\x37\x64\x64\x41\x3c\xb2\x10\x8c\x7e\xc6\xfd\xb9\xc1\x41\xa2\xf7\x66\x61\xa7\xab\x8d\xe2\x62\xba\xe9\xf3\x09\x35\x34\x93\x53\x82\xf8\x45\x26\x52\x11\x33\x63\xc4\x7e\x8a\x4f\x38\x4b\xfd\xfc\x36\xcc\x08\xbb\x2e\xcd\xe9\xb6\xf9\xba\xf5\x94\x66\x54\x08\x96\x11\x39\x21\x65\x91\x52\xc3\x34\x31\xb2\x82\xcf\x66\xf0\xb8\xce\x4b\xb3\xb9\x58\x7a\xbf\x62\x3a\xd8\x74\xfe\x9a\x66\xc5\x8c\xbe\x76\x2f\x75\x32\x63\x39\xad\xf6\x50\x16\x4c\x9c\xdf\x5c\x7f\xff\xef\xb7\x8d\x1f\x48\x7d\x29\x31\x8a\x92\x7b\xc6\x0a\x5d\x1d\x0a\x52\x16\x76\x4d\x76\x71\x64\xbc\x20\x46\xd1\xe4\x9e\x8b\x29\x2c\x7d\x8a\xeb\xbd\xc0\x8d\xd1\xa3\xa5\x29\xcb\xf1\xdf\x58\x62\xa2\xd7\x8a\xfd\x58\x72\xc5\xd2\x78\x2a\x16\xb2\x9e\x44\x34\x5e\x5b\x38\x45\xaf\x0a\x65\xa7\x65\xa2\x73\x88\x4f\x44\xa3\x6a\xef\x1b\xcb\x3c\xb6\xb0\xc0\x76\x24\xb5\xe4\xc9\x4e\x7f\xc6\xfc\xe1\x60\xa9\x03\xa0\xdd\x4e\x33\xe3\x9a\x28\x56\x28\xa6\x99\x40\x82\x65\x5f\x53\xe1\xd6\x34\x22\xb7\x4c\xd9\x8e\xf6\xc0\x96\x59\x6a\xe9\xd8\x9c\x29\x43\x14\x4b\xe4\x54\xf0\xbf\x87\xd1\x00\x44\xf6\x33\x99\xc5\x0f\x43\xe0\xb8\x09\x9a\x91\x39\xcd\x4a\x36\x20\x54\xa4\x24\xa7\x0b\xa2\x98\x1d\x97\x94\x22\x1a\x01\x9a\xe8\x11\x79\x2f\x15\x23\x5c\x4c\xe4\x1b\x32\x33\xa6\xd0\x6f\xce\xce\xa6\xdc\x78\x0a\x9c\xc8\x3c\x2f\x05\x37\x8b\x33\x20\xa6\x7c\x5c\xda\x8d\x3b\x4b\xd9\x9c\x65\x67\x9a\x4f\x87\x54\x25\x33\x6e\x58\x62\x4a\xc5\xce\x68\xc1\x87\x30\x59\x81\x24\x32\x4f\x7f\xa1\x1c\xcd\xd6\xc7\x0d\xf0\xad\x3c\x07\xc4\x53\xbd\x8d\xb0\xb6\xc4\x8f\x70\x4d\xa8\xeb\x8e\x6b\xa9\x40\x6a\x5f\x59\xa8\x7c\xbc\xba\xbd\x23\x7e\x02\x08\x76\x84\x70\xd5\x54\x57\xc0\xb6\x80\xe2\x62\xc2\x14\xb6\x9c\x28\x99\xc3\x28\x4c\xa4\x85\xe4\xc2\xc0\x1f\x49\xc6\x99\x30\xf6\x18\xe6\xdc\x68\xc0\x39\xa6\x8d\xdd\x87\x11\xb9\x00\x06\x44\xc6\xcc\x1d\xd8\x74\x44\xae\x05\xb9\xa0\x39\xcb\x2e\xa8\x66\x8f\x0e\x6a\x0b\x51\x3d\xb4\xe0\x6b\x0f\xec\x98\x7f\x2e\x77\x58\x3a\x63\x84\x78\x06\xb7\x76\x77\xe2\x03\x7f\x5b\xb0\x24\x1c\x07\x2a\xc8\x79\x51\x64\x3c\x41\x8c\x37\x33\x6a\x48\x42\x85\x85\x17\x17\xda\xd0\x2c\x03\x76\xd2\x6a\x16\xeb\x4e\x3b\x81\xa3\xdd\x60\x0e\xfe\xf5\x12\x85\xae\xff\x10\x98\x5a\xa3\xc5\x3a\xca\x60\x1f\x47\x67\x97\x7f\xd8\x00\x72\x82\x92\xc9\x84\x4f\x57\x75\x5b\x0b\xcb\x0b\xe8\x02\x32\x0d\xe5\x42\xbb\x21\x4a\x85\xd0\xac\x38\x95\xe5\x5d\xb4\xc6\xb7\x47\x6b\x67\xb7\x12\xb2\xdb\xd6\x6c\x1f\x3a\x01\x09\x6c\xb1\xfa\xd7\xc6\x2a\xae\x27\xd5\xf4\x06\x44\xce\x99\x52\x3c\x75\xf4\xb1\x90\xe9\xb1\x06\x6a\x96\x96\x19\xd0\x7e\x29\xb4\x51\x94\xc3\xd1\x14\x3c\xb3\x2b\x19\x52\x83\xe7\x81\x69\xf2\xc0\xb3\x8c\xfc\x4a\x48\xf3\xab\x30\x12\x0c\x24\x15\x9f\xf2\x40\xfa\x34\xe1\xc2\x8f\x0f\x1c\xd1\xb1\x74\xa9\x59\x63\xc0\x11\xf9\xa4\x19\x61\x79\x61\x16\x9e\x38\x9c\xfc\xe3\x5f\xa7\x96\xb0\x32\x45\x75\x34\x70\xad\x9f\x27\x9f\x6b\xd6\xbf\x05\xbc\x6d\x40\x6c\x1f\x21\x53\x76\xbe\x05\xd4\x4b\xe0\xbe\x64\x28\x21\x68\xe8\x1e\xb6\x2a\x06\xb2\x2a\x33\xa6\x83\x94\x63\x61\xb4\x61\xf0\x16\x6b\x69\xbb\x1e\x6c\xc7\x26\x4c\x29\x96\x5e\x96\xf6\x68\xdc\x86\x59\x5d\x4f\x85\x0c\xaf\xaf\x3e\xb3\xa4\x34\x2b\xb8\xee\xc6\xa5\x5b\xb9\xc9\x2d\x93\x29\x44\x15\xfc\x1c\x88\x4e\xee\x07\xbb\x5e\x60\x9c\x16\x3c\x1a\xe9\x90\xa6\x86\xeb\xc9\x02\xc0\x11\x00\xc6\x3e\x5b\x26\x01\xb2\x6d\x74\xbe\xac\xa0\x02\xfc\x81\xb3\x2c\x1d\x90\x71\x69\x08\x37\xc0\x3c\x92\x99\xb4\xf8\x45\x11\xee\x30\xee\x9c\x4b\x60\xcd\x44\x0a\x8b\x49\x24\xb7\x1c\x00\x44\x00\x16\x0f\x3f\x82\x99\x57\xdd\xb8\x26\xb9\xd4\xa6\x82\x95\x7d\x03\x58\x2e\x18\x79\xe0\x66\x06\x7f\x4c\xad\xba\x62\xd9\xbe\x2e\x73\x3b\xe8\x03\xe3\xd3\x99\xd1\x03\xc2\x47\x6c\x04\xbb\xcb\x68\x32\x8b\x86\xcd\x19\x33\x9a\xd0\x2c\xf3\x53\x88\x51\x02\xe9\x69\x6e\x79\x22\x39\x09\x4c\xd3\x31\xb8\x41\xa0\xb7\xcd\x5d\x5b\x09\xae\x01\x61\x26\x19\x9d\x0e\x48\x22\xf3\xc2\x9e\x16\x0a\x73\x1c\x2f\x08\x37\x56\xf6\x43\x06\xad\x64\x39\xc5\x95\xb0\xcc\x7d\xd8\x4b\x47\x00\x5c\x10\x5f\xac\x36\x21\xa6\xe4\x08\x17\x77\xe4\x05\x1e\x3b\x1c\xc7\x45\xc0\xfa\x72\x6a\x92\x99\xa3\x29\x89\x54\x8a\xe9\x42\x0a\xe8\x09\xbf\x5c\x55\x73\xfb\x8f\xd0\xe9\x44\x9f\x56\xc0\x9c\xf1\xe9\xcc\xc3\x92\x2a\xa4\x29\xf5\x3d\xd8\x74\x46\xaa\x73\x42\x95\xa2\x8b\x2d\x2d\xb9\x61\xf9\x96\x53\xb2\x84\xda\xe7\xc2\x11\xa9\x0a\x27\xa2\xdd\x33\x4c\xe5\x01\x06\xb0\xc1\x70\x5c\x35\xae\x8f\xe7\x96\xed\x72\xe3\x30\x84\xbc\x22\x27\x80\x22\xdc\x1c\x6b\x40\xd7\xa1\x2c\x4e\x47\xe4\x1c\xb4\xdd\x16\x1f\x10\x32\x8c\xef\x06\xb2\x1f\xd5\xb2\x1a\x6b\xeb\xda\x5a\x12\x15\x7c\xd6\xf3\xfa\xe5\x67\xe8\xe6\xcf\xc4\x0a\x56\xbf\xaa\x39\xc2\x64\x6b\xd3\xb6\xe4\xcd\xb7\xf6\x73\x68\xd3\xba\xb9\xd5\x88\xd2\x9a\x65\x2c\x31\x96\x46\x33\x95\x0f\x08\xd5\x5a\x26\xdc\x8a\x95\x15\xd2\xd6\x31\x1d\x57\xb2\x1d\xf6\xa4\x2b\xfc\x49\xe7\xf5\xdb\xa7\x79\xf0\xda\xf6\x5b\x82\x46\xc6\xb5\xb1\x94\xa1\x0e\x95\x1a\xc1\x1a\x2f\xe0\xd7\x63\x4d\x32\x3a\x66\xd9\x5a\xbe\xbc\xfc\xb4\x3f\xb5\xd5\xd3\xf2\xfc\xae\x5d\xd0\xda\x85\x38\xa5\x26\x6c\x3c\x88\xc8\x5e\xe0\x43\x89\x63\x40\x28\xb9\x67\x0b\xd4\xed\xac\xca\xe8\x94\x69\x6c\xac\x18\xb2\x1b\x8b\x1c\xf7\x6c\x01\x8d\x36\x4b\x2a\xeb\x61\xd2\x01\x39\xf0\xe9\x72\x4c\xab\x67\x68\x27\xda\xb1\x87\x5f\x74\x87\x6e\xdd\xf1\x17\x9f\x7b\xb6\x51\xf2\x5a\xf5\x2c\x89\x24\x80\x93\xb0\x1f\xb0\x49\xc0\xbf\xfc\x1e\x53\xab\x12\x81\xad\xa3\xcb\x0e\x91\x6d\x0a\xc6\xa6\xc7\x43\x6f\xaf\x75\x7d\x0c\x1a\x34\x22\xe4\xb1\x46\xe4\xb3\x27\x7d\xc6\xc1\xae\x63\x31\x19\x0e\xae\x37\x35\x7c\x4f\x33\x9e\x46\xe6\x1f\xcb\x67\xaf\xc5\x80\x7c\x90\xc6\xfe\xef\xea\x33\xd7\x56\x7c\xb9\x94\x4c\x7f\x90\x06\xfe\x1c\x91\x6f\x0c\xe2\xfa\xbb\x96\x94\xed\x00\x00\xc2\xf9\xee\x05\x9e\x73\x81\x34\xc5\x2e\x3f\x36\x52\xe8\x91\x55\x87\x40\x94\xf3\x07\x97\x6b\x72\x2d\xac\x70\xe8\xc0\x00\x66\x23\x54\x62\x70\x88\xbc\xd4\x60\x55\x10\x52\x0c\x41\x06\x58\x39\x06\x42\xcf\x8e\x13\xc3\x6f\xc3\x70\xeb\x87\xfa\xc6\xd8\x61\xde\xad\xed\x3c\xa3\x73\x10\xe9\xb8\x98\x66\x41\x78\x1b\x90\x87\x19\x4f\x66\x28\x75\x83\x4e\x6f\x98\x2a\x14\xb3\x0c\x8b\x82\xf6\x6f\xdf\x4c\x99\xb2\xc2\x2e\xf7\xe3\xa1\x25\x2c\xa3\x09\x4b\x49\x0a\xa2\x25\x5a\x75\xa8\x61\x53\x9e\x90\x9c\xa9\x29\x23\x85\xe5\x24\xbb\xed\x7e\x37\xc2\x8e\x4f\x67\xf2\x1e\x7f\xb0\x13\xba\x01\x8b\x7c\x6b\x65\xdd\x27\xe2\x8e\x20\x57\xf7\xdc\xb1\xe7\x8e\x8d\xa7\xe7\x8e\xe1\xe9\xb9\xe3\x96\xa7\xe7\x8e\x3d\x77\x7c\x74\xee\x88\xba\xec\x0e\xca\xf3\x0f\x68\xe2\x68\x6a\xcb\xc0\x69\xfd\xbd\x50\x5d\x6d\xb6\xfc\xe6\xd6\x11\x9c\x3b\x50\xb5\x9d\xed\x58\x51\x31\x65\xe4\xf5\xf0\xf5\xab\x57\x5d\x94\x6a\xb7\x91\xad\x7a\x4c\xa4\xca\xa9\x81\x3e\xff\xfe\xeb\x8d\x3d\xd6\xd9\xdf\x0e\x60\x35\x75\x38\x1e\x0c\x79\x35\xd9\x61\x8d\xe1\x13\xa8\x93\x90\x86\xe4\xcc\x10\x6a\x6a\xa6\x22\x9e\xb3\x81\x37\x2c\x23\xc2\xbb\x6b\x31\x6f\x81\x4d\x89\x14\xce\x8e\x67\x81\x3f\xda\x6d\x06\x09\xa3\x9a\x59\x4a\x3a\x66\x61\x16\x32\xb7\x5f\xe5\xc2\xf8\xe3\x62\xa7\xc0\x3c\x54\xc8\x09\x1b\x4d\x47\x24\x2d\xa1\x1b\x15\xee\x9e\xee\x14\x67\xab\x17\xda\xb0\x1c\x2c\xb9\x52\xc1\xff\xec\xb4\x8d\x5a\xc0\x5d\xc0\x9c\x09\x53\xd2\x2c\x5b\x10\x36\xe7\x89\x09\xeb\x83\x6b\x42\x6e\xd0\xd8\xde\xce\x44\xd8\x4a\x74\x68\x2f\x2e\x0c\x97\x30\x58\x6f\xe9\xd3\x85\xdb\x2f\x8d\xdd\xe6\x4c\x36\x78\x21\xae\x64\xb4\x56\x58\x35\x76\x5c\xb4\x81\xc3\x3f\x01\xb9\xbe\xfb\xb8\xdd\xe4\x4a\x3a\x53\xb2\x0e\xd4\xab\x29\x96\x96\x59\x66\x11\x03\xad\xb0\xcb\x0b\x58\x61\x1d\xc5\x25\xd5\x90\x19\x0d\xef\x68\x62\x3e\xff\x70\x69\xa1\x62\xdb\xdc\xc9\x42\x66\x72\xba\x88\x21\x0d\x2b\x03\xdb\xad\xeb\x8b\xb7\x7a\x28\x34\x58\xf4\xfb\xd0\xd8\x9a\xde\xf2\xd7\x5b\xfe\x7a\xdd\x66\xe9\xe9\x75\x9b\xf0\xf4\xba\xcd\x96\xa7\xd7\x6d\x7a\xdd\xa6\xb7\xfc\x91\x9e\x3b\x6e\x80\x49\xcf\x1d\x49\xcf\x1d\xd7\xae\xab\xe7\x8e\x1b\xc1\xd3\x73\xc7\x9e\x3b\xae\x7a\x0a\x99\xee\xe1\xe8\x58\xc8\x74\x83\x9f\x23\x5a\x7d\x12\x39\xcc\x64\x42\x8d\x73\x04\xb7\x5d\x9c\x9d\x4f\xd3\x1c\x0d\x51\x03\xf2\x77\x29\x18\x3a\xaf\xd9\xbd\x01\x73\x92\x34\x33\xa6\x6c\xf3\x13\x7d\xba\xd1\xb1\xa9\xf7\x93\xec\xfd\x24\x5f\xbc\x9f\xe4\x8c\x6a\xdc\x57\x24\x4a\xeb\xdd\x26\xa3\x03\x79\xc7\x54\xfe\x85\x7a\x4d\x5a\x74\x71\xdb\x0d\x21\x36\xd5\x96\xe2\xca\x53\x77\x5f\xc0\xd2\x9b\xfa\x7a\x9d\xbc\x0c\x8b\xa2\x69\xca\x52\x52\x30\x35\x44\x14\x91\x64\xc2\x45\xba\x62\xad\x1e\x3e\xcf\xea\xfd\x58\x5f\xc7\x33\xba\x40\xd6\x27\xb2\x83\xcd\x35\x36\x1c\xd7\x28\xfc\x8b\x70\x88\xec\x2a\xd5\x0f\x89\x71\x46\xde\x6f\x5b\xca\xf5\xdd\x45\x73\x10\xa8\xbd\x49\x78\x77\xbd\x12\xc4\xf2\x1f\x4b\xa6\x16\x10\x63\x51\x09\xac\x21\x98\xcb\xdd\x91\x71\x4d\x12\xaa\x91\x53\x74\x55\x2d\x3b\xaa\x51\xbb\xe9\x29\xbb\x5b\xa2\x49\x13\x2e\xcd\xa1\x50\x27\xf5\x3a\x38\xc2\x6c\xa5\x12\xbe\xe2\x16\xa0\xb2\xfe\x77\x9a\xcf\xae\xa2\xdb\x4e\x82\xdb\x4a\xa4\x78\xc1\xca\x39\xd9\x5d\x41\x27\x3b\x2b\xe9\x64\x27\x45\x9d\xec\xaa\xac\x93\x3d\x14\x76\xb2\x9b\xd2\x4e\x9a\xa8\x60\x77\xc8\x49\x59\x8f\xa3\xbf\x93\x7d\x54\x54\xb2\x87\x1e\x4f\x9a\x4b\x0d\x68\xaa\x1e\x4b\xa9\x07\x5c\xaf\xe9\xf5\x4f\x0d\xac\xdd\x74\x7a\xd2\x04\x95\x8f\xba\x03\x85\xf6\x0b\xd1\xf0\x9f\x44\xdd\x26\x7b\xa9\xdc\x64\x77\xb5\x9b\xec\x8e\x19\xc0\xea\xde\xc1\x75\xea\xbe\x0c\x13\x47\x41\x16\x91\xd3\xc2\x22\xc5\x3f\x2c\x27\x80\x7d\xf9\x17\x29\x28\x57\xda\xca\x77\xce\x66\x12\xff\xe6\xb4\xf3\x78\x18\x3b\x02\xd7\xc4\x92\xea\x39\xcd\x2c\xef\x41\x3f\x0e\xa7\x17\xd9\xd1\x9b\x6c\x7a\x40\x1e\x20\xea\xd3\x52\x29\xd4\x96\xb8\x26\x47\xf7\x6c\x71\x34\x58\x42\xa4\xa3\x6b\x71\x84\x3c\x6a\x09\x75\x02\x43\x93\x22\x5b\x90\x23\xf8\xed\xe8\xd0\x9c\x7d\x07\xc6\x15\x27\xdb\xd8\x95\x2f\xec\x80\x25\xc2\xc7\x4a\x1f\x5e\xd8\x44\x2e\x82\x17\x1b\xfe\x2b\xba\x62\x30\xe0\x6a\x11\x31\x97\xe0\x35\x02\x38\x06\xef\x53\xaf\xfc\x96\xc2\xa5\x56\x00\xdd\xb5\x1a\x0c\x99\xd4\xb2\x4b\x93\xdb\x78\x29\x98\x06\xc1\x8e\x05\x13\x51\xd4\x19\xda\x8e\xd0\x1d\xa4\xe2\x76\x22\x6d\x3a\x88\x54\x3d\x40\x46\xcc\x19\x15\x9a\x1c\x79\xdb\xd3\xb1\xae\x5a\x1c\x8d\xaa\xe8\xbe\x30\x22\x04\x21\xc7\x11\x7d\xd5\x80\xbd\xa4\xdd\x4b\xda\xbd\xa4\xdd\xa1\x57\x2f\x69\xaf\x7f\x7a\x49\xbb\xc3\xd3\x4b\xda\xbd\xa4\xbd\xe9\xc3\xbd\xa4\xdd\x4b\xda\xdb\x3f\xbe\x9b\xa4\xbd\xab\x9f\x50\x2c\xf7\xba\xcb\x39\xcc\x9c\x45\x0d\x4f\x2a\x1f\x22\xdf\x0a\xff\x75\x58\x79\x3b\x96\xa5\x57\x4b\xdb\xb1\x44\xbe\xa4\x5b\x8c\xb6\x88\xd6\x41\xf8\x5e\xea\xb9\x59\xea\x7e\x59\xbe\x50\x3b\xe0\x46\x74\xa1\xb0\x23\x72\xdc\xf9\xab\x70\x97\x69\x6e\xcc\xaa\x7b\xf2\x94\x9c\xf8\x1b\x97\x53\x0b\x7c\x21\x4d\xfd\x47\x61\xf8\xb0\x6a\x11\xee\x60\xe0\x7a\xb1\x16\x6f\x53\xbb\x96\x08\xb7\xee\xe1\xa6\xb8\xda\x4f\x4b\x42\x98\xaa\xcd\x81\x6b\x97\x40\x0c\xbc\x25\x54\x29\x84\x1d\x55\x0a\x7f\x7d\x8c\x34\x07\x13\xc0\x39\xcc\x43\x61\x09\xe6\x03\x12\x53\x05\xa5\xe8\xbe\x93\x1a\xcc\xb9\xe7\x5c\xf9\xa5\x70\x37\xa2\xf6\x8d\xbf\xf5\xf5\x48\x09\x2b\xe2\xe1\xeb\x23\x72\x05\x78\x18\x0f\xcc\x35\xc0\x87\x66\x99\x7c\xe8\x42\x92\x9e\x2a\x2c\xea\xa1\x73\x58\x54\xe3\xfe\xae\x8f\x8a\xfa\x99\x44\x45\xc1\x8f\x78\x84\x0e\x1e\x1e\x45\x7e\x98\x31\xc0\x22\xc5\x00\x54\x79\x99\x19\x5e\x54\xbe\x52\x1a\x3f\x95\xa1\x94\x39\x71\x9e\x27\x75\xbc\xb4\x5f\xa3\xc9\xac\x89\x9f\x30\x1e\xf8\x56\x69\x38\xb4\xce\xbb\x83\x66\x99\x8b\x29\xf2\x22\x29\xba\xb0\xf0\xe7\xf6\x4c\xb8\xf4\x59\x11\xbd\x36\x03\x44\xe6\xc4\xd2\xc2\x6c\xe1\x32\xd5\x6d\x20\xa2\xa8\x14\xcd\x99\x67\xbd\x53\x3e\x67\xa2\xa2\xa4\x27\xfa\xf4\xd4\xf3\xf0\x83\x52\xf8\x47\xa1\xd0\x7f\x88\x28\xe9\x1f\xdb\xd0\x68\x58\x50\xa0\xd2\x15\xf8\x2a\x1a\xfd\x9c\x2e\x18\x5d\xee\xf9\xbb\xd9\x18\x76\xb8\xdf\x7f\xc2\xbb\xfd\x2f\x27\xb2\xec\x99\x2d\x8c\xcf\xe1\x5b\xff\xe2\xad\x8a\xbd\x73\x7d\xf5\xec\xeb\x5c\xff\xe8\x96\xc3\xe7\xf5\xb1\xff\x02\xac\x85\xcf\xe9\x63\xdf\x5b\x08\x37\x6e\xca\x4b\x73\x7d\xaf\x3f\x3b\x59\x04\x7b\x6b\xe0\xce\x5c\xb8\x23\xc3\xd9\xd7\x0a\xd8\x11\x23\x76\xbc\x67\xef\xef\xd8\x9f\xe6\x8e\xbd\x97\x78\x5b\x3e\xbd\xc4\xbb\x16\x28\xbd\xc4\x4b\x7a\x89\x77\xdb\xf2\x7a\x89\x77\x23\x78\x7a\x89\x77\xe3\xa6\xf4\x12\x6f\x2f\xf1\x92\x2f\x4d\xe2\xdd\x25\x4b\x57\x7f\xd7\xbd\xd7\x5d\x77\x57\x6a\xd1\x89\x46\x74\xc4\x83\xce\x77\xdb\xfd\xbd\xf6\x4b\xb9\xd7\x6e\x1d\xf0\x2f\x0c\xdf\x37\xe8\x3f\xde\xab\x75\x91\xff\x74\x2e\x79\x4a\x8a\xd2\xb8\x78\xea\x3e\xfa\xff\x10\xd1\xff\x35\xc8\xf7\x29\x00\x5a\xa5\x00\x58\x07\xb3\x3e\x0f\x40\x9f\x07\xe0\xc0\x97\xd0\x7d\x1e\x80\x3e\x0f\x40\x9f\x07\xc0\x3f\x7d\x74\x12\xe9\xa3\x93\x5a\x3d\x7d\x74\xd2\xfa\xa7\x8f\x4e\x7a\xb1\xd6\x57\xd2\x47\x27\xbd\x6c\x4b\x2c\xe9\xa3\x93\x7a\xeb\x6c\xcb\x8d\xfa\x02\xa3\x93\xfa\x3c\x00\x2f\xd5\x47\x81\xf4\x92\x76\x2f\x69\xf7\x92\x76\x2f\x69\x6f\x7e\x7a\x49\xbb\xc3\xd3\x4b\xda\xbd\xa4\xbd\xe9\xc3\xbd\xa4\xdd\x4b\xda\xdb\x3f\xde\xe7\x01\xf8\x82\x7c\x23\x48\x9f\x07\xa0\xf7\x97\xe8\xf3\x00\xfc\x7c\xf3\x00\xd4\xee\xee\x9f\x2f\x19\x40\xf7\x69\xf4\x19\x01\xfa\x8c\x00\x7d\x46\x80\x3e\x23\x80\x7f\xfa\x8c\x00\xf8\xbc\x24\x5b\x63\x1f\x1f\xb5\x16\x28\x7d\x7c\x14\xe9\xe3\xa3\xb6\x2d\xef\x0b\xb0\x1b\xf6\xf1\x51\x2f\xd0\x56\xd8\xc7\x47\xf5\x76\xc1\xe6\xe6\x7c\x21\xf1\x51\x7d\x46\x80\x97\x78\xdb\xde\x4b\xbc\x2d\x9f\x5e\xe2\x5d\x0b\x94\x5e\xe2\x25\xbd\xc4\xbb\x6d\x79\xbd\xc4\xbb\x11\x3c\xbd\xc4\xbb\x71\x53\x7a\x89\xb7\x97\x78\xc9\x97\x26\xf1\xf6\x19\x01\xfa\x8c\x00\x7d\x46\x80\x2f\xf1\x86\x7b\xeb\x4e\x33\x31\x5f\xb7\xa7\xb5\x5d\xbc\x12\xf3\xba\x9e\xc2\xc4\x9c\x2b\x29\x80\x02\xcf\xa9\xe2\x74\x9c\xc1\x49\x05\x89\xc7\xc1\xdf\xd1\x4f\xa6\x46\xe4\x82\x0a\x77\xd1\x8a\x37\x99\x6b\xe7\xbf\x1d\xf1\xb7\xa0\x7a\x73\xda\xdf\xd3\xba\xa8\x26\x56\x4e\x9d\xb8\x06\x76\xea\x94\x5c\x84\x89\xaf\xfd\x4c\x2b\x02\xde\x46\x3f\x18\x02\x72\xae\x6d\xd0\x4e\x8a\xb7\x43\x6c\x3e\x9b\x35\xb0\x7c\xa0\x79\x15\xe2\xbf\x02\x1a\x23\xf2\xde\x49\x48\x94\x5c\xfc\xef\xf5\xe5\xd5\x87\xbb\xeb\xb7\xd7\x57\x1f\x37\x23\x5d\x4b\xb2\x02\x07\xa9\xc3\x64\x8f\xbf\xf7\x7b\x04\x61\xde\x4c\x58\x0a\xfc\xcb\x93\xef\xcf\x3f\xfe\xef\x87\xf3\xf7\x57\xa7\xc0\x7e\xd9\xe7\x82\x8a\x94\xa5\xa4\xd4\x9e\x24\x14\x8a\xcd\xb9\x2c\x75\xb6\x08\xc7\x7b\x35\xd2\x36\xb1\xd5\x29\x9a\x0b\xa2\x99\x9a\xf3\x64\x35\x88\x50\x8a\xa5\x15\x02\x25\x01\xc3\x15\xd3\x32\x9b\xb3\x14\x65\x8d\x30\x69\xff\x1d\x2e\x8a\xd2\x78\x89\x18\x5c\x10\xec\xa9\x10\xc9\x8c\x8a\x29\x4b\x47\xe4\x52\x96\x76\xbc\x5f\xfe\x12\x16\xa6\x58\x5a\x26\xc8\xeb\xa8\x17\x98\x7e\x39\xf0\x94\xc4\xd2\x02\x8d\x69\x14\x74\x42\x0b\xbf\xf4\x18\x3a\x7a\x21\x0c\xfd\xfc\x06\xef\xe0\x8f\x7e\x19\xfd\x74\xe4\x53\x50\x48\xfb\x09\xa4\x47\x38\xab\x0c\xb2\x1f\x64\xe4\x28\x6e\x3d\x22\x57\xf6\x1b\x2c\x8d\xf7\x01\x5d\x28\xd8\x9c\x29\x90\xa7\xdd\x2e\x0c\x88\x62\x53\xaa\xd2\x8c\x69\x70\x1e\x78\x98\x31\x48\xe7\x81\x12\x96\x03\x18\x0b\xd2\xba\x90\x66\x44\x2e\xd9\x84\x96\x99\x01\x1a\x72\x74\x34\x3a\x3e\x18\xaa\xbd\x55\x72\x4b\xf0\x7b\x0d\xdd\x6e\x31\xa9\xc4\x44\xaa\xb5\xc7\xe3\xd8\x99\x26\x6a\x64\x4d\x5b\x4e\xe2\x34\x3d\x4f\xab\x51\xbf\x68\xb1\x92\x16\x82\x60\x7b\x75\x3e\x91\x62\xc2\xa7\xef\x69\xf1\x2d\x5b\x7c\x64\x93\x8e\xde\x10\xc8\x44\x9d\x4e\x0b\x0c\xcc\x92\x43\x1c\x70\x3b\xd3\x79\xc4\xbb\xfc\x36\x46\x93\x6e\x36\x8f\xd6\x96\x8e\xa5\x94\x16\xc8\xf4\x1d\xfb\x3e\x60\x72\x9e\xea\xd9\x4e\xd1\x57\x4e\xee\x38\x26\xed\xee\x9c\x9a\x11\x79\x2f\xc1\x25\x67\x22\xdf\x90\x99\x31\x85\x7e\x73\x76\x76\x5f\x8e\x99\x12\xcc\x30\x3d\xe2\xf2\x2c\x95\x89\x3e\x4b\xa4\x48\x58\x61\xf4\x99\x9c\x5b\xca\xc7\x1e\xce\x1e\xa4\xba\xe7\x62\x3a\xb4\x92\xce\x10\x77\x55\x9f\x81\x30\x75\xf6\x0b\x94\xd8\xef\xbe\xbb\xfc\xee\x0d\x39\x4f\x53\x97\xb1\xa7\xd4\x6c\x52\x66\x2e\x7b\xc7\x88\xd0\x82\x7f\xcf\x94\x55\xca\x06\xe4\x9e\x8b\x74\x40\x4a\x9e\xfe\xe7\xe6\xc3\xbd\x23\xc4\x64\x81\xba\xd1\x0e\x50\xbb\x05\x41\x71\x51\xa3\x53\x01\xe9\x2d\x85\xe2\x46\xc3\x9e\x7b\xc3\x81\x63\x28\x1d\x96\x31\x96\x32\x63\x54\x6c\xe9\x01\x60\xeb\x7e\x66\x8f\xab\x43\x8b\x5a\x8e\x43\x80\x42\xa6\x6f\x88\x2e\x8b\x42\x2a\xa3\x49\xce\x0c\x4d\xa9\xa1\x23\xbb\x73\x83\xfa\x9f\x20\x1c\x0f\xc8\x5f\xc3\x4b\x90\x70\xf5\x9f\x8f\x8f\xff\xf0\xed\xd5\x7f\xff\xf1\xf8\xf8\x2f\x7f\x8d\x7f\x05\xb2\x87\xa6\xae\x7a\x13\x2b\x72\x8f\xac\xb8\xfb\x01\xbe\x01\x7f\x3a\x36\x7a\x9e\x24\xb2\x14\xc6\xfd\x60\xa8\x29\xf5\x68\x26\xb5\xb9\xbe\x09\x7f\x16\x32\x6d\xfe\xa5\xb7\x70\x02\xf2\xb8\x44\x07\xc0\x79\x43\xcd\xec\xc0\xa4\xa7\x3a\x17\x3b\xa0\xab\xeb\x19\x67\x48\xca\x29\xfc\xf3\xad\x9f\xae\xe5\x40\x0f\x8a\x1b\xc3\x04\xc8\x1d\xe0\x77\x27\x27\x03\x8b\xb9\x15\x9b\x9d\xbf\xee\xa4\x8e\xb6\x3e\x8a\x01\x6a\x3b\x2c\x0e\x66\xef\x56\x86\xc8\x1c\x08\xed\xb2\x5e\x77\x7e\x73\x4d\xe6\x08\x8d\x83\x2f\xc4\x7b\x61\xbd\xdd\xfb\x4c\x86\x4c\x55\x6e\x59\x41\xd2\x7c\x83\x96\xa5\xe0\xef\x45\x32\x9e\x73\x67\x00\x76\x59\xad\x34\x39\xc1\x97\xa3\xa4\x28\x07\xae\xc1\x28\x67\xb9\x54\x8b\xf0\x27\x2b\x66\x2c\xb7\x12\xdb\x50\x1b\xa9\xe8\x94\x0d\x42\x77\xec\x16\xfe\xc2\x8e\xb5\x0f\x2c\xf7\x46\x91\x3a\x29\x95\x65\x1e\xd9\xc2\x53\x10\x96\x3e\xef\x59\xf4\x60\x3a\xf0\x51\x0c\xbb\xf1\x61\x47\x96\x1b\xb4\x45\x64\xda\x61\x55\x20\x43\xce\x65\x56\xe6\x4c\x0f\x02\x7b\x42\x69\x5d\xcc\xad\x34\xa9\x1f\x85\x11\xa6\x7c\xce\xf5\x4e\xf7\xd3\xb7\xc1\x52\x07\x26\xb2\xd2\x58\x4d\x05\x9d\xc1\xa3\x8c\x70\x52\x83\x0e\x10\x7c\x14\x6b\x24\xe5\xf5\x51\xbb\xdb\x57\x6a\x0c\x53\xe2\x0d\xf9\xff\x4e\xfe\xe7\xdf\xfe\x39\x3c\xfd\xcf\x93\x93\x3f\xbf\x1a\xfe\x3f\x7f\xf9\xb7\x93\xff\x19\xc1\x3f\x7e\x75\xfa\x9f\xa7\xff\xf4\x7f\xfc\xdb\xe9\xe9\xc9\xc9\x9f\xbf\x7d\xff\xcd\xdd\xcd\xd5\x5f\xf8\xe9\x3f\xff\x2c\xca\xfc\x1e\xff\xfa\xe7\xc9\x9f\xd9\xd5\x5f\x5a\x0e\x72\x7a\xfa\x9f\xbf\x6c\x35\x3d\x2a\x16\xdf\xb5\x38\xf0\xf8\x0c\x77\xf0\xb0\xaf\x7a\x75\x30\xd0\x7f\x1e\x56\x42\xdb\x90\x0b\x33\x94\x6a\x88\xdd\xdf\x10\xa3\xca\xed\x07\xa3\x22\x6a\xbb\xe0\xb9\x4f\x07\xf6\xa6\x22\x68\x81\x34\x1f\x1c\x91\x35\x4b\x14\x33\x87\xd2\x60\x70\x34\xcf\x3f\x1a\x26\xd9\x5e\xa9\xa9\x94\x9a\x60\x97\x04\x78\x55\x9c\x77\xa2\x64\x3e\x22\x91\x59\x68\x0e\x37\x99\xae\xdd\x3d\xdb\xa2\xe5\xfa\xa7\x57\x82\xbe\x2c\x25\xe8\x16\xf7\xf7\xd1\x35\x20\x26\xe6\x9b\xcc\x34\x4d\x9b\xee\x5b\x08\x65\x89\xcd\xd1\x5e\x80\x32\x92\x14\xb2\x28\x33\x6a\xd6\x98\xed\x56\xd8\xa6\x1d\xee\x57\xb7\x00\x76\xa3\xc1\x0e\xec\xa8\x5c\xbe\xda\x18\x4a\xce\xb3\x8c\x70\x81\x27\x01\x06\xf0\xd6\x3c\xc5\x50\x5e\x22\x14\x0d\xce\x73\x3b\x85\x07\x17\x70\x13\x19\x1a\xb9\xb6\xba\x8e\x32\x60\xf1\x87\x80\x1c\xa4\x59\xce\x34\xc6\x45\x15\x96\x13\xb8\x6d\xb8\xa5\x5c\x99\x7f\x31\xa3\xda\xf8\x69\xc3\x6c\x0c\xbd\x07\x53\x68\xc2\x52\x26\x12\x06\x2e\x08\x25\xab\xd6\x3a\xb6\xc2\x20\x98\xf7\x61\x0c\x4a\xd2\xb2\xc8\x78\x62\xe1\x67\x67\xb2\x7a\x8c\xeb\x3c\x2f\x0d\x18\x8a\x9f\xca\x8a\x6f\x77\xfc\xd6\xa7\x7b\x0d\xc6\x7c\x20\x55\x41\xb4\x0e\xde\x16\x41\x75\xd7\xfb\x99\xef\xdb\x11\xde\x60\x6e\xdb\xca\xa9\x96\x28\x6e\x65\x63\xa8\x53\xda\xa7\xb6\x18\xb6\xa3\xb3\x3f\x49\x1a\xdb\x81\xbe\xb6\xa7\xad\x1d\x8c\x4b\x5d\xe9\x69\x5b\x6b\x52\xa1\xd8\x84\x7f\xee\x80\x8f\xe7\xa2\x52\x51\x78\xca\x84\xb1\x8a\x00\x64\xa6\x2e\x14\x2b\x98\x48\x43\xb8\x1f\x38\x78\x89\xfa\x3a\x1e\xf5\xc6\x08\xa5\x8c\xee\xc7\xeb\x76\x95\x14\xd3\x9f\xad\x9f\xf8\xd9\x72\xbb\x7e\xf8\x83\x25\x64\xba\xd5\xf9\xbb\xb1\x8f\x51\x8f\x86\xa7\xab\x4b\xff\xed\x26\x69\xb5\xb7\x70\xe5\x54\xc8\x14\x73\x5c\x9b\xca\x09\x61\x44\x6e\x57\xf4\x04\x5f\x03\xd7\xe2\xf8\x58\xa3\x5b\x82\x6e\x0e\xd4\x88\x6e\x46\xcf\x04\x1c\xb4\x23\x4a\x21\xab\x2b\x15\x58\x7e\xcf\xa8\xd6\x7c\x2a\x86\x85\x4c\x21\x2f\xf7\xd9\x3a\x84\x68\x71\xa8\xba\x79\x36\x6d\xc5\xab\x60\x9c\x68\xb7\x4d\x1f\x83\xfd\x2d\x92\x2d\x7c\x46\x78\x15\xfd\xe8\xec\x3a\xde\x8f\x3e\x92\x21\x2b\x89\x68\x3f\x98\xe6\x54\xd0\x29\x1b\xba\x8f\x0f\xc3\xc7\x87\xe1\x5b\xfb\x80\xb9\x0d\xd5\x42\x93\x62\xeb\xb2\x10\xc7\xef\xd0\x64\x99\x86\xf2\x10\xe8\xbf\xf7\x99\xe7\x65\x4e\x68\x2e\x4b\x74\xd1\x5b\x06\xa7\x77\x64\x39\x08\xc0\x56\x00\x4a\xaf\x85\x54\x4b\x68\x91\x9d\x5c\xee\x5e\xa8\x65\xab\x95\x45\xab\x9b\x25\xab\x83\x05\x6b\x67\xcb\x95\x37\x52\xb7\xc7\xc7\x8f\xde\x6e\xde\xc0\x48\x2e\xb6\x62\xa4\x0a\xf9\xee\xaf\x27\x24\x8c\xc3\x35\x91\x39\x37\xc6\x19\x74\x69\x75\xec\x07\x84\x9b\x9a\xf5\xd3\x9d\x05\xa8\xf7\x80\x25\x32\xd8\x67\xab\x4d\x71\xb0\xa2\xfb\x5b\x8b\x01\x72\xd9\x07\x8e\xd9\x21\xa8\x20\x3c\x2f\xd0\x99\x15\x70\x7a\xe8\x75\x33\xe7\x64\xd0\x9f\x8f\xfe\x7c\xac\xea\xa4\xbb\xc8\x22\xb1\x18\x52\x79\x30\x06\x71\xc4\x62\xb6\x2f\x3c\x03\x1e\x9a\x88\x43\xf6\x2c\x80\x13\x3d\x17\x53\xf2\x91\x81\x65\xe0\x96\x19\xed\x7c\x22\xa1\x07\x55\x6c\x39\xc4\xcc\x5b\x42\x82\xab\x2d\x9d\x4c\xea\x2d\x52\x56\x64\x72\x91\x83\x64\x7b\x6d\x62\x79\x26\x88\x2e\x2c\x2f\x32\x6a\x58\x10\x6c\x36\x5b\x1b\xf6\xe6\x7c\x5d\xe2\xbb\x9e\x37\xa2\xab\x9d\x77\x70\x0b\x9f\xe0\x97\x1f\xa7\xd5\x5a\x23\x6b\x6b\x77\x6f\x63\x73\x6f\x19\x6f\xd5\x5e\x09\x6c\x65\x94\x7f\xec\x28\xaa\x4e\xea\x58\xdb\x48\xa9\x97\x1f\x1b\xd5\x61\xd9\x6d\xe3\x9f\xfa\x88\xa7\x4d\xa0\x6e\x17\xb5\xd0\x3a\x62\xa1\xd5\xfe\xb5\x8c\x5c\xea\x63\x95\x3a\xf0\x97\x47\x10\xfe\xb6\xee\xa5\x91\x19\x43\xc9\xb5\x9d\xee\x7e\x57\xb5\x0f\xf5\xcf\xf0\x7a\x37\x1a\xe9\x69\x6e\x29\xee\xbc\xd8\x62\xcf\x56\x35\x2f\x40\x2d\x63\x28\x14\x3b\x33\xd2\xcf\xcb\x6e\x9c\x58\x10\xbb\x67\xc6\x55\xbe\x8b\x4a\xc1\x19\x05\x97\x3e\x7f\x08\xd8\x36\x60\x20\x3f\xfd\x31\xf2\x6f\x0f\xf1\x2f\x01\x43\xfe\xe0\xff\xf5\xc7\x3d\xe3\x16\xda\x31\x36\x9c\x52\x07\x01\xe3\x0a\x3a\x10\x2e\x52\xb8\x60\x72\x4b\x05\x08\xe0\x58\x16\x3e\xb0\x2c\x1f\xff\x82\x81\x54\xce\xcc\x05\x37\x51\x55\x63\xed\xae\xcc\x22\xbd\xca\x99\x14\xaa\x93\xc1\xc8\x07\xe9\x92\x12\xb2\x01\xb9\x01\x5b\x6a\xf5\x06\x4e\xd2\x07\x89\xe9\x09\xd7\xde\x65\xc5\x70\xdb\xca\x45\xb6\x32\xfa\x1a\x40\xbe\xad\x98\x3c\xae\xac\xc6\xe4\x2b\x0c\xae\x45\xc2\x6d\x82\xcc\x3d\x5b\x54\xcc\xc6\x89\x10\x40\xf2\x07\x15\x96\x78\x56\x80\xbc\xe3\x3f\xbc\x29\x2b\x1f\x73\x81\x1f\xc3\xa1\xfd\x56\xc0\xe8\x1e\xa0\x56\xb2\xcb\x32\xfc\xcc\x21\xc0\xd5\x4e\xce\xa8\xc1\xec\xbb\x0e\x32\x46\xa0\x92\xab\xa5\x8b\x48\xa4\xb8\xfa\xb1\xa4\x59\x3d\x08\xc1\xbd\x72\x8d\x96\xa8\xfa\x03\xcf\xd2\x84\x2a\xe7\xe5\x05\x67\x94\x68\x89\xbb\x87\x59\xf1\x12\x2a\xc2\x69\xaf\xf6\x08\xeb\x20\x92\x82\x2a\xc3\x93\x32\xa3\x8a\xd8\xb3\x30\x95\xaa\x55\xa0\xc0\x56\x88\x56\x48\x73\xcb\x12\x29\xd2\x2e\x0a\xc0\x5d\xb3\x6f\xf3\xae\xb5\x60\x8a\xbb\x74\x7f\x3c\x67\x4d\x24\x3d\xa9\xdb\xb4\xe5\xc4\x9f\xea\x70\xc4\x6a\x96\x8f\x2a\x26\x93\x6b\xc2\x31\x5f\xe8\x69\x44\x1e\xc3\xa9\x18\x91\xaf\x17\xde\xcc\x02\x26\x17\x17\x5d\xa1\x99\xf1\x81\x30\x1e\x65\x1d\xb0\xab\x03\x35\x91\x0a\x82\x53\x4e\x52\x89\x11\x19\x73\x9e\x98\xd3\x11\xf9\x7f\x99\x92\x18\xc1\xc9\xa6\x98\xbd\xd1\xa1\x78\x50\x5c\xa1\x70\x29\xdc\xe0\xbf\x22\x27\x98\x49\x93\xe7\x39\x4b\x39\x35\x2c\x5b\x9c\xa2\x1e\xeb\x73\x71\xb6\xd9\xba\x36\x46\x83\x28\xf1\xea\x6f\x7f\xb3\xa1\x65\xd7\x18\xaa\xef\x7d\x54\x4a\x05\x19\xf4\x21\x68\x6c\x61\xe0\x41\x72\x83\xb8\x19\xfb\x20\x54\x41\x9d\x9e\xcc\x84\x0d\xfe\x9b\xc5\x03\x4a\x14\x9b\x02\x96\x23\xe6\xee\x89\xe3\xe8\x4d\xf9\x5e\x96\x62\xbd\x49\xb0\xb6\xf0\x77\x4e\x09\xff\x3e\xea\xb8\x36\x4a\xf1\x49\xc4\x84\x68\x26\x91\x89\x92\x12\xb0\x4b\x02\x3b\xb7\xe4\x01\x5b\x55\x9e\x28\x5b\x27\x79\xd0\x88\x44\x98\xcb\x16\xaf\xf7\x83\xc4\x2d\x86\x0f\x75\xc0\x65\x70\x10\x77\x80\x69\xc4\xed\x19\x47\x0e\x00\x3f\x11\x82\x15\x82\xc2\xb7\x58\xea\xbd\xd8\x30\xd6\x18\xba\x92\xe3\x37\xc7\x07\x21\xbe\xb8\x1c\x25\x0b\x3a\xa5\xdb\xf3\x1d\xd7\x95\x91\x46\x57\x92\x32\xc3\x54\x0e\x89\x69\x67\xf2\x01\x7f\x47\xb6\x55\xb8\x56\xcc\xe5\xf4\xb5\xab\x9d\x49\x0d\x5c\xa9\x1e\xc4\x08\xe7\x17\x2e\x46\x1f\xe8\x82\x50\x25\x4b\x91\x3a\xa9\x29\x10\xd0\xf7\x8d\x0f\x7f\x90\x02\x28\x45\xa9\x2d\xac\xee\x6a\x54\x7a\xcc\x0c\xb5\xc7\xe6\xf5\xe8\xf5\x96\xdc\xd3\x2d\x01\xd6\x31\x6e\x15\x66\xd3\xb0\x14\xfa\xbb\x72\x7f\x66\x0e\x32\x2f\xc5\x68\xfa\x9d\xc8\xba\xc8\x72\xef\x11\xbd\xa0\xeb\x10\x94\x30\x3e\x01\xdb\xed\x00\x5f\x3d\x28\x6e\x58\x44\x1e\x4f\x26\x34\xd3\x50\x70\xbb\x14\x41\x84\x3d\xad\x8b\x20\xd0\xa4\xcd\x82\xb6\xfb\x83\xe8\x72\xbc\xe7\x39\x73\x07\x0a\x50\xae\x3a\x66\x01\xe1\x8e\xf5\x86\x23\x57\x0f\xee\x24\x27\xd8\xd2\x4a\x6c\x52\x9a\x8d\xe5\xdd\xdb\x3b\x89\xe0\x02\xad\x66\xdd\x45\x25\xf1\x71\xc3\xc5\x01\x57\xfb\x35\x9b\xd1\x39\xd3\x44\xf3\x9c\x67\x54\x65\x10\x2b\x78\x8b\xf3\x83\x62\xec\x2b\x23\xd0\xbb\x45\x37\xc7\x33\x89\x86\xdb\x0a\x6a\x3f\x0f\x0b\x27\xa0\x11\x7e\x5e\x98\x04\xdc\x67\x0e\xff\x9c\x64\xa5\xe6\xf3\x7d\x4f\x93\x8b\x7e\xd8\x81\x55\x37\xb9\x74\x21\xd3\xdb\x82\x25\x4f\xc9\xa3\xeb\x1a\x86\x25\x55\xa9\xdf\x74\xe0\xc9\xa8\xec\x53\x2c\xac\x3f\x66\x84\x26\x09\xd3\xda\xfb\x54\x2e\x62\x3f\xcf\xb0\x86\x2f\x25\xa1\x00\x7d\xd0\x57\x19\xd5\x86\x27\x5f\x67\x32\xb9\xbf\x35\x52\x75\x8a\xd9\x5f\xd5\xbf\x91\x86\xe1\xfc\x87\x5b\x72\xc9\xf5\x7d\x14\x4d\xe0\x2e\x4d\x63\x73\x09\x25\xf7\xe5\x98\x65\xcc\x1c\x1f\x6b\xe4\x72\x39\x4d\x66\x5c\x30\xcf\xe0\x44\x08\x49\x71\x0a\x9f\x85\x72\xd7\x3b\x53\x17\xf8\x74\xe6\xf0\xf5\x17\xf4\x41\x33\x9c\xfe\xd8\x4e\xdf\xfe\xcc\xda\x44\xa4\x1f\xf4\x9e\x02\x27\x73\x7d\x79\xa0\x3b\x88\x89\xbe\xb3\x73\xec\x66\xdc\x3e\xc6\x5e\x5e\x75\x98\xf0\x8c\xb9\xea\x03\x76\xc1\xde\x47\xcd\x9d\x0a\xd8\xbf\x85\x2c\xc9\x03\x45\x1d\x19\x28\xe2\x88\xdc\xf1\xe2\x0d\xb9\x12\xba\x54\xac\xb2\x6e\x34\x87\xe2\xba\x8a\x33\xf3\xca\x15\xec\x37\x2a\x20\x96\xee\x39\x5d\x8b\x5c\x7d\xa6\x79\x91\x31\xfd\x86\x1c\xb1\xcf\xe6\x37\x47\x03\x72\xf4\x79\xa2\xed\xff\x84\x99\xe8\xa3\x11\xb9\xce\xc3\xad\x3b\x17\x13\xa6\x14\xf3\x8e\x50\xd8\xc1\xb2\xe6\x88\xeb\x3e\x0a\xba\x38\xa7\x3a\x2b\xbb\xa5\x92\x3c\x60\x3e\x0a\x4b\xf0\x99\x52\x52\x05\x3f\xf4\x08\x0c\xc0\x6b\x12\x99\x17\x4a\xe6\x3c\x32\xf3\x01\xba\x1f\xd4\xdb\x0e\x8c\x0f\x6d\x0a\x72\x34\xb1\x21\x74\xf4\x08\x11\xbd\x10\x6d\x50\xe1\x7a\xe2\x9d\x29\x50\x8b\x74\x6a\x3d\x0c\xe7\x1a\xd9\xcd\x77\xa3\x58\x42\x16\x6f\xf7\xdb\x10\x50\x47\xce\x52\x36\x3f\xd3\x29\x7d\x3d\x80\xcf\x68\xe7\x08\x58\x9f\x13\xd5\xe4\xe8\xf5\xd1\x88\xdc\x7a\x46\x3c\x88\xe7\x58\xb5\x9b\x48\x15\x06\x04\x3b\xfb\xab\x23\x72\x22\x15\x8c\x9c\x50\x41\x32\x46\xe7\xce\xb6\x8c\xc7\x6d\x81\xea\xee\x69\xeb\x80\xc8\xb6\xb1\x61\xed\x2b\xaf\xb4\x15\x52\x97\x37\xd1\xf7\xf3\x26\x00\x55\xba\x58\x81\x89\x54\x2e\x0f\x48\x68\xa2\x99\x81\xa3\xc7\x45\x4d\x85\x7e\x06\x02\x4b\x3a\x86\xd2\x7b\xea\xd9\x15\x3a\xbe\x1f\xe8\x40\x82\xff\x58\x32\x72\x7d\x19\x02\xea\x99\xd2\x5c\x1b\x7b\x8c\xd3\x1a\xeb\xe2\xc8\xcf\x4e\xce\x73\xfa\x77\x29\xc8\xd5\xd7\xb7\x6e\x02\xa7\xcf\x0a\xaa\xad\xd4\x80\xfe\xbd\x54\xcc\x72\xe1\x0e\xcc\x3d\xf4\x69\x32\x74\xfb\x9e\x5c\x52\x43\x91\xaf\x3b\x4f\x2b\x51\x91\x72\xcb\xb2\xc7\x5c\xa4\xee\xa7\x88\x61\x3f\x35\x6f\xb5\xbb\xf7\x61\x93\x98\x14\x37\xfc\xf4\xf1\xfa\x40\x3c\x38\x01\x62\x3e\x7d\x2f\xd3\xce\x8c\x38\xea\xea\x89\xef\x9f\x2c\x4c\x2f\xf0\x3d\xc9\xed\x98\xc4\x6a\xef\x03\xf2\x91\xd1\x94\xd8\xf3\xeb\xfe\xf9\x83\xd5\x3d\x5b\xd3\xaa\x56\x2c\xc4\x03\xb0\xe3\x32\x7c\x37\xbf\x84\xd8\xd3\x3d\xb5\x98\x03\xc7\xca\xf1\x92\x71\x26\xc7\xc4\x1d\x87\x43\xcf\xfd\xd3\xc7\xeb\x1d\xa6\xfe\xe9\xe3\xb5\x9f\xb9\xfd\xa7\x9c\x3c\xdd\xa4\x77\x12\xdf\x2a\xe9\xed\x6d\x43\xdc\xaa\x58\x72\x15\xb8\xd1\x14\xc9\xda\xcb\x63\xa3\x43\x49\x62\x87\x84\xd8\x3d\x17\x2d\xa2\x70\xeb\xa7\xcc\xf6\xb1\x0a\x05\xfa\xaa\x45\xf7\x88\xb7\x33\x0a\xa1\xcf\x21\x20\x0f\xf6\xd9\x6e\xbc\xb6\x5c\xc1\xef\xb8\x55\x02\x81\xb6\x91\x4b\x86\xb7\x9c\xe9\x1b\xef\x3b\x10\x7a\xac\xee\xf0\x1e\x3c\x35\x53\x47\x5f\x09\x3a\x6e\xa6\x11\x82\x9d\xa0\x55\x49\x84\x9f\xe8\x9c\xf2\x8c\x8e\x79\xc6\x21\x95\xba\xd5\xee\x63\x6f\x54\x0d\x53\x3e\xe8\xa9\xdf\x51\xe4\x08\xe2\xc4\x92\x71\x8b\x9c\xd8\xdf\xce\xc0\x38\x76\x3a\x02\x6a\x05\x0d\x21\x47\x63\x43\x28\xf9\xb8\x4d\x28\x39\x98\xfc\x00\x3b\x60\x4f\x4c\x57\xae\x68\xfb\xac\xe4\x8a\xf0\xc3\xad\xcb\x27\xf7\x92\x19\x23\xc6\x5a\xb5\x62\x8d\x80\x5f\x5b\x5b\xb6\x67\x8e\xfb\x22\x57\xfa\x65\x20\x17\x09\x11\x6d\x3b\xf0\xcf\xaa\xa3\xe7\x43\xa0\x24\x81\xc7\x99\x8b\x76\xab\xb9\x66\x22\xf6\xdd\x3a\x5a\xe3\x52\x30\x21\xd7\xb5\x38\xd7\xa6\x2e\x5a\x97\xa4\x0d\x1e\x23\xba\xae\xca\xf7\xf3\x8b\x42\x12\x08\xaf\x49\x0b\x5c\x6c\x3d\xc9\x84\x15\xb3\x49\x97\x2b\x71\xdb\xe1\xed\x6d\xdd\x12\x78\xc1\x8a\x19\x79\x7b\xbb\xe2\x18\x03\xec\x61\xd6\x1a\xed\x83\xc7\x9a\x64\x7c\xc2\x0c\xdf\xb2\x84\x47\x38\xc8\xb9\x14\xdc\x48\xb5\x3e\x04\x9a\x74\x3a\x9c\x7e\xb8\xae\x0c\xd5\xf7\xb3\x3b\x5b\x25\x10\x79\x1f\xbd\xa5\x24\x91\x59\xc6\x12\xe3\x52\x5a\x01\x78\x43\xb7\x15\xca\x13\x73\xf6\x80\xd1\xfd\xef\x41\x7d\x72\x8a\xd2\x19\x6e\xee\xd9\xc7\xab\xf3\xcb\xf7\x57\xa3\x3c\xfd\xc5\x4c\x3e\x0c\x8d\x1c\x96\x9a\x0d\x79\x8b\x0c\x25\xcf\xe7\xbd\x88\x4f\xd1\x2a\x61\x56\xd3\x20\x83\xb9\xbe\xbe\xf3\xf1\x93\xe4\x93\x46\xaf\x05\xb0\x1d\xf9\x3b\x29\x29\xcd\x80\x28\xea\x62\x24\xa9\x33\x3d\x95\x59\x86\xd0\x36\x8a\xb1\x41\x6c\x8b\xd9\x18\x1a\xd2\x79\x61\x7b\x1b\x2a\x6a\x0b\x7c\x5c\x19\xe2\xe9\x11\xae\x0b\xc7\xd8\x2e\x93\x2c\x43\xb1\xea\x59\x87\xe3\x6d\xed\x3d\x1a\xce\xcc\xcc\x42\xf5\x9e\x2d\x08\x38\x02\x4f\xa4\xb2\xf8\xa4\xea\xb8\xc1\x4c\x02\x4b\x3f\x2b\x35\x53\x23\xc7\x76\x9e\x1c\x6c\x1d\xb2\x08\xed\x90\xbc\x2d\x74\x5c\x05\x33\xf7\xba\xca\xec\xeb\xe4\x35\x5a\x9a\x19\x13\xc6\x8a\xfd\x96\x96\x39\xc8\xac\x04\xa2\xf3\xc3\x7e\x72\xa8\xb5\x4c\x62\xd4\x2d\xe5\x50\x9f\xa6\xa7\x0b\x4e\xda\x53\xd3\x15\x1d\x6d\x1f\x08\x44\x8c\xc9\x7c\x88\xe5\x52\x34\x95\xe0\xb0\x81\x19\xe8\x6a\x88\x46\xd3\x9c\x8b\x17\x78\x3a\x13\x2e\xd2\x6d\x70\x68\x18\xc0\xa0\x47\x5d\x14\x73\xef\x9c\x41\x3f\xdc\x1b\x52\xaf\x49\x61\xc0\xbb\xbb\x41\xac\xdf\x1f\xb6\x3a\x7c\xf9\x42\xff\x98\x0d\xf1\x2b\xc3\x22\xad\xa0\xd2\x5f\x06\x2e\xdf\xe0\x1d\xd6\xa4\xf4\x04\x57\x7c\x07\xda\x6d\xf2\xc4\xd2\xd0\xe3\xea\xb9\x4f\x02\xa8\x2e\x32\xcf\xbe\xdc\xbb\xa2\x99\x50\x78\x5f\xfb\xe0\x33\xcc\x6c\x06\x67\xd4\xeb\xcb\x50\x90\x9f\x2a\x9a\x33\xc3\x14\xba\xc0\x39\xa7\x3a\xe1\xa2\x13\xbe\x2b\x98\xb8\x35\x34\xb9\x3f\x74\x2a\xd4\x9e\xe3\x3e\x1e\xc7\xdd\xfb\x2a\xd0\x23\x82\xcb\x8b\xb4\x88\x6f\x91\xb9\x70\x5c\xe8\x85\x90\x98\x90\x8e\xac\x8b\x95\x23\xa4\xa3\xaa\x73\xd7\x2a\x3d\x19\x1a\x36\xc0\xd3\x2d\xe4\xd7\x03\x0f\x7e\x84\xc2\x61\xb8\x61\xfb\x33\xe0\x48\xe0\x2e\xf7\x68\x51\xd7\x3a\x75\xc8\xed\x9b\x31\x37\xd5\xb9\xd7\xcc\x90\x82\xa9\x9c\xbb\xb0\x6e\x29\x48\xe2\xc2\x02\x80\xaf\x59\x1e\xe6\x86\x8b\x78\x9e\x20\x32\x31\xd4\xc5\xcc\x90\x31\x33\x0f\x8c\x09\xf2\xea\xd5\xab\x57\x20\x97\xbc\xfa\xdd\xef\x7e\x47\x20\x8f\x44\xca\x12\x9e\x2f\x37\x84\x56\xff\xe7\xf5\xeb\x11\xf9\xef\xf3\xf7\xef\xc0\xab\xac\x30\x9a\x8c\xa5\x99\xb9\x91\x6d\x83\x5a\x67\x3d\x20\xff\xf7\xf6\xbb\x0f\x5e\x9c\xd0\x8d\x5f\x41\x05\x09\xcb\xab\xbb\x08\xbe\xfa\xed\x6f\x7e\x33\x22\x97\x5c\x41\x3c\x31\x87\x08\x88\xe0\x04\x59\x78\xc7\x40\x28\x3c\xd4\x8c\xe0\x77\x1c\xc4\x39\x09\xe7\x7c\x3a\x03\x00\xd8\x03\x21\xc5\x24\xe3\x89\xc1\x9c\x82\x78\xf4\x11\xd0\xae\x2e\x12\x75\xe1\x5e\x4e\x8a\x80\xc9\x0d\x48\xc6\xef\x19\x99\xe8\x6f\x94\x2c\x8b\x2a\xcc\x51\x31\x6d\x65\xd9\x84\x0a\x88\x2a\x81\xc1\xaa\xbd\xd2\xcc\x3c\xab\x13\x46\x4b\x43\x50\x0d\x07\xa1\x4f\x43\x40\x19\x84\xdc\x6a\x43\xc4\x87\x82\xf2\xe0\x38\x08\x77\xea\xb5\xcc\xfe\x41\xf7\x4c\xa3\x5c\x72\x3e\x76\xa5\x50\xf2\x6f\xb8\x55\x5c\xf8\x28\x28\x27\x21\x6b\x27\x93\xb9\xa0\x53\x11\xd9\x5c\x7d\x54\xbe\xe5\x85\x2e\xe2\x3f\x8a\x9f\xba\x9e\xc4\x81\x76\x10\x96\x8e\xe5\xd5\x6a\x89\x2f\x57\x7c\xb9\x4a\xd6\x6e\xb1\x49\xe3\xbe\x96\x62\xa9\xb7\xab\xa3\xe2\xc8\x8f\xab\xae\xe3\x42\xd8\xaa\x31\xd0\x15\xd7\x05\x00\x45\x35\x9b\x6a\xc9\xe8\x6a\x5e\x3e\x9a\x99\xd2\x81\x06\x3c\xaf\xec\xb7\x99\xd6\x2e\x8e\x28\xa7\xea\xde\x2a\x09\x8e\x0a\x8c\xc0\xeb\x59\x87\x18\x26\x0c\x28\x9b\xa3\xb1\x3c\xa7\x8b\x5a\xd4\x80\xfd\xc8\xf1\x68\x74\x8c\xc7\x44\x2a\xcc\xe5\x89\x38\x6f\xdf\x3f\x53\xbc\x74\xdd\x2b\x9d\x16\x58\x76\x0f\xec\x39\xae\x6c\x09\xad\x79\x3b\x53\x07\xa9\x36\x19\x7c\x3b\x96\x2d\xec\x56\x1f\xb7\x7d\x5d\xdc\x21\x2c\xa0\x45\xd3\xae\x35\x70\x3b\xd4\xbe\x5d\x97\xad\xc1\xc1\xd8\x9d\x84\xb6\x15\x21\x3b\xe7\x02\xcf\x5b\xb1\xbe\x15\x53\x3d\xce\x1d\xe7\xfb\xae\x1b\xe7\x73\xf1\x7a\xb5\xe2\x60\x2f\x9f\xd5\x5d\x4f\x30\xd2\xa5\x4e\xba\x1c\x69\x88\x45\x81\x50\x88\xab\x0a\x7b\x79\xd1\x1c\x2d\x46\x9b\x6e\x89\xe7\xbb\x70\x37\x7c\xda\x5d\x4c\xe0\x53\xc3\x35\x7f\x3b\x81\x8b\x76\xa4\xb4\xa8\x15\xf8\xc8\xd0\x6e\x00\x32\xa6\x3f\x3c\x23\xf2\xde\x91\x5a\x44\x32\x3a\xd6\x32\x2b\x0d\x76\xad\x7e\x8c\xe9\x30\x0c\xea\xb3\x2c\x00\xf1\x0d\xcd\x22\xaa\x6c\xaa\x12\x67\xed\x08\x34\x3e\x1d\x0e\x67\x9f\xed\xf3\x11\xb3\x7d\x86\xfc\xb4\xba\x65\xbd\x26\xfd\x68\xe9\x75\x13\xcd\xbb\xe8\x57\x9a\x93\x93\xaa\x4c\x88\xbf\x8e\xbf\x16\x86\xa9\x09\x4d\xd8\x69\xac\x77\x85\x72\x2c\xc1\x45\xc8\xc7\x45\xcc\xa8\x48\x33\x14\xc0\x13\xa6\x00\xf7\xd9\x67\xc3\x94\x05\xc9\xc5\xed\x35\x49\x15\x9f\x33\xa5\xc9\xc9\xd7\xcc\xca\x8b\x8c\x9a\x52\xb1\x56\xd1\x55\x87\xf5\xad\x84\x69\x1c\x4a\xd3\x83\xc1\xba\xba\xea\x41\x27\x4f\x79\x44\x74\xbe\x2a\x30\x21\x54\x11\xa4\x3a\xd6\x65\x47\x16\x95\x80\x40\x03\xcd\x58\xc8\x52\x39\x2b\xba\xcf\xab\x9a\x48\x65\xd5\x25\x1c\x98\x6a\xa2\xd8\xd4\x4a\xb3\xca\x17\x1b\x66\x24\xc9\x4a\xfb\xe2\xa0\xee\x6c\xfb\x38\x00\x56\xa6\xd9\x4d\xbe\x7a\x13\x27\x55\xcb\x39\x4f\x3d\xab\xc4\xda\xc7\xa1\xaa\x61\x41\x75\x14\x6a\x13\x65\xa0\x8f\x00\x8b\x32\x3a\x30\xd4\x10\xc4\x5a\x73\xf6\x8f\x8d\xc2\x12\x72\x5b\xb4\x28\x1f\xd1\x85\x08\xcb\x94\xdd\x94\xe3\x8c\xeb\xd9\xed\x8e\x26\xc4\x55\x43\xa0\xb3\xc2\xd2\xad\xdf\x5a\x4b\xa2\x66\x42\x73\x60\x79\x96\x8c\x5b\xa6\xcb\xad\x1c\x25\x01\x88\xbe\x77\x8c\x90\x12\xa2\x3f\x32\xe6\x32\x18\xd8\x9f\x3e\x54\xf3\x70\x41\x69\x98\xb3\x24\x65\x9f\x44\x51\x7b\x9f\xd0\x2c\xd3\xcd\x80\x5d\x4f\x31\x51\xf6\xf0\x81\x6a\xb8\xa7\xdc\x6e\x77\xa8\x8c\xd2\xc8\x7e\xb9\x76\x61\x9a\xe4\x12\xc3\x78\x04\x91\xc2\x37\x82\xd4\x2b\xbe\x43\x14\xc8\x08\xe1\xca\x80\x32\x07\x2e\x1d\xd9\x9b\x4b\x1f\xcf\x5c\xba\xaf\x1f\x5e\x5c\xef\xbd\x8a\x86\xae\xa5\x25\x0d\xa4\xd4\x93\xdc\x2d\x4e\x1d\x07\xbd\x56\xc0\x6f\x9e\x1b\xa3\xf8\xb8\x34\xdd\xf3\xbd\x35\xba\x03\x9b\xb6\x8a\x08\x9c\xe2\xa1\x5b\x7d\x12\xa1\xa8\xd3\x10\xc2\x59\x58\x3e\xfb\x15\xcf\x01\x76\x83\x2f\x8f\x35\x49\x65\x52\x86\xbc\xb0\x00\xb4\xea\x02\xad\x4d\xf6\x44\xd2\xf5\x5c\x75\x4f\xe9\x15\x7f\x64\x2b\x7a\xa5\xf2\x41\x3c\x50\x95\x9e\xdf\x6c\xf1\xbe\xaf\xb3\xf3\xaa\x57\x2c\x28\xf9\xd7\x50\x05\x90\x8e\x65\x69\xaa\xd4\xa1\x3f\x1d\x7b\xf5\x2a\x35\xdd\x48\x4b\x1a\x5a\xda\xa3\xbb\x2a\xfa\xbd\x89\xbb\x37\x71\xd7\x9e\x5d\x4c\xdc\xd7\x68\xe2\x8e\xf3\xe0\xd6\x8e\xab\x4f\xaf\xc0\xb3\xb6\xbe\xbd\x8f\x69\x25\xbd\xac\x08\x0c\x4a\x53\x4d\x3f\xfe\x86\x00\x87\x47\xa4\xda\xdb\x48\xe8\xf3\x14\x08\x78\xf6\xf3\x5b\x54\x1f\xc9\x4e\xda\xbe\x4e\x31\x3e\xeb\x0a\x09\x6e\xaa\x5b\x0c\x52\x43\x54\x68\x78\xe0\xb2\x40\x0f\x9c\xde\x25\xd2\xaa\x84\x1f\x26\xa1\xee\x50\xa6\x14\x9f\x8e\xc0\x27\x9d\x37\x80\x74\x2c\x22\x8c\x4f\xd7\xdd\x20\x3b\x14\x14\xc6\xe7\x99\xcb\x0a\xe3\xd3\xd9\xf6\x4d\xba\x97\x18\x5e\xb1\xdc\xc7\x2d\x34\xbc\xe3\xd2\x76\x37\xeb\xef\x6a\xce\x1f\x54\xe5\xed\x5e\x3e\x5b\xef\xcd\xf9\x4b\xcf\x13\x9a\xf3\x23\xc2\xed\x89\xc1\x0a\xd3\x7e\x6c\x6e\xf3\xf6\xfd\x31\xf3\x62\xe5\xa8\xca\xbe\x66\x51\xce\x5b\xf6\xa5\xaa\x5f\xab\x1e\x8f\x46\xc7\xc7\xde\xde\xef\xf0\xb3\x34\x93\xe1\xef\x09\x13\x89\x4c\x71\x53\xed\xf8\x4a\x1b\x60\xfa\x95\x9a\x1e\xcf\x25\xf7\xdf\x8a\xaf\x66\x61\xec\x6e\x5b\xd2\xe1\x04\x77\x2f\x1b\xbe\x0a\xd2\x4f\x51\x3c\x3c\x2e\x11\x5e\xaf\x08\x8e\x2d\xf6\x29\x03\x1e\x03\xef\xd1\xf9\x6b\xeb\xc2\xe0\xf8\xec\xc2\x5e\x77\x28\x12\x8e\xcf\x13\x97\x0a\xc7\x67\x27\x8e\xda\xa9\x6c\xf8\x8a\xc5\x3d\x5d\xf1\x70\x7c\x5e\x68\x21\x99\xfa\xd3\xa9\x90\x38\x3e\xbb\x95\x13\xaf\xf7\xed\xb8\xf5\x07\x29\x2d\x8e\x4f\xb7\x02\xe3\xf8\x1c\xba\xcc\x38\x3e\x2d\x21\x01\xc6\xf0\x4b\xde\x29\x14\xc1\xf7\xa9\xbb\x4b\x1a\x96\x17\x52\x51\xb5\x20\xa9\xb3\x35\x2c\x56\x44\x84\x46\x21\xa1\x7b\xa7\x86\x81\x79\xa4\x5c\x1d\x28\x1a\xa1\x43\x34\x28\x4b\x79\xb9\xb6\x5c\xf3\x3a\xb0\x61\xaf\x18\x68\x0f\x90\x0d\xcc\x65\x12\xf3\xd7\x9d\xae\x99\x4f\xac\x48\x93\x7b\x57\x31\xc8\x43\x15\x79\x7f\x14\xe4\x72\x74\xd4\xc8\x03\x0d\xe6\x31\xb8\xfb\x73\x95\x11\x7d\x63\x1c\xbb\x66\xca\xc2\xdb\x10\xe7\x16\x70\xe2\x1a\x9e\x5a\x89\xe4\x3d\xb0\xc1\x27\xda\x25\xd2\x31\xb2\x8d\xff\x9d\x41\xb9\xb1\xce\xbe\xf1\xbe\x63\x48\x07\x2d\x41\x32\x0f\x75\xd1\x32\x99\x44\x77\xcf\x35\x0e\x05\xdb\x70\xe5\x91\xdf\xdb\xee\xed\x66\xd8\x51\x51\xbe\x00\xa3\x4f\xa6\xf1\x5e\x8f\x27\x90\xda\x12\xa4\x78\x00\x66\xd8\x80\xbb\xa8\x4a\x60\xa9\xed\x97\x20\xf3\x7c\xd4\xa6\xfa\xd0\x83\xcf\xb0\x69\xa2\x42\x6e\x75\xdd\xc3\xfe\x72\x1b\x56\x56\xe9\x6d\x10\x02\xe1\x05\x75\x5d\x82\x98\xe8\xbe\xe2\xc4\x25\x39\x81\xbb\xab\xaa\x2c\x5a\x48\xee\xb8\x84\x66\x82\x67\x75\x3c\xf3\xb9\xec\xc2\xc2\x4b\xe1\x1c\x0d\x96\x90\x66\x35\xce\x94\x9a\xa9\xe1\xb4\xe4\xe9\x2e\xd8\xf2\x82\x19\x60\x6b\xb6\xd7\x9d\xd9\x75\x64\x71\x7b\x30\xb6\xe0\x88\xd1\x81\x35\x1c\x55\xde\x1b\x35\xde\x10\xa7\xc5\xab\x7b\x72\x50\xef\x2c\x10\x8e\x9c\xbf\x12\xba\x0b\xaa\xad\xe3\x19\xc9\x22\x71\xc1\xba\xbc\x96\xee\x12\x87\x45\xcc\x03\xc7\xd6\xa1\xfd\x8f\x57\x81\xbd\x3d\x7f\xcc\x26\xb2\xaa\x90\x82\x1a\x91\x73\xc7\x4d\x59\xc6\xa0\x8c\xbc\x2f\x51\x6f\x1b\xc0\x95\x70\x2e\xe7\x16\x99\xff\x47\x90\x4f\x3e\x67\x3f\x9f\xbc\x21\xf4\xb4\x16\x02\xe1\xaa\xce\x08\xc6\x52\xf4\xd1\xcd\xaa\xef\xa8\x52\xe8\x01\x19\x9f\x7a\x7f\x14\x38\x71\xc2\x8a\x85\x99\x97\x78\x51\xaf\x56\xcc\x02\x00\xc2\x8e\x95\xcc\x89\x16\xb4\xd0\x33\x69\x40\x35\xa4\x05\x4d\xb8\x59\x10\xa3\x68\x72\x0f\x25\x8a\x14\x73\x9f\x1b\x90\xe4\xd4\x39\x76\xc5\xe0\xab\xbb\x0d\x9b\x99\x92\xe5\x74\x06\x9e\xb0\xd8\x2a\xc9\xa8\xf6\xab\x5f\xd9\xdf\x69\x3b\x9a\xa4\x0b\x41\x73\x9e\x84\xac\x81\x4a\xce\xb9\xe6\xd2\x59\x7b\xfd\xb8\x37\x21\x33\x1c\x5a\x90\x2f\x32\xca\x73\x72\xa2\x19\x23\x57\x1e\x25\xf0\x17\x57\xc6\x1e\x2d\x1b\xaa\xee\x1c\x20\x43\x4a\x73\xe1\x12\x22\x54\x04\x2e\x5c\x5e\x21\xc3\xb4\x33\x5f\xf9\xd1\xd3\xb0\x5d\xab\xe7\x24\x15\x5c\xdc\xfb\xd4\x9d\x4c\xa4\x32\xba\xb5\x3c\xbf\xb9\xd6\xb1\x36\x82\xb8\xe5\xf2\xde\xc1\x0f\x99\x14\xd3\x38\x8d\x40\x85\x99\x96\x94\x0a\x28\xef\x32\xe7\x69\x49\x33\x24\xa2\x6e\x32\x17\xb7\xd7\xd8\x9d\x4f\x67\x66\xf8\xc0\xc0\x1a\x83\xbc\xa6\x3a\x33\xfe\xa3\x7c\xc9\x5b\x87\x6b\x20\xba\xc6\x59\x13\xd0\xb2\x65\xa7\xf6\x40\x17\x90\xb6\xc6\xb9\x98\xd4\x2e\x4c\x7d\x62\x31\x1c\x62\x15\xc4\x61\x7a\xe7\xa1\x5c\x87\x15\x1b\xc0\x5c\x65\x41\x0c\x98\xba\x3c\x37\x0b\xf8\x28\x0f\x60\x78\xed\x2a\xb3\x51\xbb\x41\x56\xb8\xdb\xac\xcb\x3c\x82\x50\x36\xaf\x36\xf9\xce\x95\x4e\xec\x28\x1c\x1c\xfd\x10\x99\xcd\xa2\x8b\x0e\x7b\x6c\xa8\x48\x87\x34\xb3\x98\x73\xf3\xfd\x85\xf3\x70\xc6\x83\x50\xbb\xc8\xf7\x55\x90\xb8\x08\x69\xb3\xad\xcc\xb0\xf2\x08\x40\x1c\xfc\x98\xa5\x40\x34\xe2\x82\x91\x0f\x56\x43\x76\x9b\x77\xf3\xfd\xc5\x80\xf0\x11\x1b\xf9\xbf\x42\x53\x4f\xb5\x8c\x9c\xa2\x1b\x60\xf0\xf1\x04\xbc\x83\xa9\xc4\xc6\xa8\xb8\xef\x5f\xff\x60\x27\x69\x7f\xfd\xe3\xf0\x0f\x51\xb6\xd1\x3f\xfe\xd5\x12\x41\x65\x1b\xd4\xdf\xc6\xbe\x64\x21\xeb\xfe\x5f\x6f\x5c\x56\x6a\x97\xb3\xfa\xaf\xae\x18\x17\x13\xc6\xca\x8d\x37\x12\x6e\xe9\x79\x8a\xd8\x08\xdf\x56\xec\x6f\xde\xb0\x08\x60\x0a\x46\x9d\x84\x1a\x26\x80\x50\xfb\xa0\x0c\x21\x0d\x76\x77\x75\x67\xed\xfc\x4f\xc0\x24\x80\x41\x65\x03\x62\xa4\x84\xe3\x88\x47\xfe\x5c\x10\xe6\x6b\x75\xe2\x5a\x01\x1c\xd4\x39\xaa\x79\xde\x63\x87\xb5\x10\x0e\x21\xb8\x76\x1e\x30\xb7\x5f\x09\x69\x7e\x15\xb6\xbf\x51\x45\x9c\xce\x25\xf7\x09\xc8\xed\x49\x11\x58\xd1\x31\xa4\xc4\x1e\x2f\x48\xce\xb5\xa1\xf7\x6c\x44\x6e\x2d\x6f\x89\x6f\xc3\x10\x7a\x82\x40\x06\x4b\x96\x92\x52\x18\x9e\xc1\xaf\xd5\x38\x76\xca\x31\xcf\xb9\x9e\x10\x5d\x42\x79\xf3\x42\xb1\xa1\xe7\x62\xae\xd5\x12\x2d\xa8\xd6\x32\x08\x9b\x3d\xa3\xa8\x0b\x14\x29\x74\x05\x78\x50\xe1\xd0\x6b\xc9\x8f\xcb\xce\x53\x8a\xa4\xe2\x5c\x00\x4c\x3d\x22\x1f\x80\x59\x65\xfe\x4a\x18\xd5\x12\x67\xc0\x14\x2c\x61\x5a\x53\xb5\x18\x40\x62\x77\x1e\x92\x81\x3b\xd7\x1d\xe0\xa8\x39\x15\x98\x56\x5d\xb1\x44\x0a\x6d\x54\x99\x18\xac\xb3\x37\x56\xf2\x9e\x89\xe0\x2e\x68\x77\xb1\xee\xc0\x55\xf9\xcf\xc0\x7d\x97\x24\xc9\x8c\x8a\x69\x54\xa7\x26\xa7\x29\xc0\xfe\xdb\x20\xe5\xf8\xf5\x58\x08\xd0\x89\x15\x2c\xb8\x01\x50\x8c\x2d\x1f\x09\x66\xd8\xff\x11\x21\x1f\xcf\xa0\xb2\x93\xda\x25\xf1\x6c\x0b\xed\xea\x44\xbf\x48\x47\xa3\xde\x10\xd8\xf6\x81\x1d\xc0\x72\x66\x68\x4a\x0d\xdd\xc1\x09\xec\x7d\x55\x5c\xcf\xd7\xd7\xc7\x02\xa7\xe1\x62\xd2\xf1\x21\x2f\x6e\xc9\x82\xc7\xf1\x4f\x70\x12\x67\x1e\xf2\x10\x71\x6d\x2c\x4e\xb9\x8b\x02\xf4\xed\x02\x79\xc6\x57\x2f\xb3\xc3\xfb\xd1\x90\x5c\x54\xa5\x19\x2b\x72\xd2\xee\x1a\xaa\xa3\x05\xd6\x82\x7e\x07\x18\xdd\x55\x77\x65\x49\xdd\xbf\x6b\xa5\x08\x82\x5c\x82\x09\xc3\x15\x8b\xc3\xcd\x1c\xe8\x4a\x81\x48\xde\x00\x22\x40\x79\xca\x8c\xae\x3c\x54\x90\x0e\x5b\xe2\xe2\xf8\x9d\x53\x46\x81\x48\x3b\xc0\x3a\x7d\x6e\xb5\x2c\x84\x60\xd7\xd2\xd1\x59\x4b\xf9\x1f\x05\xae\xbb\x18\x9d\xb1\x9c\xc0\x7b\x99\x76\xb1\x53\x37\xb2\xf0\x57\x43\x54\xfe\x9b\xe8\x89\xab\x41\xa9\xc7\x06\x70\x5b\xa5\x6b\x41\x73\x48\xe4\x66\x74\xbe\xbb\x91\xaa\x92\x91\x86\x21\x95\x31\x7c\x6e\x08\x9f\x1b\xbe\x6e\x6f\xcc\xeb\xe2\x01\xe2\x9f\xd6\x9e\x20\xf5\x8f\x74\xb2\x9c\x5a\x92\x72\xdb\xd1\xdc\xd9\x88\x46\x0e\x23\x38\x9a\xef\x6e\x11\xc3\xcd\xad\x8b\x74\x60\xdc\x52\x8b\x37\xe4\x57\x35\x2e\xef\xa4\xa9\xa0\x29\xa1\xa7\xee\x89\x57\x9d\x46\x6e\x2b\x7c\xf0\x79\xbd\xf9\x69\x63\x30\x10\x2f\x56\x6b\x14\xde\x23\x38\x88\x7c\x56\x3c\x53\x60\x3c\xf3\xf1\x07\x16\xbd\x94\xcc\x32\xa6\x60\x09\x4e\x7b\x6a\xdc\xa2\x43\x2e\x53\xb4\xe9\x0e\x82\x8a\x1a\x64\x4c\xc1\x1e\x82\x30\x41\x35\xa6\x6e\xf1\x37\x5e\xcc\x15\xce\x5b\x3b\x5e\xf0\x5a\x3e\x17\x0b\x9c\xfa\x65\x04\x5a\x54\x3d\xc9\xd4\x7e\xc8\x4a\x9d\x82\x8e\x33\xbc\x3d\x0e\xcc\x16\xe6\x42\xb3\x07\xba\xd0\x80\xf7\x95\x34\x1f\xbe\xef\xb2\xaa\x55\x03\x7f\x64\x13\xec\xdd\xfa\x46\x6c\xa7\x3b\xb1\x5d\x6e\xc5\x20\x9c\x92\x8b\x36\x2e\x48\x55\x87\x8d\x85\x43\x9a\xcf\x2e\xd7\x68\xe0\xa7\x02\xd7\xe7\xdd\xee\x44\xea\x75\xca\x6f\xae\x61\x08\x2f\x93\x4f\xe1\x0f\xcf\x71\xc2\xa5\xc1\x98\x59\xac\xae\x02\xa5\x01\x43\xe2\xbe\x2b\x3c\x09\x2a\xd4\xfa\x16\xb2\xb1\x3a\x2b\x71\xa8\x34\xa6\x18\x78\x82\xc0\x17\x47\x50\x8e\x80\x8a\x85\xe3\xe4\x66\xc6\x55\x3a\x2c\xa8\x32\x0b\x54\x1f\x07\xb5\xaf\x05\xf7\xfa\x4e\x0b\xdf\xf1\x3a\xa7\x5d\xea\xe3\xb5\x10\x86\xc5\x7b\xf3\xb0\xb3\xce\xaf\x85\xeb\x53\xac\xa7\xbd\x03\xff\xca\xf5\xc4\xa9\x45\xbd\x46\xf8\x6c\xeb\x49\x63\xf2\xb1\x3f\xdf\xb0\x34\x48\xd7\xaf\x5e\x91\x0d\xc4\xa5\xab\x64\xec\x05\x1d\xb8\x3c\x28\x44\x76\xa4\x81\xd5\x43\x69\x55\x6b\x3c\x32\xec\x39\x49\xc1\xfb\xd0\xb8\x4a\x47\x62\xe1\x4c\x37\xf1\xb7\xe2\x01\xc2\x29\x21\x27\x42\x0a\x3c\x39\xd8\xf6\x14\x5d\x88\xd6\xd8\xa6\xa0\x89\x2b\x51\x57\xaf\x10\x1a\x9d\x54\xcf\x24\xb8\x48\xed\xd6\x01\xe5\x06\x1d\x49\x97\x49\xc2\x58\xd0\xaa\xe3\x12\x35\xd5\xc9\x76\x53\xf6\xa5\x2e\xb5\x84\x24\x2e\xda\xd0\x2c\xab\xb4\x59\x07\x2e\x09\x7c\xce\x5b\x00\x23\xf6\x57\x0b\xb4\x71\x8a\x3d\x14\x51\x47\xb7\x97\x52\x24\x78\x85\xcf\xcd\xc2\xcf\xe0\xb2\xc9\xea\x41\x8d\xd0\xa8\xe4\xf2\x09\xda\x9d\x22\x75\x20\x00\x13\x48\x93\x2b\xe1\x5e\xe7\x4c\x2e\x37\x83\xa5\x43\x63\x9a\xdc\x3f\x50\x95\x42\x29\xdf\x82\x1a\x8e\x69\xc1\x07\xb5\x61\x4f\xa2\x39\x40\x21\xfd\x18\x8b\x4e\x83\xd2\xa1\x59\x48\x41\x5d\x7d\x86\xd0\xd2\xc8\x9c\x1a\x9e\x80\x2a\xcb\x27\x91\x15\x31\x0f\x29\x0d\x1b\x65\x07\x81\xca\x86\x02\xf6\x77\x78\x1b\xa3\x18\x31\x0f\x92\xf0\xdc\x4a\x08\x14\x4a\x69\x4c\x42\xc4\x90\xb7\x77\x6e\x9a\xa9\x15\x83\x7e\x00\x23\x73\xd4\x0a\x95\x64\xab\x42\x69\x18\x3e\x58\x34\x83\x29\xcf\x85\xdc\x0c\x1a\x0c\xdc\xf5\xb1\x38\x6d\xe7\x1a\xa1\xea\xc0\x6e\xcf\x03\xb3\x72\x81\xde\x88\xb0\x7a\xb4\x6a\x46\x58\xd3\x56\x93\x94\xeb\x46\x61\xea\x93\x54\xc9\xa2\x70\x06\x92\xfc\xb4\x39\x23\xb8\x37\x50\x73\xa6\xa3\xda\xcb\x68\xaa\x9e\x32\x11\x8a\x87\xbb\x74\x16\x70\x72\x9b\x9f\xa8\x1d\x98\x11\x06\x84\x9e\x92\x4f\xae\xa8\x50\x40\xdc\xe0\x75\xd7\x4a\x70\x42\x6b\x8b\x93\x9d\x7a\x89\xa7\xed\xd3\x4b\x3c\xbd\xc4\xf3\xf3\x96\x78\x82\xbb\xd7\xae\xd2\x4e\xe5\xe3\xd8\x28\x48\xee\x9d\x01\xaa\x06\xeb\x8c\x18\xd7\x13\xf2\x91\x25\x72\xce\x14\x12\x39\x28\xfc\x69\x79\xf9\x5b\xca\x33\x4b\xe2\x3c\xa9\xab\xd4\x43\xc8\xa8\x5a\x37\xcd\x45\x1a\x79\x80\xa6\x43\xf3\xdc\x4d\xca\x45\xfa\xd9\xf6\xee\x92\xac\x50\x6c\xce\x65\xa9\xbd\xcb\x42\x69\xf0\x98\x69\xe3\xf8\xed\x8c\x4f\x43\x62\xee\x70\xd5\xa9\x58\x22\x55\x5a\x85\x94\x6b\x43\x4d\xa9\xeb\x71\x12\x09\x5a\xd3\x0e\x67\xa0\x09\x70\x7c\x64\xea\xbe\x1b\x25\x45\x8f\x8d\x3d\x4e\xc5\xf1\x3b\xf4\xf9\xa8\xea\x6e\x9b\xc8\x0d\xa5\x72\x81\xb1\x22\x54\x69\x58\x84\x56\x0e\x01\x3a\xc3\xba\x16\xf5\x7a\x86\x85\x5b\x86\x61\xd8\x61\xe5\x75\xd2\x22\xe3\x7a\xfc\xec\x04\x75\xb2\x47\x80\x67\xfc\xbc\x60\xc7\x93\xc6\x62\xbb\x7b\x5f\x92\x3d\x3d\x30\xc9\x3e\x5e\x98\xe4\x90\x9e\x98\x24\xf8\x73\xef\x73\x62\x3e\x7a\x4f\xf2\xc6\x99\x71\x84\x77\xd3\x99\xa9\x25\x14\x08\xe3\x70\xed\x2b\x40\xba\x6b\xcd\x70\x06\xc0\x24\x18\xfb\x03\xbb\xd3\x0a\xda\x1c\xde\x5d\xb2\xcf\x21\xeb\x6f\x24\xc7\x54\x45\xb5\x8d\x04\x0f\x84\xbc\xc0\x4c\x40\x70\xea\x86\xce\x25\xcb\x6b\x4b\xfd\x09\xee\x4f\x70\xdb\xfe\xcf\x79\x82\xd1\xe3\xb9\x8b\x43\x7e\xa3\x52\x10\x76\x77\x41\xb8\x74\xcc\x32\xf2\x63\xc9\xd4\x82\x58\x21\xa8\x72\xef\x81\xf4\xc6\x9a\xa7\xce\x41\xc6\x19\x55\xda\xcb\xec\x4f\xc8\xff\xc1\x64\x73\xf5\xd9\x4a\x80\x10\xc7\xb6\x07\x5d\x6b\x0e\x55\x0f\x55\x46\x68\x05\x08\xc6\x12\x1e\xde\x30\xd6\x64\x3e\x2b\xee\x9d\x7f\xb8\xdc\x4d\xd1\xe9\x76\xa9\x45\x76\xb9\xd8\x5a\x5a\xfc\xf9\x86\x05\x22\x20\xc2\x2f\xf5\x6a\x52\xc1\x14\x41\xee\xd9\x62\xe0\xee\xc1\x5d\xf6\x76\xdf\x18\xdd\x39\xea\x29\x45\xdb\xa6\xaa\x58\x05\xa0\x1d\x28\xe4\x6e\xd6\x03\x7c\xda\x27\xa1\xac\xf7\xf2\x40\xe8\x4a\x88\x77\x26\xe1\x9d\x92\x55\xc6\xcf\xba\xc4\x95\x88\x13\x90\x81\xcf\xfb\x35\x07\x34\x00\x5f\x6e\xa0\x16\x5d\x37\x91\xec\xae\x02\xe3\xe3\x01\xbb\xf7\x52\x03\x9a\xd6\x1c\x73\xef\xd9\xe2\x58\xbb\xa8\x41\x29\xf4\x8c\x17\x3e\x3f\x3c\x50\x02\x87\xb9\xe4\x7b\xf0\x0f\xf0\x43\xe0\x99\xbf\x16\x03\xf2\x41\x1a\xfb\xbf\x2b\x70\x15\x42\x4b\xa5\x64\xfa\x83\x34\xf0\xe6\xc9\x81\x85\xd3\xdd\x1b\x54\xce\x4c\xc9\xc1\xcc\x88\x2e\x6d\x10\x9f\xe1\x5d\x50\x00\x24\xee\xbe\x35\x80\x95\x6b\x72\x2d\x88\x54\x1e\x26\xc6\x27\x0f\xd6\x6e\x08\x6f\x5b\x8a\x2c\xc2\x2b\xc6\x70\xa0\x94\xaa\x06\xc9\x0d\xc3\x05\xe3\x32\xf7\xbf\x80\xed\x09\xac\xf1\xc1\x6f\x06\x52\xe0\x52\xc3\xa6\x3c\x21\x39\x53\x53\x88\x0f\x4d\x66\xbb\x6f\x50\x77\xba\x8d\xcf\x4e\xd4\x3b\xfe\x70\x67\xcc\x00\x56\xf7\x0e\x3c\x97\xf6\x65\x98\x38\x0a\xb2\x88\x9c\x16\x16\x29\xfe\x61\x39\x01\xec\xcb\xbf\x20\x65\xb5\x1e\x91\x73\x5f\xf0\x34\xfe\xcd\x59\x31\xe2\x61\xec\x08\x56\xa6\xff\xb1\xe4\x73\x9a\x31\xf4\xe7\xa3\x22\xa4\xf1\x94\x93\x25\x36\x3d\x70\x79\xab\x2d\x95\x0a\x37\x43\x47\xf7\x6c\x71\x34\x58\x42\xa4\xa3\x6b\x71\x54\x05\x69\xd7\x50\x27\x30\x34\xb8\x34\x38\x82\xdf\x8e\x0e\xcd\xd9\x9f\x49\xb4\xdf\x01\x4b\x9c\x41\xe8\x22\xa3\x5a\x77\x8b\x6f\x6d\x84\x16\x35\xc6\x59\x95\x80\xf1\x36\x6a\x53\x05\x17\x39\xef\xcd\x83\xdb\xb3\xc0\xcb\xbf\xbb\xa7\x51\x27\xe8\xcd\x5d\xf5\x94\xf6\x89\x1b\x56\x26\x14\x83\xb4\x05\x3e\x86\xa3\x16\x17\x57\x5d\xc6\xae\x81\xd7\xf7\x60\x57\x94\x93\xb8\xc8\x33\xd7\xa0\x06\x73\x1f\xd5\x21\xa4\x21\x5c\x24\x59\xe9\x4c\x8a\xd0\x15\x94\xe8\xae\xa2\xfe\x0e\xc0\xd9\x03\xa9\xaa\x01\x3c\x36\xf9\x6b\xdf\x25\x07\xde\xe6\x0d\x1d\xdc\x89\x86\x1b\x2f\x84\xd5\xa1\xd7\x3a\xd9\xe2\x2e\x59\x4f\xc6\x99\xd4\x65\x8f\xb7\x7c\xac\x18\xb9\x98\x51\x21\x58\x16\x45\xbb\x3a\x63\x47\x28\x67\x05\x02\x89\x2b\x62\x75\x5c\xaf\x62\xe5\xe9\x9b\x08\xb1\xd5\x07\xaf\x1d\xfc\x53\x2a\x2a\x75\xb0\x3a\xe5\x2e\x55\xe3\x4c\x3e\x90\x54\x92\x07\xa8\x5b\x30\xb7\x4c\x0b\x2e\x65\xb5\x67\x77\xd1\x4c\xc1\x45\x22\x91\x79\xa1\x64\xce\xb5\x77\x8e\x77\xdb\x78\xd0\xd0\xd0\xac\x6c\x91\x03\xa8\xbe\x07\x59\x29\xea\x29\xe1\xdf\x5e\x10\x43\xd5\x94\x19\x3b\x1a\x11\x65\x3e\x66\xad\xe3\x57\x1f\x23\x07\xd9\x97\x54\x42\xf4\xb0\x45\xb0\x70\x1b\x7e\xf8\xe1\x43\xe7\xd2\xbb\x55\xcf\x75\x7b\xfb\x20\x55\x96\x3e\xf0\x14\x59\xb4\x26\x27\xb6\xf1\xe9\xcb\xaf\x94\xfb\xf0\xc0\xd3\xce\xe0\x80\x4e\x75\x30\x78\x3f\x28\x0b\x06\x02\x70\x70\x15\x9e\x38\xa4\xd1\x86\x1e\xa7\xe4\x8a\x63\x74\x11\xf4\x87\x44\x35\xf9\x98\x8b\x2a\xc2\xac\x02\xb3\x25\xc6\xf6\xbc\x78\xd5\x44\x33\x83\x71\x21\x10\x5a\x21\xcd\x8c\x68\x9e\x97\x99\xa1\x82\xc9\x52\x67\x8b\xd6\xa8\xf2\x3c\xa0\x9e\x64\xec\x33\x62\x76\x17\x26\x17\x3a\xd5\x99\x1d\xb8\xae\x54\x61\x94\x4b\xdc\xae\x72\xae\x4a\xcf\x02\xe7\x0b\xe1\x46\xec\x33\x4b\x9c\x57\x70\x91\x95\x53\xbe\x25\xfc\xe1\x67\x96\xd5\xbc\x4a\x20\x5d\x6a\x56\x45\xea\xb7\xad\xeb\xf2\x44\x49\xc8\x9f\x97\xc3\xdf\xad\x4e\x40\x9e\xb2\x82\x89\x14\x52\xa2\xbd\xad\x30\x17\x27\x7f\x50\xc8\xb9\xf4\x62\x5d\xa9\x96\xcf\x4a\x56\xa3\xe0\x91\x0b\xd7\x4c\x66\xa9\x26\xec\xb3\x51\xd4\x12\xa6\xdc\x92\xa0\xd0\x67\x42\xa8\x68\x4f\x64\x5e\x46\x8a\x60\x72\x70\x6e\xff\xb8\xf5\x32\x5f\x62\xc9\xcb\x6a\xed\x7a\x63\xc1\xea\xfd\x52\xd7\x23\x21\x76\x67\x45\xd7\x3d\x84\x57\xa4\x98\x77\x5f\xa9\x7b\x26\xee\x97\x6a\x5e\xaf\x48\xaa\xdd\x98\x55\x5f\xa6\xf3\x8b\xc8\x3b\x3f\x81\xc0\xe0\x2e\x49\x98\x5c\x8f\x86\x46\xed\x5e\x36\x0b\x42\x6f\xd0\xa0\x1d\xde\x46\x7c\x00\x32\x9e\xba\x81\x5c\x58\x13\xd1\x16\x96\x95\xeb\x5c\x29\xc4\x36\x2a\xf6\x18\x59\xc4\xa9\xa1\x9a\x99\x76\xd6\x94\xba\xe8\x50\xf5\xb4\x07\x30\xc6\x2f\xf7\x13\x66\xb1\x07\x87\x74\x1f\x2c\x4b\x86\x7f\x74\x52\x86\xa8\xb5\xb4\xf2\x85\x87\x8f\x4f\xd2\xc4\xc2\x2d\x32\x8e\x91\xda\x5d\x49\xa8\x69\x5d\x72\xa7\x15\x5f\x70\x33\xf8\xf4\xa9\x73\x2d\xd7\xa8\xa7\x97\x43\xe0\xdf\x75\x20\x38\x5c\x80\x44\x3e\xfc\xc7\x32\x56\x07\x20\xb9\x45\x58\xb6\x6b\x7f\xa8\xb5\x4d\x13\x56\x19\xaf\x2e\xb9\xbe\xef\x92\x8c\x6c\xa9\x73\xfd\x48\x7c\x73\x71\x45\xdc\xdb\x56\xf6\xa5\x2e\x06\xa6\x7d\x33\x63\x4d\x13\x56\x19\x6d\x53\xae\xef\x9f\xbc\xac\x7a\x91\x7e\xd8\xe6\x01\xfe\x74\xf6\xaf\xa6\xd4\xeb\x53\xb4\x44\xb9\x83\x16\xb2\x24\x0f\x2e\xf5\x81\x93\x9a\xef\x78\xf1\x86\x5c\x09\x5d\x2a\x56\xdd\xdc\x36\x87\xb2\x5c\xf7\x25\x95\x5e\xdf\x0b\x4b\x5e\xb2\xf1\xad\xa0\xca\x80\x78\xdc\x15\x0d\x42\x47\x4f\x9f\xa2\x17\xa2\x0d\x1e\x5c\x4f\xbc\x63\xdd\xc0\xc5\x78\x87\xc4\x65\xbe\x91\xdd\xf9\x28\xad\x49\xbc\xd7\x6f\x43\xca\x1f\x72\x96\xb2\xf9\x99\x4e\xe9\xeb\x01\x7c\xc6\x3b\x3c\xd7\xe7\x44\x35\x39\x7a\x7d\x34\x22\xb7\x3c\xe7\x19\x55\xd9\xa2\x96\x8a\xb9\x6a\x67\x99\x85\x1f\x10\x6e\xe5\x5e\x1d\x91\x13\xa9\x60\xe4\x84\x0a\x92\x31\x1f\xd1\xe4\xce\xd9\x02\x65\xc7\xd3\xa7\x26\x2e\xe4\x51\xed\x97\x48\x67\x3a\xe3\x44\xea\x39\xb6\xe3\x47\xb5\x74\x36\x97\x15\x49\xe7\xc2\xd2\xf9\x11\xf9\xb4\xaa\x50\x39\x1c\x19\xdf\xe2\xb9\x80\xfa\x34\x7a\xdf\x4e\x1a\xdc\xb2\x39\xf8\xf9\xc0\xb4\x5d\x4b\x9c\x72\xf3\x91\x15\xb2\x93\x84\x80\x5d\x1a\xf6\x38\x6e\xec\x0b\xa9\x39\x24\x2a\xa5\x06\xca\x02\x2b\xc3\x93\x32\xa3\x56\xac\x46\x6b\xdc\x88\x5c\x5e\xdd\x7c\xbc\xba\x38\xbf\xbb\xba\x7c\x43\xbe\x71\x23\xf1\x58\xc2\x1b\x91\xbb\x38\x1b\x54\xe4\xd1\xeb\x52\xee\x84\x6f\x0d\x1c\x19\xa2\xa2\x4a\xee\x08\x39\x3e\xa8\x20\xd7\x82\x9b\x2a\x3d\x32\xfa\x9d\x65\x52\x30\x5f\x3d\xb4\x90\xce\x1a\x38\xe5\xe8\x0d\x22\xdc\x60\xf6\xe7\xfa\x68\x70\x3a\x30\xd5\x6a\x98\xca\x16\x45\xf0\x11\x44\x8b\x0a\xb8\x87\x12\xff\x7d\xfe\xd3\xae\xb2\x6f\xc8\x46\xeb\x03\x9c\xd0\xfa\x5f\xbd\x47\x66\x10\x12\xb3\xfb\x74\x37\x2b\x4a\x5a\x13\xcb\x66\x8e\x47\xc7\x5e\xa0\xc8\x96\x92\xf0\x87\x41\xe3\x8c\x5e\x75\x64\x1b\x11\xf2\x9d\x77\xd9\x86\xd0\xe3\xd5\xf9\xfc\x31\x3b\x44\x94\x15\xbe\x81\xb2\x3e\x30\xa6\x1c\xc7\x1f\x75\x29\xc0\xa6\x7c\xce\x04\x2e\xec\xb0\x14\xca\x7f\xbe\x73\x75\xb4\x6a\xde\x4e\xff\xf8\xf8\xee\xb0\x33\xc3\xf3\xd7\x79\x5e\xee\xd8\xba\x59\x25\x32\xcf\x31\x5f\xd4\x2c\x04\x18\x56\x31\x82\x81\x2a\x1c\x4c\xf3\xc1\xcc\x57\x93\x2d\xc8\xdf\xa0\x67\xbe\x53\x43\xd3\x09\xaf\x5d\x50\x82\xa8\xc4\xdc\xee\x79\x98\x5d\x92\x35\xed\x93\xa7\x38\xd2\x7e\x16\x3e\x7e\xf6\xf1\xea\xfc\xf2\xfd\xd5\x28\x4f\x9f\x9c\xb4\x30\x91\x16\x92\x0b\xa3\xb7\xeb\x37\xdb\xaa\xce\xb4\x27\x3f\xe1\xa3\x5d\xb9\x73\xe8\xe8\x71\xcc\xbf\x88\xf2\xd2\xa5\xcc\x50\x9e\xe9\x68\x0f\x8d\x2c\x64\x26\xa7\xab\xd3\x2f\x77\xd8\x9c\x5f\x60\x7e\x99\x21\x1d\xda\x5d\x3f\xac\xa8\xdf\xa6\x8e\x46\x53\xca\xaf\x2a\x62\x57\x6b\x0d\x52\x33\x94\xbb\x78\xa1\xcb\x7d\x14\xe1\x6c\x09\x06\xa8\x48\xc2\x01\xf6\x29\xfb\xaa\x1c\x78\x51\x0d\x9b\xb6\x52\xdb\x63\x83\x6e\xbb\xc0\x66\xe9\xcf\xf6\x42\x45\x75\x98\xf9\x3e\x75\x02\x57\x28\x36\x0c\xe9\x9a\xa0\xb4\x8a\x54\x11\xc3\x8d\xe9\x9d\xb7\xde\x78\x5b\x0f\xb6\xca\x16\x4d\x2b\x4e\x25\x1f\x05\xd3\x17\xe6\x18\xc8\xb2\x45\x95\x06\xd2\x69\xd1\x74\x8a\x69\x98\x94\x33\x13\x17\x8a\xcf\x79\xc6\xa6\x90\x8a\x95\x8b\x69\x14\xfe\x1a\x07\xcc\xba\xd4\xac\x75\xa3\xeb\x7b\xfb\x57\x94\x74\x1b\xf0\xe2\xc3\x77\x77\x90\xd5\x17\x2e\xb8\xf6\x16\xc2\xed\x07\xe1\xbc\x0d\x87\x43\x30\x19\x9c\xfc\xcd\xca\x93\x69\x76\x4a\x7e\x60\xee\x3b\x12\xd2\x0e\x2b\x28\x05\x34\x93\x21\x07\x2c\xcc\xb5\x82\x2c\xa0\x23\x5e\xef\xbb\x56\x67\xb6\xa5\x95\x95\x90\xd5\xd4\xda\x43\xe5\x53\x4c\xdd\x88\x77\x4c\x4f\x2f\x7b\x1e\x90\xec\xef\x4c\xe5\xbc\x69\x75\x15\x7e\x86\x8b\x1f\x4f\x0f\x29\xd1\x8b\x3c\xe3\xe2\xbe\xca\x0b\x36\x91\x16\x87\x30\x34\x81\x8b\x7b\x8f\xb1\x8a\xd1\x6c\x3d\xa5\xdc\x05\x3f\x0e\x4a\x25\xcd\x0e\x16\x40\xb0\xd0\xd9\x73\xf6\x27\x7f\xec\xdd\x35\x74\x4c\xe2\x8e\x8e\x5e\xdc\x7a\xb9\xee\x56\x06\xff\x18\x3a\xd4\x68\x9a\x20\xd7\xb7\x17\xb7\xd7\x4f\x6a\xa1\x5e\xc7\x12\x60\x76\xcf\x28\xd5\xf1\x1f\xb7\xdd\x0e\x0f\x49\x56\x6e\x6f\x83\xea\xdd\x8d\x54\x86\x66\x07\x22\x02\xc9\x8c\x16\xe7\xa5\x99\x5d\x72\x0d\x39\x14\xba\x0a\x01\x4b\xfd\x23\x4f\x67\xcc\xdd\xec\x13\x06\x72\x8f\x0e\xae\xdd\xc5\x9f\xce\x6f\x08\x2d\xed\xfe\x1a\x97\x5c\xf4\xa0\x17\xee\x7e\x66\xb7\x18\x61\xb0\xe3\xba\x5c\xef\x2d\xab\xf2\xad\x1e\x7b\x4d\x8f\xe1\x87\xdb\xdf\x45\x00\x0d\x45\x0a\xf6\x82\xef\x1f\xb8\xe0\x86\x53\x23\x5b\x16\x2a\xab\xa1\x40\xad\x6f\x30\x08\x94\xda\xc8\xdc\x61\xf0\xb5\x6f\x01\x57\xc8\xc0\xc5\x97\x3a\x55\xd6\x02\x90\xde\x01\x62\xd7\xc2\xca\xda\x34\x61\x0d\x07\xc8\x01\x24\xfd\xc4\xb1\x79\x68\xf3\x07\x67\xa0\x82\xfc\x60\xd9\x1f\xdf\xd4\x52\xb1\x2f\xd5\xb5\xf0\x56\x8a\xaa\x68\xc2\x41\x2d\x3e\xfc\xc7\xae\x44\x81\xff\x28\x1a\x96\x36\x5c\xe0\x7f\x95\x34\x43\xc0\x7c\x38\xb4\x59\xaa\x0e\xe4\xae\xf3\xad\xef\x90\x9b\x7a\xb5\x1d\x1f\x82\x96\x5e\x6a\xcc\x3c\x86\xeb\x31\x8a\x0a\x6d\xf7\xa8\xae\x8b\x1d\xbb\x8b\xa7\x63\x72\x62\x92\xa2\x75\xed\xfe\x47\x72\x6d\xcf\x4a\x51\x2b\xe4\x0c\x33\xbf\xc3\x6d\x79\x17\x5c\xdb\xdb\x4e\xf2\x51\xae\x86\x00\xcb\xbb\x5a\x55\x5c\xaf\xb0\x5b\xf1\xba\x90\xf5\x93\x77\x5c\x1b\x5f\x90\x01\x5e\x70\xed\xf2\x08\x83\xdc\x75\x63\x15\x39\x5e\xfc\x2f\x4d\x53\xf5\x06\xb9\x94\xaf\xbe\xac\x40\xfa\xf2\x49\xbe\xa8\x08\x77\x89\x27\x66\x51\xb8\x04\x80\x77\x17\x37\x04\x0b\xa4\xfc\xfe\xb7\x58\xf9\xf5\xdf\x7f\xfd\xdb\x57\xad\xb7\xfb\xf9\x9c\xc7\x77\xb4\x63\x1c\xfc\x8e\xe9\x45\xf8\x0d\xd6\xfc\x03\xed\x4a\x40\x36\xb9\x45\x77\x3c\x4b\x59\xdd\x51\x47\xc4\xb2\xbb\x1c\xe8\xfd\x6e\x12\x4c\xef\x67\xf7\xac\x7e\x76\x24\x44\x94\x20\x91\xe8\x88\x2e\x71\x57\x08\x31\x5c\x26\x3b\x48\x71\x6e\x5e\x1e\xc5\xd9\x0a\x9b\xed\x58\x54\xc7\x9e\xf8\x32\xde\x97\xbf\xa9\x5c\xd8\x2f\x3f\xdc\xfe\xef\xbb\xf3\xaf\xaf\xde\xc1\x4c\xdd\xfd\xbd\x45\x0d\x2e\x76\xf6\x9f\x6a\x8f\x6a\x6d\x94\xd7\xed\x00\xe9\x76\x2d\x23\x1a\x17\x32\x82\x7c\x78\x7b\xdb\xf5\x2e\x66\x5f\x01\x5d\x4c\x5a\xad\xfd\x69\xad\x6d\x50\xd5\x84\xa9\xc3\xc5\x8f\xec\x6c\x94\x8b\x12\x69\xd5\xf4\x2f\xbb\x53\x38\xc3\xbd\x55\xa4\xad\x3b\x40\x5e\xc0\xbd\x83\x5d\x2f\xc2\xe0\xe0\x37\x0e\x8f\x04\xab\xb6\x72\x80\xea\x1e\x58\x74\x8c\xbd\xbc\x08\x60\x0f\x29\xd2\x36\x65\x69\xb6\xa5\xd6\x4c\x87\xea\x0b\x2f\x14\x53\x8a\x55\xe9\x99\xbb\x50\xaf\x95\x03\xd4\xca\x95\xd5\xee\x62\x6a\xb1\x14\xeb\xd2\x99\x7b\x0f\x05\xea\x94\x57\x5d\xd0\xe4\xa0\x05\x55\xaa\x57\xf8\x06\x82\xdc\x9f\x9e\x00\xc2\x67\x0f\xe8\x48\x1b\xc6\xeb\x8a\xc8\xa1\x63\x33\x4a\xae\xd3\x0e\xf9\x42\x1f\x85\xf4\x11\x88\x71\x38\xdd\x33\x6f\x1f\x79\x5a\x6d\xe7\x87\x1d\x15\x9d\x43\x2b\x39\xc5\x4c\x1a\x29\x76\xf6\x92\x5f\xd5\xbd\x7e\xa0\x6f\xa0\xc5\x45\x55\xc6\x26\xaa\xf1\x08\x1e\x94\xe1\x32\xc2\xca\x73\x9e\x5d\x48\xe1\xaf\x25\xea\x97\x12\x4f\x2e\x82\xa4\xd7\x97\x07\x3a\x7c\x5f\x6e\x88\x67\x57\x63\xf0\x41\x9d\x41\xd2\xce\x31\x29\xb6\x8b\x87\xd8\xf5\xa5\x13\xcd\x7c\xc0\x89\x76\x08\x49\xd6\x63\xe4\xc1\x58\xa7\x54\xe6\x41\xaa\xee\xa1\xde\xf5\x8e\x0d\x5f\x05\xf7\xdb\x52\x28\xd6\x4b\x3c\x3d\x38\xc7\x67\x3e\x41\xb7\x70\x82\x1a\x09\xce\xd7\x9d\xa4\xc7\x38\x48\xcf\x7b\x80\xf6\x65\x54\x8f\x1b\xe5\x7b\x50\x21\xdd\xa3\x5b\xc7\xa5\xfa\x6e\xce\x98\x60\x37\xa9\xa2\x16\x14\x4c\x2e\xd1\x89\x3b\x18\x75\x50\x12\x4b\x50\x76\x21\x0c\xbe\x0f\x1a\x70\x31\xd1\x73\x96\x59\xa8\x4a\x11\xa7\x88\x76\x61\xbc\x03\x82\x59\x96\x73\x5a\xf8\x9a\xdc\xf2\x41\x3c\x50\x95\x92\xf3\x9b\xeb\xc3\x50\x83\x0e\x7e\xd6\x88\x49\xed\x32\x7a\xd5\x3d\xad\xab\x9e\x58\xe6\x66\xc6\xa0\xb6\x22\x19\x73\xa3\xab\x9a\x7e\xcc\xc4\x7a\xa5\xa5\x82\xe1\x2e\xcb\x9e\x65\x7b\x6e\xdd\x48\x11\xc3\x14\x44\x26\x86\x66\xbe\x88\x80\x2b\x93\xf3\xea\xd5\x2b\x34\x85\xbd\xfa\xdd\xef\x7e\x87\x95\x95\x52\x96\xf0\x7c\xb9\x21\xb4\xfa\x3f\xaf\x5f\x8f\xc8\x7f\x9f\xbf\x7f\x07\x95\x1f\x0b\xa3\x31\x2b\x09\x8e\x8c\x95\xe0\xa3\xce\x7a\x40\xfe\xef\xed\x77\x1f\xaa\x32\x31\xf5\x5f\x5d\x41\x6d\xb7\xbc\x11\xb9\x8c\xfc\x9f\x62\x43\x17\x35\x33\x57\xd0\xc8\x10\x3a\x99\x20\x62\x8c\x7d\x39\x5d\x3c\x70\x3e\x7a\x1c\xaa\x82\x63\xfd\x11\x8b\x12\x19\x38\x66\x59\x95\x1c\x4d\x83\x3e\xb3\x01\xfa\x99\xc1\x58\x81\x4c\xc2\x54\x06\x58\x4b\x7e\xa2\xa1\x0a\x49\x95\xfe\x4f\x31\x6d\x85\x52\x57\x5d\x11\x07\xab\x76\x46\xb3\xd6\xb9\x1e\x1e\xe3\x06\xa8\x75\x75\x8c\xba\xe9\xde\x9d\x21\x9f\xbe\xd5\xe5\x2e\xae\xca\xd4\xff\x0d\x6f\x43\xb7\x39\x09\x3f\xd2\x8d\x4c\x6d\xae\x37\x61\x36\xb8\x75\x2e\x4b\x40\x45\x27\x68\x26\xa1\x92\x57\xd8\xe9\x8a\x8b\x45\x45\xef\xb7\x2f\xa5\x73\xf2\xc5\xae\x09\x78\x91\x50\xbd\xa7\xad\xcb\xf9\xd4\xfd\x45\x7c\xef\x5a\x5e\x05\x3a\x96\xa5\xf1\x77\xd8\xee\x77\x08\xc0\xc6\x2a\xeb\x1d\xd2\x48\xee\x90\x79\x72\x97\x0c\xc4\x9d\x93\x98\xd6\xef\x9b\x81\x27\xd4\x45\x89\x01\x61\x34\x99\x91\x7b\xb6\x18\x22\xdd\x2a\x28\x44\xf3\x00\x54\x2e\x2d\x2c\x6a\x85\x4f\xaa\xda\x35\x56\x3e\x76\x20\xf3\x8e\x01\x11\xf7\xf1\xd1\x40\x5e\x08\xd5\x4e\x5e\x72\x69\x44\x45\x64\x29\xf0\xb9\xaa\xa3\x7a\xc4\x21\x6f\x28\x16\x23\xaf\x07\xa9\xd8\xf3\xc6\x52\xdb\x4d\x6f\xfa\x72\xe5\x0d\x61\xe9\xa0\xe3\x6e\xa5\x58\xea\xed\x8a\x6f\x3b\xe1\x0f\x3e\x48\x7d\x76\xe6\xc8\xa3\x02\xca\xf9\xb9\x4a\x4e\xae\xad\x87\x52\x00\x44\x2d\x88\x46\x33\x53\x3a\xd0\x60\xbd\xb0\x52\x64\x4c\x6b\xc2\x61\x85\x39\x55\xf7\xcc\x27\x8c\xa1\xd9\x88\xdc\xd8\x49\x86\xfc\x55\x98\x16\x79\x8e\x2e\x76\xf6\xcc\xc6\xd1\x41\xf6\x23\xc7\xa3\xd1\x31\x12\xf8\x15\xb1\x42\x1d\xf0\x63\xb7\x9c\xba\x3b\xe4\xd2\x6d\x94\xf6\x2e\x34\x66\x06\xb6\x22\x1f\x64\xbe\x96\x10\x05\x67\x66\x9e\x81\xd1\xd6\x49\x94\x96\x97\xb3\x43\x02\xd8\x5d\xf3\x96\xef\x92\xb5\xbc\xd5\xbd\x45\xfd\xd9\x3d\x5b\xf9\x4e\xb9\xca\xd7\x65\x2a\x77\x3b\xe5\x4e\x5b\xf7\x1c\xce\x7b\xa4\xd8\xce\x3b\xa5\x79\xf5\x4f\xdd\x48\x09\x72\x47\x2d\x4b\x4f\x2b\x19\xd1\x25\x7d\xca\xd8\x17\x25\x14\x5e\x4f\x56\x55\x9d\xf3\xc1\x82\x91\xbc\xec\x69\xa8\x85\xc0\xf3\x4b\x83\xdd\x6a\xb9\x90\xce\xe2\x61\xf3\xe9\x22\x2e\x36\x9f\x76\x97\x81\xcd\xa7\xae\xb0\x45\x61\x49\x81\xe8\xc7\x5e\xfc\x00\x52\x23\x21\x67\x77\x75\x04\x47\xe4\xbd\x63\x0a\x88\x8c\x74\xac\x65\x56\x9a\x10\xc9\xb4\x82\x63\xc0\xa0\x3e\xc3\x37\x86\x94\xfa\x66\x11\xff\x00\xce\x89\x64\xb9\x2b\x2b\xc1\x67\xa7\x23\xde\xb5\xe6\xde\x4f\xd6\x99\x64\x0f\x18\x7a\x51\x62\x67\x38\xfa\x01\x42\xde\x09\xef\x4b\x5d\x93\x71\xc0\x93\xc4\x68\x14\xa0\xbc\xb8\xe2\x0a\x3d\x75\x5e\x62\x3b\xab\x8d\x9b\xab\x33\x4c\x9c\xdf\x5c\xef\xa4\x01\x44\xfd\xd7\xe8\x00\x71\x8b\x9f\xb0\x16\x70\x8d\x5a\x40\x5c\x76\xe7\xb2\x5a\xb9\x33\x29\x5b\xb2\xf3\xe2\xc5\xc8\xa5\x69\xbf\xb5\xc4\x32\x76\x3a\xad\xe7\xd0\x43\x63\x4f\x45\x56\xa3\xbc\x7b\xfe\xd6\x11\x0e\xf1\x4b\x17\x39\x9f\x50\x7c\x04\x78\x74\x2a\x97\xee\x9f\xe5\x6a\x76\xb0\x58\x72\x0b\xa5\x6d\x50\x1f\x8c\x14\xcb\x42\xa6\x6f\x5c\x29\x69\x21\x24\x16\x90\xd3\x03\xac\x8d\xa3\x07\xa8\x30\x5a\x29\x22\xba\x2b\x56\x91\xc9\x7d\x67\xb9\x61\xa7\x2a\x47\xfb\xd4\x39\xb2\x1b\x08\x2b\xbf\xe9\xba\x8b\x64\xcf\xb2\x45\x24\x62\x4d\xbb\x15\x42\xa9\xed\xa9\x1b\x29\xd4\x79\x4f\x66\x2c\xa7\x98\xc3\xcf\x2f\xcf\x52\x99\x07\xc5\x8d\x61\x98\x4b\x89\xa9\x5c\x13\x39\x19\xd4\xee\x0c\x8e\xe6\xaf\x8f\x76\x29\x07\xb3\x67\xc5\x1e\x52\xed\xc2\x01\x80\x71\x53\x13\xd9\x2c\x5e\x83\x2e\x91\x41\xe2\x4d\xd1\x30\x48\x58\x06\x33\x47\xe8\x3d\xf9\xc2\x0f\xa1\x47\xed\xaa\x3f\x0d\x82\xc0\xd0\xeb\x4f\xbd\xfe\x74\x10\xfd\x29\x62\x2c\x9e\xe0\xac\xd0\xa5\x62\x87\x61\xaf\x50\x55\x81\x4c\x51\x02\x1e\x8b\x9a\x5e\x95\x92\xaa\x6e\x71\xb3\xfa\xd0\xb1\x57\xb0\x1c\x1e\x97\x66\x32\xfc\x3d\x61\x22\x91\x29\x6e\xbe\x1d\x5f\x69\x03\xa2\x4d\xa5\x93\xc4\x73\xc9\xfd\xb7\x62\xab\x1d\x8c\xbd\xeb\xd6\xed\x44\x07\xfc\x55\xe0\xdb\x03\x31\xf8\x8a\xad\x87\x60\x62\x5f\x2b\xdb\xe7\x1a\x70\xfc\xbd\xba\x84\xc4\xb2\xd2\x80\xdc\xbe\x62\x2e\x39\xc1\x97\xa3\xa4\x28\x07\xae\xc1\x28\x67\xb9\x54\x8b\x41\x68\x64\x7f\xac\xf5\x72\x2d\x4e\x41\x26\x48\x4a\x65\x35\xc0\x6c\xf1\xa5\x4a\x07\x1e\x40\x4f\x2c\x1c\x84\x7d\xea\x56\x34\x28\x7e\xea\x28\x51\x25\x15\x03\xfd\xbe\x2a\xa2\x34\x09\x29\x0f\xf5\xa0\x52\x3b\xed\x5b\x26\xe6\x64\x4e\x55\x87\x2a\xe8\xf1\xb3\xa7\x3c\x90\xf2\x39\xd7\xbb\xd5\x3b\x6c\x2c\xfd\xd6\x31\x0d\xb4\xeb\xc8\xd2\x14\xa5\x71\x94\xd2\x9f\x0a\x1f\x32\x1f\x4e\x43\x43\x28\x7a\x7d\xb4\xd3\x34\xbe\x98\xfa\xc2\xf8\xec\x58\x65\x18\x9f\x7d\x6b\x0d\xd7\x47\xd9\x19\x6d\x0e\x5a\x39\xdc\x3f\x1e\x2d\x0e\x71\x0e\x2b\x16\x59\xe5\x79\xf0\xc2\xe9\x13\x1d\x34\x74\x37\xd9\xc9\x6e\xe3\x32\xd4\xaf\x36\xd9\xb8\x1f\x7f\xc2\xd6\x9a\xc3\xde\xd9\xba\xf8\xc2\x9f\xf9\x85\xed\xad\xab\x67\xd0\xdf\xd6\xb6\x42\xc1\xfe\xb6\xb6\xbf\xad\xed\x6f\x6b\x7b\x6b\x43\x6f\x6d\xe8\x6f\x6b\x49\x7f\x5b\x7b\x10\x18\x1e\xee\xb6\x16\x45\xbd\x55\x77\xb6\x4e\xd8\xab\x2e\x6c\x9f\xf4\xbe\xd6\x15\xee\x39\x4f\x12\x59\x0a\x73\x27\xef\x59\xeb\x4b\x87\x86\xfc\xbf\x34\x0e\x24\x40\x58\xa3\x0f\x2c\x37\x7e\x32\xe5\xa0\xbb\x54\xd2\x49\xb6\xd8\x45\xaa\xa0\x65\xca\xad\xe4\xbf\x33\x9a\xf9\x01\xe2\xe4\x44\x22\x65\x69\xf5\x83\x3b\xca\xc6\xc2\x7a\x44\xce\x89\x62\x09\x2f\xb8\x2b\x23\x4f\xf1\x3d\x22\x5e\xa8\x8d\xc0\x8d\x66\xd9\xc4\xe5\xa8\x17\x71\xad\x9f\x4a\x7e\x77\x74\x70\xe5\x67\x90\x43\x49\x9f\xc9\xdc\xd7\x42\x52\xec\x6f\x9e\xb5\xb9\xd9\xdc\xc5\x23\xc4\xe6\x15\x58\x4a\xad\xc4\x10\x7c\xac\xe0\x2e\xc0\xfa\xb1\x8f\x3f\xfb\x5c\x70\x05\xc8\x7b\xcb\x12\x29\xda\xd4\x54\x5d\xb3\x41\x4b\x23\x55\xfc\x09\x6c\xa3\x2c\x25\x69\xa9\x42\xcd\xd4\x39\xcd\x78\xca\xcd\x22\xdc\xda\xb9\xf2\x5a\x14\x4f\x4c\xd8\x46\x5d\x81\x91\xd0\xa2\x50\x92\x26\x33\xa6\xa3\xaf\xa1\x80\xe2\x82\xc8\x82\xef\x3b\x96\x80\x03\x19\x05\xfa\x58\x06\x99\x2d\x88\x92\xc6\x5f\xbc\xaf\xf9\xe0\x5d\x34\x18\x74\x47\x2e\x67\xd4\x02\x6e\xe7\x65\x3c\x04\xce\x8a\x4f\xe2\x3f\x34\x91\x59\xea\x53\x98\xfc\xfe\x95\x15\x0a\x13\x87\x83\x96\xf8\x41\x82\x0b\x23\x49\x66\x19\xb6\x25\x88\xeb\x3b\xff\xfa\x37\x64\x26\x4b\xa5\x47\x71\xd2\x81\xd7\xf0\x0e\xf5\x3b\x2f\x54\x1a\x92\x31\xaa\x0d\x79\xfd\x8a\xe4\x5c\x94\x96\x4f\x75\x46\x9b\xee\x72\x50\x24\x01\xfd\xf6\x37\xad\xfb\x75\x95\x7d\xd6\x4a\x3d\x05\xe6\x46\x76\xa2\x8f\x3b\x49\x18\x18\x87\x99\xc5\x1b\x82\x90\x23\xba\x31\xb4\x85\x91\x8f\x70\xbe\x7e\x2c\xe5\x78\x61\xba\x04\x51\xba\x1e\xf5\xe8\xc9\xff\x72\x2f\xdb\x24\x4f\xa9\x72\xa7\x6c\xfc\xe8\xa3\x54\xb8\x98\x72\x6d\xb6\xd4\xb7\xa8\xe2\x2b\x37\x36\x6b\xcf\x56\xa6\x56\x3b\xe8\x18\x2b\x03\x7d\xbc\x44\xec\x6d\x4b\x49\xc2\xb0\x98\xe5\x65\x55\x29\x49\x48\x6c\xbb\x75\xf8\x67\x4e\x38\xe6\x11\xe4\x00\x59\xd3\x5b\x2e\xb5\x9d\xd0\xe5\x51\xa2\xf3\x5a\xb1\x5b\xfd\x14\x68\x2e\xa6\x98\xe4\x3c\x2f\x33\xc3\x8b\xac\x5a\xf7\x47\xdf\xc1\x11\xf2\xd8\xe6\x46\x23\x33\x11\xc5\xc0\x62\xcc\x36\x05\xf6\xc9\x93\x30\x16\x13\x06\x73\x75\x2b\xcb\x0f\x0a\xaa\x68\x00\x1e\x54\xd2\xd5\xa7\xce\x7c\x47\xe1\x46\xd1\xa5\xc3\xb4\xbd\x68\x56\xcd\x38\xba\x45\x3a\x24\xd2\x18\x26\xa8\x68\x61\xaa\xae\xa7\xe7\x82\x4e\x44\x3e\x04\x67\x32\x2c\x83\xd2\xc0\x16\x27\xd4\x7c\x4d\x93\x7b\x26\x52\x2c\x1a\x05\xcb\x4e\x17\x82\xe6\x2e\xdb\x56\x54\x8f\xbb\xd1\x5f\x0f\x9c\x61\x02\xc3\xf7\x7c\x98\x31\x72\xdd\x43\xc2\xa0\xd4\x9d\x53\xd9\xd8\x2e\xdb\xce\xb9\x46\x93\x8d\xe2\xf3\x84\x79\xfe\x6f\xfb\x1d\x72\xea\xf3\x16\xb1\xf4\x4b\x93\xf7\xdb\x13\xe1\x2f\x90\xfb\x60\x39\x87\xa4\x5a\x34\xb3\x47\x7b\x11\x62\x46\x1b\x9b\x3b\x5e\x1c\xb6\xea\x8d\x1a\x77\x89\xfc\x3d\x56\xe3\xb4\x7e\x88\x3f\xd2\x54\x6a\xf2\x75\x26\x93\x7b\x72\xc9\x40\xe8\x7a\xcc\xf2\x2c\x6a\x9c\x3e\x67\x0a\xef\x9c\x4e\xb7\xdd\xb3\x0d\x49\x2e\x05\x37\x52\x6d\xa6\x17\x4f\x57\x76\xb2\x4f\xf7\xbc\x36\x43\x95\xc5\xe6\x97\x9c\xec\xd9\xa2\x5b\xd7\x8d\x87\x4e\x41\x3d\x83\xd3\x89\xaf\x5c\x15\xb0\x1d\xcf\xda\x2f\x66\xf2\x61\x68\xe4\xb0\xd4\x6c\xc8\x5b\x5c\xe8\x76\x58\xe6\x3d\x5b\xc0\x2d\x76\xc7\x85\xba\x6e\x35\x9d\xc1\x48\xb0\x40\xc1\x7b\xcb\xb9\x3f\x7e\x7d\xf9\x49\x33\x35\x8a\x65\xc0\x33\x66\x92\xb3\x84\x15\xb3\x33\x37\xc2\x8b\x04\x8a\x27\x22\x5d\xa1\xe2\xfb\x21\x9b\x49\x64\x96\xb9\xc0\x6c\x39\x21\x17\xac\x98\x85\x81\x9f\x7a\xd5\xcf\x97\x11\xb8\x90\xb2\x6b\x22\xd4\x63\xdb\xa7\x7e\x88\xe0\x0d\x9e\xa1\x08\x99\xd4\xb8\x5b\x11\x8a\xa7\x42\x9f\x17\x5d\x6a\xf3\x11\x81\xf3\xb8\xe9\x94\x8f\x6b\xf9\x94\x63\x7f\xcf\x7a\xb2\x64\xef\x31\x52\x23\x41\xd7\x13\x14\xba\x53\x96\x12\x39\x67\x4a\xf1\x94\x69\x12\x68\x50\xac\xa5\xf2\xec\xa9\xe1\xd6\xe7\x6d\x7e\xf6\xbc\xcd\x3b\xa8\x43\xc7\xa0\x0f\xd5\xc8\x14\xbc\x59\x22\x53\x34\xcd\xb9\x78\x71\x84\x4a\x27\x34\x63\xd7\xdf\x75\xd0\x3f\x5c\x8f\xba\x0a\x72\xeb\x5e\x46\xf9\xd3\xb6\x64\x25\xfb\x36\xe0\x0d\x11\x32\xdd\x66\x52\x7d\x04\x45\x62\x4a\x0d\x7b\xd8\xca\x0e\x87\x15\xa1\xda\xde\x12\x84\xd3\xe7\x54\x39\x5e\x44\x8e\xc0\x08\xe7\x31\xe9\xd9\x21\x99\xaa\xdb\xb5\xae\xc6\x49\xec\x15\xa7\xdf\x6d\x26\xdd\xf5\x18\x7c\x7e\x73\x4d\xbe\xc1\xe6\x87\xcd\x5e\xa8\xa4\x41\x31\xf0\x52\xe6\x94\x77\x2d\xb2\xd1\xec\xde\xcc\xbe\x1a\x2f\xe1\x26\xb4\x25\xae\x71\x54\xc0\x65\xc2\xa7\xa5\xd5\xe9\x9c\x1e\xf6\xa2\x12\xcc\x2d\x89\x2e\x2f\x37\xc1\xdc\xfe\xd5\x20\x22\x93\x93\xf7\x8b\xac\x24\x16\xbf\x95\xc0\x4a\xc2\x1d\x28\xd1\x4c\x68\x0e\x17\x32\xd1\xad\xb8\xab\xf4\x87\xa5\x25\xd1\x09\x12\x45\x9c\x01\x79\x27\xa7\x5c\xf8\xd3\x2b\xdd\x7d\xdd\x84\xf2\xac\x2d\x30\x7a\x99\xe4\xd9\x65\x12\xad\xb3\x2b\x41\xc7\x59\x1b\x77\x83\x3a\xaa\x85\x8e\xe4\x6d\x46\xa7\x84\xc1\x1f\x67\x29\xd7\xf6\xff\xe4\xf6\xf6\x1d\x18\xe1\x4b\xe1\x25\x66\x30\x50\x3b\xda\x17\x82\x14\xf0\x20\x1e\xf6\xec\x20\xe9\xd9\x21\xfb\x5f\xd4\x93\x70\x91\xda\x89\x47\xa5\xe0\xd0\x49\x0a\x5a\x60\x3e\xc4\xe0\xf3\x8b\x6e\x03\x63\x46\xee\x66\x3c\xb9\xbf\x89\xec\xee\x52\xd9\x77\x22\x7a\x55\x63\x60\xcd\xdf\x0e\x49\x2d\xdd\x54\x6f\xba\xab\xc6\x51\x4f\xcf\x07\x3c\xc1\xb8\x75\xeb\x87\xdf\xa8\xd6\x32\xe1\xd5\x9d\x0b\xd8\x68\x2a\xe6\x90\x02\x73\x38\xec\x9a\x40\x3c\xe8\xba\x1c\x94\x3f\x56\x70\x34\xbf\x9b\xbe\x3a\xae\x8e\x39\x18\x17\x7e\xd5\x07\x5d\x02\xe2\xcc\x0e\xa9\xd1\xab\x8e\xcb\xa9\xd1\xbd\x30\xdc\xb8\x58\xf0\x6e\xea\x6e\xf3\xbc\x20\xe6\x6b\x73\x2e\x6d\x5f\x48\x91\xee\x52\x13\x1e\x6c\xe1\x6d\xc2\x36\x56\xa9\xe1\x8d\xdb\x44\x7c\xe7\xae\x1a\xe0\xcc\x15\xb2\x28\x33\xf4\xe7\xd8\x3f\xbf\xbb\xb7\x19\xe3\x77\x0e\x74\xf5\xf0\x14\x59\x4b\x8f\x63\xc7\xde\xee\x9e\xce\x3f\x8d\xdc\xa5\x91\x70\xf7\xea\xb7\xbf\xf9\xcd\x97\x9e\xcd\xb4\xad\x0a\xfe\x18\xe9\x4c\x5b\x9a\x68\x57\xc4\x17\x5d\xf7\xf1\x45\x3f\xdf\xf8\xa2\xc7\xcf\x42\x7b\xe0\x08\xa2\x8e\xbe\xb9\xdd\xfc\x72\xdb\xc7\x08\xb5\xf6\xde\xed\xea\xb9\xdb\x21\x0a\xe8\xb0\xb1\x3f\x9d\x7d\x59\xbb\xc4\xf9\xf4\xd1\x3d\x3f\xd5\xe8\x9e\x5d\x7c\x59\xbb\x47\xf2\x74\xf1\x61\xfd\x29\x46\xed\x74\x38\x9c\xed\xa3\x4b\xf6\x8e\x29\xe9\x9e\x04\xb0\xbb\x3d\x6d\x97\x82\x54\x55\xcf\x95\x1a\xa4\x0f\x2a\xf7\xb9\xc7\x8e\x8f\x75\x94\x5a\xcc\x48\x7b\x02\x9f\x44\x21\x21\x1d\xb4\x31\x1c\x5e\x76\xa9\x0d\xe9\xfa\x7c\x77\xdb\xb8\x98\x09\xaf\x9f\xe7\x3e\xe6\xe7\x70\xe1\xd1\xd7\x74\xf9\x42\x4c\xee\xba\x96\xad\xc5\x5b\x2b\x80\x04\x00\x23\x97\xe3\x38\x4b\x64\x75\x74\xce\x6f\xae\xad\x0e\x0e\x61\x44\x34\xd3\x23\xb2\x82\xcf\x7b\x73\xa9\x93\x0b\x3c\x7f\xa7\xc6\xb0\xbc\x30\xed\x77\xbd\xb7\xb8\x3f\xbb\xc5\xfd\x80\x16\xc0\x59\x99\x53\x31\xb4\x27\x0a\x6c\xee\xb5\xdb\xba\x06\x65\x1e\x11\x77\x76\x90\x3d\x81\x05\x04\x82\x0b\xea\x85\x8d\x69\x54\xe6\xf2\x71\xcc\x9e\x30\xf6\xce\x2b\x47\xbe\xda\x38\x69\x89\x5c\x72\x78\x75\xcb\x09\x50\xf0\x87\x2a\x62\xce\x35\x35\xdc\xcc\x18\xf2\xf0\x1b\x08\xc8\xa9\x5a\xd5\x25\x69\x14\xa5\x69\x96\xc9\x07\xfc\x76\xcc\xd7\x2c\xf4\xed\x5c\x5c\xa4\xd9\x98\x91\x9c\x5b\x1d\xdd\x19\x58\xe3\xe9\xe0\x95\xa9\x95\xc8\x99\x42\x81\x57\xb9\xcb\xb6\x5b\x66\xdc\x46\xc1\x46\x5b\xfd\x56\xa0\x43\xb8\xfd\xb7\xf7\x2a\x82\x6f\x7b\x9a\x30\x66\x33\x3a\xe7\xb2\x54\xd8\xdb\x48\x72\xe4\x7e\x02\xde\xb0\x90\x65\xb0\x77\x61\x31\xcc\xb0\x3a\xbd\x02\x4e\x1f\xaa\x1f\x41\x15\x48\xa5\x37\x4d\x0c\xd9\x67\xae\xcd\xf2\x5a\x3c\x88\x7c\x1a\xbc\x43\xe1\xcd\x5c\x17\x96\x2d\x74\xae\x6a\x57\xeb\x57\x97\x57\xe6\xb7\xf0\xd3\x17\x54\xd3\x6e\x6b\x76\xd7\x27\x13\x81\x7e\x86\xe2\x4f\xb8\x09\xcb\x78\xb2\xe8\x5c\xee\xad\xd1\xdb\x13\x6d\x1d\xee\xd0\xec\x7b\xf2\x35\xd5\x2c\x25\xef\xa9\xa0\x53\xd4\xf7\x4e\x6e\x6f\xbe\x7e\x7f\x6a\xf7\x15\xf4\xc9\xeb\xcb\x95\x17\x6d\xb7\xf1\xe0\x1f\x0e\x19\x2f\xb2\xb4\xf0\x1d\x58\xd5\x52\xff\x1d\x17\x7f\xd0\x40\x18\x12\xf8\x50\xbb\x64\xbd\x2b\x58\xd0\x4d\x33\x84\xb5\x59\xf3\xb3\x41\x60\xe6\x79\xba\x67\x95\x4f\x2e\xb4\xa1\x59\x76\x93\x51\x71\x5e\x14\x4a\xce\x57\x6b\xe3\xb5\xb9\xfa\x86\x7e\xa6\xe8\xe6\xe1\x5f\x16\x08\x7a\xb8\xc2\x16\xe4\xba\x1a\x7f\x44\xae\x4d\xd0\xc2\xa5\x00\x96\x7a\x74\x5e\x1a\x99\x53\xc3\x93\x23\xab\xac\x1f\xbd\xa7\xa2\xa4\xd9\x4a\xa7\xab\x8d\xcb\x58\x27\x22\x6e\xec\xb4\x3e\x75\x5d\x8b\x6e\x1b\x65\x8d\xcd\xfd\x0d\x55\x96\x3a\x5d\xdc\x7e\xdf\xa9\xaf\x36\xd4\x94\x4b\x54\x78\x03\x67\x58\xcf\x0b\x86\x24\xa3\xda\x7c\x2a\x52\x7b\xe8\x1b\xbf\x6e\x22\xf8\x09\x35\x34\x93\xd3\x3f\x31\x9a\xad\xc6\xf0\x1a\x9e\x5c\xc4\xad\xbd\x01\xca\x5d\xf8\x97\xe3\xd0\xf0\x58\x13\x2b\x60\xfb\x18\x78\xc5\x32\x36\xa7\xc2\xf8\xee\x58\x5c\x5d\x1f\xbb\xf5\x03\x16\xf1\xca\xf8\x9a\x32\xc3\x54\xce\x45\x7d\xcc\x5b\x68\x7b\x21\x45\xca\xd1\xec\x08\x06\x35\xec\x51\x1f\x77\x3d\xaa\xad\xbb\x69\xd8\x70\xb7\x50\xcf\xae\x19\xcd\xa7\x0e\x0a\x6c\x36\x76\xf2\xe5\x0c\x5f\xc2\x4d\x7b\x6d\x6e\x4b\x90\x22\xf7\xc2\x0a\x86\x90\x47\x64\x35\xd9\xda\x2a\x27\x6c\x93\x0f\x86\x7e\x8f\x71\x0a\xeb\x1d\x47\x87\x6e\xde\xeb\xee\x20\x36\xa1\x18\x3e\xdb\x25\x8b\xe6\x54\xd6\xd3\xd4\x55\x78\x17\xba\x61\x24\x4b\xa3\x20\x7f\xad\xd1\x7a\x1e\xd0\x4a\xf0\x6a\x27\x23\xb5\xcd\x6a\x5f\xa7\xb5\x55\x0e\xf6\x25\x55\xb6\x85\xc4\xb8\x95\x69\xb5\x4c\x2e\x5f\x57\xac\xaf\x9d\xff\x9f\x72\xaa\x08\x25\x05\x67\x98\xfc\x84\x0a\x07\x2c\xe0\x2c\x8c\xa6\xee\xa5\xe5\x60\x56\x25\x84\xdf\x06\xee\x32\x1c\x8d\xcb\xce\xd7\xc2\x1b\xa8\x29\x26\xff\x80\x8b\x8b\xb3\x6f\xa4\x33\xf2\xba\x20\x5d\x4b\x03\x80\x93\x0f\x88\x2e\x93\x19\xa1\xda\x4e\xcd\x22\xb4\x3d\xf1\x6c\x94\x53\xc1\x27\x4c\x9b\x51\xc8\x12\xac\xff\xfc\xeb\xbf\x8c\xc8\x5b\xa9\x88\x73\x54\x1f\xf8\xac\x1a\x6e\x9e\x15\x5e\x70\x8d\x8b\x09\x7d\x2b\xad\xb5\x90\xa9\x9b\xf4\x03\x4c\xd6\xd0\x7b\xcb\xc3\x70\xb2\x25\x83\xab\x8b\x37\xe4\xc8\x8a\x89\xd1\xa7\xff\x61\xd9\xd2\xbf\x8e\xc8\xc9\x03\x30\xed\x23\xfb\xe7\x11\x7e\x30\xb8\x4d\xc6\x4a\x75\xf5\x61\x0c\x96\x54\x7c\x3a\x65\x0a\xd5\x47\x02\x41\x85\xa7\x2e\x2b\x88\x90\x51\x63\x7f\x29\x5d\xa9\x9b\xcd\x89\xfc\xf9\xd7\x7f\x39\x22\x27\xf5\x75\x11\x2e\x52\xf6\x99\xfc\x1a\xad\xcb\x5c\xdb\x35\x9e\xba\xcb\x1c\xbd\x10\x86\x7e\xb6\x63\x26\x33\xa9\x99\x40\x55\xde\x48\x32\xa3\x73\x46\xb4\xb4\x1a\x30\xcb\xb2\xa1\xb3\xa5\x93\x07\x0a\x99\x5a\x3c\x28\x21\xb0\x9e\x14\x54\x99\x1a\x4a\x8c\x9c\x85\x04\xbe\x66\xb7\x6d\x2a\xfc\xcd\xf4\x84\x0b\x77\x7f\xe5\x6e\xce\xec\x9e\x43\x60\x28\x6e\x92\x91\x24\x99\x51\x31\x0d\xb1\xe9\x93\xd2\x94\x8a\x6d\xb9\xfa\x69\x79\x06\xee\xb9\xe8\x14\xc2\xfc\x2d\x17\x4d\xa7\x82\xd5\x76\xa5\x29\x37\x3e\x2a\xc2\xf9\x2a\x9a\xc5\x99\xdd\x05\xc5\xc7\xa5\x91\x4a\x9f\xa5\x6c\xce\xb2\x33\xcd\xa7\x43\xaa\x92\x19\x37\x2c\xb1\xcb\x3a\xa3\x05\x1f\x26\x52\xd8\x1d\x87\xac\x0c\x79\xfa\x0b\x28\x6f\x3a\xb4\x53\xdd\x92\x75\xba\xe5\xa2\xb7\x1b\xd5\x9e\xd5\x98\x76\xb0\x35\xb6\xb0\x07\x2d\x2f\x14\x6d\x33\x4f\xb0\x5a\x30\x84\x9c\x1d\x64\xb1\x3e\x69\x72\x77\x1e\x73\xec\xf2\x80\x27\xcd\x31\xec\xb1\x43\x07\x12\x38\x95\x35\x4a\x99\xd3\x14\x49\x29\x15\x8b\x47\x47\x7e\x0b\x52\x48\x97\x9f\x2c\x86\x30\x84\xcc\x86\x54\xa4\xf6\xdf\x18\xb0\x93\x2c\x0e\x02\xc3\x92\x77\x22\x04\x9f\xae\x2f\x9f\xe6\x48\x94\xfc\x00\xa7\xde\xc9\x6b\x2d\x85\x28\x14\x55\xd1\x51\x43\x95\xcc\x33\xcd\xba\x80\xca\xb5\x1f\xf5\x3f\xdc\xfd\x4b\xc8\x76\xb6\x4d\xa4\xda\x7c\x6b\x12\xc9\x8e\x2d\xe7\xfb\xae\xea\x11\xdb\xe4\xc0\xf1\x8a\x6a\xe3\x52\x6b\xf9\x1c\x04\xb5\x65\x78\x05\x05\x18\xcc\xfa\x8b\xe1\x56\x38\xe4\xfd\x05\xec\x44\x86\x2b\x73\x2e\x25\x41\x29\xd9\xae\x40\x55\xfa\x4b\xad\x0e\x1a\x2e\xca\x30\x6d\x08\x9d\x53\x9e\x81\x75\x5e\x8e\x35\x53\x73\x2c\x48\xe5\x52\x0d\xd2\xa6\x9e\xe5\x6a\x4e\xa0\x18\xf5\x44\x9a\x8f\x5f\xc3\xf2\xae\x6c\x5a\x00\x68\x43\x8d\xd9\xaf\x9d\xf5\x41\xf4\x1e\x54\x2f\xd7\xfe\x6c\xbf\xb0\xa3\x1a\x63\xf1\xef\x4f\x8c\x2a\x33\x66\xd4\xdc\xf1\x4d\x7c\x77\x09\xa5\x6b\xfd\x42\x29\xf7\x80\xd0\x0f\x8c\x4c\xa5\xb1\x22\x56\x09\xb8\x8f\x32\x29\x26\xf5\x09\x88\xf6\xd8\x18\x5d\xad\xf2\x4e\x51\x08\xf1\x91\xa2\xe3\x32\xeb\x1d\x97\xd7\xe9\xa4\x63\x87\x49\x06\x5b\x63\x22\x0d\x29\x98\xdb\x3b\xbc\xcd\x00\x0a\xf4\x34\x4b\xce\x99\xd6\x1b\x13\x6c\xd4\xbd\x0b\xb1\x35\x1e\xe5\xc6\xd5\x5a\xee\x7f\xc3\xb0\x10\x2b\x40\xa7\xcc\x50\x9e\xf9\xa3\x8c\xa0\x08\x50\xda\x46\x5d\x37\x2e\x50\x31\xaa\x37\x09\x08\xb5\x59\x7f\x84\xc6\x38\x69\x29\xd8\xf0\x41\xaa\x94\x5c\xd0\x9c\x65\x17\x54\x33\x37\x56\x1c\xa2\x87\x7b\x74\xac\x0f\x3a\xe5\xd5\xb6\xaf\x35\x53\x46\xe3\x4f\x65\x12\x86\xbf\x2a\x15\x0b\x27\x38\xf0\x26\xc8\x3b\x55\xb2\x01\x79\x6b\xb9\xd7\x80\x7c\x12\xf7\x42\x3e\xec\x37\x57\xb3\xf1\x16\xa4\x36\xd3\xd8\xfd\xc3\xa7\xd5\xa9\x19\x7c\xc2\x74\x77\x9c\x91\x23\xf8\x6b\x4c\x8d\x75\x66\x13\x9a\xfa\x19\xd9\x7f\x2e\x99\xa0\xac\xa2\xa8\xe4\x54\x31\x8d\x99\x6b\x56\x26\x49\x6c\x6b\x72\xfe\x86\x09\x17\xdc\xb7\x75\x7a\xd7\xab\x7a\xf9\x99\x7a\xbe\x36\xad\x7e\x71\xfb\xed\x3e\x56\x64\x2b\x45\x8d\xcd\x1e\x81\xd1\x44\xd7\x18\x9f\xd6\xcd\x70\xb5\xd1\x29\xe2\x7a\x51\x5b\x14\x4a\x36\x59\x47\xfd\xea\x2e\x6e\xbf\x5f\x0f\xec\xb5\xbc\x6f\x1b\x7f\xda\x6e\x96\xda\xd7\x20\xb5\xf5\xcc\x6c\x35\x42\xf5\xe6\xa7\xde\xfc\xf4\x25\x99\x9f\xb6\x62\xfc\x26\x93\xd3\x97\x61\x6c\xda\xba\xc4\x4d\x06\xa6\x17\x69\x5a\x6a\xb5\xa2\x8d\xe6\xa4\x17\x6b\x48\xda\xba\xb4\x96\xc6\xa3\x9f\x8f\xd9\x68\x2b\xc4\x36\x98\x8a\x5e\xa0\x91\xa8\x8d\x40\xc6\xd2\x36\x62\xe2\x75\xd4\x38\x16\x14\xab\x72\x96\x61\x38\xef\x94\x13\x8b\x33\xbb\x4a\x8b\x56\x80\xdb\x3a\xb7\x63\x37\xb9\xf6\xb2\x97\x13\x18\x5d\xb1\xc7\xa5\xc9\x92\xcb\xab\x9b\x8f\x57\x17\xe7\x77\x57\x97\x4d\xf9\x6e\x15\xa4\xb7\x48\x62\x9b\x6d\x10\xc3\x48\x12\x5b\xd3\xc0\x12\xe4\x35\x3f\x59\x1c\x58\xf3\x53\x59\xf2\x55\xbd\xf6\x97\x0b\xf7\xe2\x72\x7b\xf1\x8f\xed\xa7\xb3\xed\xf1\xfc\x84\x8e\x53\xd4\xf9\x9c\x59\xb9\x67\x26\xb3\x54\x7b\xbf\xd5\xeb\xcb\x10\x49\xc5\x45\x92\x95\xa9\x15\x2e\x3e\x7d\xba\xbe\xd4\x23\x42\xbe\x66\x09\x2d\x35\x58\x61\x52\x29\x8e\x0d\xf9\xee\xc3\xbb\xff\x06\x7f\x6c\x68\x31\x08\x79\x4d\x20\x2b\x2f\xa7\x98\x58\xd8\x60\xba\x36\xf2\x35\x43\x41\x05\xbe\x9c\xd0\xc2\x52\x31\x8d\x95\x2b\x0c\xc8\x22\x33\x96\x15\x96\x62\xde\x33\x52\x65\x50\xb5\x03\x57\x15\xe6\xbd\xfb\xe4\x94\x19\x8c\xba\xda\xe4\x21\xb9\x11\x6a\x5b\x2c\xae\x7b\xd8\x5a\x6b\xea\xa3\xd3\xc6\x1f\xa8\x76\x16\xab\x95\xb3\xdd\xb2\xbf\xdb\xed\x33\xeb\x4d\x1c\x6b\x8c\x1b\x48\x9e\xe1\xaf\xa5\x39\xdb\xc9\x56\x76\x0c\x74\x22\xe1\xa6\xb5\x35\x75\xbd\x1b\xd0\xea\x3a\x00\x4b\xb6\x0c\xd6\x04\x72\xed\xc3\xc1\x23\x3b\x9a\x72\xbb\xb9\x40\x11\x91\xb4\x56\xfb\xd3\xf9\xcf\xd5\xdf\x95\xe3\x50\xfd\xb5\x9a\xaf\xb3\xc8\x90\x7f\xfc\xeb\xab\xff\x3f\x00\x00\xff\xff\x01\xa8\x18\xd1\x2e\x5c\x02\x00") +var _operatorsCoreosCom_subscriptionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x7b\x73\xe3\xb8\x95\x28\xfe\xff\x7c\x0a\x94\x93\x2a\xdb\x59\x49\xee\xce\xe6\x26\xb9\xbd\xa9\x6c\x79\x6c\xf7\xc4\x77\xba\x7b\x7c\xdb\xee\x99\xda\x5f\x36\xbf\x0d\x44\x42\x12\x62\x12\xe0\x00\xa0\xdc\xca\xe3\xbb\xdf\xc2\x39\x00\x08\x52\x2f\x52\x92\x1f\x3d\x43\xfe\x31\xd3\xa6\x00\x10\x38\x38\x38\x2f\x9c\x07\x2d\xf8\xf7\x4c\x69\x2e\xc5\x1b\x42\x0b\xce\x3e\x1b\x26\xec\x5f\x7a\x74\xff\x7b\x3d\xe2\xf2\x6c\xfe\xfa\xab\x7b\x2e\xd2\x37\xe4\xa2\xd4\x46\xe6\x1f\x99\x96\xa5\x4a\xd8\x25\x9b\x70\xc1\x0d\x97\xe2\xab\x9c\x19\x9a\x52\x43\xdf\x7c\x45\x08\x15\x42\x1a\x6a\x5f\x6b\xfb\x27\x21\x89\x14\x46\xc9\x2c\x63\x6a\x38\x65\x62\x74\x5f\x8e\xd9\xb8\xe4\x59\xca\x14\x0c\xee\x3f\x3d\x7f\x35\xfa\xdf\xa3\x57\x5f\x11\x92\x28\x06\xdd\xef\x78\xce\xb4\xa1\x79\xf1\x86\x88\x32\xcb\xbe\x22\x44\xd0\x9c\xbd\x21\xba\x1c\xeb\x44\xf1\x02\x3e\x31\x92\x05\x53\xd4\x48\xa5\x47\x89\x54\x4c\xda\xff\xe5\x5f\xe9\x82\x25\xf6\xe3\x53\x25\xcb\xe2\x0d\x59\xd9\x06\x87\xf3\x73\xa4\x86\x4d\xa5\xe2\xfe\x6f\x42\x86\x44\x66\x39\xfc\x1b\xd7\x7e\x1b\x7d\x15\x5e\x67\x5c\x9b\x6f\x97\x7e\x7a\xc7\xb5\x81\x9f\x8b\xac\x54\x34\x6b\xcc\x16\x7e\xd1\x33\xa9\xcc\x87\xea\xdb\xf6\x5b\xba\x1c\xc7\xff\x76\x0d\xb9\x98\x96\x19\x55\xf5\x41\xbe\x22\x44\x27\xb2\x60\x6f\x08\x8c\x51\xd0\x84\xa5\x5f\x11\xe2\xe0\xe8\xc6\x1c\x12\x9a\xa6\xb0\x37\x34\xbb\x51\x5c\x18\xa6\x2e\x64\x56\xe6\x22\x7c\xd3\xb6\x49\x59\x18\xf5\x0d\xb9\x9b\x31\x52\xd0\xe4\x9e\x4e\x99\xff\xde\x98\xa5\xc4\xc8\xd0\x81\x90\xbf\x69\x29\x6e\xa8\x99\xbd\x21\x23\x0b\xe2\x91\x85\x60\xf4\x33\xee\xcf\x0d\x0e\x12\xbd\x37\x0b\x3b\x5d\x6d\x14\x17\xd3\x4d\x9f\x4f\xa8\xa1\x99\x9c\x12\xc4\x2f\x32\x91\x8a\x98\x19\x23\xf6\x53\x7c\xc2\x59\xea\xe7\xb7\x61\x46\xd8\x75\x69\x4e\xb7\xcd\xd7\xad\xa7\x34\xa3\x42\xb0\x8c\xc8\x09\x29\x8b\x94\x1a\xa6\x89\x91\x15\x7c\x36\x83\xc7\x75\x5e\x9a\xcd\xc5\xd2\xfb\x15\xd3\xc1\xa6\xf3\xd7\x34\x2b\x66\xf4\xb5\x7b\xa9\x93\x19\xcb\x69\xb5\x87\xb2\x60\xe2\xfc\xe6\xfa\xfb\x7f\xbf\x6d\xfc\x40\xea\x4b\x89\x51\x94\xdc\x33\x56\xe8\xea\x50\x90\xb2\xb0\x6b\xb2\x8b\x23\xe3\x05\x31\x8a\x26\xf7\x5c\x4c\x61\xe9\x53\x5c\xef\x05\x6e\x8c\x1e\x2d\x4d\x59\x8e\xff\xc6\x12\x13\xbd\x56\xec\xc7\x92\x2b\x96\xc6\x53\xb1\x90\xf5\x24\xa2\xf1\xda\xc2\x29\x7a\x55\x28\x3b\x2d\x13\x9d\x43\x7c\x22\x1a\x55\x7b\xdf\x58\xe6\xb1\x85\x05\xb6\x23\xa9\x25\x4f\x76\xfa\x33\xe6\x0f\x07\x4b\x1d\x00\xed\x76\x9a\x19\xd7\x44\xb1\x42\x31\xcd\x04\x12\x2c\xfb\x9a\x0a\xb7\xa6\x11\xb9\x65\xca\x76\xb4\x07\xb6\xcc\x52\x4b\xc7\xe6\x4c\x19\xa2\x58\x22\xa7\x82\xff\x3d\x8c\x06\x20\xb2\x9f\xc9\x2c\x7e\x18\x02\xc7\x4d\xd0\x8c\xcc\x69\x56\xb2\x01\xa1\x22\x25\x39\x5d\x10\xc5\xec\xb8\xa4\x14\xd1\x08\xd0\x44\x8f\xc8\x7b\xa9\x18\xe1\x62\x22\xdf\x90\x99\x31\x85\x7e\x73\x76\x36\xe5\xc6\x53\xe0\x44\xe6\x79\x29\xb8\x59\x9c\x01\x31\xe5\xe3\xd2\x6e\xdc\x59\xca\xe6\x2c\x3b\xd3\x7c\x3a\xa4\x2a\x99\x71\xc3\x12\x53\x2a\x76\x46\x0b\x3e\x84\xc9\x0a\x24\x91\x79\xfa\x0b\xe5\x68\xb6\x3e\x6e\x80\x6f\xe5\x39\x20\x9e\xea\x6d\x84\xb5\x25\x7e\x84\x6b\x42\x5d\x77\x5c\x4b\x05\x52\xfb\xca\x42\xe5\xe3\xd5\xed\x1d\xf1\x13\x40\xb0\x23\x84\xab\xa6\xba\x02\xb6\x05\x14\x17\x13\xa6\xb0\xe5\x44\xc9\x1c\x46\x61\x22\x2d\x24\x17\x06\xfe\x48\x32\xce\x84\xb1\xc7\x30\xe7\x46\x03\xce\x31\x6d\xec\x3e\x8c\xc8\x05\x30\x20\x32\x66\xee\xc0\xa6\x23\x72\x2d\xc8\x05\xcd\x59\x76\x41\x35\x7b\x74\x50\x5b\x88\xea\xa1\x05\x5f\x7b\x60\xc7\xfc\x73\xb9\xc3\xd2\x19\x23\xc4\x33\xb8\xb5\xbb\x13\x1f\xf8\xdb\x82\x25\xe1\x38\x50\x41\xce\x8b\x22\xe3\x09\x62\xbc\x99\x51\x43\x12\x2a\x2c\xbc\xb8\xd0\x86\x66\x19\xb0\x93\x56\xb3\x58\x77\xda\x09\x1c\xed\x06\x73\xf0\xaf\x97\x28\x74\xfd\x87\xc0\xd4\x1a\x2d\xd6\x51\x06\xfb\x38\x3a\xbb\xfc\xc3\x06\x90\x13\x94\x4c\x26\x7c\xba\xaa\xdb\x5a\x58\x5e\x40\x17\x90\x69\x28\x17\xda\x0d\x51\x2a\x84\x66\xc5\xa9\x2c\xef\xa2\x35\xbe\x3d\x5a\x3b\xbb\x95\x90\xdd\xb6\x66\xfb\xd0\x09\x48\x60\x8b\xd5\xbf\x36\x56\x71\x3d\xa9\xa6\x37\x20\x72\xce\x94\xe2\xa9\xa3\x8f\x85\x4c\x8f\x35\x50\xb3\xb4\xcc\x80\xf6\x4b\xa1\x8d\xa2\x1c\x8e\xa6\xe0\x99\x5d\xc9\x90\x1a\x3c\x0f\x4c\x93\x07\x9e\x65\xe4\x57\x42\x9a\x5f\x85\x91\x60\x20\xa9\xf8\x94\x07\xd2\xa7\x09\x17\x7e\x7c\xe0\x88\x8e\xa5\x4b\xcd\x1a\x03\x8e\xc8\x27\xcd\x08\xcb\x0b\xb3\xf0\xc4\xe1\xe4\x1f\xff\x3a\xb5\x84\x95\x29\xaa\xa3\x81\x6b\xfd\x3c\xf9\x5c\xb3\xfe\x2d\xe0\x6d\x03\x62\xfb\x08\x99\xb2\xf3\x2d\xa0\x5e\x02\xf7\x25\x43\x09\x41\x43\xf7\xb0\x55\x31\x90\x55\x99\x31\x1d\xa4\x1c\x0b\xa3\x0d\x83\xb7\x58\x4b\xdb\xf5\x60\x3b\x36\x61\x4a\xb1\xf4\xb2\xb4\x47\xe3\x36\xcc\xea\x7a\x2a\x64\x78\x7d\xf5\x99\x25\xa5\x59\xc1\x75\x37\x2e\xdd\xca\x4d\x6e\x99\x4c\x21\xaa\xe0\xe7\x40\x74\x72\x3f\xd8\xf5\x02\xe3\xb4\xe0\xd1\x48\x87\x34\x35\x5c\x4f\x16\x00\x8e\x00\x30\xf6\xd9\x32\x09\x90\x6d\xa3\xf3\x65\x05\x15\xe0\x0f\x9c\x65\xe9\x80\x8c\x4b\x43\xb8\x01\xe6\x91\xcc\xa4\xc5\x2f\x8a\x70\x87\x71\xe7\x5c\x02\x6b\x26\x52\x58\x4c\x22\xb9\xe5\x00\x20\x02\xb0\x78\xf8\x11\xcc\xbc\xea\xc6\x35\xc9\xa5\x36\x15\xac\xec\x1b\xc0\x72\xc1\xc8\x03\x37\x33\xf8\x63\x6a\xd5\x15\xcb\xf6\x75\x99\xdb\x41\x1f\x18\x9f\xce\x8c\x1e\x10\x3e\x62\x23\xd8\x5d\x46\x93\x59\x34\x6c\xce\x98\xd1\x84\x66\x99\x9f\x42\x8c\x12\x48\x4f\x73\xcb\x13\xc9\x49\x60\x9a\x8e\xc1\x0d\x02\xbd\x6d\xee\xda\x4a\x70\x0d\x08\x33\xc9\xe8\x74\x40\x12\x99\x17\xf6\xb4\x50\x98\xe3\x78\x41\xb8\xb1\xb2\x1f\x32\x68\x25\xcb\x29\xae\x84\x65\xee\xc3\x5e\x3a\x02\xe0\x82\xf8\x62\xb5\x09\x31\x25\x47\xb8\xb8\x23\x2f\xf0\xd8\xe1\x38\x2e\x02\xd6\x97\x53\x93\xcc\x1c\x4d\x49\xa4\x52\x4c\x17\x52\x40\x4f\xf8\xe5\xaa\x9a\xdb\x7f\x84\x4e\x27\xfa\xb4\x02\xe6\x8c\x4f\x67\x1e\x96\x54\x21\x4d\xa9\xef\xc1\xa6\x33\x52\x9d\x13\xaa\x14\x5d\x6c\x69\xc9\x0d\xcb\xb7\x9c\x92\x25\xd4\x3e\x17\x8e\x48\x55\x38\x11\xed\x9e\x61\x2a\x0f\x30\x80\x0d\x86\xe3\xaa\x71\x7d\x3c\xb7\x6c\x97\x1b\x87\x21\xe4\x15\x39\x01\x14\xe1\xe6\x58\x03\xba\x0e\x65\x71\x3a\x22\xe7\xa0\xed\xb6\xf8\x80\x90\x61\x7c\x37\x90\xfd\xa8\x96\xd5\x58\x5b\xd7\xd6\x92\xa8\xe0\xb3\x9e\xd7\x2f\x3f\x43\x37\x7f\x26\x56\xb0\xfa\x55\xcd\x11\x26\x5b\x9b\xb6\x25\x6f\xbe\xb5\x9f\x43\x9b\xd6\xcd\xad\x46\x94\xd6\x2c\x63\x89\xb1\x34\x9a\xa9\x7c\x40\xa8\xd6\x32\xe1\x56\xac\xac\x90\xb6\x8e\xe9\xb8\x92\xed\xb0\x27\x5d\xe1\x4f\x3a\xaf\xdf\x3e\xcd\x83\xd7\xb6\xdf\x12\x34\x32\xae\x8d\xa5\x0c\x75\xa8\xd4\x08\xd6\x78\x01\xbf\x1e\x6b\x92\xd1\x31\xcb\xd6\xf2\xe5\xe5\xa7\xfd\xa9\xad\x9e\x96\xe7\x77\xed\x82\xd6\x2e\xc4\x29\x35\x61\xe3\x41\x44\xf6\x02\x1f\x4a\x1c\x03\x42\xc9\x3d\x5b\xa0\x6e\x67\x55\x46\xa7\x4c\x63\x63\xc5\x90\xdd\x58\xe4\xb8\x67\x0b\x68\xb4\x59\x52\x59\x0f\x93\x0e\xc8\x81\x4f\x97\x63\x5a\x3d\x43\x3b\xd1\x8e\x3d\xfc\xa2\x3b\x74\xeb\x8e\xbf\xf8\xdc\xb3\x8d\x92\xd7\xaa\x67\x49\x24\x01\x9c\x84\xfd\x80\x4d\x02\xfe\xe5\xf7\x98\x5a\x95\x08\x6c\x1d\x5d\x76\x88\x6c\x53\x30\x36\x3d\x1e\x7a\x7b\xad\xeb\x63\xd0\xa0\x11\x21\x8f\x35\x22\x9f\x3d\xe9\x33\x0e\x76\x1d\x8b\xc9\x70\x70\xbd\xa9\xe1\x7b\x9a\xf1\x34\x32\xff\x58\x3e\x7b\x2d\x06\xe4\x83\x34\xf6\x7f\x57\x9f\xb9\xb6\xe2\xcb\xa5\x64\xfa\x83\x34\xf0\xe7\x88\x7c\x63\x10\xd7\xdf\xb5\xa4\x6c\x07\x00\x10\xce\x77\x2f\xf0\x9c\x0b\xa4\x29\x76\xf9\xb1\x91\x42\x8f\xac\x3a\x04\xa2\x9c\x3f\xb8\x5c\x93\x6b\x61\x85\x43\x07\x06\x30\x1b\xa1\x12\x83\x43\xe4\xa5\x06\xab\x82\x90\x62\x08\x32\xc0\xca\x31\x10\x7a\x76\x9c\x18\x7e\x1b\x86\x5b\x3f\xd4\x37\xc6\x0e\xf3\x6e\x6d\xe7\x19\x9d\x83\x48\xc7\xc5\x34\x0b\xc2\xdb\x80\x3c\xcc\x78\x32\x43\xa9\x1b\x74\x7a\xc3\x54\xa1\x98\x65\x58\x14\xb4\x7f\xfb\x66\xca\x94\x15\x76\xb9\x1f\x0f\x2d\x61\x19\x4d\x58\x4a\x52\x10\x2d\xd1\xaa\x43\x0d\x9b\xf2\x84\xe4\x4c\x4d\x19\x29\x2c\x27\xd9\x6d\xf7\xbb\x11\x76\x7c\x3a\x93\xf7\xf8\x83\x9d\xd0\x0d\x58\xe4\x5b\x2b\xeb\x3e\x11\x77\x04\xb9\xba\xe7\x8e\x3d\x77\x6c\x3c\x3d\x77\x0c\x4f\xcf\x1d\xb7\x3c\x3d\x77\xec\xb9\xe3\xa3\x73\x47\xd4\x65\x77\x50\x9e\x7f\x40\x13\x47\x53\x5b\x06\x4e\xeb\xef\x85\xea\x6a\xb3\xe5\x37\xb7\x8e\xe0\xdc\x81\xaa\xed\x6c\xc7\x8a\x8a\x29\x23\xaf\x87\xaf\x5f\xbd\xea\xa2\x54\xbb\x8d\x6c\xd5\x63\x22\x55\x4e\x0d\xf4\xf9\xf7\x5f\x6f\xec\xb1\xce\xfe\x76\x00\xab\xa9\xc3\xf1\x60\xc8\xab\xc9\x0e\x6b\x0c\x9f\x40\x9d\x84\x34\x24\x67\x86\x50\x53\x33\x15\xf1\x9c\x0d\xbc\x61\x19\x11\xde\x5d\x8b\x79\x0b\x6c\x4a\xa4\x70\x76\x3c\x0b\xfc\xd1\x6e\x33\x48\x18\xd5\xcc\x52\xd2\x31\x0b\xb3\x90\xb9\xfd\x2a\x17\xc6\x1f\x17\x3b\x05\xe6\xa1\x42\x4e\xd8\x68\x3a\x22\x69\x09\xdd\xa8\x70\xf7\x74\xa7\x38\x5b\xbd\xd0\x86\xe5\x60\xc9\x95\x0a\xfe\x67\xa7\x6d\xd4\x02\xee\x02\xe6\x4c\x98\x92\x66\xd9\x82\xb0\x39\x4f\x4c\x58\x1f\x5c\x13\x72\x83\xc6\xf6\x76\x26\xc2\x56\xa2\x43\x7b\x71\x61\xb8\x84\xc1\x7a\x4b\x9f\x2e\xdc\x7e\x69\xec\x36\x67\xb2\xc1\x0b\x71\x25\xa3\xb5\xc2\xaa\xb1\xe3\xa2\x0d\x1c\xfe\x09\xc8\xf5\xdd\xc7\xed\x26\x57\xd2\x99\x92\x75\xa0\x5e\x4d\xb1\xb4\xcc\x32\x8b\x18\x68\x85\x5d\x5e\xc0\x0a\xeb\x28\x2e\xa9\x86\xcc\x68\x78\x47\x13\xf3\xf9\x87\x4b\x0b\x15\xdb\xe6\x4e\x16\x32\x93\xd3\x45\x0c\x69\x58\x19\xd8\x6e\x5d\x5f\xbc\xd5\x43\xa1\xc1\xa2\xdf\x87\xc6\xd6\xf4\x96\xbf\xde\xf2\xd7\xeb\x36\x4b\x4f\xaf\xdb\x84\xa7\xd7\x6d\xb6\x3c\xbd\x6e\xd3\xeb\x36\xbd\xe5\x8f\xf4\xdc\x71\x03\x4c\x7a\xee\x48\x7a\xee\xb8\x76\x5d\x3d\x77\xdc\x08\x9e\x9e\x3b\xf6\xdc\x71\xd5\x53\xc8\x74\x0f\x47\xc7\x42\xa6\x1b\xfc\x1c\xd1\xea\x93\xc8\x61\x26\x13\x6a\x9c\x23\xb8\xed\xe2\xec\x7c\x9a\xe6\x68\x88\x1a\x90\xbf\x4b\xc1\xd0\x79\xcd\xee\x0d\x98\x93\xa4\x99\x31\x65\x9b\x9f\xe8\xd3\x8d\x8e\x4d\xbd\x9f\x64\xef\x27\xf9\xe2\xfd\x24\x67\x54\xe3\xbe\x22\x51\x5a\xef\x36\x19\x1d\xc8\x3b\xa6\xf2\x2f\xd4\x6b\xd2\xa2\x8b\xdb\x6e\x08\xb1\xa9\xb6\x14\x57\x9e\xba\xfb\x02\x96\xde\xd4\xd7\xeb\xe4\x65\x58\x14\x4d\x53\x96\x92\x82\xa9\x21\xa2\x88\x24\x13\x2e\xd2\x15\x6b\xf5\xf0\x79\x56\xef\xc7\xfa\x3a\x9e\xd1\x05\xb2\x3e\x91\x1d\x6c\xae\xb1\xe1\xb8\x46\xe1\x5f\x84\x43\x64\x57\xa9\x7e\x48\x8c\x33\xf2\x7e\xdb\x52\xae\xef\x2e\x9a\x83\x40\xed\x4d\xc2\xbb\xeb\x95\x20\x96\xff\x58\x32\xb5\x80\x18\x8b\x4a\x60\x0d\xc1\x5c\xee\x8e\x8c\x6b\x92\x50\x8d\x9c\xa2\xab\x6a\xd9\x51\x8d\xda\x4d\x4f\xd9\xdd\x12\x4d\x9a\x70\x69\x0e\x85\x3a\xa9\xd7\xc1\x11\x66\x2b\x95\xf0\x15\xb7\x00\x95\xf5\xbf\xd3\x7c\x76\x15\xdd\x76\x12\xdc\x56\x22\xc5\x0b\x56\xce\xc9\xee\x0a\x3a\xd9\x59\x49\x27\x3b\x29\xea\x64\x57\x65\x9d\xec\xa1\xb0\x93\xdd\x94\x76\xd2\x44\x05\xbb\x43\x4e\xca\x7a\x1c\xfd\x9d\xec\xa3\xa2\x92\x3d\xf4\x78\xd2\x5c\x6a\x40\x53\xf5\x58\x4a\x3d\xe0\x7a\x4d\xaf\x7f\x6a\x60\xed\xa6\xd3\x93\x26\xa8\x7c\xd4\x1d\x28\xb4\x5f\x88\x86\xff\x24\xea\x36\xd9\x4b\xe5\x26\xbb\xab\xdd\x64\x77\xcc\x00\x56\xf7\x0e\xae\x53\xf7\x65\x98\x38\x0a\xb2\x88\x9c\x16\x16\x29\xfe\x61\x39\x01\xec\xcb\xbf\x48\x41\xb9\xd2\x56\xbe\x73\x36\x93\xf8\x37\xa7\x9d\xc7\xc3\xd8\x11\xb8\x26\x96\x54\xcf\x69\x66\x79\x0f\xfa\x71\x38\xbd\xc8\x8e\xde\x64\xd3\x03\xf2\x00\x51\x9f\x96\x4a\xa1\xb6\xc4\x35\x39\xba\x67\x8b\xa3\xc1\x12\x22\x1d\x5d\x8b\x23\xe4\x51\x4b\xa8\x13\x18\x9a\x14\xd9\x82\x1c\xc1\x6f\x47\x87\xe6\xec\x3b\x30\xae\x38\xd9\xc6\xae\x7c\x61\x07\x2c\x11\x3e\x56\xfa\xf0\xc2\x26\x72\x11\xbc\xd8\xf0\x5f\xd1\x15\x83\x01\x57\x8b\x88\xb9\x04\xaf\x11\xc0\x31\x78\x9f\x7a\xe5\xb7\x14\x2e\xb5\x02\xe8\xae\xd5\x60\xc8\xa4\x96\x5d\x9a\xdc\xc6\x4b\xc1\x34\x08\x76\x2c\x98\x88\xa2\xce\xd0\x76\x84\xee\x20\x15\xb7\x13\x69\xd3\x41\xa4\xea\x01\x32\x62\xce\xa8\xd0\xe4\xc8\xdb\x9e\x8e\x75\xd5\xe2\x68\x54\x45\xf7\x85\x11\x21\x08\x39\x8e\xe8\xab\x06\xec\x25\xed\x5e\xd2\xee\x25\xed\x0e\xbd\x7a\x49\x7b\xfd\xd3\x4b\xda\x1d\x9e\x5e\xd2\xee\x25\xed\x4d\x1f\xee\x25\xed\x5e\xd2\xde\xfe\xf1\xdd\x24\xed\x5d\xfd\x84\x62\xb9\xd7\x5d\xce\x61\xe6\x2c\x6a\x78\x52\xf9\x10\xf9\x56\xf8\xaf\xc3\xca\xdb\xb1\x2c\xbd\x5a\xda\x8e\x25\xf2\x25\xdd\x62\xb4\x45\xb4\x0e\xc2\xf7\x52\xcf\xcd\x52\xf7\xcb\xf2\x85\xda\x01\x37\xa2\x0b\x85\x1d\x91\xe3\xce\x5f\x85\xbb\x4c\x73\x63\x56\xdd\x93\xa7\xe4\xc4\xdf\xb8\x9c\x5a\xe0\x0b\x69\xea\x3f\x0a\xc3\x87\x55\x8b\x70\x07\x03\xd7\x8b\xb5\x78\x9b\xda\xb5\x44\xb8\x75\x0f\x37\xc5\xd5\x7e\x5a\x12\xc2\x54\x6d\x0e\x5c\xbb\x04\x62\xe0\x2d\xa1\x4a\x21\xec\xa8\x52\xf8\xeb\x63\xa4\x39\x98\x00\xce\x61\x1e\x0a\x4b\x30\x1f\x90\x98\x2a\x28\x45\xf7\x9d\xd4\x60\xce\x3d\xe7\xca\x2f\x85\xbb\x11\xb5\x6f\xfc\xad\xaf\x47\x4a\x58\x11\x0f\x5f\x1f\x91\x2b\xc0\xc3\x78\x60\xae\x01\x3e\x34\xcb\xe4\x43\x17\x92\xf4\x54\x61\x51\x0f\x9d\xc3\xa2\x1a\xf7\x77\x7d\x54\xd4\xcf\x24\x2a\x0a\x7e\xc4\x23\x74\xf0\xf0\x28\xf2\xc3\x8c\x01\x16\x29\x06\xa0\xca\xcb\xcc\xf0\xa2\xf2\x95\xd2\xf8\xa9\x0c\xa5\xcc\x89\xf3\x3c\xa9\xe3\xa5\xfd\x1a\x4d\x66\x4d\xfc\x84\xf1\xc0\xb7\x4a\xc3\xa1\x75\xde\x1d\x34\xcb\x5c\x4c\x91\x17\x49\xd1\x85\x85\x3f\xb7\x67\xc2\xa5\xcf\x8a\xe8\xb5\x19\x20\x32\x27\x96\x16\x66\x0b\x97\xa9\x6e\x03\x11\x45\xa5\x68\xce\x3c\xeb\x9d\xf2\x39\x13\x15\x25\x3d\xd1\xa7\xa7\x9e\x87\x1f\x94\xc2\x3f\x0a\x85\xfe\x43\x44\x49\xff\xd8\x86\x46\xc3\x82\x02\x95\xae\xc0\x57\xd1\xe8\xe7\x74\xc1\xe8\x72\xcf\xdf\xcd\xc6\xb0\xc3\xfd\xfe\x13\xde\xed\x7f\x39\x91\x65\xcf\x6c\x61\x7c\x0e\xdf\xfa\x17\x6f\x55\xec\x9d\xeb\xab\x67\x5f\xe7\xfa\x47\xb7\x1c\x3e\xaf\x8f\xfd\x17\x60\x2d\x7c\x4e\x1f\xfb\xde\x42\xb8\x71\x53\x5e\x9a\xeb\x7b\xfd\xd9\xc9\x22\xd8\x5b\x03\x77\xe6\xc2\x1d\x19\xce\xbe\x56\xc0\x8e\x18\xb1\xe3\x3d\x7b\x7f\xc7\xfe\x34\x77\xec\xbd\xc4\xdb\xf2\xe9\x25\xde\xb5\x40\xe9\x25\x5e\xd2\x4b\xbc\xdb\x96\xd7\x4b\xbc\x1b\xc1\xd3\x4b\xbc\x1b\x37\xa5\x97\x78\x7b\x89\x97\x7c\x69\x12\xef\x2e\x59\xba\xfa\xbb\xee\xbd\xee\xba\xbb\x52\x8b\x4e\x34\xa2\x23\x1e\x74\xbe\xdb\xee\xef\xb5\x5f\xca\xbd\x76\xeb\x80\x7f\x61\xf8\xbe\x41\xff\xf1\x5e\xad\x8b\xfc\xa7\x73\xc9\x53\x52\x94\xc6\xc5\x53\xf7\xd1\xff\x87\x88\xfe\xaf\x41\xbe\x4f\x01\xd0\x2a\x05\xc0\x3a\x98\xf5\x79\x00\xfa\x3c\x00\x07\xbe\x84\xee\xf3\x00\xf4\x79\x00\xfa\x3c\x00\xfe\xe9\xa3\x93\x48\x1f\x9d\xd4\xea\xe9\xa3\x93\xd6\x3f\x7d\x74\xd2\x8b\xb5\xbe\x92\x3e\x3a\xe9\x65\x5b\x62\x49\x1f\x9d\xd4\x5b\x67\x5b\x6e\xd4\x17\x18\x9d\xd4\xe7\x01\x78\xa9\x3e\x0a\xa4\x97\xb4\x7b\x49\xbb\x97\xb4\x7b\x49\x7b\xf3\xd3\x4b\xda\x1d\x9e\x5e\xd2\xee\x25\xed\x4d\x1f\xee\x25\xed\x5e\xd2\xde\xfe\xf1\x3e\x0f\xc0\x17\xe4\x1b\x41\xfa\x3c\x00\xbd\xbf\x44\x9f\x07\xe0\xe7\x9b\x07\xa0\x76\x77\xff\x7c\xc9\x00\xba\x4f\xa3\xcf\x08\xd0\x67\x04\xe8\x33\x02\xf4\x19\x01\xfc\xd3\x67\x04\xc0\xe7\x25\xd9\x1a\xfb\xf8\xa8\xb5\x40\xe9\xe3\xa3\x48\x1f\x1f\xb5\x6d\x79\x5f\x80\xdd\xb0\x8f\x8f\x7a\x81\xb6\xc2\x3e\x3e\xaa\xb7\x0b\x36\x37\xe7\x0b\x89\x8f\xea\x33\x02\xbc\xc4\xdb\xf6\x5e\xe2\x6d\xf9\xf4\x12\xef\x5a\xa0\xf4\x12\x2f\xe9\x25\xde\x6d\xcb\xeb\x25\xde\x8d\xe0\xe9\x25\xde\x8d\x9b\xd2\x4b\xbc\xbd\xc4\x4b\xbe\x34\x89\xb7\xcf\x08\xd0\x67\x04\xe8\x33\x02\x7c\x89\x37\xdc\x5b\x77\x9a\x89\xf9\xba\x3d\xad\xed\xe2\x95\x98\xd7\xf5\x14\x26\xe6\x5c\x49\x01\x14\x78\x4e\x15\xa7\xe3\x0c\x4e\x2a\x48\x3c\x0e\xfe\x8e\x7e\x32\x35\x22\x17\x54\xb8\x8b\x56\xbc\xc9\x5c\x3b\xff\xed\x88\xbf\x05\xd5\x9b\xd3\xfe\x9e\xd6\x45\x35\xb1\x72\xea\xc4\x35\xb0\x53\xa7\xe4\x22\x4c\x7c\xed\x67\x5a\x11\xf0\x36\xfa\xc1\x10\x90\x73\x6d\x83\x76\x52\xbc\x1d\x62\xf3\xd9\xac\x81\xe5\x03\xcd\xab\x10\xff\x15\xd0\x18\x91\xf7\x4e\x42\xa2\xe4\xe2\x7f\xae\x2f\xaf\x3e\xdc\x5d\xbf\xbd\xbe\xfa\xb8\x19\xe9\x5a\x92\x15\x38\x48\x1d\x26\x7b\xfc\xbd\xdf\x23\x08\xf3\x66\xc2\x52\xe0\x5f\x9e\x7c\x7f\xfe\xf1\x7f\x3e\x9c\xbf\xbf\x3a\x05\xf6\xcb\x3e\x17\x54\xa4\x2c\x25\xa5\xf6\x24\xa1\x50\x6c\xce\x65\xa9\xb3\x45\x38\xde\xab\x91\xb6\x89\xad\x4e\xd1\x5c\x10\xcd\xd4\x9c\x27\xab\x41\x84\x52\x2c\xad\x10\x28\x09\x18\xae\x98\x96\xd9\x9c\xa5\x28\x6b\x84\x49\xfb\xef\x70\x51\x94\xc6\x4b\xc4\xe0\x82\x60\x4f\x85\x48\x66\x54\x4c\x59\x3a\x22\x97\xb2\xb4\xe3\xfd\xf2\x97\xb0\x30\xc5\xd2\x32\x41\x5e\x47\xbd\xc0\xf4\xcb\x81\xa7\x24\x96\x16\x68\x4c\xa3\xa0\x13\x5a\xf8\xa5\xc7\xd0\xd1\x0b\x61\xe8\xe7\x37\x78\x07\x7f\xf4\xcb\xe8\xa7\x23\x9f\x82\x42\xda\x4f\x20\x3d\xc2\x59\x65\x90\xfd\x20\x23\x47\x71\xeb\x11\xb9\xb2\xdf\x60\x69\xbc\x0f\xe8\x42\xc1\xe6\x4c\x81\x3c\xed\x76\x61\x40\x14\x9b\x52\x95\x66\x4c\x83\xf3\xc0\xc3\x8c\x41\x3a\x0f\x94\xb0\x1c\xc0\x58\x90\xd6\x85\x34\x23\x72\xc9\x26\xb4\xcc\x0c\xd0\x90\xa3\xa3\xd1\xf1\xc1\x50\xed\xad\x92\x5b\x82\xdf\x6b\xe8\x76\x8b\x49\x25\x26\x52\xad\x3d\x1e\xc7\xce\x34\x51\x23\x6b\xda\x72\x12\xa7\xe9\x79\x5a\x8d\xfa\x45\x8b\x95\xb4\x10\x04\xdb\xab\xf3\x89\x14\x13\x3e\x7d\x4f\x8b\x6f\xd9\xe2\x23\x9b\x74\xf4\x86\x40\x26\xea\x74\x5a\x60\x60\x96\x1c\xe2\x80\xdb\x99\xce\x23\xde\xe5\xb7\x31\x9a\x74\xb3\x79\xb4\xb6\x74\x2c\xa5\xb4\x40\xa6\xef\xd8\xf7\x01\x93\xf3\x54\xcf\x76\x8a\xbe\x72\x72\xc7\x31\x69\x77\xe7\xd4\x8c\xc8\x7b\x09\x2e\x39\x13\xf9\x86\xcc\x8c\x29\xf4\x9b\xb3\xb3\xfb\x72\xcc\x94\x60\x86\xe9\x11\x97\x67\xa9\x4c\xf4\x59\x22\x45\xc2\x0a\xa3\xcf\xe4\xdc\x52\x3e\xf6\x70\xf6\x20\xd5\x3d\x17\xd3\xa1\x95\x74\x86\xb8\xab\xfa\x0c\x84\xa9\xb3\x5f\xa0\xc4\x7e\xf7\xdd\xe5\x77\x6f\xc8\x79\x9a\xba\x8c\x3d\xa5\x66\x93\x32\x73\xd9\x3b\x46\x84\x16\xfc\x7b\xa6\xac\x52\x36\x20\xf7\x5c\xa4\x03\x52\xf2\xf4\x3f\x37\x1f\xee\x1d\x21\x26\x0b\xd4\x8d\x76\x80\xda\x2d\x08\x8a\x8b\x1a\x9d\x0a\x48\x6f\x29\x14\x37\x1a\xf6\xdc\x1b\x0e\x1c\x43\xe9\xb0\x8c\xb1\x94\x19\xa3\x62\x4b\x0f\x00\x5b\xf7\x33\x7b\x5c\x1d\x5a\xd4\x72\x1c\x02\x14\x32\x7d\x43\x74\x59\x14\x52\x19\x4d\x72\x66\x68\x4a\x0d\x1d\xd9\x9d\x1b\xd4\xff\x04\xe1\x78\x40\xfe\x1a\x5e\x82\x84\xab\xff\x7c\x7c\xfc\x87\x6f\xaf\xfe\xeb\x8f\xc7\xc7\x7f\xf9\x6b\xfc\x2b\x90\x3d\x34\x75\xd5\x9b\x58\x91\x7b\x64\xc5\xdd\x0f\xf0\x0d\xf8\xd3\xb1\xd1\xf3\x24\x91\xa5\x30\xee\x07\x43\x4d\xa9\x47\x33\xa9\xcd\xf5\x4d\xf8\xb3\x90\x69\xf3\x2f\xbd\x85\x13\x90\xc7\x25\x3a\x00\xce\x1b\x6a\x66\x07\x26\x3d\xd5\xb9\xd8\x01\x5d\x5d\xcf\x38\x43\x52\x4e\xe1\x9f\x6f\xfd\x74\x2d\x07\x7a\x50\xdc\x18\x26\x40\xee\x00\xbf\x3b\x39\x19\x58\xcc\xad\xd8\xec\xfc\x75\x27\x75\xb4\xf5\x51\x0c\x50\xdb\x61\x71\x30\x7b\xb7\x32\x44\xe6\x40\x68\x97\xf5\xba\xf3\x9b\x6b\x32\x47\x68\x1c\x7c\x21\xde\x0b\xeb\xed\xde\x67\x32\x64\xaa\x72\xcb\x0a\x92\xe6\x1b\xb4\x2c\x05\x7f\x2f\x92\xf1\x9c\x3b\x03\xb0\xcb\x6a\xa5\xc9\x09\xbe\x1c\x25\x45\x39\x70\x0d\x46\x39\xcb\xa5\x5a\x84\x3f\x59\x31\x63\xb9\x95\xd8\x86\xda\x48\x45\xa7\x6c\x10\xba\x63\xb7\xf0\x17\x76\xac\x7d\x60\xb9\x37\x8a\xd4\x49\xa9\x2c\xf3\xc8\x16\x9e\x82\xb0\xf4\x79\xcf\xa2\x07\xd3\x81\x8f\x62\xd8\x8d\x0f\x3b\xb2\xdc\xa0\x2d\x22\xd3\x0e\xab\x02\x19\x72\x2e\xb3\x32\x67\x7a\x10\xd8\x13\x4a\xeb\x62\x6e\xa5\x49\xfd\x28\x8c\x30\xe5\x73\xae\x77\xba\x9f\xbe\x0d\x96\x3a\x30\x91\x95\xc6\x6a\x2a\xe8\x0c\x1e\x65\x84\x93\x1a\x74\x80\xe0\xa3\x58\x23\x29\xaf\x8f\xda\xdd\xbe\x52\x63\x98\x12\x6f\xc8\xff\x7f\xf2\xdf\xff\xf6\xcf\xe1\xe9\x7f\x9e\x9c\xfc\xf9\xd5\xf0\x7f\xff\xe5\xdf\x4e\xfe\x7b\x04\xff\xf8\xd5\xe9\x7f\x9e\xfe\xd3\xff\xf1\x6f\xa7\xa7\x27\x27\x7f\xfe\xf6\xfd\x37\x77\x37\x57\x7f\xe1\xa7\xff\xfc\xb3\x28\xf3\x7b\xfc\xeb\x9f\x27\x7f\x66\x57\x7f\x69\x39\xc8\xe9\xe9\x7f\xfe\xb2\xd5\xf4\xa8\x58\x7c\xd7\xe2\xc0\xe3\x33\xdc\xc1\xc3\xbe\xea\xd5\xc1\x40\xff\x79\x58\x09\x6d\x43\x2e\xcc\x50\xaa\x21\x76\x7f\x43\x8c\x2a\xb7\x1f\x8c\x8a\xa8\xed\x82\xe7\x3e\x1d\xd8\x9b\x8a\xa0\x05\xd2\x7c\x70\x44\xd6\x2c\x51\xcc\x1c\x4a\x83\xc1\xd1\x3c\xff\x68\x98\x64\x7b\xa5\xa6\x52\x6a\x82\x5d\x12\xe0\x55\x71\xde\x89\x92\xf9\x88\x44\x66\xa1\x39\xdc\x64\xba\x76\xf7\x6c\x8b\x96\xeb\x9f\x5e\x09\xfa\xb2\x94\xa0\x5b\xdc\xdf\x47\xd7\x80\x98\x98\x6f\x32\xd3\x34\x6d\xba\x6f\x21\x94\x25\x36\x47\x7b\x01\xca\x48\x52\xc8\xa2\xcc\xa8\x59\x63\xb6\x5b\x61\x9b\x76\xb8\x5f\xdd\x02\xd8\x8d\x06\x3b\xb0\xa3\x72\xf9\x6a\x63\x28\x39\xcf\x32\xc2\x05\x9e\x04\x18\xc0\x5b\xf3\x14\x43\x79\x89\x50\x34\x38\xcf\xed\x14\x1e\x5c\xc0\x4d\x64\x68\xe4\xda\xea\x3a\xca\x80\xc5\x1f\x02\x72\x90\x66\x39\xd3\x18\x17\x55\x58\x4e\xe0\xb6\xe1\x96\x72\x65\xfe\xc5\x8c\x6a\xe3\xa7\x0d\xb3\x31\xf4\x1e\x4c\xa1\x09\x4b\x99\x48\x18\xb8\x20\x94\xac\x5a\xeb\xd8\x0a\x83\x60\xde\x87\x31\x28\x49\xcb\x22\xe3\x89\x85\x9f\x9d\xc9\xea\x31\xae\xf3\xbc\x34\x60\x28\x7e\x2a\x2b\xbe\xdd\xf1\x5b\x9f\xee\x35\x18\xf3\x81\x54\x05\xd1\x3a\x78\x5b\x04\xd5\x5d\xef\x67\xbe\x6f\x47\x78\x83\xb9\x6d\x2b\xa7\x5a\xa2\xb8\x95\x8d\xa1\x4e\x69\x9f\xda\x62\xd8\x8e\xce\xfe\x24\x69\x6c\x07\xfa\xda\x9e\xb6\x76\x30\x2e\x75\xa5\xa7\x6d\xad\x49\x85\x62\x13\xfe\xb9\x03\x3e\x9e\x8b\x4a\x45\xe1\x29\x13\xc6\x2a\x02\x90\x99\xba\x50\xac\x60\x22\x0d\xe1\x7e\xe0\xe0\x25\xea\xeb\x78\xd4\x1b\x23\x94\x32\xba\x1f\xaf\xdb\x55\x52\x4c\x7f\xb6\x7e\xe2\x67\xcb\xed\xfa\xe1\x0f\x96\x90\xe9\x56\xe7\xef\xc6\x3e\x46\x3d\x1a\x9e\xae\x2e\xfd\xb7\x9b\xa4\xd5\xde\xc2\x95\x53\x21\x53\xcc\x71\x6d\x2a\x27\x84\x11\xb9\x5d\xd1\x13\x7c\x0d\x5c\x8b\xe3\x63\x8d\x6e\x09\xba\x39\x50\x23\xba\x19\x3d\x13\x70\xd0\x8e\x28\x85\xac\xae\x54\x60\xf9\x3d\xa3\x5a\xf3\xa9\x18\x16\x32\x85\xbc\xdc\x67\xeb\x10\xa2\xc5\xa1\xea\xe6\xd9\xb4\x15\xaf\x82\x71\xa2\xdd\x36\x7d\x0c\xf6\xb7\x48\xb6\xf0\x19\xe1\x55\xf4\xa3\xb3\xeb\x78\x3f\xfa\x48\x86\xac\x24\xa2\xfd\x60\x9a\x53\x41\xa7\x6c\xe8\x3e\x3e\x0c\x1f\x1f\x86\x6f\xed\x03\xe6\x36\x54\x0b\x4d\x8a\xad\xcb\x42\x1c\xbf\x43\x93\x65\x1a\xca\x43\xa0\xff\xde\x67\x9e\x97\x39\xa1\xb9\x2c\xd1\x45\x6f\x19\x9c\xde\x91\xe5\x20\x00\x5b\x01\x28\xbd\x16\x52\x2d\xa1\x45\x76\x72\xb9\x7b\xa1\x96\xad\x56\x16\xad\x6e\x96\xac\x0e\x16\xac\x9d\x2d\x57\xde\x48\xdd\x1e\x1f\x3f\x7a\xbb\x79\x03\x23\xb9\xd8\x8a\x91\x2a\xe4\xbb\xbf\x9e\x90\x30\x0e\xd7\x44\xe6\xdc\x18\x67\xd0\xa5\xd5\xb1\x1f\x10\x6e\x6a\xd6\x4f\x77\x16\xa0\xde\x03\x96\xc8\x60\x9f\xad\x36\xc5\xc1\x8a\xee\x6f\x2d\x06\xc8\x65\x1f\x38\x66\x87\xa0\x82\xf0\xbc\x40\x67\x56\xc0\xe9\xa1\xd7\xcd\x9c\x93\x41\x7f\x3e\xfa\xf3\xb1\xaa\x93\xee\x22\x8b\xc4\x62\x48\xe5\xc1\x18\xc4\x11\x8b\xd9\xbe\xf0\x0c\x78\x68\x22\x0e\xd9\xb3\x00\x4e\xf4\x5c\x4c\xc9\x47\x06\x96\x81\x5b\x66\xb4\xf3\x89\x84\x1e\x54\xb1\xe5\x10\x33\x6f\x09\x09\xae\xb6\x74\x32\xa9\xb7\x48\x59\x91\xc9\x45\x0e\x92\xed\xb5\x89\xe5\x99\x20\xba\xb0\xbc\xc8\xa8\x61\x41\xb0\xd9\x6c\x6d\xd8\x9b\xf3\x75\x89\xef\x7a\xde\x88\xae\x76\xde\xc1\x2d\x7c\x82\x5f\x7e\x9c\x56\x6b\x8d\xac\xad\xdd\xbd\x8d\xcd\xbd\x65\xbc\x55\x7b\x25\xb0\x95\x51\xfe\xb1\xa3\xa8\x3a\xa9\x63\x6d\x23\xa5\x5e\x7e\x6c\x54\x87\x65\xb7\x8d\x7f\xea\x23\x9e\x36\x81\xba\x5d\xd4\x42\xeb\x88\x85\x56\xfb\xd7\x32\x72\xa9\x8f\x55\xea\xc0\x5f\x1e\x41\xf8\xdb\xba\x97\x46\x66\x0c\x25\xd7\x76\xba\xfb\x5d\xd5\x3e\xd4\x3f\xc3\xeb\xdd\x68\xa4\xa7\xb9\xa5\xb8\xf3\x62\x8b\x3d\x5b\xd5\xbc\x00\xb5\x8c\xa1\x50\xec\xcc\x48\x3f\x2f\xbb\x71\x62\x41\xec\x9e\x19\x57\xf9\x2e\x2a\x05\x67\x14\x5c\xfa\xfc\x21\x60\xdb\x80\x81\xfc\xf4\xc7\xc8\xbf\x3d\xc4\xbf\x04\x0c\xf9\x83\xff\xd7\x1f\xf7\x8c\x5b\x68\xc7\xd8\x70\x4a\x1d\x04\x8c\x2b\xe8\x40\xb8\x48\xe1\x82\xc9\x2d\x15\x20\x80\x63\x59\xf8\xc0\xb2\x7c\xfc\x0b\x06\x52\x39\x33\x17\xdc\x44\x55\x8d\xb5\xbb\x32\x8b\xf4\x2a\x67\x52\xa8\x4e\x06\x23\x1f\xa4\x4b\x4a\xc8\x06\xe4\x06\x6c\xa9\xd5\x1b\x38\x49\x1f\x24\xa6\x27\x5c\x7b\x97\x15\xc3\x6d\x2b\x17\xd9\xca\xe8\x6b\x00\xf9\xb6\x62\xf2\xb8\xb2\x1a\x93\xaf\x30\xb8\x16\x09\xb7\x09\x32\xf7\x6c\x51\x31\x1b\x27\x42\x00\xc9\x1f\x54\x58\xe2\x59\x01\xf2\x8e\xff\xf0\xa6\xac\x7c\xcc\x05\x7e\x0c\x87\xf6\x5b\x01\xa3\x7b\x80\x5a\xc9\x2e\xcb\xf0\x33\x87\x00\x57\x3b\x39\xa3\x06\xb3\xef\x3a\xc8\x18\x81\x4a\xae\x96\x2e\x22\x91\xe2\xea\xc7\x92\x66\xf5\x20\x04\xf7\xca\x35\x5a\xa2\xea\x0f\x3c\x4b\x13\xaa\x9c\x97\x17\x9c\x51\xa2\x25\xee\x1e\x66\xc5\x4b\xa8\x08\xa7\xbd\xda\x23\xac\x83\x48\x0a\xaa\x0c\x4f\xca\x8c\x2a\x62\xcf\xc2\x54\xaa\x56\x81\x02\x5b\x21\x5a\x21\xcd\x2d\x4b\xa4\x48\xbb\x28\x00\x77\xcd\xbe\xcd\xbb\xd6\x82\x29\xee\xd2\xfd\xf1\x9c\x35\x91\xf4\xa4\x6e\xd3\x96\x13\x7f\xaa\xc3\x11\xab\x59\x3e\xaa\x98\x4c\xae\x09\xc7\x7c\xa1\xa7\x11\x79\x0c\xa7\x62\x44\xbe\x5e\x78\x33\x0b\x98\x5c\x5c\x74\x85\x66\xc6\x07\xc2\x78\x94\x75\xc0\xae\x0e\xd4\x44\x2a\x08\x4e\x39\x49\x25\x46\x64\xcc\x79\x62\x4e\x47\xe4\xff\x63\x4a\x62\x04\x27\x9b\x62\xf6\x46\x87\xe2\x41\x71\x85\xc2\xa5\x70\x83\xff\x8a\x9c\x60\x26\x4d\x9e\xe7\x2c\xe5\xd4\xb0\x6c\x71\x8a\x7a\xac\xcf\xc5\xd9\x66\xeb\xda\x18\x0d\xa2\xc4\xab\xbf\xfd\xcd\x86\x96\x5d\x63\xa8\xbe\xf7\x51\x29\x15\x64\xd0\x87\xa0\xb1\x85\x81\x07\xc9\x0d\xe2\x66\xec\x83\x50\x05\x75\x7a\x32\x13\x36\xf8\x6f\x16\x0f\x28\x51\x6c\x0a\x58\x8e\x98\xbb\x27\x8e\xa3\x37\xe5\x7b\x59\x8a\xf5\x26\xc1\xda\xc2\xdf\x39\x25\xfc\xfb\xa8\xe3\xda\x28\xc5\x27\x11\x13\xa2\x99\x44\x26\x4a\x4a\xc0\x2e\x09\xec\xdc\x92\x07\x6c\x55\x79\xa2\x6c\x9d\xe4\x41\x23\x12\x61\x2e\x5b\xbc\xde\x0f\x12\xb7\x18\x3e\xd4\x01\x97\xc1\x41\xdc\x01\xa6\x11\xb7\x67\x1c\x39\x00\xfc\x44\x08\x56\x08\x0a\xdf\x62\xa9\xf7\x62\xc3\x58\x63\xe8\x4a\x8e\xdf\x1c\x1f\x84\xf8\xe2\x72\x94\x2c\xe8\x94\x6e\xcf\x77\x5c\x57\x46\x1a\x5d\x49\xca\x0c\x53\x39\x24\xa6\x9d\xc9\x07\xfc\x1d\xd9\x56\xe1\x5a\x31\x97\xd3\xd7\xae\x76\x26\x35\x70\xa5\x7a\x10\x23\x9c\x5f\xb8\x18\x7d\xa0\x0b\x42\x95\x2c\x45\xea\xa4\xa6\x40\x40\xdf\x37\x3e\xfc\x41\x0a\xa0\x14\xa5\xb6\xb0\xba\xab\x51\xe9\x31\x33\xd4\x1e\x9b\xd7\xa3\xd7\x5b\x72\x4f\xb7\x04\x58\xc7\xb8\x55\x98\x4d\xc3\x52\xe8\xef\xca\xfd\x99\x39\xc8\xbc\x14\xa3\xe9\x77\x22\xeb\x22\xcb\xbd\x47\xf4\x82\xae\x43\x50\xc2\xf8\x04\x6c\xb7\x03\x7c\xf5\xa0\xb8\x61\x11\x79\x3c\x99\xd0\x4c\x43\xc1\xed\x52\x04\x11\xf6\xb4\x2e\x82\x40\x93\x36\x0b\xda\xee\x0f\xa2\xcb\xf1\x9e\xe7\xcc\x1d\x28\x40\xb9\xea\x98\x05\x84\x3b\xd6\x1b\x8e\x5c\x3d\xb8\x93\x9c\x60\x4b\x2b\xb1\x49\x69\x36\x96\x77\x6f\xef\x24\x82\x0b\xb4\x9a\x75\x17\x95\xc4\xc7\x0d\x17\x07\x5c\xed\xd7\x6c\x46\xe7\x4c\x13\xcd\x73\x9e\x51\x95\x41\xac\xe0\x2d\xce\x0f\x8a\xb1\xaf\x8c\x40\xef\x16\xdd\x1c\xcf\x24\x1a\x6e\x2b\xa8\xfd\x3c\x2c\x9c\x80\x46\xf8\x79\x61\x12\x70\x9f\x39\xfc\x73\x92\x95\x9a\xcf\xf7\x3d\x4d\x2e\xfa\x61\x07\x56\xdd\xe4\xd2\x85\x4c\x6f\x0b\x96\x3c\x25\x8f\xae\x6b\x18\x96\x54\xa5\x7e\xd3\x81\x27\xa3\xb2\x4f\xb1\xb0\xfe\x98\x11\x9a\x24\x4c\x6b\xef\x53\xb9\x88\xfd\x3c\xc3\x1a\xbe\x94\x84\x02\xf4\x41\x5f\x65\x54\x1b\x9e\x7c\x9d\xc9\xe4\xfe\xd6\x48\xd5\x29\x66\x7f\x55\xff\x46\x1a\x86\xf3\x1f\x6e\xc9\x25\xd7\xf7\x51\x34\x81\xbb\x34\x8d\xcd\x25\x94\xdc\x97\x63\x96\x31\x73\x7c\xac\x91\xcb\xe5\x34\x99\x71\xc1\x3c\x83\x13\x21\x24\xc5\x29\x7c\x16\xca\x5d\xef\x4c\x5d\xe0\xd3\x99\xc3\xd7\x5f\xd0\x07\xcd\x70\xfa\x63\x3b\x7d\xfb\x33\x6b\x13\x91\x7e\xd0\x7b\x0a\x9c\xcc\xf5\xe5\x81\xee\x20\x26\xfa\xce\xce\xb1\x9b\x71\xfb\x18\x7b\x79\xd5\x61\xc2\x33\xe6\xaa\x0f\xd8\x05\x7b\x1f\x35\x77\x2a\x60\xff\x16\xb2\x24\x0f\x14\x75\x64\xa0\x88\x23\x72\xc7\x8b\x37\xe4\x4a\xe8\x52\xb1\xca\xba\xd1\x1c\x8a\xeb\x2a\xce\xcc\x2b\x57\xb0\xdf\xa8\x80\x58\xba\xe7\x74\x2d\x72\xf5\x99\xe6\x45\xc6\xf4\x1b\x72\xc4\x3e\x9b\xdf\x1c\x0d\xc8\xd1\xe7\x89\xb6\xff\x13\x66\xa2\x8f\x46\xe4\x3a\x0f\xb7\xee\x5c\x4c\x98\x52\xcc\x3b\x42\x61\x07\xcb\x9a\x23\xae\xfb\x28\xe8\xe2\x9c\xea\xac\xec\x96\x4a\xf2\x80\xf9\x28\x2c\xc1\x67\x4a\x49\x15\xfc\xd0\x23\x30\x00\xaf\x49\x64\x5e\x28\x99\xf3\xc8\xcc\x07\xe8\x7e\x50\x6f\x3b\x30\x3e\xb4\x29\xc8\xd1\xc4\x86\xd0\xd1\x23\x44\xf4\x42\xb4\x41\x85\xeb\x89\x77\xa6\x40\x2d\xd2\xa9\xf5\x30\x9c\x6b\x64\x37\xdf\x8d\x62\x09\x59\xbc\xdd\x6f\x43\x40\x1d\x39\x4b\xd9\xfc\x4c\xa7\xf4\xf5\x00\x3e\xa3\x9d\x23\x60\x7d\x4e\x54\x93\xa3\xd7\x47\x23\x72\xeb\x19\xf1\x20\x9e\x63\xd5\x6e\x22\x55\x18\x10\xec\xec\xaf\x8e\xc8\x89\x54\x30\x72\x42\x05\xc9\x18\x9d\x3b\xdb\x32\x1e\xb7\x05\xaa\xbb\xa7\xad\x03\x22\xdb\xc6\x86\xb5\xaf\xbc\xd2\x56\x48\x5d\xde\x44\xdf\xcf\x9b\x00\x54\xe9\x62\x05\x26\x52\xb9\x3c\x20\xa1\x89\x66\x06\x8e\x1e\x17\x35\x15\xfa\x19\x08\x2c\xe9\x18\x4a\xef\xa9\x67\x57\xe8\xf8\x7e\xa0\x03\x09\xfe\x63\xc9\xc8\xf5\x65\x08\xa8\x67\x4a\x73\x6d\xec\x31\x4e\x6b\xac\x8b\x23\x3f\x3b\x39\xcf\xe9\xdf\xa5\x20\x57\x5f\xdf\xba\x09\x9c\x3e\x2b\xa8\xb6\x52\x03\xfa\xf7\x52\x31\xcb\x85\x3b\x30\xf7\xd0\xa7\xc9\xd0\xed\x7b\x72\x49\x0d\x45\xbe\xee\x3c\xad\x44\x45\xca\x2d\xcb\x1e\x73\x91\xba\x9f\x22\x86\xfd\xd4\xbc\xd5\xee\xde\x87\x4d\x62\x52\xdc\xf0\xd3\xc7\xeb\x03\xf1\xe0\x04\x88\xf9\xf4\xbd\x4c\x3b\x33\xe2\xa8\xab\x27\xbe\x7f\xb2\x30\xbd\xc0\xf7\x24\xb7\x63\x12\xab\xbd\x0f\xc8\x47\x46\x53\x62\xcf\xaf\xfb\xe7\x0f\x56\xf7\x6c\x4d\xab\x5a\xb1\x10\x0f\xc0\x8e\xcb\xf0\xdd\xfc\x12\x62\x4f\xf7\xd4\x62\x0e\x1c\x2b\xc7\x4b\xc6\x99\x1c\x13\x77\x1c\x0e\x3d\xf7\x4f\x1f\xaf\x77\x98\xfa\xa7\x8f\xd7\x7e\xe6\xf6\x9f\x72\xf2\x74\x93\xde\x49\x7c\xab\xa4\xb7\xb7\x0d\x71\xab\x62\xc9\x55\xe0\x46\x53\x24\x6b\x2f\x8f\x8d\x0e\x25\x89\x1d\x12\x62\xf7\x5c\xb4\x88\xc2\xad\x9f\x32\xdb\xc7\x2a\x14\xe8\xab\x16\xdd\x23\xde\xce\x28\x84\x3e\x87\x80\x3c\xd8\x67\xbb\xf1\xda\x72\x05\xbf\xe3\x56\x09\x04\xda\x46\x2e\x19\xde\x72\xa6\x6f\xbc\xef\x40\xe8\xb1\xba\xc3\x7b\xf0\xd4\x4c\x1d\x7d\x25\xe8\xb8\x99\x46\x08\x76\x82\x56\x25\x11\x7e\xa2\x73\xca\x33\x3a\xe6\x19\x87\x54\xea\x56\xbb\x8f\xbd\x51\x35\x4c\xf9\xa0\xa7\x7e\x47\x91\x23\x88\x13\x4b\xc6\x2d\x72\x62\x7f\x3b\x03\xe3\xd8\xe9\x08\xa8\x15\x34\x84\x1c\x8d\x0d\xa1\xe4\xe3\x36\xa1\xe4\x60\xf2\x03\xec\x80\x3d\x31\x5d\xb9\xa2\xed\xb3\x92\x2b\xc2\x0f\xb7\x2e\x9f\xdc\x4b\x66\x8c\x18\x6b\xd5\x8a\x35\x02\x7e\x6d\x6d\xd9\x9e\x39\xee\x8b\x5c\xe9\x97\x81\x5c\x24\x44\xb4\xed\xc0\x3f\xab\x8e\x9e\x0f\x81\x92\x04\x1e\x67\x2e\xda\xad\xe6\x9a\x89\xd8\x77\xeb\x68\x8d\x4b\xc1\x84\x5c\xd7\xe2\x5c\x9b\xba\x68\x5d\x92\x36\x78\x8c\xe8\xba\x2a\xdf\xcf\x2f\x0a\x49\x20\xbc\x26\x2d\x70\xb1\xf5\x24\x13\x56\xcc\x26\x5d\xae\xc4\x6d\x87\xb7\xb7\x75\x4b\xe0\x05\x2b\x66\xe4\xed\xed\x8a\x63\x0c\xb0\x87\x59\x6b\xb4\x0f\x1e\x6b\x92\xf1\x09\x33\x7c\xcb\x12\x1e\xe1\x20\xe7\x52\x70\x23\xd5\xfa\x10\x68\xd2\xe9\x70\xfa\xe1\xba\x32\x54\xdf\xcf\xee\x6c\x95\x40\xe4\x7d\xf4\x96\x92\x44\x66\x19\x4b\x8c\x4b\x69\x05\xe0\x0d\xdd\x56\x28\x4f\xcc\xd9\x03\x46\xf7\xbf\x07\xf5\xc9\x29\x4a\x67\xb8\xb9\x67\x1f\xaf\xce\x2f\xdf\x5f\x8d\xf2\xf4\x17\x33\xf9\x30\x34\x72\x58\x6a\x36\xe4\x2d\x32\x94\x3c\x9f\xf7\x22\x3e\x45\xab\x84\x59\x4d\x83\x0c\xe6\xfa\xfa\xce\xc7\x4f\x92\x4f\x1a\xbd\x16\xc0\x76\xe4\xef\xa4\xa4\x34\x03\xa2\xa8\x8b\x91\xa4\xce\xf4\x54\x66\x19\x42\xdb\x28\xc6\x06\xb1\x2d\x66\x63\x68\x48\xe7\x85\xed\x6d\xa8\xa8\x2d\xf0\x71\x65\x88\xa7\x47\xb8\x2e\x1c\x63\xbb\x4c\xb2\x0c\xc5\xaa\x67\x1d\x8e\xb7\xb5\xf7\x68\x38\x33\x33\x0b\xd5\x7b\xb6\x20\xe0\x08\x3c\x91\xca\xe2\x93\xaa\xe3\x06\x33\x09\x2c\xfd\xac\xd4\x4c\x8d\x1c\xdb\x79\x72\xb0\x75\xc8\x22\xb4\x43\xf2\xb6\xd0\x71\x15\xcc\xdc\xeb\x2a\xb3\xaf\x93\xd7\x68\x69\x66\x4c\x18\x2b\xf6\x5b\x5a\xe6\x20\xb3\x12\x88\xce\x0f\xfb\xc9\xa1\xd6\x32\x89\x51\xb7\x94\x43\x7d\x9a\x9e\x2e\x38\x69\x4f\x4d\x57\x74\xb4\x7d\x20\x10\x31\x26\xf3\x21\x96\x4b\xd1\x54\x82\xc3\x06\x66\xa0\xab\x21\x1a\x4d\x73\x2e\x5e\xe0\xe9\x4c\xb8\x48\xb7\xc1\xa1\x61\x00\x83\x1e\x75\x51\xcc\xbd\x73\x06\xfd\x70\x6f\x48\xbd\x26\x85\x01\xef\xee\x06\xb1\x7e\x7f\xd8\xea\xf0\xe5\x0b\xfd\x63\x36\xc4\xaf\x0c\x8b\xb4\x82\x4a\x7f\x19\xb8\x7c\x83\x77\x58\x93\xd2\x13\x5c\xf1\x1d\x68\xb7\xc9\x13\x4b\x43\x8f\xab\xe7\x3e\x09\xa0\xba\xc8\x3c\xfb\x72\xef\x8a\x66\x42\xe1\x7d\xed\x83\xcf\x30\xb3\x19\x9c\x51\xaf\x2f\x43\x41\x7e\xaa\x68\xce\x0c\x53\xe8\x02\xe7\x9c\xea\x84\x8b\x4e\xf8\xae\x60\xe2\xd6\xd0\xe4\xfe\xd0\xa9\x50\x7b\x8e\xfb\x78\x1c\x77\xef\xab\x40\x8f\x08\x2e\x2f\xd2\x22\xbe\x45\xe6\xc2\x71\xa1\x17\x42\x62\x42\x3a\xb2\x2e\x56\x8e\x90\x8e\xaa\xce\x5d\xab\xf4\x64\x68\xd8\x00\x4f\xb7\x90\x5f\x0f\x3c\xf8\x11\x0a\x87\xe1\x86\xed\xcf\x80\x23\x81\xbb\xdc\xa3\x45\x5d\xeb\xd4\x21\xb7\x6f\xc6\xdc\x54\xe7\x5e\x33\x43\x0a\xa6\x72\xee\xc2\xba\xa5\x20\x89\x0b\x0b\x00\xbe\x66\x79\x98\x1b\x2e\xe2\x79\x82\xc8\xc4\x50\x17\x33\x43\xc6\xcc\x3c\x30\x26\xc8\xab\x57\xaf\x5e\x81\x5c\xf2\xea\x77\xbf\xfb\x1d\x81\x3c\x12\x29\x4b\x78\xbe\xdc\x10\x5a\xfd\xaf\xd7\xaf\x47\xe4\xbf\xce\xdf\xbf\x03\xaf\xb2\xc2\x68\x32\x96\x66\xe6\x46\xb6\x0d\x6a\x9d\xf5\x80\xfc\x9f\xdb\xef\x3e\x78\x71\x42\x37\x7e\x05\x15\x24\x2c\xaf\xee\x22\xf8\xea\xb7\xbf\xf9\xcd\x88\x5c\x72\x05\xf1\xc4\x1c\x22\x20\x82\x13\x64\xe1\x1d\x03\xa1\xf0\x50\x33\x82\xdf\x71\x10\xe7\x24\x9c\xf3\xe9\x0c\x00\x60\x0f\x84\x14\x93\x8c\x27\x06\x73\x0a\xe2\xd1\x47\x40\xbb\xba\x48\xd4\x85\x7b\x39\x29\x02\x26\x37\x20\x19\xbf\x67\x64\xa2\xbf\x51\xb2\x2c\xaa\x30\x47\xc5\xb4\x95\x65\x13\x2a\x20\xaa\x04\x06\xab\xf6\x4a\x33\xf3\xac\x4e\x18\x2d\x0d\x41\x35\x1c\x84\x3e\x0d\x01\x65\x10\x72\xab\x0d\x11\x1f\x0a\xca\x83\xe3\x20\xdc\xa9\xd7\x32\xfb\x07\xdd\x33\x8d\x72\xc9\xf9\xd8\x95\x42\xc9\xbf\xe1\x56\x71\xe1\xa3\xa0\x9c\x84\xac\x9d\x4c\xe6\x82\x4e\x45\x64\x73\xf5\x51\xf9\x96\x17\xba\x88\xff\x28\x7e\xea\x7a\x12\x07\xda\x41\x58\x3a\x96\x57\xab\x25\xbe\x5c\xf1\xe5\x2a\x59\xbb\xc5\x26\x8d\xfb\x5a\x8a\xa5\xde\xae\x8e\x8a\x23\x3f\xae\xba\x8e\x0b\x61\xab\xc6\x40\x57\x5c\x17\x00\x14\xd5\x6c\xaa\x25\xa3\xab\x79\xf9\x68\x66\x4a\x07\x1a\xf0\xbc\xb2\xdf\x66\x5a\xbb\x38\xa2\x9c\xaa\x7b\xab\x24\x38\x2a\x30\x02\xaf\x67\x1d\x62\x98\x30\xa0\x6c\x8e\xc6\xf2\x9c\x2e\x6a\x51\x03\xf6\x23\xc7\xa3\xd1\x31\x1e\x13\xa9\x30\x97\x27\xe2\xbc\x7d\xff\x4c\xf1\xd2\x75\xaf\x74\x5a\x60\xd9\x3d\xb0\xe7\xb8\xb2\x25\xb4\xe6\xed\x4c\x1d\xa4\xda\x64\xf0\xed\x58\xb6\xb0\x5b\x7d\xdc\xf6\x75\x71\x87\xb0\x80\x16\x4d\xbb\xd6\xc0\xed\x50\xfb\x76\x5d\xb6\x06\x07\x63\x77\x12\xda\x56\x84\xec\x9c\x0b\x3c\x6f\xc5\xfa\x56\x4c\xf5\x38\x77\x9c\xef\xbb\x6e\x9c\xcf\xc5\xeb\xd5\x8a\x83\xbd\x7c\x56\x77\x3d\xc1\x48\x97\x3a\xe9\x72\xa4\x21\x16\x05\x42\x21\xae\x2a\xec\xe5\x45\x73\xb4\x18\x6d\xba\x25\x9e\xef\xc2\xdd\xf0\x69\x77\x31\x81\x4f\x0d\xd7\xfc\xed\x04\x2e\xda\x91\xd2\xa2\x56\xe0\x23\x43\xbb\x01\xc8\x98\xfe\xf0\x8c\xc8\x7b\x47\x6a\x11\xc9\xe8\x58\xcb\xac\x34\xd8\xb5\xfa\x31\xa6\xc3\x30\xa8\xcf\xb2\x00\xc4\x37\x34\x8b\xa8\xb2\xa9\x4a\x9c\xb5\x23\xd0\xf8\x74\x38\x9c\x7d\xb6\xcf\x47\xcc\xf6\x19\xf2\xd3\xea\x96\xf5\x9a\xf4\xa3\xa5\xd7\x4d\x34\xef\xa2\x5f\x69\x4e\x4e\xaa\x32\x21\xfe\x3a\xfe\x5a\x18\xa6\x26\x34\x61\xa7\xb1\xde\x15\xca\xb1\x04\x17\x21\x1f\x17\x31\xa3\x22\xcd\x50\x00\x4f\x98\x02\xdc\x67\x9f\x0d\x53\x16\x24\x17\xb7\xd7\x24\x55\x7c\xce\x94\x26\x27\x5f\x33\x2b\x2f\x32\x6a\x4a\xc5\x5a\x45\x57\x1d\xd6\xb7\x12\xa6\x71\x28\x4d\x0f\x06\xeb\xea\xaa\x07\x9d\x3c\xe5\x11\xd1\xf9\xaa\xc0\x84\x50\x45\x90\xea\x58\x97\x1d\x59\x54\x02\x02\x0d\x34\x63\x21\x4b\xe5\xac\xe8\x3e\xaf\x6a\x22\x95\x55\x97\x70\x60\xaa\x89\x62\x53\x2b\xcd\x2a\x5f\x6c\x98\x91\x24\x2b\xed\x8b\x83\xba\xb3\xed\xe3\x00\x58\x99\x66\x37\xf9\xea\x4d\x9c\x54\x2d\xe7\x3c\xf5\xac\x12\x6b\x1f\x87\xaa\x86\x05\xd5\x51\xa8\x4d\x94\x81\x3e\x02\x2c\xca\xe8\xc0\x50\x43\x10\x6b\xcd\xd9\x3f\x36\x0a\x4b\xc8\x6d\xd1\xa2\x7c\x44\x17\x22\x2c\x53\x76\x53\x8e\x33\xae\x67\xb7\x3b\x9a\x10\x57\x0d\x81\xce\x0a\x4b\xb7\x7e\x6b\x2d\x89\x9a\x09\xcd\x81\xe5\x59\x32\x6e\x99\x2e\xb7\x72\x94\x04\x20\xfa\xde\x31\x42\x4a\x88\xfe\xc8\x98\xcb\x60\x60\x7f\xfa\x50\xcd\xc3\x05\xa5\x61\xce\x92\x94\x7d\x12\x45\xed\x7d\x42\xb3\x4c\x37\x03\x76\x3d\xc5\x44\xd9\xc3\x07\xaa\xe1\x9e\x72\xbb\xdd\xa1\x32\x4a\x23\xfb\xe5\xda\x85\x69\x92\x4b\x0c\xe3\x11\x44\x0a\xdf\x08\x52\xaf\xf8\x0e\x51\x20\x23\x84\x2b\x03\xca\x1c\xb8\x74\x64\x6f\x2e\x7d\x3c\x73\xe9\xbe\x7e\x78\x71\xbd\xf7\x2a\x1a\xba\x96\x96\x34\x90\x52\x4f\x72\xb7\x38\x75\x1c\xf4\x5a\x01\xbf\x79\x6e\x8c\xe2\xe3\xd2\x74\xcf\xf7\xd6\xe8\x0e\x6c\xda\x2a\x22\x70\x8a\x87\x6e\xf5\x49\x84\xa2\x4e\x43\x08\x67\x61\xf9\xec\x57\x3c\x07\xd8\x0d\xbe\x3c\xd6\x24\x95\x49\x19\xf2\xc2\x02\xd0\xaa\x0b\xb4\x36\xd9\x13\x49\xd7\x73\xd5\x3d\xa5\x57\xfc\x91\xad\xe8\x95\xca\x07\xf1\x40\x55\x7a\x7e\xb3\xc5\xfb\xbe\xce\xce\xab\x5e\xb1\xa0\xe4\x5f\x43\x15\x40\x3a\x96\xa5\xa9\x52\x87\xfe\x74\xec\xd5\xab\xd4\x74\x23\x2d\x69\x68\x69\x8f\xee\xaa\xe8\xf7\x26\xee\xde\xc4\x5d\x7b\x76\x31\x71\x5f\xa3\x89\x3b\xce\x83\x5b\x3b\xae\x3e\xbd\x02\xcf\xda\xfa\xf6\x3e\xa6\x95\xf4\xb2\x22\x30\x28\x4d\x35\xfd\xf8\x1b\x02\x1c\x1e\x91\x6a\x6f\x23\xa1\xcf\x53\x20\xe0\xd9\xcf\x6f\x51\x7d\x24\x3b\x69\xfb\x3a\xc5\xf8\xac\x2b\x24\xb8\xa9\x6e\x31\x48\x0d\x51\xa1\xe1\x81\xcb\x02\x3d\x70\x7a\x97\x48\xab\x12\x7e\x98\x84\xba\x43\x99\x52\x7c\x3a\x02\x9f\x74\xde\x00\xd2\xb1\x88\x30\x3e\x5d\x77\x83\xec\x50\x50\x18\x9f\x67\x2e\x2b\x8c\x4f\x67\xdb\x37\xe9\x5e\x62\x78\xc5\x72\x1f\xb7\xd0\xf0\x8e\x4b\xdb\xdd\xac\xbf\xab\x39\x7f\x50\x95\xb7\x7b\xf9\x6c\xbd\x37\xe7\x2f\x3d\x4f\x68\xce\x8f\x08\xb7\x27\x06\x2b\x4c\xfb\xb1\xb9\xcd\xdb\xf7\xc7\xcc\x8b\x95\xa3\x2a\xfb\x9a\x45\x39\x6f\xd9\x97\xaa\x7e\xad\x7a\x3c\x1a\x1d\x1f\x7b\x7b\xbf\xc3\xcf\xd2\x4c\x86\xbf\x27\x4c\x24\x32\xc5\x4d\xb5\xe3\x2b\x6d\x80\xe9\x57\x6a\x7a\x3c\x97\xdc\x7f\x2b\xbe\x9a\x85\xb1\xbb\x6d\x49\x87\x13\xdc\xbd\x6c\xf8\x2a\x48\x3f\x45\xf1\xf0\xb8\x44\x78\xbd\x22\x38\xb6\xd8\xa7\x0c\x78\x0c\xbc\x47\xe7\xaf\xad\x0b\x83\xe3\xb3\x0b\x7b\xdd\xa1\x48\x38\x3e\x4f\x5c\x2a\x1c\x9f\x9d\x38\x6a\xa7\xb2\xe1\x2b\x16\xf7\x74\xc5\xc3\xf1\x79\xa1\x85\x64\xea\x4f\xa7\x42\xe2\xf8\xec\x56\x4e\xbc\xde\xb7\xe3\xd6\x1f\xa4\xb4\x38\x3e\xdd\x0a\x8c\xe3\x73\xe8\x32\xe3\xf8\xb4\x84\x04\x18\xc3\x2f\x79\xa7\x50\x04\xdf\xa7\xee\x2e\x69\x58\x5e\x48\x45\xd5\x82\xa4\xce\xd6\xb0\x58\x11\x11\x1a\x85\x84\xee\x9d\x1a\x06\xe6\x91\x72\x75\xa0\x68\x84\x0e\xd1\xa0\x2c\xe5\xe5\xda\x72\xcd\xeb\xc0\x86\xbd\x62\xa0\x3d\x40\x36\x30\x97\x49\xcc\x5f\x77\xba\x66\x3e\xb1\x22\x4d\xee\x5d\xc5\x20\x0f\x55\xe4\xfd\x51\x90\xcb\xd1\x51\x23\x0f\x34\x98\xc7\xe0\xee\xcf\x55\x46\xf4\x8d\x71\xec\x9a\x29\x0b\x6f\x43\x9c\x5b\xc0\x89\x6b\x78\x6a\x25\x92\xf7\xc0\x06\x9f\x68\x97\x48\xc7\xc8\x36\xfe\x77\x06\xe5\xc6\x3a\xfb\xc6\xfb\x8e\x21\x1d\xb4\x04\xc9\x3c\xd4\x45\xcb\x64\x12\xdd\x3d\xd7\x38\x14\x6c\xc3\x95\x47\x7e\x6f\xbb\xb7\x9b\x61\x47\x45\xf9\x02\x8c\x3e\x99\xc6\x7b\x3d\x9e\x40\x6a\x4b\x90\xe2\x01\x98\x61\x03\xee\xa2\x2a\x81\xa5\xb6\x5f\x82\xcc\xf3\x51\x9b\xea\x43\x0f\x3e\xc3\xa6\x89\x0a\xb9\xd5\x75\x0f\xfb\xcb\x6d\x58\x59\xa5\xb7\x41\x08\x84\x17\xd4\x75\x09\x62\xa2\xfb\x8a\x13\x97\xe4\x04\xee\xae\xaa\xb2\x68\x21\xb9\xe3\x12\x9a\x09\x9e\xd5\xf1\xcc\xe7\xb2\x0b\x0b\x2f\x85\x73\x34\x58\x42\x9a\xd5\x38\x53\x6a\xa6\x86\xd3\x92\xa7\xbb\x60\xcb\x0b\x66\x80\xad\xd9\x5e\x77\x66\xd7\x91\xc5\xed\xc1\xd8\x82\x23\x46\x07\xd6\x70\x54\x79\x6f\xd4\x78\x43\x9c\x16\xaf\xee\xc9\x41\xbd\xb3\x40\x38\x72\xfe\x4a\xe8\x2e\xa8\xb6\x8e\x67\x24\x8b\xc4\x05\xeb\xf2\x5a\xba\x4b\x1c\x16\x31\x0f\x1c\x5b\x87\xf6\x3f\x5e\x05\xf6\xf6\xfc\x31\x9b\xc8\xaa\x42\x0a\x6a\x44\xce\x1d\x37\x65\x19\x83\x32\xf2\xbe\x44\xbd\x6d\x00\x57\xc2\xb9\x9c\x5b\x64\xfe\x6f\x41\x3e\xf9\x9c\xfd\x7c\xf2\x86\xd0\xd3\x5a\x08\x84\xab\x3a\x23\x18\x4b\xd1\x47\x37\xab\xbe\xa3\x4a\xa1\x07\x64\x7c\xea\xfd\x51\xe0\xc4\x09\x2b\x16\x66\x5e\xe2\x45\xbd\x5a\x31\x0b\x00\x08\x3b\x56\x32\x27\x5a\xd0\x42\xcf\xa4\x01\xd5\x90\x16\x34\xe1\x66\x41\x8c\xa2\xc9\x3d\x94\x28\x52\xcc\x7d\x6e\x40\x92\x53\xe7\xd8\x15\x83\xaf\xee\x36\x6c\x66\x4a\x96\xd3\x19\x78\xc2\x62\xab\x24\xa3\xda\xaf\x7e\x65\x7f\xa7\xed\x68\x92\x2e\x04\xcd\x79\x12\xb2\x06\x2a\x39\xe7\x9a\x4b\x67\xed\xf5\xe3\xde\x84\xcc\x70\x68\x41\xbe\xc8\x28\xcf\xc9\x89\x66\x8c\x5c\x79\x94\xc0\x5f\x5c\x19\x7b\xb4\x6c\xa8\xba\x73\x80\x0c\x29\xcd\x85\x4b\x88\x50\x11\xb8\x70\x79\x85\x0c\xd3\xce\x7c\xe5\x47\x4f\xc3\x76\xad\x9e\x93\x54\x70\x71\xef\x53\x77\x32\x91\xca\xe8\xd6\xf2\xfc\xe6\x5a\xc7\xda\x08\xe2\x96\xcb\x7b\x07\x3f\x64\x52\x4c\xe3\x34\x02\x15\x66\x5a\x52\x2a\xa0\xbc\xcb\x9c\xa7\x25\xcd\x90\x88\xba\xc9\x5c\xdc\x5e\x63\x77\x3e\x9d\x99\xe1\x03\x03\x6b\x0c\xf2\x9a\xea\xcc\xf8\x8f\xf2\x25\x6f\x1d\xae\x81\xe8\x1a\x67\x4d\x40\xcb\x96\x9d\xda\x03\x5d\x40\xda\x1a\xe7\x62\x52\xbb\x30\xf5\x89\xc5\x70\x88\x55\x10\x87\xe9\x9d\x87\x72\x1d\x56\x6c\x00\x73\x95\x05\x31\x60\xea\xf2\xdc\x2c\xe0\xa3\x3c\x80\xe1\xb5\xab\xcc\x46\xed\x06\x59\xe1\x6e\xb3\x2e\xf3\x08\x42\xd9\xbc\xda\xe4\x3b\x57\x3a\xb1\xa3\x70\x70\xf4\x43\x64\x36\x8b\x2e\x3a\xec\xb1\xa1\x22\x1d\xd2\xcc\x62\xce\xcd\xf7\x17\xce\xc3\x19\x0f\x42\xed\x22\xdf\x57\x41\xe2\x22\xa4\xcd\xb6\x32\xc3\xca\x23\x00\x71\xf0\x63\x96\x02\xd1\x88\x0b\x46\x3e\x58\x0d\xd9\x6d\xde\xcd\xf7\x17\x03\xc2\x47\x6c\xe4\xff\x0a\x4d\x3d\xd5\x32\x72\x8a\x6e\x80\xc1\xc7\x13\xf0\x0e\xa6\x12\x1b\xa3\xe2\xbe\x7f\xfd\x83\x9d\xa4\xfd\xf5\x8f\xc3\x3f\x44\xd9\x46\xff\xf8\x57\x4b\x04\x95\x6d\x50\x7f\x1b\xfb\x92\x85\xac\xfb\x7f\xbd\x71\x59\xa9\x5d\xce\xea\xbf\xba\x62\x5c\x4c\x18\x2b\x37\xde\x48\xb8\xa5\xe7\x29\x62\x23\x7c\x5b\xb1\xbf\x79\xc3\x22\x80\x29\x18\x75\x12\x6a\x98\x00\x42\xed\x83\x32\x84\x34\xd8\xdd\xd5\x9d\xb5\xf3\x3f\x01\x93\x00\x06\x95\x0d\x88\x91\x12\x8e\x23\x1e\xf9\x73\x41\x98\xaf\xd5\x89\x6b\x05\x70\x50\xe7\xa8\xe6\x79\x8f\x1d\xd6\x42\x38\x84\xe0\xda\x79\xc0\xdc\x7e\x25\xa4\xf9\x55\xd8\xfe\x46\x15\x71\x3a\x97\xdc\x27\x20\xb7\x27\x45\x60\x45\xc7\x90\x12\x7b\xbc\x20\x39\xd7\x86\xde\xb3\x11\xb9\xb5\xbc\x25\xbe\x0d\x43\xe8\x09\x02\x19\x2c\x59\x4a\x4a\x61\x78\x06\xbf\x56\xe3\xd8\x29\xc7\x3c\xe7\x7a\x42\x74\x09\xe5\xcd\x0b\xc5\x86\x9e\x8b\xb9\x56\x4b\xb4\xa0\x5a\xcb\x20\x6c\xf6\x8c\xa2\x2e\x50\xa4\xd0\x15\xe0\x41\x85\x43\xaf\x25\x3f\x2e\x3b\x4f\x29\x92\x8a\x73\x01\x30\xf5\x88\x7c\x00\x66\x95\xf9\x2b\x61\x54\x4b\x9c\x01\x53\xb0\x84\x69\x4d\xd5\x62\x00\x89\xdd\x79\x48\x06\xee\x5c\x77\x80\xa3\xe6\x54\x60\x5a\x75\xc5\x12\x29\xb4\x51\x65\x62\xb0\xce\xde\x58\xc9\x7b\x26\x82\xbb\xa0\xdd\xc5\xba\x03\x57\xe5\x3f\x03\xf7\x5d\x92\x24\x33\x2a\xa6\x51\x9d\x9a\x9c\xa6\x00\xfb\x6f\x83\x94\xe3\xd7\x63\x21\x40\x27\x56\xb0\xe0\x06\x40\x31\xb6\x7c\x24\x98\x61\xff\x5b\x84\x7c\x3c\x83\xca\x4e\x6a\x97\xc4\xb3\x2d\xb4\xab\x13\xfd\x22\x1d\x8d\x7a\x43\x60\xdb\x07\x76\x00\xcb\x99\xa1\x29\x35\x74\x07\x27\xb0\xf7\x55\x71\x3d\x5f\x5f\x1f\x0b\x9c\x86\x8b\x49\xc7\x87\xbc\xb8\x25\x0b\x1e\xc7\x3f\xc1\x49\x9c\x79\xc8\x43\xc4\xb5\xb1\x38\xe5\x2e\x0a\xd0\xb7\x0b\xe4\x19\x5f\xbd\xcc\x0e\xef\x47\x43\x72\x51\x95\x66\xac\xc8\x49\xbb\x6b\xa8\x8e\x16\x58\x0b\xfa\x1d\x60\x74\x57\xdd\x95\x25\x75\xff\xae\x95\x22\x08\x72\x09\x26\x0c\x57\x2c\x0e\x37\x73\xa0\x2b\x05\x22\x79\x03\x88\x00\xe5\x29\x33\xba\xf2\x50\x41\x3a\x6c\x89\x8b\xe3\x77\x4e\x19\x05\x22\xed\x00\xeb\xf4\xb9\xd5\xb2\x10\x82\x5d\x4b\x47\x67\x2d\xe5\x7f\x14\xb8\xee\x62\x74\xc6\x72\x02\xef\x65\xda\xc5\x4e\xdd\xc8\xc2\x5f\x0d\x51\xf9\x6f\xa2\x27\xae\x06\xa5\x1e\x1b\xc0\x6d\x95\xae\x05\xcd\x21\x91\x9b\xd1\xf9\xee\x46\xaa\x4a\x46\x1a\x86\x54\xc6\xf0\xb9\x21\x7c\x6e\xf8\xba\xbd\x31\xaf\x8b\x07\x88\x7f\x5a\x7b\x82\xd4\x3f\xd2\xc9\x72\x6a\x49\xca\x6d\x47\x73\x67\x23\x1a\x39\x8c\xe0\x68\xbe\xbb\x45\x0c\x37\xb7\x2e\xd2\x81\x71\x4b\x2d\xde\x90\x5f\xd5\xb8\xbc\x93\xa6\x82\xa6\x84\x9e\xba\x27\x5e\x75\x1a\xb9\xad\xf0\xc1\xe7\xf5\xe6\xa7\x8d\xc1\x40\xbc\x58\xad\x51\x78\x8f\xe0\x20\xf2\x59\xf1\x4c\x81\xf1\xcc\xc7\x1f\x58\xf4\x52\x32\xcb\x98\x82\x25\x38\xed\xa9\x71\x8b\x0e\xb9\x4c\xd1\xa6\x3b\x08\x2a\x6a\x90\x31\x05\x7b\x08\xc2\x04\xd5\x98\xba\xc5\xdf\x78\x31\x57\x38\x6f\xed\x78\xc1\x6b\xf9\x5c\x2c\x70\xea\x97\x11\x68\x51\xf5\x24\x53\xfb\x21\x2b\x75\x0a\x3a\xce\xf0\xf6\x38\x30\x5b\x98\x0b\xcd\x1e\xe8\x42\x03\xde\x57\xd2\x7c\xf8\xbe\xcb\xaa\x56\x0d\xfc\x91\x4d\xb0\x77\xeb\x1b\xb1\x9d\xee\xc4\x76\xb9\x15\x83\x70\x4a\x2e\xda\xb8\x20\x55\x1d\x36\x16\x0e\x69\x3e\xbb\x5c\xa3\x81\x9f\x0a\x5c\x9f\x77\xbb\x13\xa9\xd7\x29\xbf\xb9\x86\x21\xbc\x4c\x3e\x85\x3f\x3c\xc7\x09\x97\x06\x63\x66\xb1\xba\x0a\x94\x06\x0c\x89\xfb\xae\xf0\x24\xa8\x50\xeb\x5b\xc8\xc6\xea\xac\xc4\xa1\xd2\x98\x62\xe0\x09\x02\x5f\x1c\x41\x39\x02\x2a\x16\x8e\x93\x9b\x19\x57\xe9\xb0\xa0\xca\x2c\x50\x7d\x1c\xd4\xbe\x16\xdc\xeb\x3b\x2d\x7c\xc7\xeb\x9c\x76\xa9\x8f\xd7\x42\x18\x16\xef\xcd\xc3\xce\x3a\xbf\x16\xae\x4f\xb1\x9e\xf6\x0e\xfc\x2b\xd7\x13\xa7\x16\xf5\x1a\xe1\xb3\xad\x27\x8d\xc9\xc7\xfe\x7c\xc3\xd2\x20\x5d\xbf\x7a\x45\x36\x10\x97\xae\x92\xb1\x17\x74\xe0\xf2\xa0\x10\xd9\x91\x06\x56\x0f\xa5\x55\xad\xf1\xc8\xb0\xe7\x24\x05\xef\x43\xe3\x2a\x1d\x89\x85\x33\xdd\xc4\xdf\x8a\x07\x08\xa7\x84\x9c\x08\x29\xf0\xe4\x60\xdb\x53\x74\x21\x5a\x63\x9b\x82\x26\xae\x44\x5d\xbd\x42\x68\x74\x52\x3d\x93\xe0\x22\xb5\x5b\x07\x94\x1b\x74\x24\x5d\x26\x09\x63\x41\xab\x8e\x4b\xd4\x54\x27\xdb\x4d\xd9\x97\xba\xd4\x12\x92\xb8\x68\x43\xb3\xac\xd2\x66\x1d\xb8\x24\xf0\x39\x6f\x01\x8c\xd8\x5f\x2d\xd0\xc6\x29\xf6\x50\x44\x1d\xdd\x5e\x4a\x91\xe0\x15\x3e\x37\x0b\x3f\x83\xcb\x26\xab\x07\x35\x42\xa3\x92\xcb\x27\x68\x77\x8a\xd4\x81\x00\x4c\x20\x4d\xae\x84\x7b\x9d\x33\xb9\xdc\x0c\x96\x0e\x8d\x69\x72\xff\x40\x55\x0a\xa5\x7c\x0b\x6a\x38\xa6\x05\x1f\xd4\x86\x3d\x89\xe6\x00\x85\xf4\x63\x2c\x3a\x0d\x4a\x87\x66\x21\x05\x75\xf5\x19\x42\x4b\x23\x73\x6a\x78\x02\xaa\x2c\x9f\x44\x56\xc4\x3c\xa4\x34\x6c\x94\x1d\x04\x2a\x1b\x0a\xd8\xdf\xe1\x6d\x8c\x62\xc4\x3c\x48\xc2\x73\x2b\x21\x50\x28\xa5\x31\x09\x11\x43\xde\xde\xb9\x69\xa6\x56\x0c\xfa\x01\x8c\xcc\x51\x2b\x54\x92\xad\x0a\xa5\x61\xf8\x60\xd1\x0c\xa6\x3c\x17\x72\x33\x68\x30\x70\xd7\xc7\xe2\xb4\x9d\x6b\x84\xaa\x03\xbb\x3d\x0f\xcc\xca\x05\x7a\x23\xc2\xea\xd1\xaa\x19\x61\x4d\x5b\x4d\x52\xae\x1b\x85\xa9\x4f\x52\x25\x8b\xc2\x19\x48\xf2\xd3\xe6\x8c\xe0\xde\x40\xcd\x99\x8e\x6a\x2f\xa3\xa9\x7a\xca\x44\x28\x1e\xee\xd2\x59\xc0\xc9\x6d\x7e\xa2\x76\x60\x46\x18\x10\x7a\x4a\x3e\xb9\xa2\x42\x01\x71\x83\xd7\x5d\x2b\xc1\x09\xad\x2d\x4e\x76\xea\x25\x9e\xb6\x4f\x2f\xf1\xf4\x12\xcf\xcf\x5b\xe2\x09\xee\x5e\xbb\x4a\x3b\x95\x8f\x63\xa3\x20\xb9\x77\x06\xa8\x1a\xac\x33\x62\x5c\x4f\xc8\x47\x96\xc8\x39\x53\x48\xe4\xa0\xf0\xa7\xe5\xe5\x6f\x29\xcf\x2c\x89\xf3\xa4\xae\x52\x0f\x21\xa3\x6a\xdd\x34\x17\x69\xe4\x01\x9a\x0e\xcd\x73\x37\x29\x17\xe9\x67\xdb\xbb\x4b\xb2\x42\xb1\x39\x97\xa5\xf6\x2e\x0b\xa5\xc1\x63\xa6\x8d\xe3\xb7\x33\x3e\x0d\x89\xb9\xc3\x55\xa7\x62\x89\x54\x69\x15\x52\xae\x0d\x35\xa5\xae\xc7\x49\x24\x68\x4d\x3b\x9c\x81\x26\xc0\xf1\x91\xa9\xfb\x6e\x94\x14\x3d\x36\xf6\x38\x15\xc7\xef\xd0\xe7\xa3\xaa\xbb\x6d\x22\x37\x94\xca\x05\xc6\x8a\x50\xa5\x61\x11\x5a\x39\x04\xe8\x0c\xeb\x5a\xd4\xeb\x19\x16\x6e\x19\x86\x61\x87\x95\xd7\x49\x8b\x8c\xeb\xf1\xb3\x13\xd4\xc9\x1e\x01\x9e\xf1\xf3\x82\x1d\x4f\x1a\x8b\xed\xee\x7d\x49\xf6\xf4\xc0\x24\xfb\x78\x61\x92\x43\x7a\x62\x92\xe0\xcf\xbd\xcf\x89\xf9\xe8\x3d\xc9\x1b\x67\xc6\x11\xde\x4d\x67\xa6\x96\x50\x20\x8c\xc3\xb5\xaf\x00\xe9\xae\x35\xc3\x19\x00\x93\x60\xec\x0f\xec\x4e\x2b\x68\x73\x78\x77\xc9\x3e\x87\xac\xbf\x91\x1c\x53\x15\xd5\x36\x12\x3c\x10\xf2\x02\x33\x01\xc1\xa9\x1b\x3a\x97\x2c\xaf\x2d\xf5\x27\xb8\x3f\xc1\x6d\xfb\x3f\xe7\x09\x46\x8f\xe7\x2e\x0e\xf9\x8d\x4a\x41\xd8\xdd\x05\xe1\xd2\x31\xcb\xc8\x8f\x25\x53\x0b\x62\x85\xa0\xca\xbd\x07\xd2\x1b\x6b\x9e\x3a\x07\x19\x67\x54\x69\x2f\xb3\x3f\x21\xff\x07\x93\xcd\xd5\x67\x2b\x01\x42\x1c\xdb\x1e\x74\xad\x39\x54\x3d\x54\x19\xa1\x15\x20\x18\x4b\x78\x78\xc3\x58\x93\xf9\xac\xb8\x77\xfe\xe1\x72\x37\x45\xa7\xdb\xa5\x16\xd9\xe5\x62\x6b\x69\xf1\xe7\x1b\x16\x88\x80\x08\xbf\xd4\xab\x49\x05\x53\x04\xb9\x67\x8b\x81\xbb\x07\x77\xd9\xdb\x7d\x63\x74\xe7\xa8\xa7\x14\x6d\x9b\xaa\x62\x15\x80\x76\xa0\x90\xbb\x59\x0f\xf0\x69\x9f\x84\xb2\xde\xcb\x03\xa1\x2b\x21\xde\x99\x84\x77\x4a\x56\x19\x3f\xeb\x12\x57\x22\x4e\x40\x06\x3e\xef\xd7\x1c\xd0\x00\x7c\xb9\x81\x5a\x74\xdd\x44\xb2\xbb\x0a\x8c\x8f\x07\xec\xde\x4b\x0d\x68\x5a\x73\xcc\xbd\x67\x8b\x63\xed\xa2\x06\xa5\xd0\x33\x5e\xf8\xfc\xf0\x40\x09\x1c\xe6\x92\xef\xc1\x3f\xc0\x0f\x81\x67\xfe\x5a\x0c\xc8\x07\x69\xec\xff\xae\xc0\x55\x08\x2d\x95\x92\xe9\x0f\xd2\xc0\x9b\x27\x07\x16\x4e\x77\x6f\x50\x39\x33\x25\x07\x33\x23\xba\xb4\x41\x7c\x86\x77\x41\x01\x90\xb8\xfb\xd6\x00\x56\xae\xc9\xb5\x20\x52\x79\x98\x18\x9f\x3c\x58\xbb\x21\xbc\x6d\x29\xb2\x08\xaf\x18\xc3\x81\x52\xaa\x1a\x24\x37\x0c\x17\x8c\xcb\xdc\xff\x02\xb6\x27\xb0\xc6\x07\xbf\x19\x48\x81\x4b\x0d\x9b\xf2\x84\xe4\x4c\x4d\x21\x3e\x34\x99\xed\xbe\x41\xdd\xe9\x36\x3e\x3b\x51\xef\xf8\xc3\x9d\x31\x03\x58\xdd\x3b\xf0\x5c\xda\x97\x61\xe2\x28\xc8\x22\x72\x5a\x58\xa4\xf8\x87\xe5\x04\xb0\x2f\xff\x82\x94\xd5\x7a\x44\xce\x7d\xc1\xd3\xf8\x37\x67\xc5\x88\x87\xb1\x23\x58\x99\xfe\xc7\x92\xcf\x69\xc6\xd0\x9f\x8f\x8a\x90\xc6\x53\x4e\x96\xd8\xf4\xc0\xe5\xad\xb6\x54\x2a\xdc\x0c\x1d\xdd\xb3\xc5\xd1\x60\x09\x91\x8e\xae\xc5\x51\x15\xa4\x5d\x43\x9d\xc0\xd0\xe0\xd2\xe0\x08\x7e\x3b\x3a\x34\x67\x7f\x26\xd1\x7e\x07\x2c\x71\x06\xa1\x8b\x8c\x6a\xdd\x2d\xbe\xb5\x11\x5a\xd4\x18\x67\x55\x02\xc6\xdb\xa8\x4d\x15\x5c\xe4\xbc\x37\x0f\x6e\xcf\x02\x2f\xff\xee\x9e\x46\x9d\xa0\x37\x77\xd5\x53\xda\x27\x6e\x58\x99\x50\x0c\xd2\x16\xf8\x18\x8e\x5a\x5c\x5c\x75\x19\xbb\x06\x5e\xdf\x83\x5d\x51\x4e\xe2\x22\xcf\x5c\x83\x1a\xcc\x7d\x54\x87\x90\x86\x70\x91\x64\xa5\x33\x29\x42\x57\x50\xa2\xbb\x8a\xfa\x3b\x00\x67\x0f\xa4\xaa\x06\xf0\xd8\xe4\xaf\x7d\x97\x1c\x78\x9b\x37\x74\x70\x27\x1a\x6e\xbc\x10\x56\x87\x5e\xeb\x64\x8b\xbb\x64\x3d\x19\x67\x52\x97\x3d\xde\xf2\xb1\x62\xe4\x62\x46\x85\x60\x59\x14\xed\xea\x8c\x1d\xa1\x9c\x15\x08\x24\xae\x88\xd5\x71\xbd\x8a\x95\xa7\x6f\x22\xc4\x56\x1f\xbc\x76\xf0\x4f\xa9\xa8\xd4\xc1\xea\x94\xbb\x54\x8d\x33\xf9\x40\x52\x49\x1e\xa0\x6e\xc1\xdc\x32\x2d\xb8\x94\xd5\x9e\xdd\x45\x33\x05\x17\x89\x44\xe6\x85\x92\x39\xd7\xde\x39\xde\x6d\xe3\x41\x43\x43\xb3\xb2\x45\x0e\xa0\xfa\x1e\x64\xa5\xa8\xa7\x84\x7f\x7b\x41\x0c\x55\x53\x66\xec\x68\x44\x94\xf9\x98\xb5\x8e\x5f\x7d\x8c\x1c\x64\x5f\x52\x09\xd1\xc3\x16\xc1\xc2\x6d\xf8\xe1\x87\x0f\x9d\x4b\xef\x56\x3d\xd7\xed\xed\x83\x54\x59\xfa\xc0\x53\x64\xd1\x9a\x9c\xd8\xc6\xa7\x2f\xbf\x52\xee\xc3\x03\x4f\x3b\x83\x03\x3a\xd5\xc1\xe0\xfd\xa0\x2c\x18\x08\xc0\xc1\x55\x78\xe2\x90\x46\x1b\x7a\x9c\x92\x2b\x8e\xd1\x45\xd0\x1f\x12\xd5\xe4\x63\x2e\xaa\x08\xb3\x0a\xcc\x96\x18\xdb\xf3\xe2\x55\x13\xcd\x0c\xc6\x85\x40\x68\x85\x34\x33\xa2\x79\x5e\x66\x86\x0a\x26\x4b\x9d\x2d\x5a\xa3\xca\xf3\x80\x7a\x92\xb1\xcf\x88\xd9\x5d\x98\x5c\xe8\x54\x67\x76\xe0\xba\x52\x85\x51\x2e\x71\xbb\xca\xb9\x2a\x3d\x0b\x9c\x2f\x84\x1b\xb1\xcf\x2c\x71\x5e\xc1\x45\x56\x4e\xf9\x96\xf0\x87\x9f\x59\x56\xf3\x2a\x81\x74\xa9\x59\x15\xa9\xdf\xb6\xae\xcb\x13\x25\x21\x7f\x5e\x0e\x7f\xb7\x3a\x01\x79\xca\x0a\x26\x52\x48\x89\xf6\xb6\xc2\x5c\x9c\xfc\x41\x21\xe7\xd2\x8b\x75\xa5\x5a\x3e\x2b\x59\x8d\x82\x47\x2e\x5c\x33\x99\xa5\x9a\xb0\xcf\x46\x51\x4b\x98\x72\x4b\x82\x42\x9f\x09\xa1\xa2\x3d\x91\x79\x19\x29\x82\xc9\xc1\xb9\xfd\xe3\xd6\xcb\x7c\x89\x25\x2f\xab\xb5\xeb\x8d\x05\xab\xf7\x4b\x5d\x8f\x84\xd8\x9d\x15\x5d\xf7\x10\x5e\x91\x62\xde\x7d\xa5\xee\x99\xb8\x5f\xaa\x79\xbd\x22\xa9\x76\x63\x56\x7d\x99\xce\x2f\x22\xef\xfc\x04\x02\x83\xbb\x24\x61\x72\x3d\x1a\x1a\xb5\x7b\xd9\x2c\x08\xbd\x41\x83\x76\x78\x1b\xf1\x01\xc8\x78\xea\x06\x72\x61\x4d\x44\x5b\x58\x56\xae\x73\xa5\x10\xdb\xa8\xd8\x63\x64\x11\xa7\x86\x6a\x66\xda\x59\x53\xea\xa2\x43\xd5\xd3\x1e\xc0\x18\xbf\xdc\x4f\x98\xc5\x1e\x1c\xd2\x7d\xb0\x2c\x19\xfe\xd1\x49\x19\xa2\xd6\xd2\xca\x17\x1e\x3e\x3e\x49\x13\x0b\xb7\xc8\x38\x46\x6a\x77\x25\xa1\xa6\x75\xc9\x9d\x56\x7c\xc1\xcd\xe0\xd3\xa7\xce\xb5\x5c\xa3\x9e\x5e\x0e\x81\x7f\xd7\x81\xe0\x70\x01\x12\xf9\xf0\x1f\xcb\x58\x1d\x80\xe4\x16\x61\xd9\xae\xfd\xa1\xd6\x36\x4d\x58\x65\xbc\xba\xe4\xfa\xbe\x4b\x32\xb2\xa5\xce\xf5\x23\xf1\xcd\xc5\x15\x71\x6f\x5b\xd9\x97\xba\x18\x98\xf6\xcd\x8c\x35\x4d\x58\x65\xb4\x4d\xb9\xbe\x7f\xf2\xb2\xea\x45\xfa\x61\x9b\x07\xf8\xd3\xd9\xbf\x9a\x52\xaf\x4f\xd1\x12\xe5\x0e\x5a\xc8\x92\x3c\xb8\xd4\x07\x4e\x6a\xbe\xe3\xc5\x1b\x72\x25\x74\xa9\x58\x75\x73\xdb\x1c\xca\x72\xdd\x97\x54\x7a\x7d\x2f\x2c\x79\xc9\xc6\xb7\x82\x2a\x03\xe2\x71\x57\x34\x08\x1d\x3d\x7d\x8a\x5e\x88\x36\x78\x70\x3d\xf1\x8e\x75\x03\x17\xe3\x1d\x12\x97\xf9\x46\x76\xe7\xa3\xb4\x26\xf1\x5e\xbf\x0d\x29\x7f\xc8\x59\xca\xe6\x67\x3a\xa5\xaf\x07\xf0\x19\xef\xf0\x5c\x9f\x13\xd5\xe4\xe8\xf5\xd1\x88\xdc\xf2\x9c\x67\x54\x65\x8b\x5a\x2a\xe6\xaa\x9d\x65\x16\x7e\x40\xb8\x95\x7b\x75\x44\x4e\xa4\x82\x91\x13\x2a\x48\xc6\x7c\x44\x93\x3b\x67\x0b\x94\x1d\x4f\x9f\x9a\xb8\x90\x47\xb5\x5f\x22\x9d\xe9\x8c\x13\xa9\xe7\xd8\x8e\x1f\xd5\xd2\xd9\x5c\x56\x24\x9d\x0b\x4b\xe7\x47\xe4\xd3\xaa\x42\xe5\x70\x64\x7c\x8b\xe7\x02\xea\xd3\xe8\x7d\x3b\x69\x70\xcb\xe6\xe0\xe7\x03\xd3\x76\x2d\x71\xca\xcd\x47\x56\xc8\x4e\x12\x02\x76\x69\xd8\xe3\xb8\xb1\x2f\xa4\xe6\x90\xa8\x94\x1a\x28\x0b\xac\x0c\x4f\xca\x8c\x5a\xb1\x1a\xad\x71\x23\x72\x79\x75\xf3\xf1\xea\xe2\xfc\xee\xea\xf2\x0d\xf9\xc6\x8d\xc4\x63\x09\x6f\x44\xee\xe2\x6c\x50\x91\x47\xaf\x4b\xb9\x13\xbe\x35\x70\x64\x88\x8a\x2a\xb9\x23\xe4\xf8\xa0\x82\x5c\x0b\x6e\xaa\xf4\xc8\xe8\x77\x96\x49\xc1\x7c\xf5\xd0\x42\x3a\x6b\xe0\x94\xa3\x37\x88\x70\x83\xd9\x9f\xeb\xa3\xc1\xe9\xc0\x54\xab\x61\x2a\x5b\x14\xc1\x47\x10\x2d\x2a\xe0\x1e\x4a\xfc\xf7\xf9\x4f\xbb\xca\xbe\x21\x1b\xad\x0f\x70\x42\xeb\x7f\xf5\x1e\x99\x41\x48\xcc\xee\xd3\xdd\xac\x28\x69\x4d\x2c\x9b\x39\x1e\x1d\x7b\x81\x22\x5b\x4a\xc2\x1f\x06\x8d\x33\x7a\xd5\x91\x6d\x44\xc8\x77\xde\x65\x1b\x42\x8f\x57\xe7\xf3\xc7\xec\x10\x51\x56\xf8\x06\xca\xfa\xc0\x98\x72\x1c\x7f\xd4\xa5\x00\x9b\xf2\x39\x13\xb8\xb0\xc3\x52\x28\xff\xf9\xce\xd5\xd1\xaa\x79\x3b\xfd\xe3\xe3\xbb\xc3\xce\x0c\xcf\x5f\xe7\x79\xb9\x63\xeb\x66\x95\xc8\x3c\xc7\x7c\x51\xb3\x10\x60\x58\xc5\x08\x06\xaa\x70\x30\xcd\x07\x33\x5f\x4d\xb6\x20\x7f\x83\x9e\xf9\x4e\x0d\x4d\x27\xbc\x76\x41\x09\xa2\x12\x73\xbb\xe7\x61\x76\x49\xd6\xb4\x4f\x9e\xe2\x48\xfb\x59\xf8\xf8\xd9\xc7\xab\xf3\xcb\xf7\x57\xa3\x3c\x7d\x72\xd2\xc2\x44\x5a\x48\x2e\x8c\xde\xae\xdf\x6c\xab\x3a\xd3\x9e\xfc\x84\x8f\x76\xe5\xce\xa1\xa3\xc7\x31\xff\x22\xca\x4b\x97\x32\x43\x79\xa6\xa3\x3d\x34\xb2\x90\x99\x9c\xae\x4e\xbf\xdc\x61\x73\x7e\x81\xf9\x65\x86\x74\x68\x77\xfd\xb0\xa2\x7e\x9b\x3a\x1a\x4d\x29\xbf\xaa\x88\x5d\xad\x35\x48\xcd\x50\xee\xe2\x85\x2e\xf7\x51\x84\xb3\x25\x18\xa0\x22\x09\x07\xd8\xa7\xec\xab\x72\xe0\x45\x35\x6c\xda\x4a\x6d\x8f\x0d\xba\xed\x02\x9b\xa5\x3f\xdb\x0b\x15\xd5\x61\xe6\xfb\xd4\x09\x5c\xa1\xd8\x30\xa4\x6b\x82\xd2\x2a\x52\x45\x0c\x37\xa6\x77\xde\x7a\xe3\x6d\x3d\xd8\x2a\x5b\x34\xad\x38\x95\x7c\x14\x4c\x5f\x98\x63\x20\xcb\x16\x55\x1a\x48\xa7\x45\xd3\x29\xa6\x61\x52\xce\x4c\x5c\x28\x3e\xe7\x19\x9b\x42\x2a\x56\x2e\xa6\x51\xf8\x6b\x1c\x30\xeb\x52\xb3\xd6\x8d\xae\xef\xed\x5f\x51\xd2\x6d\xc0\x8b\x0f\xdf\xdd\x41\x56\x5f\xb8\xe0\xda\x5b\x08\xb7\x1f\x84\xf3\x36\x1c\x0e\xc1\x64\x70\xf2\x37\x2b\x4f\xa6\xd9\x29\xf9\x81\xb9\xef\x48\x48\x3b\xac\xa0\x14\xd0\x4c\x86\x1c\xb0\x30\xd7\x0a\xb2\x80\x8e\x78\xbd\xef\x5a\x9d\xd9\x96\x56\x56\x42\x56\x53\x6b\x0f\x95\x4f\x31\x75\x23\xde\x31\x3d\xbd\xec\x79\x40\xb2\xbf\x33\x95\xf3\xa6\xd5\x55\xf8\x19\x2e\x7e\x3c\x3d\xa4\x44\x2f\xf2\x8c\x8b\xfb\x2a\x2f\xd8\x44\x5a\x1c\xc2\xd0\x04\x2e\xee\x3d\xc6\x2a\x46\xb3\xf5\x94\x72\x17\xfc\x38\x28\x95\x34\x3b\x58\x00\xc1\x42\x67\xcf\xd9\x9f\xfc\xb1\x77\xd7\xd0\x31\x89\x3b\x3a\x7a\x71\xeb\xe5\xba\x5b\x19\xfc\x63\xe8\x50\xa3\x69\x82\x5c\xdf\x5e\xdc\x5e\x3f\xa9\x85\x7a\x1d\x4b\x80\xd9\x3d\xa3\x54\xc7\x7f\xdc\x76\x3b\x3c\x24\x59\xb9\xbd\x0d\xaa\x77\x37\x52\x19\x9a\x1d\x88\x08\x24\x33\x5a\x9c\x97\x66\x76\xc9\x35\xe4\x50\xe8\x2a\x04\x2c\xf5\x8f\x3c\x9d\x31\x77\xb3\x4f\x18\xc8\x3d\x3a\xb8\x76\x17\x7f\x3a\xbf\x21\xb4\xb4\xfb\x6b\x5c\x72\xd1\x83\x5e\xb8\xfb\x99\xdd\x62\x84\xc1\x8e\xeb\x72\xbd\xb7\xac\xca\xb7\x7a\xec\x35\x3d\x86\x1f\x6e\x7f\x17\x01\x34\x14\x29\xd8\x0b\xbe\x7f\xe0\x82\x1b\x4e\x8d\x6c\x59\xa8\xac\x86\x02\xb5\xbe\xc1\x20\x50\x6a\x23\x73\x87\xc1\xd7\xbe\x05\x5c\x21\x03\x17\x5f\xea\x54\x59\x0b\x40\x7a\x07\x88\x5d\x0b\x2b\x6b\xd3\x84\x35\x1c\x20\x07\x90\xf4\x13\xc7\xe6\xa1\xcd\x1f\x9c\x81\x0a\xf2\x83\x65\x7f\x7c\x53\x4b\xc5\xbe\x54\xd7\xc2\x5b\x29\xaa\xa2\x09\x07\xb5\xf8\xf0\x1f\xbb\x12\x05\xfe\xa3\x68\x58\xda\x70\x81\xff\xb7\xa4\x19\x02\xe6\xc3\xa1\xcd\x52\x75\x20\x77\x9d\x6f\x7d\x87\xdc\xd4\xab\xed\xf8\x10\xb4\xf4\x52\x63\xe6\x31\x5c\x8f\x51\x54\x68\xbb\x47\x75\x5d\xec\xd8\x5d\x3c\x1d\x93\x13\x93\x14\xad\x6b\xf7\x3f\x92\x6b\x7b\x56\x8a\x5a\x21\x67\x98\xf9\x1d\x6e\xcb\xbb\xe0\xda\xde\x76\x92\x8f\x72\x35\x04\x58\xde\xd5\xaa\xe2\x7a\x85\xdd\x8a\xd7\x85\xac\x9f\xbc\xe3\xda\xf8\x82\x0c\xf0\x82\x6b\x97\x47\x18\xe4\xae\x1b\xab\xc8\xf1\xe2\x7f\x68\x9a\xaa\x37\xc8\xa5\x7c\xf5\x65\x05\xd2\x97\x4f\xf2\x45\x45\xb8\x4b\x3c\x31\x8b\xc2\x25\x00\xbc\xbb\xb8\x21\x58\x20\xe5\xf7\xbf\xc5\xca\xaf\xff\xfe\xeb\xdf\xbe\x6a\xbd\xdd\xcf\xe7\x3c\xbe\xa3\x1d\xe3\xe0\x77\x4c\x2f\xc2\x6f\xb0\xe6\x1f\x68\x57\x02\xb2\xc9\x2d\xba\xe3\x59\xca\xea\x8e\x3a\x22\x96\xdd\xe5\x40\xef\x77\x93\x60\x7a\x3f\xbb\x67\xf5\xb3\x23\x21\xa2\x04\x89\x44\x47\x74\x89\xbb\x42\x88\xe1\x32\xd9\x41\x8a\x73\xf3\xf2\x28\xce\x56\xd8\x6c\xc7\xa2\x3a\xf6\xc4\x97\xf1\xbe\xfc\x4d\xe5\xc2\x7e\xf9\xe1\xf6\x7f\xde\x9d\x7f\x7d\xf5\x0e\x66\xea\xee\xef\x2d\x6a\x70\xb1\xb3\xff\x54\x7b\x54\x6b\xa3\xbc\x6e\x07\x48\xb7\x6b\x19\xd1\xb8\x90\x11\xe4\xc3\xdb\xdb\xae\x77\x31\xfb\x0a\xe8\x62\xd2\x6a\xed\x4f\x6b\x6d\x83\xaa\x26\x4c\x1d\x2e\x7e\x64\x67\xa3\x5c\x94\x48\xab\xa6\x7f\xd9\x9d\xc2\x19\xee\xad\x22\x6d\xdd\x01\xf2\x02\xee\x1d\xec\x7a\x11\x06\x07\xbf\x71\x78\x24\x58\xb5\x95\x03\x54\xf7\xc0\xa2\x63\xec\xe5\x45\x00\x7b\x48\x91\xb6\x29\x4b\xb3\x2d\xb5\x66\x3a\x54\x5f\x78\xa1\x98\x52\xac\x4a\xcf\xdc\x85\x7a\xad\x1c\xa0\x56\xae\xac\x76\x17\x53\x8b\xa5\x58\x97\xce\xdc\x7b\x28\x50\xa7\xbc\xea\x82\x26\x07\x2d\xa8\x52\xbd\xc2\x37\x10\xe4\xfe\xf4\x04\x10\x3e\x7b\x40\x47\xda\x30\x5e\x57\x44\x0e\x1d\x9b\x51\x72\x9d\x76\xc8\x17\xfa\x28\xa4\x8f\x40\x8c\xc3\xe9\x9e\x79\xfb\xc8\xd3\x6a\x3b\x3f\xec\xa8\xe8\x1c\x5a\xc9\x29\x66\xd2\x48\xb1\xb3\x97\xfc\xaa\xee\xf5\x03\x7d\x03\x2d\x2e\xaa\x32\x36\x51\x8d\x47\xf0\xa0\x0c\x97\x11\x56\x9e\xf3\xec\x42\x0a\x7f\x2d\x51\xbf\x94\x78\x72\x11\x24\xbd\xbe\x3c\xd0\xe1\xfb\x72\x43\x3c\xbb\x1a\x83\x0f\xea\x0c\x92\x76\x8e\x49\xb1\x5d\x3c\xc4\xae\x2f\x9d\x68\xe6\x03\x4e\xb4\x43\x48\xb2\x1e\x23\x0f\xc6\x3a\xa5\x32\x0f\x52\x75\x0f\xf5\xae\x77\x6c\xf8\x2a\xb8\xdf\x96\x42\xb1\x5e\xe2\xe9\xc1\x39\x3e\xf3\x09\xba\x85\x13\xd4\x48\x70\xbe\xee\x24\x3d\xc6\x41\x7a\xde\x03\xb4\x2f\xa3\x7a\xdc\x28\xdf\x83\x0a\xe9\x1e\xdd\x3a\x2e\xd5\x77\x73\xc6\x04\xbb\x49\x15\xb5\xa0\x60\x72\x89\x4e\xdc\xc1\xa8\x83\x92\x58\x82\xb2\x0b\x61\xf0\x7d\xd0\x80\x8b\x89\x9e\xb3\xcc\x42\x55\x8a\x38\x45\xb4\x0b\xe3\x1d\x10\xcc\xb2\x9c\xd3\xc2\xd7\xe4\x96\x0f\xe2\x81\xaa\x94\x9c\xdf\x5c\x1f\x86\x1a\x74\xf0\xb3\x46\x4c\x6a\x97\xd1\xab\xee\x69\x5d\xf5\xc4\x32\x37\x33\x06\xb5\x15\xc9\x98\x1b\x5d\xd5\xf4\x63\x26\xd6\x2b\x2d\x15\x0c\x77\x59\xf6\x2c\xdb\x73\xeb\x46\x8a\x18\xa6\x20\x32\x31\x34\xf3\x45\x04\x5c\x99\x9c\x57\xaf\x5e\xa1\x29\xec\xd5\xef\x7e\xf7\x3b\xac\xac\x94\xb2\x84\xe7\xcb\x0d\xa1\xd5\xff\x7a\xfd\x7a\x44\xfe\xeb\xfc\xfd\x3b\xa8\xfc\x58\x18\x8d\x59\x49\x70\x64\xac\x04\x1f\x75\xd6\x03\xf2\x7f\x6e\xbf\xfb\x50\x95\x89\xa9\xff\xea\x0a\x6a\xbb\xe5\x8d\xc8\x65\xe4\xff\x14\x1b\xba\xa8\x99\xb9\x82\x46\x86\xd0\xc9\x04\x11\x63\xec\xcb\xe9\xe2\x81\xf3\xd1\xe3\x50\x15\x1c\xeb\x8f\x58\x94\xc8\xc0\x31\xcb\xaa\xe4\x68\x1a\xf4\x99\x0d\xd0\xcf\x0c\xc6\x0a\x64\x12\xa6\x32\xc0\x5a\xf2\x13\x0d\x55\x48\xaa\xf4\x7f\x8a\x69\x2b\x94\xba\xea\x8a\x38\x58\xb5\x33\x9a\xb5\xce\xf5\xf0\x18\x37\x40\xad\xab\x63\xd4\x4d\xf7\xee\x0c\xf9\xf4\xad\x2e\x77\x71\x55\xa6\xfe\x6f\x78\x1b\xba\xcd\x49\xf8\x91\x6e\x64\x6a\x73\xbd\x09\xb3\xc1\xad\x73\x59\x02\x2a\x3a\x41\x33\x09\x95\xbc\xc2\x4e\x57\x5c\x2c\x2a\x7a\xbf\x7d\x29\x9d\x93\x2f\x76\x4d\xc0\x8b\x84\xea\x3d\x6d\x5d\xce\xa7\xee\x2f\xe2\x7b\xd7\xf2\x2a\xd0\xb1\x2c\x8d\xbf\xc3\x76\xbf\x43\x00\x36\x56\x59\xef\x90\x46\x72\x87\xcc\x93\xbb\x64\x20\xee\x9c\xc4\xb4\x7e\xdf\x0c\x3c\xa1\x2e\x4a\x0c\x08\xa3\xc9\x8c\xdc\xb3\xc5\x10\xe9\x56\x41\x21\x9a\x07\xa0\x72\x69\x61\x51\x2b\x7c\x52\xd5\xae\xb1\xf2\xb1\x03\x99\x77\x0c\x88\xb8\x8f\x8f\x06\xf2\x42\xa8\x76\xf2\x92\x4b\x23\x2a\x22\x4b\x81\xcf\x55\x1d\xd5\x23\x0e\x79\x43\xb1\x18\x79\x3d\x48\xc5\x9e\x37\x96\xda\x6e\x7a\xd3\x97\x2b\x6f\x08\x4b\x07\x1d\x77\x2b\xc5\x52\x6f\x57\x7c\xdb\x09\x7f\xf0\x41\xea\xb3\x33\x47\x1e\x15\x50\xce\xcf\x55\x72\x72\x6d\x3d\x94\x02\x20\x6a\x41\x34\x9a\x99\xd2\x81\x06\xeb\x85\x95\x22\x63\x5a\x13\x0e\x2b\xcc\xa9\xba\x67\x3e\x61\x0c\xcd\x46\xe4\xc6\x4e\x32\xe4\xaf\xc2\xb4\xc8\x73\x74\xb1\xb3\x67\x36\x8e\x0e\xb2\x1f\x39\x1e\x8d\x8e\x91\xc0\xaf\x88\x15\xea\x80\x1f\xbb\xe5\xd4\xdd\x21\x97\x6e\xa3\xb4\x77\xa1\x31\x33\xb0\x15\xf9\x20\xf3\xb5\x84\x28\x38\x33\xf3\x0c\x8c\xb6\x4e\xa2\xb4\xbc\x9c\x1d\x12\xc0\xee\x9a\xb7\x7c\x97\xac\xe5\xad\xee\x2d\xea\xcf\xee\xd9\xca\x77\xca\x55\xbe\x2e\x53\xb9\xdb\x29\x77\xda\xba\xe7\x70\xde\x23\xc5\x76\xde\x29\xcd\xab\x7f\xea\x46\x4a\x90\x3b\x6a\x59\x7a\x5a\xc9\x88\x2e\xe9\x53\xc6\xbe\x28\xa1\xf0\x7a\xb2\xaa\xea\x9c\x0f\x16\x8c\xe4\x65\x4f\x43\x2d\x04\x9e\x5f\x1a\xec\x56\xcb\x85\x74\x16\x0f\x9b\x4f\x17\x71\xb1\xf9\xb4\xbb\x0c\x6c\x3e\x75\x85\x2d\x0a\x4b\x0a\x44\x3f\xf6\xe2\x07\x90\x1a\x09\x39\xbb\xab\x23\x38\x22\xef\x1d\x53\x40\x64\xa4\x63\x2d\xb3\xd2\x84\x48\xa6\x15\x1c\x03\x06\xf5\x19\xbe\x31\xa4\xd4\x37\x8b\xf8\x07\x70\x4e\x24\xcb\x5d\x59\x09\x3e\x3b\x1d\xf1\xae\x35\xf7\x7e\xb2\xce\x24\x7b\xc0\xd0\x8b\x12\x3b\xc3\xd1\x0f\x10\xf2\x4e\x78\x5f\xea\x9a\x8c\x03\x9e\x24\x46\xa3\x00\xe5\xc5\x15\x57\xe8\xa9\xf3\x12\xdb\x59\x6d\xdc\x5c\x9d\x61\xe2\xfc\xe6\x7a\x27\x0d\x20\xea\xbf\x46\x07\x88\x5b\xfc\x84\xb5\x80\x6b\xd4\x02\xe2\xb2\x3b\x97\xd5\xca\x9d\x49\xd9\x92\x9d\x17\x2f\x46\x2e\x4d\xfb\xad\x25\x96\xb1\xd3\x69\x3d\x87\x1e\x1a\x7b\x2a\xb2\x1a\xe5\xdd\xf3\xb7\x8e\x70\x88\x5f\xba\xc8\xf9\x84\xe2\x23\xc0\xa3\x53\xb9\x74\xff\x2c\x57\xb3\x83\xc5\x92\x5b\x28\x6d\x83\xfa\x60\xa4\x58\x16\x32\x7d\xe3\x4a\x49\x0b\x21\xb1\x80\x9c\x1e\x60\x6d\x1c\x3d\x40\x85\xd1\x4a\x11\xd1\x5d\xb1\x8a\x4c\xee\x3b\xcb\x0d\x3b\x55\x39\xda\xa7\xce\x91\xdd\x40\x58\xf9\x4d\xd7\x5d\x24\x7b\x96\x2d\x22\x11\x6b\xda\xad\x10\x4a\x6d\x4f\xdd\x48\xa1\xce\x7b\x32\x63\x39\xc5\x1c\x7e\x7e\x79\x96\xca\x3c\x28\x6e\x0c\xc3\x5c\x4a\x4c\xe5\x9a\xc8\xc9\xa0\x76\x67\x70\x34\x7f\x7d\xb4\x4b\x39\x98\x3d\x2b\xf6\x90\x6a\x17\x0e\x00\x8c\x9b\x9a\xc8\x66\xf1\x1a\x74\x89\x0c\x12\x6f\x8a\x86\x41\xc2\x32\x98\x39\x42\xef\xc9\x17\x7e\x08\x3d\x6a\x57\xfd\x69\x10\x04\x86\x5e\x7f\xea\xf5\xa7\x83\xe8\x4f\x11\x63\xf1\x04\x67\x85\x2e\x15\x3b\x0c\x7b\x85\xaa\x0a\x64\x8a\x12\xf0\x58\xd4\xf4\xaa\x94\x54\x75\x8b\x9b\xd5\x87\x8e\xbd\x82\xe5\xf0\xb8\x34\x93\xe1\xef\x09\x13\x89\x4c\x71\xf3\xed\xf8\x4a\x1b\x10\x6d\x2a\x9d\x24\x9e\x4b\xee\xbf\x15\x5b\xed\x60\xec\x5d\xb7\x6e\x27\x3a\xe0\xaf\x02\xdf\x1e\x88\xc1\x57\x6c\x3d\x04\x13\xfb\x5a\xd9\x3e\xd7\x80\xe3\xef\xd5\x25\x24\x96\x95\x06\xe4\xf6\x15\x73\xc9\x09\xbe\x1c\x25\x45\x39\x70\x0d\x46\x39\xcb\xa5\x5a\x0c\x42\x23\xfb\x63\xad\x97\x6b\x71\x0a\x32\x41\x52\x2a\xab\x01\x66\x8b\x2f\x55\x3a\xf0\x00\x7a\x62\xe1\x20\xec\x53\xb7\xa2\x41\xf1\x53\x47\x89\x2a\xa9\x18\xe8\xf7\x55\x11\xa5\x49\x48\x79\xa8\x07\x95\xda\x69\xdf\x32\x31\x27\x73\xaa\x3a\x54\x41\x8f\x9f\x3d\xe5\x81\x94\xcf\xb9\xde\xad\xde\x61\x63\xe9\xb7\x8e\x69\xa0\x5d\x47\x96\xa6\x28\x8d\xa3\x94\xfe\x54\xf8\x90\xf9\x70\x1a\x1a\x42\xd1\xeb\xa3\x9d\xa6\xf1\xc5\xd4\x17\xc6\x67\xc7\x2a\xc3\xf8\xec\x5b\x6b\xb8\x3e\xca\xce\x68\x73\xd0\xca\xe1\xfe\xf1\x68\x71\x88\x73\x58\xb1\xc8\x2a\xcf\x83\x17\x4e\x9f\xe8\xa0\xa1\xbb\xc9\x4e\x76\x1b\x97\xa1\x7e\xb5\xc9\xc6\xfd\xf8\x13\xb6\xd6\x1c\xf6\xce\xd6\xc5\x17\xfe\xcc\x2f\x6c\x6f\x5d\x3d\x83\xfe\xb6\xb6\x15\x0a\xf6\xb7\xb5\xfd\x6d\x6d\x7f\x5b\xdb\x5b\x1b\x7a\x6b\x43\x7f\x5b\x4b\xfa\xdb\xda\x83\xc0\xf0\x70\xb7\xb5\x28\xea\xad\xba\xb3\x75\xc2\x5e\x75\x61\xfb\xa4\xf7\xb5\xae\x70\xcf\x79\x92\xc8\x52\x98\x3b\x79\xcf\x5a\x5f\x3a\x34\xe4\xff\xa5\x71\x20\x01\xc2\x1a\x7d\x60\xb9\xf1\x93\x29\x07\xdd\xa5\x92\x4e\xb2\xc5\x2e\x52\x05\x2d\x53\x6e\x25\xff\x9d\xd1\xcc\x0f\x10\x27\x27\x12\x29\x4b\xab\x1f\xdc\x51\x36\x16\xd6\x23\x72\x4e\x14\x4b\x78\xc1\x5d\x19\x79\x8a\xef\x11\xf1\x42\x6d\x04\x6e\x34\xcb\x26\x2e\x47\xbd\x88\x6b\xfd\x54\xf2\xbb\xa3\x83\x2b\x3f\x83\x1c\x4a\xfa\x4c\xe6\xbe\x16\x92\x62\x7f\xf3\xac\xcd\xcd\xe6\x2e\x1e\x21\x36\xaf\xc0\x52\x6a\x25\x86\xe0\x63\x05\x77\x01\xd6\x8f\x7d\xfc\xd9\xe7\x82\x2b\x40\xde\x5b\x96\x48\xd1\xa6\xa6\xea\x9a\x0d\x5a\x1a\xa9\xe2\x4f\x60\x1b\x65\x29\x49\x4b\x15\x6a\xa6\xce\x69\xc6\x53\x6e\x16\xe1\xd6\xce\x95\xd7\xa2\x78\x62\xc2\x36\xea\x0a\x8c\x84\x16\x85\x92\x34\x99\x31\x1d\x7d\x0d\x05\x14\x17\x44\x16\x7c\xdf\xb1\x04\x1c\xc8\x28\xd0\xc7\x32\xc8\x6c\x41\x94\x34\xfe\xe2\x7d\xcd\x07\xef\xa2\xc1\xa0\x3b\x72\x39\xa3\x16\x70\x3b\x2f\xe3\x21\x70\x56\x7c\x12\xff\xa1\x89\xcc\x52\x9f\xc2\xe4\xf7\xaf\xac\x50\x98\x38\x1c\xb4\xc4\x0f\x12\x5c\x18\x49\x32\xcb\xb0\x2d\x41\x5c\xdf\xf9\xd7\xbf\x21\x33\x59\x2a\x3d\x8a\x93\x0e\xbc\x86\x77\xa8\xdf\x79\xa1\xd2\x90\x8c\x51\x6d\xc8\xeb\x57\x24\xe7\xa2\xb4\x7c\xaa\x33\xda\x74\x97\x83\x22\x09\xe8\xb7\xbf\x69\xdd\xaf\xab\xec\xb3\x56\xea\x29\x30\x37\xb2\x13\x7d\xdc\x49\xc2\xc0\x38\xcc\x2c\xde\x10\x84\x1c\xd1\x8d\xa1\x2d\x8c\x7c\x84\xf3\xf5\x63\x29\xc7\x0b\xd3\x25\x88\xd2\xf5\xa8\x47\x4f\xfe\x5f\xf7\xb2\x4d\xf2\x94\x2a\x77\xca\xc6\x8f\x3e\x4a\x85\x8b\x29\xd7\x66\x4b\x7d\x8b\x2a\xbe\x72\x63\xb3\xf6\x6c\x65\x6a\xb5\x83\x8e\xb1\x32\xd0\xc7\x4b\xc4\xde\xb6\x94\x24\x0c\x8b\x59\x5e\x56\x95\x92\x84\xc4\xb6\x5b\x87\x7f\xe6\x84\x63\x1e\x41\x0e\x90\x35\xbd\xe5\x52\xdb\x09\x5d\x1e\x25\x3a\xaf\x15\xbb\xd5\x4f\x81\xe6\x62\x8a\x49\xce\xf3\x32\x33\xbc\xc8\xaa\x75\x7f\xf4\x1d\x1c\x21\x8f\x6d\x6e\x34\x32\x13\x51\x0c\x2c\xc6\x6c\x53\x60\x9f\x3c\x09\x63\x31\x61\x30\x57\xb7\xb2\xfc\xa0\xa0\x8a\x06\xe0\x41\x25\x5d\x7d\xea\xcc\x77\x14\x6e\x14\x5d\x3a\x4c\xdb\x8b\x66\xd5\x8c\xa3\x5b\xa4\x43\x22\x8d\x61\x82\x8a\x16\xa6\xea\x7a\x7a\x2e\xe8\x44\xe4\x43\x70\x26\xc3\x32\x28\x0d\x6c\x71\x42\xcd\xd7\x34\xb9\x67\x22\xc5\xa2\x51\xb0\xec\x74\x21\x68\xee\xb2\x6d\x45\xf5\xb8\x1b\xfd\xf5\xc0\x19\x26\x30\x7c\xcf\x87\x19\x23\xd7\x3d\x24\x0c\x4a\xdd\x39\x95\x8d\xed\xb2\xed\x9c\x6b\x34\xd9\x28\x3e\x4f\x98\xe7\xff\xb6\xdf\x21\xa7\x3e\x6f\x11\x4b\xbf\x34\x79\xbf\x3d\x11\xfe\x02\xb9\x0f\x96\x73\x48\xaa\x45\x33\x7b\xb4\x17\x21\x66\xb4\xb1\xb9\xe3\xc5\x61\xab\xde\xa8\x71\x97\xc8\xdf\x63\x35\x4e\xeb\x87\xf8\x23\x4d\xa5\x26\x5f\x67\x32\xb9\x27\x97\x0c\x84\xae\xc7\x2c\xcf\xa2\xc6\xe9\x73\xa6\xf0\xce\xe9\x74\xdb\x3d\xdb\x90\xe4\x52\x70\x23\xd5\x66\x7a\xf1\x74\x65\x27\xfb\x74\xcf\x6b\x33\x54\x59\x6c\x7e\xc9\xc9\x9e\x2d\xba\x75\xdd\x78\xe8\x14\xd4\x33\x38\x9d\xf8\xca\x55\x01\xdb\xf1\xac\xfd\x62\x26\x1f\x86\x46\x0e\x4b\xcd\x86\xbc\xc5\x85\x6e\x87\x65\xde\xb3\x05\xdc\x62\x77\x5c\xa8\xeb\x56\xd3\x19\x8c\x04\x0b\x14\xbc\xb7\x9c\xfb\xe3\xd7\x97\x9f\x34\x53\xa3\x58\x06\x3c\x63\x26\x39\x4b\x58\x31\x3b\x73\x23\xbc\x48\xa0\x78\x22\xd2\x15\x2a\xbe\x1f\xb2\x99\x44\x66\x99\x0b\xcc\x96\x13\x72\xc1\x8a\x59\x18\xf8\xa9\x57\xfd\x7c\x19\x81\x0b\x29\xbb\x26\x42\x3d\xb6\x7d\xea\x87\x08\xde\xe0\x19\x8a\x90\x49\x8d\xbb\x15\xa1\x78\x2a\xf4\x79\xd1\xa5\x36\x1f\x11\x38\x8f\x9b\x4e\xf9\xb8\x96\x4f\x39\xf6\xf7\xac\x27\x4b\xf6\x1e\x23\x35\x12\x74\x3d\x41\xa1\x3b\x65\x29\x91\x73\xa6\x14\x4f\x99\x26\x81\x06\xc5\x5a\x2a\xcf\x9e\x1a\x6e\x7d\xde\xe6\x67\xcf\xdb\xbc\x83\x3a\x74\x0c\xfa\x50\x8d\x4c\xc1\x9b\x25\x32\x45\xd3\x9c\x8b\x17\x47\xa8\x74\x42\x33\x76\xfd\x5d\x07\xfd\xc3\xf5\xa8\xab\x20\xb7\xee\x65\x94\x3f\x6d\x4b\x56\xb2\x6f\x03\xde\x10\x21\xd3\x6d\x26\xd5\x47\x50\x24\xa6\xd4\xb0\x87\xad\xec\x70\x58\x11\xaa\xed\x2d\x41\x38\x7d\x4e\x95\xe3\x45\xe4\x08\x8c\x70\x1e\x93\x9e\x1d\x92\xa9\xba\x5d\xeb\x6a\x9c\xc4\x5e\x71\xfa\xdd\x66\xd2\x5d\x8f\xc1\xe7\x37\xd7\xe4\x1b\x6c\x7e\xd8\xec\x85\x4a\x1a\x14\x03\x2f\x65\x4e\x79\xd7\x22\x1b\xcd\xee\xcd\xec\xab\xf1\x12\x6e\x42\x5b\xe2\x1a\x47\x05\x5c\x26\x7c\x5a\x5a\x9d\xce\xe9\x61\x2f\x2a\xc1\xdc\x92\xe8\xf2\x72\x13\xcc\xed\x5f\x0d\x22\x32\x39\x79\xbf\xc8\x4a\x62\xf1\x5b\x09\xac\x24\xdc\x81\x12\xcd\x84\xe6\x70\x21\x13\xdd\x8a\xbb\x4a\x7f\x58\x5a\x12\x9d\x20\x51\xc4\x19\x90\x77\x72\xca\x85\x3f\xbd\xd2\xdd\xd7\x4d\x28\xcf\xda\x02\xa3\x97\x49\x9e\x5d\x26\xd1\x3a\xbb\x12\x74\x9c\xb5\x71\x37\xa8\xa3\x5a\xe8\x48\xde\x66\x74\x4a\x18\xfc\x71\x96\x72\x6d\xff\x4f\x6e\x6f\xdf\x81\x11\xbe\x14\x5e\x62\x06\x03\xb5\xa3\x7d\x21\x48\x01\x0f\xe2\x61\xcf\x0e\x92\x9e\x1d\xb2\xff\x45\x3d\x09\x17\xa9\x9d\x78\x54\x0a\x0e\x9d\xa4\xa0\x05\xe6\x43\x0c\x3e\xbf\xe8\x36\x30\x66\xe4\x6e\xc6\x93\xfb\x9b\xc8\xee\x2e\x95\x7d\x27\xa2\x57\x35\x06\xd6\xfc\xed\x90\xd4\xd2\x4d\xf5\xa6\xbb\x6a\x1c\xf5\xf4\x7c\xc0\x13\x8c\x5b\xb7\x7e\xf8\x8d\x6a\x2d\x13\x5e\xdd\xb9\x80\x8d\xa6\x62\x0e\x29\x30\x87\xc3\xae\x09\xc4\x83\xae\xcb\x41\xf9\x63\x05\x47\xf3\xbb\xe9\xab\xe3\xea\x98\x83\x71\xe1\x57\x7d\xd0\x25\x20\xce\xec\x90\x1a\xbd\xea\xb8\x9c\x1a\xdd\x0b\xc3\x8d\x8b\x05\xef\xa6\xee\x36\xcf\x0b\x62\xbe\x36\xe7\xd2\xf6\x85\x14\xe9\x2e\x35\xe1\xc1\x16\xde\x26\x6c\x63\x95\x1a\xde\xb8\x4d\xc4\x77\xee\xaa\x01\xce\x5c\x21\x8b\x32\x43\x7f\x8e\xfd\xf3\xbb\x7b\x9b\x31\x7e\xe7\x40\x57\x0f\x4f\x91\xb5\xf4\x38\x76\xec\xed\xee\xe9\xfc\xd3\xc8\x5d\x1a\x09\x77\xaf\x7e\xfb\x9b\xdf\x7c\xe9\xd9\x4c\xdb\xaa\xe0\x8f\x91\xce\xb4\xa5\x89\x76\x45\x7c\xd1\x75\x1f\x5f\xf4\xf3\x8d\x2f\x7a\xfc\x2c\xb4\x07\x8e\x20\xea\xe8\x9b\xdb\xcd\x2f\xb7\x7d\x8c\x50\x6b\xef\xdd\xae\x9e\xbb\x1d\xa2\x80\x0e\x1b\xfb\xd3\xd9\x97\xb5\x4b\x9c\x4f\x1f\xdd\xf3\x53\x8d\xee\xd9\xc5\x97\xb5\x7b\x24\x4f\x17\x1f\xd6\x9f\x62\xd4\x4e\x87\xc3\xd9\x3e\xba\x64\xef\x98\x92\xee\x49\x00\xbb\xdb\xd3\x76\x29\x48\x55\xf5\x5c\xa9\x41\xfa\xa0\x72\x9f\x7b\xec\xf8\x58\x47\xa9\xc5\x8c\xb4\x27\xf0\x49\x14\x12\xd2\x41\x1b\xc3\xe1\x65\x97\xda\x90\xae\xcf\x77\xb7\x8d\x8b\x99\xf0\xfa\x79\xee\x63\x7e\x0e\x17\x1e\x7d\x4d\x97\x2f\xc4\xe4\xae\x6b\xd9\x5a\xbc\xb5\x02\x48\x00\x30\x72\x39\x8e\xb3\x44\x56\x47\xe7\xfc\xe6\xda\xea\xe0\x10\x46\x44\x33\x3d\x22\x2b\xf8\xbc\x37\x97\x3a\xb9\xc0\xf3\x77\x6a\x0c\xcb\x0b\xd3\x7e\xd7\x7b\x8b\xfb\xb3\x5b\xdc\x0f\x68\x01\x9c\x95\x39\x15\x43\x7b\xa2\xc0\xe6\x5e\xbb\xad\x6b\x50\xe6\x11\x71\x67\x07\xd9\x13\x58\x40\x20\xb8\xa0\x5e\xd8\x98\x46\x65\x2e\x1f\xc7\xec\x09\x63\xef\xbc\x72\xe4\xab\x8d\x93\x96\xc8\x25\x87\x57\xb7\x9c\x00\x05\x7f\xa8\x22\xe6\x5c\x53\xc3\xcd\x8c\x21\x0f\xbf\x81\x80\x9c\xaa\x55\x5d\x92\x46\x51\x9a\x66\x99\x7c\xc0\x6f\xc7\x7c\xcd\x42\xdf\xce\xc5\x45\x9a\x8d\x19\xc9\xb9\xd5\xd1\x9d\x81\x35\x9e\x0e\x5e\x99\x5a\x89\x9c\x29\x14\x78\x95\xbb\x6c\xbb\x65\xc6\x6d\x14\x6c\xb4\xd5\x6f\x05\x3a\x84\xdb\x7f\x7b\xaf\x22\xf8\xb6\xa7\x09\x63\x36\xa3\x73\x2e\x4b\x85\xbd\x8d\x24\x47\xee\x27\xe0\x0d\x0b\x59\x06\x7b\x17\x16\xc3\x0c\xab\xd3\x2b\xe0\xf4\xa1\xfa\x11\x54\x81\x54\x7a\xd3\xc4\x90\x7d\xe6\xda\x2c\xaf\xc5\x83\xc8\xa7\xc1\x3b\x14\xde\xcc\x75\x61\xd9\x42\xe7\xaa\x76\xb5\x7e\x75\x79\x65\x7e\x0b\x3f\x7d\x41\x35\xed\xb6\x66\x77\x7d\x32\x11\xe8\x67\x28\xfe\x84\x9b\xb0\x8c\x27\x8b\xce\xe5\xde\x1a\xbd\x3d\xd1\xd6\xe1\x0e\xcd\xbe\x27\x5f\x53\xcd\x52\xf2\x9e\x0a\x3a\x45\x7d\xef\xe4\xf6\xe6\xeb\xf7\xa7\x76\x5f\x41\x9f\xbc\xbe\x5c\x79\xd1\x76\x1b\x0f\xfe\xe1\x90\xf1\x22\x4b\x0b\xdf\x81\x55\x2d\xf5\xdf\x71\xf1\x07\x0d\x84\x21\x81\x0f\xb5\x4b\xd6\xbb\x82\x05\xdd\x34\x43\x58\x9b\x35\x3f\x1b\x04\x66\x9e\xa7\x7b\x56\xf9\xe4\x42\x1b\x9a\x65\x37\x19\x15\xe7\x45\xa1\xe4\x7c\xb5\x36\x5e\x9b\xab\x6f\xe8\x67\x8a\x6e\x1e\xfe\x65\x81\xa0\x87\x2b\x6c\x41\xae\xab\xf1\x47\xe4\xda\x04\x2d\x5c\x0a\x60\xa9\x47\xe7\xa5\x91\x39\x35\x3c\x39\xb2\xca\xfa\xd1\x7b\x2a\x4a\x9a\xad\x74\xba\xda\xb8\x8c\x75\x22\xe2\xc6\x4e\xeb\x53\xd7\xb5\xe8\xb6\x51\xd6\xd8\xdc\xdf\x50\x65\xa9\xd3\xc5\xed\xf7\x9d\xfa\x6a\x43\x4d\xb9\x44\x85\x37\x70\x86\xf5\xbc\x60\x48\x32\xaa\xcd\xa7\x22\xb5\x87\xbe\xf1\xeb\x26\x82\x9f\x50\x43\x33\x39\xfd\x13\xa3\xd9\x6a\x0c\xaf\xe1\xc9\x45\xdc\xda\x1b\xa0\xdc\x85\x7f\x39\x0e\x0d\x8f\x35\xb1\x02\xb6\x8f\x81\x57\x2c\x63\x73\x2a\x8c\xef\x8e\xc5\xd5\xf5\xb1\x5b\x3f\x60\x11\xaf\x8c\xaf\x29\x33\x4c\xe5\x5c\xd4\xc7\xbc\x85\xb6\x17\x52\xa4\x1c\xcd\x8e\x60\x50\xc3\x1e\xf5\x71\xd7\xa3\xda\xba\x9b\x86\x0d\x77\x0b\xf5\xec\x9a\xd1\x7c\xea\xa0\xc0\x66\x63\x27\x5f\xce\xf0\x25\xdc\xb4\xd7\xe6\xb6\x04\x29\x72\x2f\xac\x60\x08\x79\x44\x56\x93\xad\xad\x72\xc2\x36\xf9\x60\xe8\xf7\x18\xa7\xb0\xde\x71\x74\xe8\xe6\xbd\xee\x0e\x62\x13\x8a\xe1\xb3\x5d\xb2\x68\x4e\x65\x3d\x4d\x5d\x85\x77\xa1\x1b\x46\xb2\x34\x0a\xf2\xd7\x1a\xad\xe7\x01\xad\x04\xaf\x76\x32\x52\xdb\xac\xf6\x75\x5a\x5b\xe5\x60\x5f\x52\x65\x5b\x48\x8c\x5b\x99\x56\xcb\xe4\xf2\x75\xc5\xfa\xda\xf9\xff\x29\xa7\x8a\x50\x52\x70\x86\xc9\x4f\xa8\x70\xc0\x02\xce\xc2\x68\xea\x5e\x5a\x0e\x66\x55\x42\xf8\x6d\xe0\x2e\xc3\xd1\xb8\xec\x7c\x2d\xbc\x81\x9a\x62\xf2\x0f\xb8\xb8\x38\xfb\x46\x3a\x23\xaf\x0b\xd2\xb5\x34\x00\x38\xf9\x80\xe8\x32\x99\x11\xaa\xed\xd4\x2c\x42\xdb\x13\xcf\x46\x39\x15\x7c\xc2\xb4\x19\x85\x2c\xc1\xfa\xcf\xbf\xfe\xcb\x88\xbc\x95\x8a\x38\x47\xf5\x81\xcf\xaa\xe1\xe6\x59\xe1\x05\xd7\xb8\x98\xd0\xb7\xd2\x5a\x0b\x99\xba\x49\x3f\xc0\x64\x0d\xbd\xb7\x3c\x0c\x27\x5b\x32\xb8\xba\x78\x43\x8e\xac\x98\x18\x7d\xfa\x1f\x96\x2d\xfd\xeb\x88\x9c\x3c\x00\xd3\x3e\xb2\x7f\x1e\xe1\x07\x83\xdb\x64\xac\x54\x57\x1f\xc6\x60\x49\xc5\xa7\x53\xa6\x50\x7d\x24\x10\x54\x78\xea\xb2\x82\x08\x19\x35\xf6\x97\xd2\x95\xba\xd9\x9c\xc8\x9f\x7f\xfd\x97\x23\x72\x52\x5f\x17\xe1\x22\x65\x9f\xc9\xaf\xd1\xba\xcc\xb5\x5d\xe3\xa9\xbb\xcc\xd1\x0b\x61\xe8\x67\x3b\x66\x32\x93\x9a\x09\x54\xe5\x8d\x24\x33\x3a\x67\x44\x4b\xab\x01\xb3\x2c\x1b\x3a\x5b\x3a\x79\xa0\x90\xa9\xc5\x83\x12\x02\xeb\x49\x41\x95\xa9\xa1\xc4\xc8\x59\x48\xe0\x6b\x76\xdb\xa6\xc2\xdf\x4c\x4f\xb8\x70\xf7\x57\xee\xe6\xcc\xee\x39\x04\x86\xe2\x26\x19\x49\x92\x19\x15\xd3\x10\x9b\x3e\x29\x4d\xa9\xd8\x96\xab\x9f\x96\x67\xe0\x9e\x8b\x4e\x21\xcc\xdf\x72\xd1\x74\x2a\x58\x6d\x57\x9a\x72\xe3\xa3\x22\x9c\xaf\xa2\x59\x9c\xd9\x5d\x50\x7c\x5c\x1a\xa9\xf4\x59\xca\xe6\x2c\x3b\xd3\x7c\x3a\xa4\x2a\x99\x71\xc3\x12\xbb\xac\x33\x5a\xf0\x61\x22\x85\xdd\x71\xc8\xca\x90\xa7\xbf\x80\xf2\xa6\x43\x3b\xd5\x2d\x59\xa7\x5b\x2e\x7a\xbb\x51\xed\x59\x8d\x69\x07\x5b\x63\x0b\x7b\xd0\xf2\x42\xd1\x36\xf3\x04\xab\x05\x43\xc8\xd9\x41\x16\xeb\x93\x26\x77\xe7\x31\xc7\x2e\x0f\x78\xd2\x1c\xc3\x1e\x3b\x74\x20\x81\x53\x59\xa3\x94\x39\x4d\x91\x94\x52\xb1\x78\x74\xe4\xb7\x20\x85\x74\xf9\xc9\x62\x08\x43\xc8\x6c\x48\x45\x6a\xff\x8d\x01\x3b\xc9\xe2\x20\x30\x2c\x79\x27\x42\xf0\xe9\xfa\xf2\x69\x8e\x44\xc9\x0f\x70\xea\x9d\xbc\xd6\x52\x88\x42\x51\x15\x1d\x35\x54\xc9\x3c\xd3\xac\x0b\xa8\x5c\xfb\x51\xff\xc3\xdd\xbf\x84\x6c\x67\xdb\x44\xaa\xcd\xb7\x26\x91\xec\xd8\x72\xbe\xef\xaa\x1e\xb1\x4d\x0e\x1c\xaf\xa8\x36\x2e\xb5\x96\xcf\x41\x50\x5b\x86\x57\x50\x80\xc1\xac\xbf\x18\x6e\x85\x43\xde\x5f\xc0\x4e\x64\xb8\x32\xe7\x52\x12\x94\x92\xed\x0a\x54\xa5\xbf\xd4\xea\xa0\xe1\xa2\x0c\xd3\x86\xd0\x39\xe5\x19\x58\xe7\xe5\x58\x33\x35\xc7\x82\x54\x2e\xd5\x20\x6d\xea\x59\xae\xe6\x04\x8a\x51\x4f\xa4\xf9\xf8\x35\x2c\xef\xca\xa6\x05\x80\x36\xd4\x98\xfd\xda\x59\x1f\x44\xef\x41\xf5\x72\xed\xcf\xf6\x0b\x3b\xaa\x31\x16\xff\xfe\xc4\xa8\x32\x63\x46\xcd\x1d\xdf\xc4\x77\x97\x50\xba\xd6\x2f\x94\x72\x0f\x08\xfd\xc0\xc8\x54\x1a\x2b\x62\x95\x80\xfb\x28\x93\x62\x52\x9f\x80\x68\x8f\x8d\xd1\xd5\x2a\xef\x14\x85\x10\x1f\x29\x3a\x2e\xb3\xde\x71\x79\x9d\x4e\x3a\x76\x98\x64\xb0\x35\x26\xd2\x90\x82\xb9\xbd\xc3\xdb\x0c\xa0\x40\x4f\xb3\xe4\x9c\x69\xbd\x31\xc1\x46\xdd\xbb\x10\x5b\xe3\x51\x6e\x5c\xad\xe5\xfe\x37\x0c\x0b\xb1\x02\x74\xca\x0c\xe5\x99\x3f\xca\x08\x8a\x00\xa5\x6d\xd4\x75\xe3\x02\x15\xa3\x7a\x93\x80\x50\x9b\xf5\x47\x68\x8c\x93\x96\x82\x0d\x1f\xa4\x4a\xc9\x05\xcd\x59\x76\x41\x35\x73\x63\xc5\x21\x7a\xb8\x47\xc7\xfa\xa0\x53\x5e\x6d\xfb\x5a\x33\x65\x34\xfe\x54\x26\x61\xf8\xab\x52\xb1\x70\x82\x03\x6f\x82\xbc\x53\x25\x1b\x90\xb7\x96\x7b\x0d\xc8\x27\x71\x2f\xe4\xc3\x7e\x73\x35\x1b\x6f\x41\x6a\x33\x8d\xdd\x3f\x7c\x5a\x9d\x9a\xc1\x27\x4c\x77\xc7\x19\x39\x82\xbf\xc6\xd4\x58\x67\x36\xa1\xa9\x9f\x91\xfd\xe7\x92\x09\xca\x2a\x8a\x4a\x4e\x15\xd3\x98\xb9\x66\x65\x92\xc4\xb6\x26\xe7\x6f\x98\x70\xc1\x7d\x5b\xa7\x77\xbd\xaa\x97\x9f\xa9\xe7\x6b\xd3\xea\x17\xb7\xdf\xee\x63\x45\xb6\x52\xd4\xd8\xec\x11\x18\x4d\x74\x8d\xf1\x69\xdd\x0c\x57\x1b\x9d\x22\xae\x17\xb5\x45\xa1\x64\x93\x75\xd4\xaf\xee\xe2\xf6\xfb\xf5\xc0\x5e\xcb\xfb\xb6\xf1\xa7\xed\x66\xa9\x7d\x0d\x52\x5b\xcf\xcc\x56\x23\x54\x6f\x7e\xea\xcd\x4f\x5f\x92\xf9\x69\x2b\xc6\x6f\x32\x39\x7d\x19\xc6\xa6\xad\x4b\xdc\x64\x60\x7a\x91\xa6\xa5\x56\x2b\xda\x68\x4e\x7a\xb1\x86\xa4\xad\x4b\x6b\x69\x3c\xfa\xf9\x98\x8d\xb6\x42\x6c\x83\xa9\xe8\x05\x1a\x89\xda\x08\x64\x2c\x6d\x23\x26\x5e\x47\x8d\x63\x41\xb1\x2a\x67\x19\x86\xf3\x4e\x39\xb1\x38\xb3\xab\xb4\x68\x05\xb8\xad\x73\x3b\x76\x93\x6b\x2f\x7b\x39\x81\xd1\x15\x7b\x5c\x9a\x2c\xb9\xbc\xba\xf9\x78\x75\x71\x7e\x77\x75\xd9\x94\xef\x56\x41\x7a\x8b\x24\xb6\xd9\x06\x31\x8c\x24\xb1\x35\x0d\x2c\x41\x5e\xf3\x93\xc5\x81\x35\x3f\x95\x25\x5f\xd5\x6b\x7f\xb9\x70\x2f\x2e\xb7\x17\xff\xd8\x7e\x3a\xdb\x1e\xcf\x4f\xe8\x38\x45\x9d\xcf\x99\x95\x7b\x66\x32\x4b\xb5\xf7\x5b\xbd\xbe\x0c\x91\x54\x5c\x24\x59\x99\x5a\xe1\xe2\xd3\xa7\xeb\x4b\x3d\x22\xe4\x6b\x96\xd0\x52\x83\x15\x26\x95\xe2\xd8\x90\xef\x3e\xbc\xfb\x2f\xf0\xc7\x86\x16\x83\x90\xd7\x04\xb2\xf2\x72\x8a\x89\x85\x0d\xa6\x6b\x23\x5f\x33\x14\x54\xe0\xcb\x09\x2d\x2c\x15\xd3\x58\xb9\xc2\x80\x2c\x32\x63\x59\x61\x29\xe6\x3d\x23\x55\x06\x55\x3b\x70\x55\x61\xde\xbb\x4f\x4e\x99\xc1\xa8\xab\x4d\x1e\x92\x1b\xa1\xb6\xc5\xe2\xba\x87\xad\xb5\xa6\x3e\x3a\x6d\xfc\x81\x6a\x67\xb1\x5a\x39\xdb\x2d\xfb\xbb\xdd\x3e\xb3\xde\xc4\xb1\xc6\xb8\x81\xe4\x19\xfe\x5a\x9a\xb3\x9d\x6c\x65\xc7\x40\x27\x12\x6e\x5a\x5b\x53\xd7\xbb\x01\xad\xae\x03\xb0\x64\xcb\x60\x4d\x20\xd7\x3e\x1c\x3c\xb2\xa3\x29\xb7\x9b\x0b\x14\x11\x49\x6b\xb5\x3f\x9d\xff\x5c\xfd\x5d\x39\x0e\xd5\x5f\xab\xf9\x3a\x8b\x0c\xf9\xc7\xbf\xbe\xfa\x7f\x01\x00\x00\xff\xff\x49\x53\xc6\xeb\x2e\x5c\x02\x00") func operatorsCoreosCom_subscriptionsYamlBytes() ([]byte, error) { return bindataRead( @@ -311,11 +311,13 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error diff --git a/staging/api/go.mod b/staging/api/go.mod index afa9ff25f9..a41ef21cc7 100644 --- a/staging/api/go.mod +++ b/staging/api/go.mod @@ -1,35 +1,33 @@ module github.com/operator-framework/api -go 1.18 +go 1.19 require ( - github.com/blang/semver v3.5.1+incompatible github.com/blang/semver/v4 v4.0.0 github.com/ghodss/yaml v1.0.0 github.com/go-bindata/go-bindata/v3 v3.1.3 - github.com/google/cel-go v0.10.1 - github.com/google/go-cmp v0.5.6 // indirect + github.com/google/cel-go v0.12.4 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.7.0 - google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 - k8s.io/api v0.24.0 - k8s.io/apiextensions-apiserver v0.24.0 - k8s.io/apimachinery v0.24.0 - k8s.io/client-go v0.24.0 - sigs.k8s.io/controller-runtime v0.12.1 + google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 + k8s.io/api v0.25.0 + k8s.io/apiextensions-apiserver v0.25.0 + k8s.io/apimachinery v0.25.0 + k8s.io/client-go v0.25.0 + sigs.k8s.io/controller-runtime v0.13.0 ) require ( github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e // indirect + github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect @@ -51,7 +49,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect @@ -68,28 +66,27 @@ require ( go.opentelemetry.io/otel/trace v0.20.0 // indirect go.opentelemetry.io/proto/otlp v0.7.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect + golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/text v0.3.8 // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect + golang.org/x/tools v0.1.12 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/grpc v1.40.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/grpc v1.47.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - k8s.io/apiserver v0.24.0 // indirect - k8s.io/component-base v0.24.0 // indirect - k8s.io/klog/v2 v2.60.1 // indirect - k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 // indirect - sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiserver v0.25.0 // indirect + k8s.io/component-base v0.25.0 // indirect + k8s.io/klog/v2 v2.70.1 // indirect + k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect + k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/staging/api/go.sum b/staging/api/go.sum index c5357c9828..4c66bda067 100644 --- a/staging/api/go.sum +++ b/staging/api/go.sum @@ -13,11 +13,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -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/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 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= @@ -26,7 +21,6 @@ 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/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 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= @@ -37,19 +31,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 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/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= @@ -60,31 +43,19 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF 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/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e h1:GCzyKMDDjSGnlpl3clrdAK7I1AaVoaiKDOYkUzChZzg= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= -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/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/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/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -93,53 +64,28 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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-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/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.3.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/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -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/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= -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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -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 h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= 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.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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI= @@ -154,29 +100,22 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 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 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-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -189,7 +128,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 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/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= @@ -205,15 +143,12 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.10.1 h1:MQBGSZGnDwh7T/un+mzGKOMz3x+4E/GDPprWjDL+1Jg= -github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= +github.com/google/cel-go v0.12.4 h1:YINKfuHZ8n72tPOqSPZBwGiDpew2CJS48mdM5W8LZQU= +github.com/google/cel-go v0.12.4/go.mod h1:Av7CU6r6X3YmcHR9GXqVDaEJYfEtSxl6wvIjUQTriCw= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -223,18 +158,15 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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/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/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.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/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= @@ -242,55 +174,20 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 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/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -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/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= 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/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.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-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 v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -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/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/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -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/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 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/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= 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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -301,17 +198,14 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 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/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= 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/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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -319,29 +213,15 @@ 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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -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/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -349,97 +229,56 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.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/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= 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_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 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/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/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/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 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/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -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/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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -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/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -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/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 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/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -451,38 +290,17 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= @@ -503,26 +321,13 @@ go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52l go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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= @@ -545,7 +350,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 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= @@ -556,18 +360,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 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-20180906233101-161cd47e91fd/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-20181114220301-adae6a3d119a/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-20181220203305-927f97764cc3/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= @@ -590,37 +387,20 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -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/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -634,13 +414,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20181026203630-95b1ffbd15a5/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -651,11 +426,8 @@ 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-20190904154756-749cb33beabd/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -670,36 +442,21 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-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-20210603081109-ebe580a85c40/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-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -708,18 +465,15 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= 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= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -727,19 +481,15 @@ 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= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/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-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-20191108193012-7d206e10da11/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= @@ -759,7 +509,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -767,21 +516,12 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -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/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 h1:hI3jKY4Hpf63ns040onEbB3dAkR/H/P83hw1TG8dD3Y= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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= -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= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -799,11 +539,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -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/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= @@ -833,7 +568,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -843,22 +577,9 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= 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= @@ -871,17 +592,12 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -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.37.0/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.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -894,8 +610,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj 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/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= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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= @@ -903,16 +620,9 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 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/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= 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.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -924,10 +634,8 @@ 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-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -935,42 +643,35 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.24.0 h1:J0hann2hfxWr1hinZIDefw7Q96wmCBx6SSB8IY0MdDg= -k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I= -k8s.io/apiextensions-apiserver v0.24.0 h1:JfgFqbA8gKJ/uDT++feAqk9jBIwNnL9YGdQvaI9DLtY= -k8s.io/apiextensions-apiserver v0.24.0/go.mod h1:iuVe4aEpe6827lvO6yWQVxiPSpPoSKVjkq+MIdg84cM= -k8s.io/apimachinery v0.24.0 h1:ydFCyC/DjCvFCHK5OPMKBlxayQytB8pxy8YQInd5UyQ= -k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apiserver v0.24.0 h1:GR7kGsjOMfilRvlG3Stxv/3uz/ryvJ/aZXc5pqdsNV0= -k8s.io/apiserver v0.24.0/go.mod h1:WFx2yiOMawnogNToVvUYT9nn1jaIkMKj41ZYCVycsBA= -k8s.io/client-go v0.24.0 h1:lbE4aB1gTHvYFSwm6eD3OF14NhFDKCejlnsGYlSJe5U= -k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw= -k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/component-base v0.24.0 h1:h5jieHZQoHrY/lHG+HyrSbJeyfuitheBvqvKwKHVC0g= -k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= +k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= +k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= +k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= +k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= +k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= +k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= +k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= +k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= +k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= +k8s.io/component-base v0.25.0 h1:haVKlLkPCFZhkcqB6WCvpVxftrg6+FK5x1ZuaIDaQ5Y= +k8s.io/component-base v0.25.0/go.mod h1:F2Sumv9CnbBlqrpdf7rKZTmmd2meJq0HizeyY/yAFxk= 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.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 h1:dUk62HQ3ZFhD48Qr8MIXCiKA8wInBQCtuE4QGfFW7yA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= -sigs.k8s.io/controller-runtime v0.12.1 h1:4BJY01xe9zKQti8oRjj/NeHKRXthf1YkYJAgLONFFoI= -sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXez/vp1Y8dxTU0= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/staging/api/pkg/manifests/bundleloader.go b/staging/api/pkg/manifests/bundleloader.go index 5d5bf2dc1a..94f14a22ac 100644 --- a/staging/api/pkg/manifests/bundleloader.go +++ b/staging/api/pkg/manifests/bundleloader.go @@ -51,6 +51,10 @@ func (b *bundleLoader) LoadBundle() error { // Add values from the annotations when the values are not loaded func (b *bundleLoader) addChannelsFromAnnotationsFile() { + if b.bundle == nil { + // None of this is relevant if the bundle was not found + return + } // Note that they will not get load for Bundle Format directories // and PackageManifest should not have the annotationsFile. However, // the following check to ensure that channels and default channels diff --git a/staging/api/pkg/operators/v1alpha1/catalogsource_types.go b/staging/api/pkg/operators/v1alpha1/catalogsource_types.go index 020fecc0ec..6641a614a6 100644 --- a/staging/api/pkg/operators/v1alpha1/catalogsource_types.go +++ b/staging/api/pkg/operators/v1alpha1/catalogsource_types.go @@ -89,6 +89,11 @@ type CatalogSourceSpec struct { // +optional Secrets []string `json:"secrets,omitempty"` + // RunAsRoot allows admins to indicate that they wish to run the CatalogSource pod in a privileged + // pod as root. This should only be enabled when running older catalog images which could not be run as non-root. + // +optional + RunAsRoot bool `json:"runAsRoot,omitempty"` + // Metadata DisplayName string `json:"displayName,omitempty"` Description string `json:"description,omitempty"` diff --git a/staging/api/pkg/validation/internal/annotations.go b/staging/api/pkg/validation/internal/annotations.go index 2ab63aa9fb..715b04171f 100644 --- a/staging/api/pkg/validation/internal/annotations.go +++ b/staging/api/pkg/validation/internal/annotations.go @@ -30,13 +30,13 @@ which are known to be case sensitive. It also checks to see if the olm.propertie annotation is defined in order to add a warning if present. This function can be used anywhere annotations need to be checked for case sensitivity. -Arguments +# Arguments • annotations: annotations map usually obtained from ObjectMeta.GetAnnotations() • value: is the field or file that caused an error or warning -Returns +# Returns • errs: Any errors that may have been detected with the annotation keys provided */ diff --git a/staging/api/pkg/validation/internal/community.go b/staging/api/pkg/validation/internal/community.go index dfc7c4aabe..debaae2bab 100644 --- a/staging/api/pkg/validation/internal/community.go +++ b/staging/api/pkg/validation/internal/community.go @@ -7,7 +7,7 @@ import ( "os" "strings" - "github.com/blang/semver" + "github.com/blang/semver/v4" "github.com/operator-framework/api/pkg/manifests" "github.com/operator-framework/api/pkg/validation/errors" diff --git a/staging/api/pkg/validation/internal/operatorhub.go b/staging/api/pkg/validation/internal/operatorhub.go index ac9fd0cf53..f5da37a274 100644 --- a/staging/api/pkg/validation/internal/operatorhub.go +++ b/staging/api/pkg/validation/internal/operatorhub.go @@ -71,15 +71,15 @@ import ( // containing a list of categories will enable those categories to be used when comparing CSV categories for // OperatorHub validation. The json file should be in the following format: // -// ```json -// { -// "categories":[ -// "Cloud Pak", -// "Registry", -// "MyCoolThing", -// ] -// } -// ``` +// ```json +// { +// "categories":[ +// "Cloud Pak", +// "Registry", +// "MyCoolThing", +// ] +// } +// ``` // // - The `csv.Spec.Provider.Name` was provided // diff --git a/staging/api/pkg/validation/internal/removed_apis.go b/staging/api/pkg/validation/internal/removed_apis.go index 44dee85d06..13feafb5d2 100644 --- a/staging/api/pkg/validation/internal/removed_apis.go +++ b/staging/api/pkg/validation/internal/removed_apis.go @@ -2,12 +2,17 @@ package internal import ( "fmt" - "github.com/blang/semver" + "sort" + "strings" + + "github.com/blang/semver/v4" "github.com/operator-framework/api/pkg/manifests" + "github.com/operator-framework/api/pkg/operators/v1alpha1" "github.com/operator-framework/api/pkg/validation/errors" interfaces "github.com/operator-framework/api/pkg/validation/interfaces" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sort" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) // k8sVersionKey defines the key which can be used by its consumers @@ -147,11 +152,12 @@ func checkRemovedAPIsForVersion( errs []error, warns []error) ([]error, []error) { found := map[string][]string{} + warnsFound := map[string][]string{} switch k8sVersionToCheck.String() { case "1.22.0": found = getRemovedAPIsOn1_22From(bundle) case "1.25.0": - found = getRemovedAPIsOn1_25From(bundle) + found, warnsFound = getRemovedAPIsOn1_25From(bundle) case "1.26.0": found = getRemovedAPIsOn1_26From(bundle) default: @@ -172,6 +178,16 @@ func checkRemovedAPIsForVersion( warns = append(warns, msg) } } + + if len(warnsFound) > 0 { + deprecatedAPIsMessage := generateMessageWithDeprecatedAPIs(warnsFound) + msg := fmt.Errorf(DeprecateMessage, + k8sVersionToCheck.Major, k8sVersionToCheck.Minor, + k8sVersionToCheck.Major, k8sVersionToCheck.Minor, + deprecatedAPIsMessage) + warns = append(warns, msg) + } + return errs, warns } @@ -287,40 +303,115 @@ func getRemovedAPIsOn1_22From(bundle *manifests.Bundle) map[string][]string { // add manifests on the bundle using these APIs. On top of that some Kinds such as the CronJob // are not currently a valid/supported by OLM and never would to be added to bundle. // See: https://github.com/operator-framework/operator-registry/blob/v1.19.5/pkg/lib/bundle/supported_resources.go#L3-L23 -func getRemovedAPIsOn1_25From(bundle *manifests.Bundle) map[string][]string { +func getRemovedAPIsOn1_25From(bundle *manifests.Bundle) (map[string][]string, map[string][]string) { deprecatedAPIs := make(map[string][]string) + warnDeprecatedAPIs := make(map[string][]string) + + deprecatedGvk := map[schema.GroupVersionKind]struct{}{ + {Group: "batch", Version: "v1beta1", Kind: "CronJob"}: {}, + {Group: "discovery.k8s.io", Version: "v1beta1", Kind: "EndpointSlice"}: {}, + {Group: "events.k8s.io", Version: "v1beta1", Kind: "Event"}: {}, + {Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"}: {}, + {Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"}: {}, + {Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {}, + {Group: "node.k8s.io", Version: "v1beta1", Kind: "RuntimeClass"}: {}, + } + + addIfDeprecated := func(u *unstructured.Unstructured) { + if _, ok := deprecatedGvk[u.GetObjectKind().GroupVersionKind()]; ok { + deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], u.GetName()) + } + } + + deprecatedGroupResource := map[schema.GroupResource]struct{}{ + {Group: "batch", Resource: "cronjobs"}: {}, + {Group: "discovery.k8s.io", Resource: "endpointslices"}: {}, + {Group: "events.k8s.io", Resource: "events"}: {}, + {Group: "autoscaling", Resource: "horizontalpodautoscalers"}: {}, + {Group: "policy", Resource: "poddisruptionbudgets"}: {}, + {Group: "policy", Resource: "podsecuritypolicies"}: {}, + {Group: "node.k8s.io", Resource: "runtimeclasses"}: {}, + } + + warnIfDeprecated := func(gr schema.GroupResource, msg string) { + if _, ok := deprecatedGroupResource[gr]; ok { + warnDeprecatedAPIs[gr.Resource] = append(warnDeprecatedAPIs[gr.Resource], msg) + } + } + for _, obj := range bundle.Objects { switch u := obj.GetObjectKind().(type) { case *unstructured.Unstructured: switch u.GetAPIVersion() { - case "batch/v1beta1": - if u.GetKind() == "CronJob" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "discovery.k8s.io/v1beta1": - if u.GetKind() == "EndpointSlice" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "events.k8s.io/v1beta1": - if u.GetKind() == "Event" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "autoscaling/v2beta1": - if u.GetKind() == "HorizontalPodAutoscaler" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "policy/v1beta1": - if u.GetKind() == "PodDisruptionBudget" || u.GetKind() == "PodSecurityPolicy" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "node.k8s.io/v1beta1": - if u.GetKind() == "RuntimeClass" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) + case "operators.coreos.com/v1alpha1": + // Check a couple CSV fields for references to deprecated APIs + if u.GetKind() == "ClusterServiceVersion" { + resInCsvCrds := make(map[string]struct{}) + csv := &v1alpha1.ClusterServiceVersion{} + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, csv) + if err != nil { + fmt.Println("failed to convert unstructured.Unstructed to v1alpha1.ClusterServiceVersion:", err) + } + + // Loop through all the CRDDescriptions to see + // if there is any with an API Version & Kind that is deprecated + crdCheck := func(crdsField string, crdDescriptions []v1alpha1.CRDDescription) { + for i, desc := range crdDescriptions { + for j, res := range desc.Resources { + resFromKind := fmt.Sprintf("%ss", strings.ToLower(res.Kind)) + resInCsvCrds[resFromKind] = struct{}{} + unstruct := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": res.Version, + "kind": res.Kind, + "metadata": map[string]interface{}{ + "name": fmt.Sprintf("ClusterServiceVersion.Spec.CustomResourceDefinitions.%s[%d].Resource[%d]", crdsField, i, j), + }, + }, + } + addIfDeprecated(unstruct) + } + } + } + + // Check the Owned Resources + crdCheck("Owned", csv.Spec.CustomResourceDefinitions.Owned) + + // Check the Required Resources + crdCheck("Required", csv.Spec.CustomResourceDefinitions.Required) + + // Loop through all the StrategyDeploymentPermissions to see + // if the rbacv1.PolicyRule that is defined specifies a resource that + // *may* have a deprecated API then add it to the warnings. + // Only present a warning if the resource was NOT found as a resource + // in the ClusterServiceVersion.Spec.CustomResourceDefinitions fields + permCheck := func(permField string, perms []v1alpha1.StrategyDeploymentPermissions) { + for i, perm := range perms { + for j, rule := range perm.Rules { + for _, apiGroup := range rule.APIGroups { + for _, res := range rule.Resources { + if _, ok := resInCsvCrds[res]; ok { + continue + } + warnIfDeprecated(schema.GroupResource{Group: apiGroup, Resource: res}, fmt.Sprintf("ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.%s[%d].Rules[%d]", permField, i, j)) + } + } + } + } + } + + // Check the ClusterPermissions + permCheck("ClusterPermissions", csv.Spec.InstallStrategy.StrategySpec.ClusterPermissions) + + // Check the Permissions + permCheck("Permissions", csv.Spec.InstallStrategy.StrategySpec.Permissions) } + default: + addIfDeprecated(u) } } } - return deprecatedAPIs + return deprecatedAPIs, warnDeprecatedAPIs } // getRemovedAPIsOn1_26From return the list of resources which were deprecated diff --git a/staging/api/pkg/validation/internal/removed_apis_test.go b/staging/api/pkg/validation/internal/removed_apis_test.go index 60cc3a2ff8..ac238fabb7 100644 --- a/staging/api/pkg/validation/internal/removed_apis_test.go +++ b/staging/api/pkg/validation/internal/removed_apis_test.go @@ -72,27 +72,47 @@ func Test_GetRemovedAPIsOn1_25From(t *testing.T) { mock["HorizontalPodAutoscaler"] = []string{"memcached-operator-hpa"} mock["PodDisruptionBudget"] = []string{"memcached-operator-policy-manager"} + warnMock := make(map[string][]string) + warnMock["cronjobs"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.ClusterPermissions[0].Rules[7]"} + warnMock["endpointslices"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[3]"} + warnMock["events"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[2]"} + warnMock["horizontalpodautoscalers"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[4]"} + warnMock["poddisruptionbudgets"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[5]"} + warnMock["podsecuritypolicies"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[5]"} + warnMock["runtimeclasses"] = []string{"ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.Permissions[0].Rules[6]"} + type args struct { bundleDir string } tests := []struct { - name string - args args - want map[string][]string + name string + args args + errWant map[string][]string + warnWant map[string][]string }{ { name: "should return an empty map when no deprecated apis are found", args: args{ bundleDir: "./testdata/valid_bundle_v1", }, - want: map[string][]string{}, + errWant: map[string][]string{}, + warnWant: map[string][]string{}, }, { name: "should fail return the removed APIs in 1.25", args: args{ bundleDir: "./testdata/removed_api_1_25", }, - want: mock, + errWant: mock, + warnWant: map[string][]string{}, + }, + { + name: "should return warnings with all deprecated APIs in 1.25", + args: args{ + bundleDir: "./testdata/deprecated_api_1_25", + }, + errWant: mock, + warnWant: warnMock, }, } for _, tt := range tests { @@ -102,8 +122,14 @@ func Test_GetRemovedAPIsOn1_25From(t *testing.T) { bundle, err := manifests.GetBundleFromDir(tt.args.bundleDir) require.NoError(t, err) - if got := getRemovedAPIsOn1_25From(bundle); !reflect.DeepEqual(got, tt.want) { - t.Errorf("getRemovedAPIsOn1_25From() = %v, want %v", got, tt.want) + errGot, warnGot := getRemovedAPIsOn1_25From(bundle) + + if !reflect.DeepEqual(errGot, tt.errWant) { + t.Errorf("getRemovedAPIsOn1_25From() = %v, want %v", errGot, tt.errWant) + } + + if !reflect.DeepEqual(warnGot, tt.warnWant) { + t.Errorf("getRemovedAPIsOn1_25From() = %v, want %v", warnGot, tt.warnWant) } }) } @@ -252,8 +278,8 @@ func TestValidateDeprecatedAPIS(t *testing.T) { wantWarning: true, warnStrings: []string{"this bundle is using APIs which were deprecated and removed in v1.22. " + "More info: https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-22. " + - "Migrate the API(s) for CRD: ([\"etcdbackups.etcd.database.coreos.com\"" + - " \"etcdclusters.etcd.database.coreos.com\" \"etcdrestores.etcd.database.coreos.com\"])"}, + "Migrate the API(s) for CRD: ([\"etcdbackups.etcd.database.coreos.com\" " + + "\"etcdclusters.etcd.database.coreos.com\" \"etcdrestores.etcd.database.coreos.com\"])"}, }, { name: "should return an error when the csv.spec.minKubeVersion informed is invalid", diff --git a/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/cache.example.com_memcacheds.yaml b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/cache.example.com_memcacheds.yaml new file mode 100644 index 0000000000..a8ea3eb8d3 --- /dev/null +++ b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/cache.example.com_memcacheds.yaml @@ -0,0 +1,66 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: memcacheds.cache.example.com +spec: + group: cache.example.com + names: + kind: Memcached + listKind: MemcachedList + plural: memcacheds + singular: memcached + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Memcached is the Schema for the memcacheds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: MemcachedSpec defines the desired state of Memcached + properties: + foo: + description: Foo is an example field of Memcached. Edit memcached_types.go + to remove/update + type: string + size: + description: Size defines the number of Memcached instances + format: int32 + type: integer + type: object + status: + description: MemcachedStatus defines the observed state of Memcached + properties: + nodes: + description: Nodes store the name of the pods which are running Memcached + instances + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/horizontal-pod.yaml b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/horizontal-pod.yaml new file mode 100644 index 0000000000..69f77b5f49 --- /dev/null +++ b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/horizontal-pod.yaml @@ -0,0 +1,18 @@ +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: memcached-operator-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: memcached-operator-controller-manager + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 \ No newline at end of file diff --git a/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/memcached-operator.clusterserviceversion.yaml b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/memcached-operator.clusterserviceversion.yaml new file mode 100644 index 0000000000..a28ca3a117 --- /dev/null +++ b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/memcached-operator.clusterserviceversion.yaml @@ -0,0 +1,287 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "cache.example.com/v1alpha1", + "kind": "Memcached", + "metadata": { + "name": "memcached-sample" + }, + "spec": { + "size": 1 + } + } + ] + capabilities: Basic Install + name: memcached-operator.v0.0.1 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Memcached is the Schema for the memcacheds API + displayName: Memcached + kind: Memcached + name: memcacheds.cache.example.com + version: v1alpha1 + description: Memcached Operator description. TODO. + displayName: Memcached Operator + icon: + - base64data: "" + mediatype: "" + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - cache.example.com + resources: + - memcacheds/finalizers + verbs: + - update + - apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get + - patch + - update + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - apiGroups: + - batch + resources: + - cronjobs + verbs: + - get + serviceAccountName: memcached-operator-controller-manager + deployments: + - name: memcached-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + strategy: {} + template: + metadata: + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: {} + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: quay.io/example/memcached-operator:v0.0.1 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + securityContext: + runAsNonRoot: true + serviceAccountName: memcached-operator-controller-manager + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - create + - patch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - patch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - podsecuritypolicies + verbs: + - create + - patch + - apiGroups: + - node.k8s.io + resources: + - runtimeclasses + verbs: + - create + - patch + serviceAccountName: memcached-operator-controller-manager + strategy: deployment + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - memcached-operator + links: + - name: Memcached Operator + url: https://memcached-operator.domain + maintainers: + - email: your@email.com + name: Maintainer Name + maturity: alpha + provider: + name: Provider Name + url: https://your.domain + version: 0.0.1 + webhookdefinitions: + - admissionReviewVersions: + - v1 + - v1beta1 + containerPort: 443 + deploymentName: memcached-operator-controller-manager + failurePolicy: Fail + generateName: vmemcached.kb.io + rules: + - apiGroups: + - cache.example.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - memcacheds + sideEffects: None + targetPort: 9443 + type: ValidatingAdmissionWebhook + webhookPath: /validate-cache-example-com-v1alpha1-memcached + - admissionReviewVersions: + - v1 + - v1beta1 + containerPort: 443 + deploymentName: memcached-operator-controller-manager + failurePolicy: Fail + generateName: mmemcached.kb.io + rules: + - apiGroups: + - cache.example.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - memcacheds + sideEffects: None + targetPort: 9443 + type: MutatingAdmissionWebhook + webhookPath: /mutate-cache-example-com-v1alpha1-memcached diff --git a/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/policy.yaml b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/policy.yaml new file mode 100644 index 0000000000..15714a60c3 --- /dev/null +++ b/staging/api/pkg/validation/internal/testdata/deprecated_api_1_25/policy.yaml @@ -0,0 +1,9 @@ +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: memcached-operator-policy-manager +spec: + minAvailable: 2 + selector: + matchLabels: + app: memcached-operator \ No newline at end of file diff --git a/staging/api/pkg/validation/internal/testdata/valid_bundle_v1/memcached-operator.clusterserviceversion.yaml b/staging/api/pkg/validation/internal/testdata/valid_bundle_v1/memcached-operator.clusterserviceversion.yaml index bddc807691..66794210ec 100644 --- a/staging/api/pkg/validation/internal/testdata/valid_bundle_v1/memcached-operator.clusterserviceversion.yaml +++ b/staging/api/pkg/validation/internal/testdata/valid_bundle_v1/memcached-operator.clusterserviceversion.yaml @@ -176,13 +176,6 @@ spec: - update - patch - delete - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch serviceAccountName: memcached-operator-controller-manager strategy: deployment installModes: diff --git a/staging/operator-lifecycle-manager/.github/workflows/goreleaser.yaml b/staging/operator-lifecycle-manager/.github/workflows/goreleaser.yaml index c66e177213..b4cd95607a 100644 --- a/staging/operator-lifecycle-manager/.github/workflows/goreleaser.yaml +++ b/staging/operator-lifecycle-manager/.github/workflows/goreleaser.yaml @@ -37,6 +37,10 @@ jobs: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + if: startsWith(github.ref, 'refs/tags') + - name: Docker Login uses: docker/login-action@v1 if: startsWith(github.ref, 'refs/tags') diff --git a/staging/operator-lifecycle-manager/.github/workflows/sanity.yaml b/staging/operator-lifecycle-manager/.github/workflows/sanity.yaml index 695c48f889..ea701cec8b 100644 --- a/staging/operator-lifecycle-manager/.github/workflows/sanity.yaml +++ b/staging/operator-lifecycle-manager/.github/workflows/sanity.yaml @@ -19,7 +19,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: actions/setup-go@v3 + with: + go-version-file: "go.mod" - name: Run linting checks - uses: "golangci/golangci-lint-action@v2" + uses: "golangci/golangci-lint-action@v3" with: - version: "v1.46.0" + version: "v1.50.1" diff --git a/staging/operator-lifecycle-manager/Dockerfile b/staging/operator-lifecycle-manager/Dockerfile index 075a5dbd4e..72df7fa0fe 100644 --- a/staging/operator-lifecycle-manager/Dockerfile +++ b/staging/operator-lifecycle-manager/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/fedora/fedora:34-x86_64 as builder +FROM quay.io/fedora/fedora:37-x86_64 as builder LABEL stage=builder WORKDIR /build diff --git a/staging/operator-lifecycle-manager/Dockerfile.goreleaser b/staging/operator-lifecycle-manager/Dockerfile.goreleaser index a117f6623e..5308799547 100644 --- a/staging/operator-lifecycle-manager/Dockerfile.goreleaser +++ b/staging/operator-lifecycle-manager/Dockerfile.goreleaser @@ -1,4 +1,4 @@ -FROM --platform=$BUILDPLATFORM gcr.io/distroless/static:debug +FROM gcr.io/distroless/static:debug LABEL stage=olm WORKDIR / # bundle unpack Jobs require cp at /bin/cp diff --git a/staging/operator-lifecycle-manager/Makefile b/staging/operator-lifecycle-manager/Makefile index f892f12e95..ae104d6de2 100644 --- a/staging/operator-lifecycle-manager/Makefile +++ b/staging/operator-lifecycle-manager/Makefile @@ -29,7 +29,11 @@ GO := GO111MODULE=on GOFLAGS="$(MOD_FLAGS)" go GINKGO := $(GO) run github.com/onsi/ginkgo/v2/ginkgo BINDATA := $(GO) run github.com/go-bindata/go-bindata/v3/go-bindata GIT_COMMIT := $(shell git rev-parse HEAD) - +ifeq ($(shell arch), arm64) +ARCH := arm64 +else +ARCH := 386 +endif # Phony prerequisite for targets that rely on the go build cache to determine staleness. .PHONY: build test clean vendor \ coverage coverage-html e2e \ @@ -82,15 +86,15 @@ build-coverage: build_cmd=test -c -covermode=count -coverpkg ./pkg/controller/.. build-coverage: clean $(CMDS) build-linux: build_cmd=build -build-linux: arch_flags=GOOS=linux GOARCH=386 +build-linux: arch_flags=GOOS=linux GOARCH=$(ARCH) build-linux: clean $(CMDS) build-wait: clean bin/wait bin/wait: FORCE - GOOS=linux GOARCH=386 go build $(MOD_FLAGS) -o $@ $(PKG)/test/e2e/wait + GOOS=linux GOARCH=$(ARCH) go build $(MOD_FLAGS) -o $@ $(PKG)/test/e2e/wait -build-util-linux: arch_flags=GOOS=linux GOARCH=386 +build-util-linux: arch_flags=GOOS=linux GOARCH=$(ARCH) build-util-linux: build-util build-util: bin/cpb diff --git a/staging/operator-lifecycle-manager/deploy/chart/templates/0000_50_olm_17-upstream-operators.catalogsource.yaml b/staging/operator-lifecycle-manager/deploy/chart/templates/0000_50_olm_17-upstream-operators.catalogsource.yaml index 534a21c2c8..3a072034f0 100644 --- a/staging/operator-lifecycle-manager/deploy/chart/templates/0000_50_olm_17-upstream-operators.catalogsource.yaml +++ b/staging/operator-lifecycle-manager/deploy/chart/templates/0000_50_olm_17-upstream-operators.catalogsource.yaml @@ -9,6 +9,8 @@ spec: image: quay.io/operatorhubio/catalog:latest displayName: Community Operators publisher: OperatorHub.io + grpcPodConfig: + securityContextConfig: restricted updateStrategy: registryPoll: interval: 60m diff --git a/staging/operator-lifecycle-manager/doc/install/install.md b/staging/operator-lifecycle-manager/doc/install/install.md index b842906146..4be3e31aba 100644 --- a/staging/operator-lifecycle-manager/doc/install/install.md +++ b/staging/operator-lifecycle-manager/doc/install/install.md @@ -25,7 +25,7 @@ This command starts minikube, builds the OLM containers locally with the minikub $ make run-local ``` -You can verify that the OLM components have been successfully deployed by running `kubectl -n local get deployments` +You can verify that the OLM components have been successfully deployed by running `kubectl -n olm get deployments` **NOTE** It is recommended for development purposes and will use the source locally diff --git a/staging/operator-lifecycle-manager/go.mod b/staging/operator-lifecycle-manager/go.mod index bbbb46a0d4..e463273473 100644 --- a/staging/operator-lifecycle-manager/go.mod +++ b/staging/operator-lifecycle-manager/go.mod @@ -7,152 +7,135 @@ require ( github.com/coreos/go-semver v0.3.0 github.com/davecgh/go-spew v1.1.1 github.com/distribution/distribution v2.7.1+incompatible - github.com/fsnotify/fsnotify v1.5.4 + github.com/fsnotify/fsnotify v1.6.0 github.com/ghodss/yaml v1.0.0 github.com/go-air/gini v1.0.4 github.com/go-bindata/go-bindata/v3 v3.1.3 github.com/go-logr/logr v1.2.3 github.com/golang/mock v1.6.0 - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.5.9 github.com/googleapis/gnostic v0.5.5 github.com/itchyny/gojq v0.11.0 github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37 github.com/mitchellh/hashstructure v1.0.0 github.com/mitchellh/mapstructure v1.4.1 - github.com/onsi/ginkgo/v2 v2.1.6 - github.com/onsi/gomega v1.20.1 + github.com/onsi/ginkgo/v2 v2.6.0 + github.com/onsi/gomega v1.24.1 github.com/openshift/api v3.9.0+incompatible github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a + github.com/openshift/cluster-policy-controller v0.0.0-20230217170320-ac01e3463245 github.com/operator-framework/api v0.17.3 github.com/operator-framework/operator-registry v1.17.5 github.com/otiai10/copy v1.2.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.12.2 - github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.32.1 - github.com/sirupsen/logrus v1.8.1 - github.com/spf13/cobra v1.4.0 + github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_model v0.3.0 + github.com/prometheus/common v0.37.0 + github.com/sirupsen/logrus v1.9.0 + github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.0 - golang.org/x/net v0.0.0-20220909164309-bea034e7d591 - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 - google.golang.org/grpc v1.47.0 + github.com/stretchr/testify v1.8.2 + golang.org/x/net v0.7.0 + golang.org/x/time v0.3.0 + google.golang.org/grpc v1.52.0 gopkg.in/yaml.v2 v2.4.0 - helm.sh/helm/v3 v3.9.0 - k8s.io/api v0.25.3 - k8s.io/apiextensions-apiserver v0.25.3 - k8s.io/apimachinery v0.25.3 - k8s.io/apiserver v0.25.3 - k8s.io/client-go v0.25.3 - k8s.io/code-generator v0.25.3 - k8s.io/component-base v0.25.3 + helm.sh/helm/v3 v3.11.1 + k8s.io/api v0.26.1 + k8s.io/apiextensions-apiserver v0.26.1 + k8s.io/apimachinery v0.26.1 + k8s.io/apiserver v0.26.1 + k8s.io/client-go v0.26.1 + k8s.io/code-generator v0.26.1 + k8s.io/component-base v0.26.1 k8s.io/klog v1.0.0 k8s.io/kube-aggregator v0.25.3 - k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 - k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 - sigs.k8s.io/controller-runtime v0.13.0 + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 + k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 + sigs.k8s.io/controller-runtime v0.14.5 sigs.k8s.io/controller-tools v0.8.0 sigs.k8s.io/kind v0.16.0 ) replace google.golang.org/grpc => google.golang.org/grpc v1.40.0 -replace ( - go.opentelemetry.io/contrib => go.opentelemetry.io/contrib v0.20.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 - go.opentelemetry.io/otel/exporters/otlp => go.opentelemetry.io/otel/exporters/otlp v0.20.0 - go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v0.20.0 - go.opentelemetry.io/otel/oteltest => go.opentelemetry.io/otel/oteltest v0.20.0 - go.opentelemetry.io/otel/sdk/export/metric => go.opentelemetry.io/otel/sdk/export/metric v0.20.0 - go.opentelemetry.io/otel/sdk/metric => go.opentelemetry.io/otel/sdk/metric v0.20.0 - go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v0.20.0 - go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v0.7.0 -) - require ( cloud.google.com/go v0.99.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.27 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/BurntSushi/toml v1.0.0 // indirect - github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.2 // indirect - github.com/Masterminds/squirrel v1.5.2 // indirect + github.com/Masterminds/semver/v3 v3.2.0 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/squirrel v1.5.3 // indirect github.com/Masterminds/vcs v1.13.3 // indirect - github.com/Microsoft/go-winio v0.5.1 // indirect - github.com/Microsoft/hcsshim v0.9.2 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/Microsoft/hcsshim v0.9.6 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/alessio/shellescape v1.4.1 // indirect - github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect + github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect - github.com/containerd/cgroups v1.0.3 // indirect - github.com/containerd/containerd v1.6.3 // indirect - github.com/containerd/continuity v0.2.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/containerd v1.6.15 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/ttrpc v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect - github.com/docker/cli v20.10.11+incompatible // indirect + github.com/docker/cli v20.10.21+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.14+incompatible // indirect - github.com/docker/docker-credential-helpers v0.6.4 // indirect + github.com/docker/docker v20.10.21+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/emicklei/go-restful/v3 v3.8.0 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.10.2 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/color v1.13.0 // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fvbommel/sortorder v1.0.1 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-gorp/gorp/v3 v3.0.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.2.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.5 // indirect - github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/gobuffalo/flect v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-yaml v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.2.0 // indirect github.com/golang-migrate/migrate/v4 v4.6.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/cel-go v0.12.5 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/cel-go v0.12.6 // indirect + github.com/google/gnostic v0.6.9 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/h2non/filetype v1.1.1 // indirect github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // indirect - github.com/huandu/xstrings v1.3.2 // indirect - github.com/imdario/mergo v0.3.12 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/huandu/xstrings v1.3.3 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645 // indirect - github.com/jmoiron/sqlx v1.3.4 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kisielk/errcheck v1.5.0 // indirect @@ -161,35 +144,34 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lestrrat-go/strftime v1.0.1 // indirect - github.com/lib/pq v1.10.4 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/mattn/go-sqlite3 v1.14.6 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mattn/go-sqlite3 v1.14.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/sys/mountinfo v0.5.0 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rubenv/sql-migrate v1.1.1 // indirect - github.com/russross/blackfriday v1.5.2 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rubenv/sql-migrate v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/cast v1.4.1 // indirect @@ -197,55 +179,55 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect + github.com/xlab/treeprint v1.1.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.etcd.io/etcd/api/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/v3 v3.5.4 // indirect + go.etcd.io/etcd/api/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/v3 v3.5.5 // indirect go.opencensus.io v0.23.0 // indirect - go.opentelemetry.io/contrib v1.3.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect - go.opentelemetry.io/otel v1.3.0 // indirect - go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect - go.opentelemetry.io/otel/metric v0.20.0 // indirect - go.opentelemetry.io/otel/sdk v1.3.0 // indirect - go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect - go.opentelemetry.io/otel/trace v1.3.0 // indirect - go.opentelemetry.io/proto/otlp v0.12.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 // indirect + go.opentelemetry.io/otel v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0 // indirect + go.opentelemetry.io/otel/metric v0.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.10.0 // indirect + go.opentelemetry.io/otel/trace v1.10.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.5.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.12 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.29.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/cli-runtime v0.24.0 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kubectl v0.24.0 // indirect - oras.land/oras-go v1.1.0 // indirect + k8s.io/cli-runtime v0.26.0 // indirect + k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/kms v0.26.2 // indirect + k8s.io/kubectl v0.26.0 // indirect + oras.land/oras-go v1.2.2 // indirect rsc.io/letsencrypt v0.0.3 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/kustomize/api v0.11.4 // indirect - sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.12.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) @@ -254,10 +236,4 @@ replace ( // controller runtime github.com/openshift/api => github.com/openshift/api v0.0.0-20221021112143-4226c2167e40 // release-4.12 github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c // release-4.12 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 - go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0 ) - -// downstream only -require github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f diff --git a/staging/operator-lifecycle-manager/go.sum b/staging/operator-lifecycle-manager/go.sum index 9c6a34e5dd..68db8fc52f 100644 --- a/staging/operator-lifecycle-manager/go.sum +++ b/staging/operator-lifecycle-manager/go.sum @@ -1,5 +1,4 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -53,54 +52,42 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg= -github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE= -github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc= +github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Masterminds/vcs v1.13.3 h1:IIA2aBdXvfbIM+yl/eTnL4hb1XwdpvuQLglAix1gweE= github.com/Masterminds/vcs v1.13.3/go.mod h1:TiE7xuEjl1N4j016moRd6vezp6e6Lz23gypeXfzXeW8= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -111,8 +98,8 @@ 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.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 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= @@ -121,8 +108,8 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= -github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY= +github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= 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= @@ -132,10 +119,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -154,8 +139,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -169,7 +154,6 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -193,6 +177,7 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v1.5.3 h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04= github.com/bugsnag/bugsnag-go v1.5.3/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= @@ -201,13 +186,17 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA= github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= 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/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= 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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -237,8 +226,8 @@ github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4S github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= @@ -259,8 +248,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.6.3 h1:JfgUEIAH07xDWk6kqz0P3ArZt+KJ9YeihSC9uyFtSKg= -github.com/containerd/containerd v1.6.3/go.mod h1:gCVGrYRYFm2E8GmuUIbj/NGD7DLZQLzSJQazjVKDOig= +github.com/containerd/containerd v1.6.15 h1:4wWexxzLNHNE46aIETc6ge4TofO550v+BlLoANrbses= +github.com/containerd/containerd v1.6.15/go.mod h1:U2NnBPIhzJDm59xF7xB2MMHnKtggpZ+phKg8o2TKj2c= 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= @@ -269,8 +258,8 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -340,12 +329,12 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc 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/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/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/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= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= @@ -363,7 +352,6 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= -github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -377,12 +365,12 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= github.com/distribution/distribution v2.7.1+incompatible h1:aGFx4EvJWKEh//lHPLwFhFgwFHKH06TzNVPamrMn04M= github.com/distribution/distribution v2.7.1+incompatible/go.mod h1:EgLm2NgWtdKgzF9NpMzUKgzmR7AMmb0VQi2B+ZzDRjc= -github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684 h1:DBZ2sN7CK6dgvHVpQsQj4sRMCbWTmd17l+5SUCjnQSY= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc= -github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= +github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -394,11 +382,11 @@ github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.14+incompatible h1:+T9/PRYWNDo5SZl5qS1r9Mo/0Q8AwxKKPtu9S1yxM0w= -github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= +github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= -github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -426,8 +414,8 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7fo 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= -github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= -github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 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= @@ -435,9 +423,8 @@ github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMi github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.2.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= @@ -450,24 +437,24 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= 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= @@ -497,9 +484,11 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 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.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -507,8 +496,9 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= @@ -524,15 +514,15 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -555,16 +545,17 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -602,13 +593,12 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -642,8 +632,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 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/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -656,10 +647,10 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8= -github.com/google/cel-go v0.12.5/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M= +github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -672,8 +663,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -698,16 +689,18 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe 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 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ= +github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= 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= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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= @@ -747,6 +740,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-health-probe v0.3.2/go.mod h1:izVOQ4RWbjUR6lm4nn+VLJyQ+FyaiGmprEYgI04Gs7U= github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4= github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= @@ -770,6 +765,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 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= @@ -779,18 +775,21 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645 h1:3gyXljUyTWWTv/NMFPvwgxJSdE9Mamg2r3x8HMBl+Uo= github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645/go.mod h1:296z3W7Xsrp2mlIY88ruDKscuvrkL6zXCNRtaYVshzw= github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA= @@ -808,15 +807,14 @@ github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= -github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joefitzgerald/rainbow-reporter v0.1.0 h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d h1:A2/B900ip/Z20TzkLeGRNy1s6J2HmH9AmGt+dHyqb4I= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d/go.mod h1:7HQupe4vyNxMKXmM5DFuwXHsqwMyglcYmZBtlDPIcZ8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= 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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -876,8 +874,8 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= @@ -891,8 +889,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= @@ -918,7 +916,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -926,11 +923,13 @@ github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -939,7 +938,7 @@ github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37 h1:lPmsut5Sk7eK2Bm github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37/go.mod h1:dYWq+UWoFCDY1TndvFUQuhBbIYmZpjreC8adEAx93zE= 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.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -970,8 +969,8 @@ github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9 github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -998,7 +997,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1010,11 +1008,10 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= +github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1026,8 +1023,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1037,8 +1034,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I 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/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= 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= @@ -1060,8 +1057,8 @@ github.com/openshift/api v0.0.0-20221021112143-4226c2167e40 h1:PxjGCA72RtsdHWToZ github.com/openshift/api v0.0.0-20221021112143-4226c2167e40/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A= github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c h1:CV76yFOTXmq9VciBR3Bve5ZWzSxdft7gaMVB3kS0rwg= github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c/go.mod h1:lFMO8mLHXWFzSdYvGNo8ivF9SfF6zInA8ZGw4phRnUE= -github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f h1:ll0eE7rgGHsFlrI6ksr6nXL2ur8GYBe8Jj0GwNQ/1+o= -github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f/go.mod h1:r9ZZT5wjwoS2heBfYR26uJhhkGYwgmFqomu9ww0y9Qw= +github.com/openshift/cluster-policy-controller v0.0.0-20230217170320-ac01e3463245 h1:BoNt9Hemwyc32xX+CZZaNGegWEiN7bGTVk4XaRboO8k= +github.com/openshift/cluster-policy-controller v0.0.0-20230217170320-ac01e3463245/go.mod h1:vlkRuwyRueLOQ/ZRRle+rCrh+YNoh+pzJm9WaN9e6mU= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/operator-framework/api v0.7.1/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY= github.com/operator-framework/api v0.17.3 h1:wddE1SLKTNiIzwt28DbBIO+vPG2GOV6dkB9xBkDfT3o= @@ -1082,12 +1079,13 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= 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/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 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/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1112,15 +1110,16 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1129,8 +1128,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= 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= @@ -1143,17 +1143,17 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY= -github.com/rubenv/sql-migrate v1.1.1/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/rubenv/sql-migrate v1.2.0 h1:fOXMPLMd41sK7Tg75SXDec15k3zg5WNV6SjuDRiNfcU= +github.com/rubenv/sql-migrate v1.2.0/go.mod h1:Z5uVnq7vrIrPmHbVFfR4YLHRZquxeHpckCnRq0P/K9Y= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1179,8 +1179,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -1189,7 +1190,6 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= 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/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -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/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1201,8 +1201,9 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL 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.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1222,8 +1223,9 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1233,8 +1235,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1247,7 +1251,6 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -1276,8 +1279,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1285,7 +1288,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= @@ -1307,18 +1310,18 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao= -go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/pkg/v3 v3.5.4 h1:V5Dvl7S39ZDwjkKqJG2BfXgxZ3QREqqKifWQgIw5IM0= -go.etcd.io/etcd/raft/v3 v3.5.4 h1:YGrnAgRfgXloBNuqa+oBI/aRZMcK/1GS6trJePJ/Gqc= -go.etcd.io/etcd/server/v3 v3.5.4 h1:CMAZd0g8Bn5NRhynW6pKhc4FRg41/0QYy3d7aNm9874= +go.etcd.io/etcd/client/v2 v2.305.5 h1:DktRP60//JJpnPC0VBymAN/7V71GHMdjDCBt4ZPXDjI= +go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI= +go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= +go.etcd.io/etcd/pkg/v3 v3.5.5 h1:Ablg7T7OkR+AeeeU32kdVhw/AGDsitkKPl7aW73ssjU= +go.etcd.io/etcd/raft/v3 v3.5.5 h1:Ibz6XyZ60OYyRopu73lLM/P+qco3YtlZMOhnXNS051I= +go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1333,30 +1336,27 @@ 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/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 h1:xFSRQBbXF6VvYRf2lqMJXxoB72XI1K/azav8TekHHSw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 h1:Ajldaqhxqw/gNzQA45IKFWLdG7jZuXX/wBW1d5qvbUI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0 h1:TaB+1rQhddO1sF71MpZOZAuSPW1klK2M8XxfrBMfK7Y= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0 h1:pDDYmo0QadUPal5fwXoY1pmMpFcdyhXOmL5drCrI3vU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0 h1:KtiUEhQmj/Pa874bVYKGNVdq8NPKiacPbaRRtgXi+t4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= +go.opentelemetry.io/otel/metric v0.31.0 h1:6SiklT+gfWAwWUR0meEMxQBtihpiEs4c+vL9spDTqUs= +go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= +go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1365,8 +1365,6 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1378,8 +1376,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= 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= @@ -1406,10 +1404,9 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= 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= @@ -1445,9 +1442,9 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1508,11 +1505,12 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/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-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1531,8 +1529,9 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ 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-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= 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= @@ -1544,8 +1543,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1653,18 +1653,22 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc 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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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= @@ -1674,17 +1678,18 @@ 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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1757,14 +1762,15 @@ 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.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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= -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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= @@ -1896,8 +1902,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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= @@ -1944,6 +1951,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= @@ -1951,8 +1959,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -helm.sh/helm/v3 v3.9.0 h1:qDSWViuF6SzZX5s5AB/NVRGWmdao7T5j4S4ebIkMGag= -helm.sh/helm/v3 v3.9.0/go.mod h1:fzZfyslcPAWwSdkXrXlpKexFeE2Dei8N27FFQWt+PN0= +helm.sh/helm/v3 v3.11.1 h1:cmL9fFohOoNQf+wnp2Wa0OhNFH0KFnSzEkVxi3fcc3I= +helm.sh/helm/v3 v3.11.1/go.mod h1:z/Bu/BylToGno/6dtNGuSmjRqxKq5gaH+FU0BPO+AQ8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1964,54 +1972,48 @@ k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I= -k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ= -k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= k8s.io/apiextensions-apiserver v0.20.6/go.mod h1:qO8YMqeMmZH+lV21LUNzV41vfpoE9QVAJRA+MNqj0mo= -k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= -k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= +k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= +k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.2/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.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= -k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.25.3 h1:m7+xGuG5+KYAnEsqaFtDyWMkmMMEOFYlu+NlWv5qSBI= -k8s.io/apiserver v0.25.3/go.mod h1:9bT47iM2fzRuhICJpM/RcQR9sqDDfZ7Yw60h0p3JW08= +k8s.io/apiserver v0.26.1 h1:6vmnAqCDO194SVCPU3MU8NcDgSqsUA62tBUSWrFXhsc= +k8s.io/apiserver v0.26.1/go.mod h1:wr75z634Cv+sifswE9HlAo5FQ7UoUauIICRlOE+5dCg= k8s.io/cli-runtime v0.20.6/go.mod h1:JVERW478qcxWrUjJuWQSqyJeiz9QC4T6jmBznHFBC8w= -k8s.io/cli-runtime v0.24.0 h1:ot3Qf49T852uEyNApABO1UHHpFIckKK/NqpheZYN2gM= -k8s.io/cli-runtime v0.24.0/go.mod h1:9XxoZDsEkRFUThnwqNviqzljtT/LdHtNWvcNFrAXl0A= +k8s.io/cli-runtime v0.26.0 h1:aQHa1SyUhpqxAw1fY21x2z2OS5RLtMJOCj7tN4oq8mw= +k8s.io/cli-runtime v0.26.0/go.mod h1:o+4KmwHzO/UK0wepE1qpRk6l3o60/txUZ1fEXWGIKTY= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw= -k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0= -k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA= +k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= +k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/code-generator v0.20.6/go.mod h1:i6FmG+QxaLxvJsezvZp0q/gAEzzOz3U53KFibghWToU= -k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/code-generator v0.25.3 h1:BEH+wDi90bGyrYcY4abGtUqaOX7G94RRrEu8l+SvIeo= -k8s.io/code-generator v0.25.3/go.mod h1:9F5fuVZOMWRme7MYj2YT3L9ropPWPokd9VRhVyD3+0w= +k8s.io/code-generator v0.26.1 h1:dusFDsnNSKlMFYhzIM0jAO1OlnTN5WYwQQ+Ai12IIlo= +k8s.io/code-generator v0.26.1/go.mod h1:OMoJ5Dqx1wgaQzKgc+ZWaZPfGjdRq/Y3WubFrZmeI3I= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA= -k8s.io/component-base v0.25.3 h1:UrsxciGdrCY03ULT1h/S/gXFCOPnLhUVwSyx+hM/zq4= -k8s.io/component-base v0.25.3/go.mod h1:WYoS8L+IlTZgU7rhAl5Ctpw0WdMxDfCC5dkxcEFa/TI= +k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= +k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU= k8s.io/component-helpers v0.20.6/go.mod h1:d4rFhZS/wxrZCxRiJJiWf1mVGVeMB5/ey3Yv8/rOp78= -k8s.io/component-helpers v0.24.0/go.mod h1:Q2SlLm4h6g6lPTC9GMMfzdywfLSvJT2f1hOnnjaWD8c= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -2021,9 +2023,8 @@ k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4 h1:aClvVG6GbX10ISHcc24J+tqbr0S7fEe1MWkFJ7cWWCI= +k8s.io/gengo v0.0.0-20230306165830-ab3349d207d4/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= @@ -2031,32 +2032,28 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= 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.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.26.2 h1:GM1gg3tFK3OUU/QQFi93yGjG3lJT8s8l3Wkn2+VxBLM= +k8s.io/kms v0.26.2/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= k8s.io/kube-aggregator v0.25.3 h1:eOG9S4GPICAXWIFeQDHjnhqYaYPpgLIC1NunJu9pZCs= k8s.io/kube-aggregator v0.25.3/go.mod h1:w87nqmzJMf7S73FRYcnexqfYW0AFiLJiCkvVCwM3feE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= 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-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kubectl v0.20.6/go.mod h1:yTCGVrlkBuQhFbKA1R65+lQ9hH7XeyOqUd0FUPFicPg= -k8s.io/kubectl v0.24.0 h1:nA+WtMLVdXUs4wLogGd1mPTAesnLdBpCVgCmz3I7dXo= -k8s.io/kubectl v0.24.0/go.mod h1:pdXkmCyHiRTqjYfyUJiXtbVNURhv0/Q1TyRhy2d5ic0= +k8s.io/kubectl v0.26.0 h1:xmrzoKR9CyNdzxBmXV7jW9Ln8WMrwRK6hGbbf69o4T0= +k8s.io/kubectl v0.26.0/go.mod h1:eInP0b+U9XUJWSYeU9XZnTA+cVYuWyl3iYPGtru0qhQ= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.20.6/go.mod h1:d+OAIaXutom9kGWcBit/M8OkDpIzBKTsm47+KcUt7VI= -k8s.io/metrics v0.24.0/go.mod h1:jrLlFGdKl3X+szubOXPG0Lf2aVxuV3QJcbsgVRAM6fI= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 h1:H9TCJUUx+2VA0ZiD9lvtaX8fthFsMoD+Izn93E/hm8U= -k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg= -oras.land/oras-go v1.1.0/go.mod h1:1A7vR/0KknT2UkJVWh+xMi95I/AhK8ZrxrnUSmXN0bQ= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go v1.2.2 h1:0E9tOHUfrNH7TCDk5KU0jVBEzCqbfdyuVfGmJ7ZeRPE= +oras.land/oras-go v1.2.2/go.mod h1:Apa81sKoZPpP7CDciE006tSZ0x3Q3+dOoBcMZ/aNxvw= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM= rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= @@ -2065,33 +2062,29 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= 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.33 h1:LYqFq+6Cj2D0gFfrJvL7iElD4ET6ir3VDdhDdTK7rgc= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33/go.mod h1:soWkSNf2tZC7aMibXEqVhCd73GOY5fJikn8qbdzemB0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 h1:+xBL5uTc+BkPBwmMi3vYfUJjq+N3K+H6PXeETwf5cPI= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4= -sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= -sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s= +sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/controller-tools v0.4.1/go.mod h1:G9rHdZMVlBDocIxGkK3jHLWqcTMNvveypYJwrvYKjWU= sigs.k8s.io/controller-tools v0.8.0 h1:uUkfTGEwrguqYYfcI2RRGUnC8mYdCFDqfwPKUcNJh1o= sigs.k8s.io/controller-tools v0.8.0/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= sigs.k8s.io/kind v0.16.0 h1:GFXyyxtPnHFKqXr3ZG8/X0+0K9sl69lejStlPn2WQyM= sigs.k8s.io/kind v0.16.0/go.mod h1:cKTqagdRyUQmihhBOd+7p43DpOPRn9rHsUC08K1Jbsk= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo= -sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI= -sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= -sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVYCA4BzxeAaLI05Bg= -sigs.k8s.io/kustomize/kyaml v0.13.6 h1:eF+wsn4J7GOAXlvajv6OknSunxpcOBQQqsnPxObtkGs= -sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go b/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go index aa24543eef..6d1cbfb097 100644 --- a/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go +++ b/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go @@ -39,8 +39,7 @@ type Interface interface { OperatorsV2() operatorsv2.OperatorsV2Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient operatorsV1alpha1 *operatorsv1alpha1.OperatorsV1alpha1Client diff --git a/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/decorator.go b/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/decorator.go index 1a90295744..154b595519 100644 --- a/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/decorator.go +++ b/staging/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/decorator.go @@ -5,7 +5,7 @@ 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 + 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, diff --git a/staging/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go b/staging/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go index f037340b49..3a265e8e4c 100644 --- a/staging/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go +++ b/staging/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go @@ -47,6 +47,11 @@ type sharedInformerFactory struct { // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -107,20 +112,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -167,11 +191,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Operators() operators.Interface } diff --git a/staging/operator-lifecycle-manager/pkg/controller/install/deployment.go b/staging/operator-lifecycle-manager/pkg/controller/install/deployment.go index 559520aad7..43aab8e1ce 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/install/deployment.go +++ b/staging/operator-lifecycle-manager/pkg/controller/install/deployment.go @@ -175,7 +175,7 @@ func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1 // By default, each deployment created by OLM could spawn up to 10 replicaSets. // By setting the deployments revisionHistoryLimit to 1, OLM will only create up // to 2 ReplicaSets per deployment it manages, saving memory. - dep.Spec.RevisionHistoryLimit = pointer.Int32Ptr(1) + dep.Spec.RevisionHistoryLimit = pointer.Int32(1) hash = HashDeploymentSpec(dep.Spec) dep.Labels[DeploymentSpecHashLabelKey] = hash diff --git a/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go b/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go index dfc9f855dd..0c3531e780 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go +++ b/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go @@ -749,16 +749,19 @@ func (o *Operator) syncRegistryServer(logger *logrus.Entry, in *v1alpha1.Catalog logger.Debug("ensured registry server") // requeue the catalog sync based on the polling interval, for accurate syncs of catalogs with polling enabled - if out.Spec.UpdateStrategy != nil { - if out.Spec.UpdateStrategy.RegistryPoll != nil { - if out.Spec.UpdateStrategy.RegistryPoll.ParsingError != "" && out.Status.Reason != v1alpha1.CatalogSourceIntervalInvalidError { - out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, fmt.Errorf(out.Spec.UpdateStrategy.RegistryPoll.ParsingError)) - } - logger.Debugf("requeuing registry server sync based on polling interval %s", out.Spec.UpdateStrategy.Interval.Duration.String()) - resyncPeriod := reconciler.SyncRegistryUpdateInterval(out, time.Now()) - o.catsrcQueueSet.RequeueAfter(out.GetNamespace(), out.GetName(), queueinformer.ResyncWithJitter(resyncPeriod, 0.1)()) + if out.Spec.UpdateStrategy != nil && out.Spec.UpdateStrategy.RegistryPoll != nil { + if out.Spec.UpdateStrategy.Interval == nil { + syncError = fmt.Errorf("empty polling interval; cannot requeue registry server sync without a provided polling interval") + out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, syncError) return } + if out.Spec.UpdateStrategy.RegistryPoll.ParsingError != "" && out.Status.Reason != v1alpha1.CatalogSourceIntervalInvalidError { + out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, fmt.Errorf(out.Spec.UpdateStrategy.RegistryPoll.ParsingError)) + } + logger.Debugf("requeuing registry server sync based on polling interval %s", out.Spec.UpdateStrategy.Interval.Duration.String()) + resyncPeriod := reconciler.SyncRegistryUpdateInterval(out, time.Now()) + o.catsrcQueueSet.RequeueAfter(out.GetNamespace(), out.GetName(), queueinformer.ResyncWithJitter(resyncPeriod, 0.1)()) + return } if err := o.sources.Remove(sourceKey); err != nil { diff --git a/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator_test.go b/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator_test.go index 51b07250c7..2c351d4a2e 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator_test.go +++ b/staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator_test.go @@ -5,8 +5,8 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "math/rand" + "os" "reflect" "strings" "testing" @@ -1333,7 +1333,8 @@ func TestCompetingCRDOwnersExist(t *testing.T) { expectedResult: true, }, } - for _, tt := range tests { + for _, xt := range tests { + tt := xt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -1353,7 +1354,7 @@ func TestCompetingCRDOwnersExist(t *testing.T) { func TestValidateExistingCRs(t *testing.T) { unstructuredForFile := func(file string) *unstructured.Unstructured { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) require.NoError(t, err) dec := utilyaml.NewYAMLOrJSONDecoder(strings.NewReader(string(data)), 30) k8sFile := &unstructured.Unstructured{} @@ -1362,7 +1363,7 @@ func TestValidateExistingCRs(t *testing.T) { } unversionedCRDForV1beta1File := func(file string) *apiextensions.CustomResourceDefinition { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) require.NoError(t, err) dec := utilyaml.NewYAMLOrJSONDecoder(strings.NewReader(string(data)), 30) k8sFile := &apiextensionsv1beta1.CustomResourceDefinition{} @@ -1415,6 +1416,54 @@ func TestValidateExistingCRs(t *testing.T) { } } +func TestSyncRegistryServer(t *testing.T) { + namespace := "ns" + + tests := []struct { + testName string + err error + catSrc *v1alpha1.CatalogSource + clientObjs []runtime.Object + }{ + { + testName: "EmptyRegistryPoll", + err: fmt.Errorf("empty polling interval; cannot requeue registry server sync without a provided polling interval"), + catSrc: &v1alpha1.CatalogSource{ + Spec: v1alpha1.CatalogSourceSpec{ + UpdateStrategy: &v1alpha1.UpdateStrategy{ + RegistryPoll: &v1alpha1.RegistryPoll{}, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + tt.clientObjs = append(tt.clientObjs, tt.catSrc) + op, err := NewFakeOperator(ctx, namespace, []string{namespace}, withClientObjs(tt.clientObjs...)) + require.NoError(t, err) + + op.reconciler = &fakes.FakeRegistryReconcilerFactory{ + ReconcilerForSourceStub: func(source *v1alpha1.CatalogSource) reconciler.RegistryReconciler { + return &fakes.FakeRegistryReconciler{ + EnsureRegistryServerStub: func(source *v1alpha1.CatalogSource) error { + return nil + }, + } + }, + } + require.NotPanics(t, func() { + _, _, err = op.syncRegistryServer(logrus.NewEntry(op.logger), tt.catSrc) + }) + require.Equal(t, tt.err, err) + }) + } +} + func fakeConfigMapData() map[string]string { data := make(map[string]string) yaml, err := yaml.Marshal([]apiextensionsv1beta1.CustomResourceDefinition{crd("fake-crd")}) @@ -1744,7 +1793,7 @@ func objectReference(name string) *corev1.ObjectReference { } func yamlFromFilePath(t *testing.T, fileName string) string { - yaml, err := ioutil.ReadFile(fileName) + yaml, err := os.ReadFile(fileName) require.NoError(t, err) return string(yaml) diff --git a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go index 08f6b95a8f..78b5cb7e6b 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go +++ b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go @@ -1246,7 +1246,7 @@ func (a *Operator) removeDanglingChildCSVs(csv *v1alpha1.ClusterServiceVersion) func (a *Operator) deleteChild(csv *v1alpha1.ClusterServiceVersion, logger *logrus.Entry) error { logger.Debug("gcing csv") - return a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Delete(context.TODO(), csv.GetName(), *metav1.NewDeleteOptions(0)) + return a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Delete(context.TODO(), csv.GetName(), metav1.DeleteOptions{}) } // syncClusterServiceVersion is the method that gets called when we see a CSV event in the cluster @@ -2287,7 +2287,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v syncError = fmt.Errorf("marked as replacement, but no replacement CSV found in cluster") } case v1alpha1.CSVPhaseDeleting: - syncError = a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Delete(context.TODO(), out.GetName(), *metav1.NewDeleteOptions(0)) + syncError = a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Delete(context.TODO(), out.GetName(), metav1.DeleteOptions{}) if syncError != nil { logger.Debugf("unable to get delete csv marked for deletion: %s", syncError.Error()) } diff --git a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_test.go b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_test.go index dd4af8d939..f2d4b3842c 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_test.go +++ b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_test.go @@ -3852,7 +3852,8 @@ func TestUpdates(t *testing.T) { in: []*v1alpha1.ClusterServiceVersion{c, a, b}, }, } - for _, tt := range tests { + for _, xt := range tests { + tt := xt t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -3923,9 +3924,10 @@ func TestUpdates(t *testing.T) { simulateSuccessfulRollout(current, op.opClient) } for current.Status.Phase != e.whenIn.phase { - fmt.Printf("waiting for (when) %s to be %s\n", e.whenIn.name, e.whenIn.phase) csvsToSync = syncCSVs(csvsToSync, deletedCSVs(e.shouldBe)) current = csvsToSync[e.whenIn.name] + fmt.Printf("waiting for (when) %s to be %s\n", e.whenIn.name, e.whenIn.phase) + time.Sleep(1 * time.Millisecond) } // sync the other csvs until they're in the expected status diff --git a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go index 50432767c9..8d105fbfa5 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go +++ b/staging/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go @@ -235,10 +235,12 @@ func InjectNodeSelectorIntoDeployment(podSpec *corev1.PodSpec, nodeSelector map[ // with the given corev1.Affinity. Any nil top-level sub-attributes (e.g. NodeAffinity, PodAffinity, and PodAntiAffinity) // will be ignored. Hint: to overwrite those top-level attributes, empty them out. I.e. use the empty/default object ({}) // e.g. NodeAffinity{}. In yaml: -// affinity: -// nodeAffinity: {} -// podAffinity: {} -// podAntiAffinity: {} +// +// affinity: +// nodeAffinity: {} +// podAffinity: {} +// podAntiAffinity: {} +// // will completely remove the deployment podSpec.affinity and is equivalent to // affinity: {} func OverrideDeploymentAffinity(podSpec *corev1.PodSpec, affinity *corev1.Affinity) error { diff --git a/staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver_test.go b/staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver_test.go index c75da4affc..8fca62b389 100644 --- a/staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver_test.go +++ b/staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver_test.go @@ -1182,7 +1182,7 @@ func TestResolver(t *testing.T) { steps: [][]*v1alpha1.Step{}, subs: []*v1alpha1.Subscription{}, errAssert: func(t *testing.T, err error) { - assert.Contains(t, err.Error(), "failed to populate resolver cache from source @existing/catsrc-namespace: csv catsrc-namespace/a.v1") + assert.Contains(t, err.Error(), "failed to populate resolver cache from source @existing/catsrc-namespace: csv") assert.Contains(t, err.Error(), "in phase Failed instead of Replacing") }, }, diff --git a/staging/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go b/staging/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go index c8a58caaea..821ed00b96 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go +++ b/staging/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go @@ -12,7 +12,8 @@ import ( "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" ) -/* UpdateStatus can be used to update the status of the provided catalog source. Note that +/* +UpdateStatus can be used to update the status of the provided catalog source. Note that the caller is responsible for ensuring accurate status values in the catsrc argument (i.e. the status is used as-is). @@ -34,7 +35,8 @@ func UpdateStatus(logger *logrus.Entry, client versioned.Interface, catsrc *v1al return nil } -/* UpdateStatusWithConditions can be used to update the status conditions for the provided catalog source. +/* +UpdateStatusWithConditions can be used to update the status conditions for the provided catalog source. This function will make no changes to the other status fields (those fields will be used as-is). If the provided conditions do not result in any status condition changes, then the API server will not be updated. Note that the caller is responsible for ensuring accurate status values for all other fields. @@ -71,7 +73,8 @@ func UpdateStatusWithConditions(logger *logrus.Entry, client versioned.Interface return nil } -/* UpdateSpecAndStatusConditions can be used to update the catalog source with the provided status conditions. +/* +UpdateSpecAndStatusConditions can be used to update the catalog source with the provided status conditions. This will update the spec and status portions of the catalog source. Calls to the API server will occur even if the provided conditions result in no changes. @@ -98,7 +101,8 @@ func UpdateSpecAndStatusConditions(logger *logrus.Entry, client versioned.Interf return nil } -/* RemoveStatusConditions can be used to remove the status conditions for the provided catalog source. +/* +RemoveStatusConditions can be used to remove the status conditions for the provided catalog source. This function will make no changes to the other status fields (those fields will be used as-is). If the provided conditions do not result in any status condition changes, then the API server will not be updated. Note that the caller is responsible for ensuring accurate status values for all other fields. diff --git a/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go b/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go index a7e04cb873..3044cd6d9b 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go +++ b/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go @@ -35,8 +35,7 @@ type fakeStatusWriter struct { k8scontrollerclient.StatusWriter } -func (c fakeStatusWriter) Patch(ctx context.Context, obj k8scontrollerclient.Object, patch k8scontrollerclient.Patch, opts ...k8scontrollerclient.PatchOption) error { - patch, opts = convertApplyToMergePatch(patch, opts...) +func (c fakeStatusWriter) Patch(ctx context.Context, obj k8scontrollerclient.Object, patch k8scontrollerclient.Patch, opts ...k8scontrollerclient.SubResourcePatchOption) error { return c.StatusWriter.Patch(ctx, obj, patch, opts...) } diff --git a/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go b/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go index b13f923b3d..ebedcee31b 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go +++ b/staging/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go @@ -90,10 +90,11 @@ type ServerSideApplier struct { // plan := &InstallPlan{} // plan.SetNamespace("ns") // plan.SetName("install-123def") -// Eventually(c.Apply(plan, func(p *v1alpha1.InstallPlan) error { -// p.Spec.Approved = true -// return nil -// })).Should(Succeed()) +// +// Eventually(c.Apply(plan, func(p *v1alpha1.InstallPlan) error { +// p.Spec.Approved = true +// return nil +// })).Should(Succeed()) func (c *ServerSideApplier) Apply(ctx context.Context, obj Object, changeFunc interface{}) func() error { // Ensure given object is a pointer objType := reflect.TypeOf(obj) @@ -182,7 +183,10 @@ func (c *ServerSideApplier) Apply(ctx context.Context, obj Object, changeFunc in return err } - if err := c.client.Status().Patch(ctx, cp, k8scontrollerclient.Apply, k8scontrollerclient.ForceOwnership, c.Owner); err != nil { + pos := &k8scontrollerclient.SubResourcePatchOptions{} + k8scontrollerclient.ForceOwnership.ApplyToPatch(&pos.PatchOptions) + + if err := c.client.Status().Patch(ctx, cp, k8scontrollerclient.Apply, pos, c.Owner); err != nil { fmt.Printf("second patch error: %s\n", err) return err } diff --git a/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go b/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go index 4fcee4e457..58f577ef45 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go +++ b/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go @@ -2,7 +2,7 @@ package filemonitor import ( "crypto/x509" - "io/ioutil" + "os" "sync" "github.com/fsnotify/fsnotify" @@ -16,7 +16,7 @@ type certPoolStore struct { } func NewCertPoolStore(clientCAPath string) (*certPoolStore, error) { - pem, err := ioutil.ReadFile(clientCAPath) + pem, err := os.ReadFile(clientCAPath) if err != nil { return nil, err } @@ -31,7 +31,7 @@ func NewCertPoolStore(clientCAPath string) (*certPoolStore, error) { } func (c *certPoolStore) storeCABundle(clientCAPath string) error { - pem, err := ioutil.ReadFile(clientCAPath) + pem, err := os.ReadFile(clientCAPath) if err == nil { c.mutex.Lock() defer c.mutex.Unlock() diff --git a/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cert_updater_test.go b/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cert_updater_test.go index 022b22fc30..039e5ceac2 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cert_updater_test.go +++ b/staging/operator-lifecycle-manager/pkg/lib/filemonitor/cert_updater_test.go @@ -6,7 +6,6 @@ import ( "crypto/x509" "fmt" "html" - "io/ioutil" "net" "net/http" "os" @@ -88,7 +87,7 @@ func TestOLMGetCertRotationFn(t *testing.T) { } }() - caCert, err := ioutil.ReadFile(caCrt) + caCert, err := os.ReadFile(caCrt) require.NoError(t, err) caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) diff --git a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go index b3d5891bb7..04e9556e17 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go +++ b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go index 7bf8d13745..a4ff45d659 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go +++ b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go index f0d53c1721..ba7fdabd85 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go +++ b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go index 33518a9868..0f7023a2db 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go +++ b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go index add7c3896e..f96239dc0d 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go +++ b/staging/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go @@ -150,7 +150,9 @@ func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1beta1.Ta // ValidateRowPrintHandlerFunc validates print handler signature. // printFunc is the function that will be called to print an object. // It must be of the following type: -// func printFunc(object ObjectType, options GenerateOptions) ([]metav1beta1.TableRow, error) +// +// func printFunc(object ObjectType, options GenerateOptions) ([]metav1beta1.TableRow, error) +// // where ObjectType is the type of the object that will be printed, and the first // return value is an array of rows, with each row containing a number of cells that // match the number of columns defined for that printer function. diff --git a/staging/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go b/staging/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go index 99e41817da..0bf77a89e4 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go +++ b/staging/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go @@ -28,6 +28,7 @@ import ( //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -o ./operatorlisterfakes/fake_clusterserviceversion_v1alpha1_namespace_lister.go ../../api/client/listers/operators/v1alpha1.ClusterServiceVersionNamespaceLister // OperatorLister is a union of versioned informer listers +// //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . OperatorLister type OperatorLister interface { AppsV1() AppsV1Lister diff --git a/staging/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go b/staging/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go index eb8c57ab20..bf2b9b51b7 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go +++ b/staging/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go @@ -86,8 +86,8 @@ type handler struct { // OnAddOrUpdate is invoked when a CSV has been added or edited. We tap into // this notification and do the following: // -// a. Make sure this is the CSV related to the cluster operator resource we are -// tracking. Otherwise, do nothing. +// a. Make sure this is the CSV related to the cluster operator resource we are tracking. Otherwise, do nothing. +// // b. If this is the right CSV then send it to the monitor. func (h *handler) OnAddOrUpdate(in *v1alpha1.ClusterServiceVersion) { h.onNotification(in, false) @@ -96,8 +96,8 @@ func (h *handler) OnAddOrUpdate(in *v1alpha1.ClusterServiceVersion) { // OnDelete is invoked when a CSV has been deleted. We tap into // this notification and do the following: // -// a. Make sure this is the CSV related to the cluster operator resource we are -// tracking. Otherwise, do nothing. +// a. Make sure this is the CSV related to the cluster operator resource we are tracking. Otherwise, do nothing. +// // b. If this is the right CSV then send it to the monitor. func (h *handler) OnDelete(in *v1alpha1.ClusterServiceVersion) { h.onNotification(in, true) diff --git a/staging/operator-lifecycle-manager/pkg/lib/proxy/overridden.go b/staging/operator-lifecycle-manager/pkg/lib/proxy/overridden.go index 8ad45f1a78..42eec7acd6 100644 --- a/staging/operator-lifecycle-manager/pkg/lib/proxy/overridden.go +++ b/staging/operator-lifecycle-manager/pkg/lib/proxy/overridden.go @@ -6,8 +6,9 @@ import ( // IsOverridden returns true if the given container overrides proxy env variable(s). // We apply the following rule: -// If a container already defines any of the proxy env variable then it -// overrides all of these. +// +// If a container already defines any of the proxy env variable then it +// overrides all of these. func IsOverridden(envVar []corev1.EnvVar) (overrides bool) { for _, envVarName := range allProxyEnvVarNames { _, found := find(envVar, envVarName) diff --git a/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go b/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go index c62d34765e..7869695b27 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go @@ -33,8 +33,7 @@ type Interface interface { Operators() operatorsinternalversion.OperatorsInterface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient operators *operatorsinternalversion.OperatorsClient diff --git a/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go b/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go index b14e68fa0c..54c1733ce5 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go @@ -33,8 +33,7 @@ type Interface interface { OperatorsV1() operatorsv1.OperatorsV1Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient operatorsV1 *operatorsv1.OperatorsV1Client diff --git a/staging/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go b/staging/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go index 659f23161f..4a778610e6 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go @@ -47,6 +47,11 @@ type sharedInformerFactory struct { // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -107,20 +112,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -167,11 +191,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Operators() operators.Interface } diff --git a/staging/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go b/staging/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go index bb656715a5..f984dc4e56 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go @@ -47,6 +47,11 @@ type sharedInformerFactory struct { // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -107,20 +112,39 @@ func NewSharedInformerFactoryWithOptions(client internalversion.Interface, defau return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -167,11 +191,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Operators() operators.Interface } diff --git a/staging/operator-lifecycle-manager/pkg/package-server/provider/registry.go b/staging/operator-lifecycle-manager/pkg/package-server/provider/registry.go index c048e4e8d6..cb48c6efa6 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/provider/registry.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/provider/registry.go @@ -512,6 +512,9 @@ func (p *RegistryProvider) List(namespace string, selector labels.Selector) (*op func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Package, client *registryClient, entriesByChannel map[string][]operators.ChannelEntry) (*operators.PackageManifest, error) { pkgChannels := pkg.GetChannels() + sort.Slice(pkgChannels, func(i, j int) bool { + return pkgChannels[i].Name < pkgChannels[j].Name + }) catsrc := client.catsrc manifest := &operators.PackageManifest{ ObjectMeta: metav1.ObjectMeta{ diff --git a/staging/operator-lifecycle-manager/pkg/package-server/provider/registry_test.go b/staging/operator-lifecycle-manager/pkg/package-server/provider/registry_test.go index 5a8b027353..2f0b5277f1 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/provider/registry_test.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/provider/registry_test.go @@ -133,6 +133,7 @@ func TestMain(m *testing.M) { var ( etcdCSVJSON = "{\"apiVersion\":\"operators.coreos.com/v1alpha1\",\"kind\":\"ClusterServiceVersion\",\"metadata\":{\"annotations\":{\"alm-examples\":\"[{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdCluster\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example\\\",\\\"namespace\\\":\\\"default\\\"},\\\"spec\\\":{\\\"size\\\":3,\\\"version\\\":\\\"3.2.13\\\"}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdRestore\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"spec\\\":{\\\"etcdCluster\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"backupStorageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdBackup\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster-backup\\\"},\\\"spec\\\":{\\\"etcdEndpoints\\\":[\\\"\\u003cetcd-cluster-endpoints\\u003e\\\"],\\\"storageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}}]\",\"tectonic-visibility\":\"ocs\"},\"name\":\"etcdoperator.v0.9.2\",\"namespace\":\"placeholder\"},\"spec\":{\"customresourcedefinitions\":{\"owned\":[{\"description\":\"Represents a cluster of etcd nodes.\",\"displayName\":\"etcd Cluster\",\"kind\":\"EtcdCluster\",\"name\":\"etcdclusters.etcd.database.coreos.com\",\"resources\":[{\"kind\":\"Service\",\"version\":\"v1\"},{\"kind\":\"Pod\",\"version\":\"v1\"}],\"specDescriptors\":[{\"description\":\"The desired number of member Pods for the etcd cluster.\",\"displayName\":\"Size\",\"path\":\"size\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podCount\"]},{\"description\":\"Limits describes the minimum/maximum amount of compute resources required/allowed\",\"displayName\":\"Resource Requirements\",\"path\":\"pod.resources\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:resourceRequirements\"]}],\"statusDescriptors\":[{\"description\":\"The status of each of the member Pods for the etcd cluster.\",\"displayName\":\"Member Status\",\"path\":\"members\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podStatuses\"]},{\"description\":\"The service at which the running etcd cluster can be accessed.\",\"displayName\":\"Service\",\"path\":\"serviceName\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Service\"]},{\"description\":\"The current size of the etcd cluster.\",\"displayName\":\"Cluster Size\",\"path\":\"size\"},{\"description\":\"The current version of the etcd cluster.\",\"displayName\":\"Current Version\",\"path\":\"currentVersion\"},{\"description\":\"The target version of the etcd cluster, after upgrading.\",\"displayName\":\"Target Version\",\"path\":\"targetVersion\"},{\"description\":\"The current status of the etcd cluster.\",\"displayName\":\"Status\",\"path\":\"phase\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase\"]},{\"description\":\"Explanation for the current status of the cluster.\",\"displayName\":\"Status Details\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to backup an etcd cluster.\",\"displayName\":\"etcd Backup\",\"kind\":\"EtcdBackup\",\"name\":\"etcdbackups.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"Specifies the endpoints of an etcd cluster.\",\"displayName\":\"etcd Endpoint(s)\",\"path\":\"etcdEndpoints\",\"x-descriptors\":[\"urn:alm:descriptor:etcd:endpoint\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the backup was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any backup related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to restore an etcd cluster from a backup.\",\"displayName\":\"etcd Restore\",\"kind\":\"EtcdRestore\",\"name\":\"etcdrestores.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"References the EtcdCluster which should be restored,\",\"displayName\":\"etcd Cluster\",\"path\":\"etcdCluster.name\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:EtcdCluster\",\"urn:alm:descriptor:text\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the restore was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any restore related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"}]},\"description\":\"etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.\\nA simple use-case is to store database connection details or feature flags within etcd as key value pairs. These values can be watched, allowing your app to reconfigure itself when they change. Advanced uses take advantage of the consistency guarantees to implement database leader elections or do distributed locking across a cluster of workers.\\n\\n_The etcd Open Cloud Service is Public Alpha. The goal before Beta is to fully implement backup features._\\n\\n### Reading and writing to etcd\\n\\nCommunicate with etcd though its command line utility `etcdctl` or with the API using the automatically generated Kubernetes Service.\\n\\n[Read the complete guide to using the etcd Open Cloud Service](https://coreos.com/tectonic/docs/latest/alm/etcd-ocs.html)\\n\\n### Supported Features\\n\\n\\n**High availability**\\n\\n\\nMultiple instances of etcd are networked together and secured. Individual failures or networking issues are transparently handled to keep your cluster up and running.\\n\\n\\n**Automated updates**\\n\\n\\nRolling out a new etcd version works like all Kubernetes rolling updates. Simply declare the desired version, and the etcd service starts a safe rolling update to the new version automatically.\\n\\n\\n**Backups included**\\n\\n\\nComing soon, the ability to schedule backups to happen on or off cluster.\\n\",\"displayName\":\"etcd\",\"icon\":[{\"base64data\":\"iVBORw0KGgoAAAANSUhEUgAAAOEAAADZCAYAAADWmle6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAEKlJREFUeNrsndt1GzkShmEev4sTgeiHfRYdgVqbgOgITEVgOgLTEQydwIiKwFQCayoCU6+7DyYjsBiBFyVVz7RkXvqCSxXw/+f04XjGQ6IL+FBVuL769euXgZ7r39f/G9iP0X+u/jWDNZzZdGI/Ftama1jjuV4BwmcNpbAf1Fgu+V/9YRvNAyzT2a59+/GT/3hnn5m16wKWedJrmOCxkYztx9Q+py/+E0GJxtJdReWfz+mxNt+QzS2Mc0AI+HbBBwj9QViKbH5t64DsP2fvmGXUkWU4WgO+Uve2YQzBUGd7r+zH2ZG/tiUQc4QxKwgbwFfVGwwmdLL5wH78aPC/ZBem9jJpCAX3xtcNASSNgJLzUPSQyjB1zQNl8IQJ9MIU4lx2+Jo72ysXYKl1HSzN02BMa/vbZ5xyNJIshJzwf3L0dQhJw4Sih/SFw9Tk8sVeghVPoefaIYCkMZCKbrcP9lnZuk0uPUjGE/KE8JQry7W2tgfuC3vXgvNV+qSQbyFtAtyWk7zWiYevvuUQ9QEQCvJ+5mmu6dTjz1zFHLFj8Eb87MtxaZh/IQFIHom+9vgTWwZxAQjT9X4vtbEVPojwjiV471s00mhAckpwGuCn1HtFtRDaSh6y9zsL+LNBvCG/24ThcxHObdlWc1v+VQJe8LcO0jwtuF8BwnAAUgP9M8JPU2Me+Oh12auPGT6fHuTePE3bLDy+x9pTLnhMn+07TQGh//Bz1iI0c6kvtqInjvPZcYR3KsPVmUsPYt9nFig9SCY8VQNhpPBzn952bbgcsk2EvM89wzh3UEffBbyPqvBUBYQ8ODGPFOLsa7RF096WJ69L+E4EmnpjWu5o4ChlKaRTKT39RMMaVPEQRsz/nIWlDN80chjdJlSd1l0pJCAMVZsniobQVuxceMM9OFoaMd9zqZtjMEYYDW38Drb8Y0DYPLShxn0pvIFuOSxd7YCPet9zk452wsh54FJoeN05hcgSQoG5RR0Qh9Q4E4VvL4wcZq8UACgaRFEQKgSwWrkr5WFnGxiHSutqJGlXjBgIOayhwYBTA0ER0oisIVSUV0AAMT0IASCUO4hRIQSAEECMCCEPwqyQA0JCQBzEGjWNAqHiUVAoXUWbvggOIQCEAOJzxTjoaQ4AIaE64/aZridUsBYUgkhB15oGg1DBIl8IqirYwV6hPSGBSFteMCUBSVXwfYixBmamRubeMyjzMJQBDDowE3OesDD+zwqFoDqiEwXoXJpljB+PvWJGy75BKF1FPxhKygJuqUdYQGlLxNEXkrYyjQ0GbaAwEnUIlLRNvVjQDYUAsJB0HKLE4y0AIpQNgCIhBIhQTgCKhZBBpAN/v6LtQI50JfUgYOnnjmLUFHKhjxbAmdTCaTiBm3ovLPqG2urWAij6im0Nd9aTN9ygLUEt9LgSRnohxUPIKxlGaE+/6Y7znFf0yX+GnkvFFWmarkab2o9PmTeq8sbd2a7DaysXz7i64VeznN4jCQhN9gdDbRiuWrfrsq0mHIrlaq+hlotCtd3Um9u0BYWY8y5D67wccJoZjFca7iUs9VqZcfsZwTd1sbWGG+OcYaTnPAP7rTQVVlM4Sg3oGvB1tmNh0t/HKXZ1jFoIMwCQjtqbhNxUmkGYqgZEDZP11HN/S3gAYRozf0l8C5kKEKUvW0t1IfeWG/5MwgheZTT1E0AEhDkAePQO+Ig2H3DncAkQM4cwUQCD530dU4B5Yvmi2LlDqXfWrxMCcMth51RToRMNUXFnfc2KJ0+Ryl0VNOUwlhh6NoxK5gnViTgQpUG4SqSyt5z3zRJpuKmt3Q1614QaCBPaN6je+2XiFcWAKOXcUfIYKRyL/1lb7pe5VxSxxjQ6hImshqGRt5GWZVKO6q2wHwujfwDtIvaIdexj8Cm8+a68EqMfox6x/voMouZF4dHnEGNeCDMwT6vdNfekH1MafMk4PI06YtqLVGl95aEM9Z5vAeCTOA++YLtoVJRrsqNCaJ6WRmkdYaNec5BT/lcTRMqrhmwfjbpkj55+OKp8IEbU/JLgPJE6Wa3TTe9sHS+ShVD5QIyqIxMEwKh12olC6mHIed5ewEop80CNlfIOADYOT2nd6ZXCop+Ebqchc0JqxKcKASxChycJgUh1rnHA5ow9eTrhqNI7JWiAYYwBGGdpyNLoGw0Pkh96h1BpHihyywtATDM/7Hk2fN9EnH8BgKJCU4ooBkbXFMZJiPbrOyecGl3zgQDQL4hk10IZiOe+5w99Q/gBAEIJgPhJM4QAEEoFREAIAAEiIASAkD8Qt4AQAEIAERAGFlX4CACKAXGVM4ivMwWwCLFAlyeoaa70QePKm5Dlp+/n+ye/5dYgva6YsUaVeMa+tzNFeJtWwc+udbJ0Fg399kLielQJ5Ze61c2+7ytA6EZetiPxZC6tj22yJCv6jUwOyj/zcbqAxOMyAKEbfeHtNa7DtYXptjsk2kJxR+eIeim/tHNofUKYy8DMrQcAKWz6brpvzyIAlpwPhQ49l6b7skJf5Z+YTOYQc4FwLDxvoTDwaygQK+U/kVr+ytSFBG01Q3gnJJR4cNiAhx4HDub8/b5DULXlj6SVZghFiE+LdvE9vo/o8Lp1RmH5hzm0T6wdbZ6n+D6i44zDRc3ln6CpAEJfXiRU45oqLz8gFAThWsh7ughrRibc0QynHgZpNJa/ENJ+loCwu/qOGnFIjYR/n7TfgycULhcQhu6VC+HfF+L3BoAQ4WiZTw1M+FPCnA2gKC6/FAhXgDC+ojQGh3NuWsvfF1L/D5ohlCKtl1j2ldu9a/nPAKFwN56Bst10zCG0CPleXN/zXPgHQZXaZaBgrbzyY5V/mUA+6F0hwtGN9rwu5DVZPuwWqfxdFz1LWbJ2lwKEa+0Qsm4Dl3fp+Pu0lV97PgwIPfSsS+UQhj5Oo+vvFULazRIQyvGEcxPuNLCth2MvFsrKn8UOilAQShkh7TTczYNMoS6OdP47msrPi82lXKGWhCdMZYS0bFy+vcnGAjP1CIfvgbKNA9glecEH9RD6Ol4wRuWyN/G9MHnksS6o/GPf5XcwNSUlHzQhDuAKtWJmkwKElU7lylP5rgIcsquh/FI8YZCDpkJBuE4FQm7Icw8N+SrUGaQKyi8FwiDt1ve5o+Vu7qYHy/psgK8cvh+FTYuO77bhEC7GuaPiys/L1X4IgXDL+e3M5+ovLxBy5VLuIebw1oqcHoPfoaMJUsHays878r8KbDc3xtPx/84gZPBG/JwaufrsY/SRG/OY3//8QMNdsvdZCFtbW6f8pFuf5bflILAlX7O+4fdfugKyFYS8T2zAsXthdG0VurPGKwI06oF5vkBgHWkNp6ry29+lsPZMU3vijnXFNmoclr+6+Ou/FIb8yb30sS8YGjmTqCLyQsi5N/6ZwKs0Yenj68pfPjF6N782Dp2FzV9CTyoSeY8mLK16qGxIkLI8oa1n8tz9juP40DlK0epxYEbojbq+9QfurBeVIlCO9D2396bxiV4lkYQ3hOAFw2pbhqMGISkkQOMcQ9EqhDmGZZdo92JC0YHRNTfoSg+5e0IT+opqCKHoIU+4ztQIgBD1EFNrQAgIpYSil9lDmPHqkROPt+JC6AgPquSuumJmg0YARVCuneDfvPVeJokZ6pIXDkNxQtGzTF9/BQjRG0tQznfb74RwCQghpALBtIQnfK4zhxdyQvVCUeknMIT3hLyY+T5jo0yABqKPQNpUNw/09tGZod5jgCaYFxyYvJcNPkv9eof+I3pnCFEHIETjSM8L9tHZHYCQT9PaZGycU6yg8S4akDnJ+P03L0+t23XGzCLzRgII/Wqa+fv/xlfvmKvMUOcOrlCDdoei1MGdZm6G5VEIfRzzjd4aQs69n699Rx7ewhvCGzr2gmTPs8zNsJOrXt24FbkhhOjCfT4ICA/rPbyhUy94Dks0gJCX1NzCZui9YUd3oei+c257TalFbgg19ILHrlrL2gvWgXAL26EX76gZTNASQnad8Ibwhl284NhgXpB0c+jKhWO3Ms1hP9ihJYB9eMF6qd1BCPk0qA1s+LimFIu7m4nsdQIzPK4VbQ8hYvrnuSH2G9b2ggP78QmWqBdF9Vx8SSY6QYdUW7BTA1schZATyhvY8lHvcRbNUS9YGFy2U+qmzh2YPVc0I7yAOFyHfRpyUwtCSzOdPXMHmz7qDIM0e0V2wZTEk+6Ym6N63eBLp/b5Bts+2cKCSJ/LuoZO3ANSiE5hKAZjnvNSS4931jcw9jpwT0feV/qSJ1pVtCyfHKDkvK8Ejx7pUxGh2xFNSwx8QTi2H9ceC0/nni64MS/5N5dG39pDqvRV+WgGk71c9VFXF9b+xYvOw/d61iv7m3MvEHryhvecwC52jSSx4VIIgwnMNT/UsTxIgpPt3K/ARj15CptwL3Zd/ceDSATj2DGQjbxgWwhdeMMte7zpy5On9vymRm/YxBYljGVjKWF9VJf7I1+sex3wY8w/V1QPTborW/72gkdsRDaZMJBdbdHIC7aCkAu9atlLbtnrzerMnyToDaGwelOnk3/hHSem/ZK7e/t7jeeR20LYBgqa8J80gS8jbwi5F02Uj1u2NYJxap8PLkJfLxA2hIJyvnHX/AfeEPLpBfe0uSFHbnXaea3Qd5d6HcpYZ8L6M7lnFwMQ3MNg+RxUR1+6AshtbsVgfXTEg1sIGax9UND2p7f270wdG3eK9gXVGHdw2k5sOyZv+Nbs39Z308XR9DqWb2J+PwKDhuKHPobfuXf7gnYGHdCs7bhDDadD4entDug7LWNsnRNW4mYqwJ9dk+GGSTPBiA2j0G8RWNM5upZtcG4/3vMfP7KnbK2egx6CCnDPhRn7NgD3cghLIad5WcM2SO38iqHvvMOosyeMpQ5zlVCaaj06GVs9xUbHdiKoqrHWgquFEFMWUEWfXUxJAML23hAHFOctmjZQffKD2pywkhtSGHKNtpitLroscAeE7kCkSsC60vxEl6yMtL9EL5HKGCMszU5bk8gdkklAyEn5FO0yK419rIxBOIqwFMooDE0tHEVYijAUECIshRCGIhxFWIowFJ5QkEYIS5PTJrUwNGlPyN6QQPyKtpuM1E/K5+YJDV/MiA3AaehzqgAm7QnZG9IGYKo8bHnSK7VblLL3hOwNHziPuEGOqE5brrdR6i+atCfckyeWD47HkAkepRGLY/e8A8J0gCwYSNypF08bBm+e6zVz2UL4AshhBUjML/rXLefqC82bcQFhGC9JDwZ1uuu+At0S5gCETYHsV4DUeD9fDN2Zfy5OXaW2zAwQygCzBLJ8cvaW5OXKC1FxfTggFAHmoAJnSiOw2wps9KwRWgJCLaEswaj5NqkLwAYIU4BxqTSXbHXpJdRMPZgAOiAMqABCNGYIEEJutEK5IUAIwYMDQgiCACEEAcJs1Vda7gGqDhCmoiEghAAhBAHCrKXVo2C1DCBMRlp37uMIEECoX7xrX3P5C9QiINSuIcoPAUI0YkAICLNWgfJDh4T9hH7zqYH9+JHAq7zBqWjwhPAicTVCVQJCNF50JghHocahKK0X/ZnQKyEkhSdUpzG8OgQI42qC94EQjsYLRSmH+pbgq73L6bYkeEJ4DYTYmeg1TOBFc/usTTp3V9DdEuXJ2xDCUbXhaXk0/kAYmBvuMB4qkC35E5e5AMKkwSQgyxufyuPy6fMMgAFCSI73LFXU/N8AmEL9X4ABACNSKMHAgb34AAAAAElFTkSuQmCC\",\"mediatype\":\"image/png\"}],\"install\":{\"spec\":{\"deployments\":[{\"name\":\"etcd-operator\",\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"name\":\"etcd-operator-alm-owned\"}},\"template\":{\"metadata\":{\"labels\":{\"name\":\"etcd-operator-alm-owned\"},\"name\":\"etcd-operator-alm-owned\"},\"spec\":{\"containers\":[{\"command\":[\"etcd-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-operator\"},{\"command\":[\"etcd-backup-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-backup-operator\"},{\"command\":[\"etcd-restore-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-restore-operator\"}],\"serviceAccountName\":\"etcd-operator\"}}}}],\"permissions\":[{\"rules\":[{\"apiGroups\":[\"etcd.database.coreos.com\"],\"resources\":[\"etcdclusters\",\"etcdbackups\",\"etcdrestores\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"pods\",\"services\",\"endpoints\",\"persistentvolumeclaims\",\"events\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"apps\"],\"resources\":[\"deployments\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\"]}],\"serviceAccountName\":\"etcd-operator\"}]},\"strategy\":\"deployment\"},\"keywords\":[\"etcd\",\"key value\",\"database\",\"coreos\",\"open source\"],\"labels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"},\"links\":[{\"name\":\"Blog\",\"url\":\"https://coreos.com/etcd\"},{\"name\":\"Documentation\",\"url\":\"https://coreos.com/operators/etcd/docs/latest/\"},{\"name\":\"etcd Operator Source Code\",\"url\":\"https://github.com/coreos/etcd-operator\"}],\"maintainers\":[{\"email\":\"support@coreos.com\",\"name\":\"CoreOS, Inc\"}],\"maturity\":\"alpha\",\"provider\":{\"name\":\"CoreOS, Inc\"},\"replaces\":\"etcdoperator.v0.9.0\",\"selector\":{\"matchLabels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"}},\"version\":\"0.9.2\"}}" + etcdCSVJSONv10 = "{\"apiVersion\":\"operators.coreos.com/v1alpha1\",\"kind\":\"ClusterServiceVersion\",\"metadata\":{\"annotations\":{\"alm-examples\":\"[{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdCluster\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example\\\",\\\"namespace\\\":\\\"default\\\"},\\\"spec\\\":{\\\"size\\\":3,\\\"version\\\":\\\"3.2.13\\\"}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdRestore\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"spec\\\":{\\\"etcdCluster\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"backupStorageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdBackup\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster-backup\\\"},\\\"spec\\\":{\\\"etcdEndpoints\\\":[\\\"\\u003cetcd-cluster-endpoints\\u003e\\\"],\\\"storageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}}]\",\"tectonic-visibility\":\"ocs\"},\"name\":\"etcdoperator.v0.10.1\",\"namespace\":\"placeholder\"},\"spec\":{\"customresourcedefinitions\":{\"owned\":[{\"description\":\"Represents a cluster of etcd nodes.\",\"displayName\":\"etcd Cluster\",\"kind\":\"EtcdCluster\",\"name\":\"etcdclusters.etcd.database.coreos.com\",\"resources\":[{\"kind\":\"Service\",\"version\":\"v1\"},{\"kind\":\"Pod\",\"version\":\"v1\"}],\"specDescriptors\":[{\"description\":\"The desired number of member Pods for the etcd cluster.\",\"displayName\":\"Size\",\"path\":\"size\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podCount\"]},{\"description\":\"Limits describes the minimum/maximum amount of compute resources required/allowed\",\"displayName\":\"Resource Requirements\",\"path\":\"pod.resources\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:resourceRequirements\"]}],\"statusDescriptors\":[{\"description\":\"The status of each of the member Pods for the etcd cluster.\",\"displayName\":\"Member Status\",\"path\":\"members\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podStatuses\"]},{\"description\":\"The service at which the running etcd cluster can be accessed.\",\"displayName\":\"Service\",\"path\":\"serviceName\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Service\"]},{\"description\":\"The current size of the etcd cluster.\",\"displayName\":\"Cluster Size\",\"path\":\"size\"},{\"description\":\"The current version of the etcd cluster.\",\"displayName\":\"Current Version\",\"path\":\"currentVersion\"},{\"description\":\"The target version of the etcd cluster, after upgrading.\",\"displayName\":\"Target Version\",\"path\":\"targetVersion\"},{\"description\":\"The current status of the etcd cluster.\",\"displayName\":\"Status\",\"path\":\"phase\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase\"]},{\"description\":\"Explanation for the current status of the cluster.\",\"displayName\":\"Status Details\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to backup an etcd cluster.\",\"displayName\":\"etcd Backup\",\"kind\":\"EtcdBackup\",\"name\":\"etcdbackups.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"Specifies the endpoints of an etcd cluster.\",\"displayName\":\"etcd Endpoint(s)\",\"path\":\"etcdEndpoints\",\"x-descriptors\":[\"urn:alm:descriptor:etcd:endpoint\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the backup was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any backup related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to restore an etcd cluster from a backup.\",\"displayName\":\"etcd Restore\",\"kind\":\"EtcdRestore\",\"name\":\"etcdrestores.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"References the EtcdCluster which should be restored,\",\"displayName\":\"etcd Cluster\",\"path\":\"etcdCluster.name\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:EtcdCluster\",\"urn:alm:descriptor:text\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the restore was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any restore related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"}]},\"description\":\"etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.\\nA simple use-case is to store database connection details or feature flags within etcd as key value pairs. These values can be watched, allowing your app to reconfigure itself when they change. Advanced uses take advantage of the consistency guarantees to implement database leader elections or do distributed locking across a cluster of workers.\\n\\n_The etcd Open Cloud Service is Public Alpha. The goal before Beta is to fully implement backup features._\\n\\n### Reading and writing to etcd\\n\\nCommunicate with etcd though its command line utility `etcdctl` or with the API using the automatically generated Kubernetes Service.\\n\\n[Read the complete guide to using the etcd Open Cloud Service](https://coreos.com/tectonic/docs/latest/alm/etcd-ocs.html)\\n\\n### Supported Features\\n\\n\\n**High availability**\\n\\n\\nMultiple instances of etcd are networked together and secured. Individual failures or networking issues are transparently handled to keep your cluster up and running.\\n\\n\\n**Automated updates**\\n\\n\\nRolling out a new etcd version works like all Kubernetes rolling updates. Simply declare the desired version, and the etcd service starts a safe rolling update to the new version automatically.\\n\\n\\n**Backups included**\\n\\n\\nComing soon, the ability to schedule backups to happen on or off cluster.\\n\",\"displayName\":\"etcd\",\"icon\":[{\"base64data\":\"iVBORw0KGgoAAAANSUhEUgAAAOEAAADZCAYAAADWmle6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAEKlJREFUeNrsndt1GzkShmEev4sTgeiHfRYdgVqbgOgITEVgOgLTEQydwIiKwFQCayoCU6+7DyYjsBiBFyVVz7RkXvqCSxXw/+f04XjGQ6IL+FBVuL769euXgZ7r39f/G9iP0X+u/jWDNZzZdGI/Ftama1jjuV4BwmcNpbAf1Fgu+V/9YRvNAyzT2a59+/GT/3hnn5m16wKWedJrmOCxkYztx9Q+py/+E0GJxtJdReWfz+mxNt+QzS2Mc0AI+HbBBwj9QViKbH5t64DsP2fvmGXUkWU4WgO+Uve2YQzBUGd7r+zH2ZG/tiUQc4QxKwgbwFfVGwwmdLL5wH78aPC/ZBem9jJpCAX3xtcNASSNgJLzUPSQyjB1zQNl8IQJ9MIU4lx2+Jo72ysXYKl1HSzN02BMa/vbZ5xyNJIshJzwf3L0dQhJw4Sih/SFw9Tk8sVeghVPoefaIYCkMZCKbrcP9lnZuk0uPUjGE/KE8JQry7W2tgfuC3vXgvNV+qSQbyFtAtyWk7zWiYevvuUQ9QEQCvJ+5mmu6dTjz1zFHLFj8Eb87MtxaZh/IQFIHom+9vgTWwZxAQjT9X4vtbEVPojwjiV471s00mhAckpwGuCn1HtFtRDaSh6y9zsL+LNBvCG/24ThcxHObdlWc1v+VQJe8LcO0jwtuF8BwnAAUgP9M8JPU2Me+Oh12auPGT6fHuTePE3bLDy+x9pTLnhMn+07TQGh//Bz1iI0c6kvtqInjvPZcYR3KsPVmUsPYt9nFig9SCY8VQNhpPBzn952bbgcsk2EvM89wzh3UEffBbyPqvBUBYQ8ODGPFOLsa7RF096WJ69L+E4EmnpjWu5o4ChlKaRTKT39RMMaVPEQRsz/nIWlDN80chjdJlSd1l0pJCAMVZsniobQVuxceMM9OFoaMd9zqZtjMEYYDW38Drb8Y0DYPLShxn0pvIFuOSxd7YCPet9zk452wsh54FJoeN05hcgSQoG5RR0Qh9Q4E4VvL4wcZq8UACgaRFEQKgSwWrkr5WFnGxiHSutqJGlXjBgIOayhwYBTA0ER0oisIVSUV0AAMT0IASCUO4hRIQSAEECMCCEPwqyQA0JCQBzEGjWNAqHiUVAoXUWbvggOIQCEAOJzxTjoaQ4AIaE64/aZridUsBYUgkhB15oGg1DBIl8IqirYwV6hPSGBSFteMCUBSVXwfYixBmamRubeMyjzMJQBDDowE3OesDD+zwqFoDqiEwXoXJpljB+PvWJGy75BKF1FPxhKygJuqUdYQGlLxNEXkrYyjQ0GbaAwEnUIlLRNvVjQDYUAsJB0HKLE4y0AIpQNgCIhBIhQTgCKhZBBpAN/v6LtQI50JfUgYOnnjmLUFHKhjxbAmdTCaTiBm3ovLPqG2urWAij6im0Nd9aTN9ygLUEt9LgSRnohxUPIKxlGaE+/6Y7znFf0yX+GnkvFFWmarkab2o9PmTeq8sbd2a7DaysXz7i64VeznN4jCQhN9gdDbRiuWrfrsq0mHIrlaq+hlotCtd3Um9u0BYWY8y5D67wccJoZjFca7iUs9VqZcfsZwTd1sbWGG+OcYaTnPAP7rTQVVlM4Sg3oGvB1tmNh0t/HKXZ1jFoIMwCQjtqbhNxUmkGYqgZEDZP11HN/S3gAYRozf0l8C5kKEKUvW0t1IfeWG/5MwgheZTT1E0AEhDkAePQO+Ig2H3DncAkQM4cwUQCD530dU4B5Yvmi2LlDqXfWrxMCcMth51RToRMNUXFnfc2KJ0+Ryl0VNOUwlhh6NoxK5gnViTgQpUG4SqSyt5z3zRJpuKmt3Q1614QaCBPaN6je+2XiFcWAKOXcUfIYKRyL/1lb7pe5VxSxxjQ6hImshqGRt5GWZVKO6q2wHwujfwDtIvaIdexj8Cm8+a68EqMfox6x/voMouZF4dHnEGNeCDMwT6vdNfekH1MafMk4PI06YtqLVGl95aEM9Z5vAeCTOA++YLtoVJRrsqNCaJ6WRmkdYaNec5BT/lcTRMqrhmwfjbpkj55+OKp8IEbU/JLgPJE6Wa3TTe9sHS+ShVD5QIyqIxMEwKh12olC6mHIed5ewEop80CNlfIOADYOT2nd6ZXCop+Ebqchc0JqxKcKASxChycJgUh1rnHA5ow9eTrhqNI7JWiAYYwBGGdpyNLoGw0Pkh96h1BpHihyywtATDM/7Hk2fN9EnH8BgKJCU4ooBkbXFMZJiPbrOyecGl3zgQDQL4hk10IZiOe+5w99Q/gBAEIJgPhJM4QAEEoFREAIAAEiIASAkD8Qt4AQAEIAERAGFlX4CACKAXGVM4ivMwWwCLFAlyeoaa70QePKm5Dlp+/n+ye/5dYgva6YsUaVeMa+tzNFeJtWwc+udbJ0Fg399kLielQJ5Ze61c2+7ytA6EZetiPxZC6tj22yJCv6jUwOyj/zcbqAxOMyAKEbfeHtNa7DtYXptjsk2kJxR+eIeim/tHNofUKYy8DMrQcAKWz6brpvzyIAlpwPhQ49l6b7skJf5Z+YTOYQc4FwLDxvoTDwaygQK+U/kVr+ytSFBG01Q3gnJJR4cNiAhx4HDub8/b5DULXlj6SVZghFiE+LdvE9vo/o8Lp1RmH5hzm0T6wdbZ6n+D6i44zDRc3ln6CpAEJfXiRU45oqLz8gFAThWsh7ughrRibc0QynHgZpNJa/ENJ+loCwu/qOGnFIjYR/n7TfgycULhcQhu6VC+HfF+L3BoAQ4WiZTw1M+FPCnA2gKC6/FAhXgDC+ojQGh3NuWsvfF1L/D5ohlCKtl1j2ldu9a/nPAKFwN56Bst10zCG0CPleXN/zXPgHQZXaZaBgrbzyY5V/mUA+6F0hwtGN9rwu5DVZPuwWqfxdFz1LWbJ2lwKEa+0Qsm4Dl3fp+Pu0lV97PgwIPfSsS+UQhj5Oo+vvFULazRIQyvGEcxPuNLCth2MvFsrKn8UOilAQShkh7TTczYNMoS6OdP47msrPi82lXKGWhCdMZYS0bFy+vcnGAjP1CIfvgbKNA9glecEH9RD6Ol4wRuWyN/G9MHnksS6o/GPf5XcwNSUlHzQhDuAKtWJmkwKElU7lylP5rgIcsquh/FI8YZCDpkJBuE4FQm7Icw8N+SrUGaQKyi8FwiDt1ve5o+Vu7qYHy/psgK8cvh+FTYuO77bhEC7GuaPiys/L1X4IgXDL+e3M5+ovLxBy5VLuIebw1oqcHoPfoaMJUsHays878r8KbDc3xtPx/84gZPBG/JwaufrsY/SRG/OY3//8QMNdsvdZCFtbW6f8pFuf5bflILAlX7O+4fdfugKyFYS8T2zAsXthdG0VurPGKwI06oF5vkBgHWkNp6ry29+lsPZMU3vijnXFNmoclr+6+Ou/FIb8yb30sS8YGjmTqCLyQsi5N/6ZwKs0Yenj68pfPjF6N782Dp2FzV9CTyoSeY8mLK16qGxIkLI8oa1n8tz9juP40DlK0epxYEbojbq+9QfurBeVIlCO9D2396bxiV4lkYQ3hOAFw2pbhqMGISkkQOMcQ9EqhDmGZZdo92JC0YHRNTfoSg+5e0IT+opqCKHoIU+4ztQIgBD1EFNrQAgIpYSil9lDmPHqkROPt+JC6AgPquSuumJmg0YARVCuneDfvPVeJokZ6pIXDkNxQtGzTF9/BQjRG0tQznfb74RwCQghpALBtIQnfK4zhxdyQvVCUeknMIT3hLyY+T5jo0yABqKPQNpUNw/09tGZod5jgCaYFxyYvJcNPkv9eof+I3pnCFEHIETjSM8L9tHZHYCQT9PaZGycU6yg8S4akDnJ+P03L0+t23XGzCLzRgII/Wqa+fv/xlfvmKvMUOcOrlCDdoei1MGdZm6G5VEIfRzzjd4aQs69n699Rx7ewhvCGzr2gmTPs8zNsJOrXt24FbkhhOjCfT4ICA/rPbyhUy94Dks0gJCX1NzCZui9YUd3oei+c257TalFbgg19ILHrlrL2gvWgXAL26EX76gZTNASQnad8Ibwhl284NhgXpB0c+jKhWO3Ms1hP9ihJYB9eMF6qd1BCPk0qA1s+LimFIu7m4nsdQIzPK4VbQ8hYvrnuSH2G9b2ggP78QmWqBdF9Vx8SSY6QYdUW7BTA1schZATyhvY8lHvcRbNUS9YGFy2U+qmzh2YPVc0I7yAOFyHfRpyUwtCSzOdPXMHmz7qDIM0e0V2wZTEk+6Ym6N63eBLp/b5Bts+2cKCSJ/LuoZO3ANSiE5hKAZjnvNSS4931jcw9jpwT0feV/qSJ1pVtCyfHKDkvK8Ejx7pUxGh2xFNSwx8QTi2H9ceC0/nni64MS/5N5dG39pDqvRV+WgGk71c9VFXF9b+xYvOw/d61iv7m3MvEHryhvecwC52jSSx4VIIgwnMNT/UsTxIgpPt3K/ARj15CptwL3Zd/ceDSATj2DGQjbxgWwhdeMMte7zpy5On9vymRm/YxBYljGVjKWF9VJf7I1+sex3wY8w/V1QPTborW/72gkdsRDaZMJBdbdHIC7aCkAu9atlLbtnrzerMnyToDaGwelOnk3/hHSem/ZK7e/t7jeeR20LYBgqa8J80gS8jbwi5F02Uj1u2NYJxap8PLkJfLxA2hIJyvnHX/AfeEPLpBfe0uSFHbnXaea3Qd5d6HcpYZ8L6M7lnFwMQ3MNg+RxUR1+6AshtbsVgfXTEg1sIGax9UND2p7f270wdG3eK9gXVGHdw2k5sOyZv+Nbs39Z308XR9DqWb2J+PwKDhuKHPobfuXf7gnYGHdCs7bhDDadD4entDug7LWNsnRNW4mYqwJ9dk+GGSTPBiA2j0G8RWNM5upZtcG4/3vMfP7KnbK2egx6CCnDPhRn7NgD3cghLIad5WcM2SO38iqHvvMOosyeMpQ5zlVCaaj06GVs9xUbHdiKoqrHWgquFEFMWUEWfXUxJAML23hAHFOctmjZQffKD2pywkhtSGHKNtpitLroscAeE7kCkSsC60vxEl6yMtL9EL5HKGCMszU5bk8gdkklAyEn5FO0yK419rIxBOIqwFMooDE0tHEVYijAUECIshRCGIhxFWIowFJ5QkEYIS5PTJrUwNGlPyN6QQPyKtpuM1E/K5+YJDV/MiA3AaehzqgAm7QnZG9IGYKo8bHnSK7VblLL3hOwNHziPuEGOqE5brrdR6i+atCfckyeWD47HkAkepRGLY/e8A8J0gCwYSNypF08bBm+e6zVz2UL4AshhBUjML/rXLefqC82bcQFhGC9JDwZ1uuu+At0S5gCETYHsV4DUeD9fDN2Zfy5OXaW2zAwQygCzBLJ8cvaW5OXKC1FxfTggFAHmoAJnSiOw2wps9KwRWgJCLaEswaj5NqkLwAYIU4BxqTSXbHXpJdRMPZgAOiAMqABCNGYIEEJutEK5IUAIwYMDQgiCACEEAcJs1Vda7gGqDhCmoiEghAAhBAHCrKXVo2C1DCBMRlp37uMIEECoX7xrX3P5C9QiINSuIcoPAUI0YkAICLNWgfJDh4T9hH7zqYH9+JHAq7zBqWjwhPAicTVCVQJCNF50JghHocahKK0X/ZnQKyEkhSdUpzG8OgQI42qC94EQjsYLRSmH+pbgq73L6bYkeEJ4DYTYmeg1TOBFc/usTTp3V9DdEuXJ2xDCUbXhaXk0/kAYmBvuMB4qkC35E5e5AMKkwSQgyxufyuPy6fMMgAFCSI73LFXU/N8AmEL9X4ABACNSKMHAgb34AAAAAElFTkSuQmCC\",\"mediatype\":\"image/png\"}],\"install\":{\"spec\":{\"deployments\":[{\"name\":\"etcd-operator\",\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"name\":\"etcd-operator-alm-owned\"}},\"template\":{\"metadata\":{\"labels\":{\"name\":\"etcd-operator-alm-owned\"},\"name\":\"etcd-operator-alm-owned\"},\"spec\":{\"containers\":[{\"command\":[\"etcd-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-operator\"},{\"command\":[\"etcd-backup-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-backup-operator\"},{\"command\":[\"etcd-restore-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-restore-operator\"}],\"serviceAccountName\":\"etcd-operator\"}}}}],\"permissions\":[{\"rules\":[{\"apiGroups\":[\"etcd.database.coreos.com\"],\"resources\":[\"etcdclusters\",\"etcdbackups\",\"etcdrestores\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"pods\",\"services\",\"endpoints\",\"persistentvolumeclaims\",\"events\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"apps\"],\"resources\":[\"deployments\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\"]}],\"serviceAccountName\":\"etcd-operator\"}]},\"strategy\":\"deployment\"},\"keywords\":[\"etcd\",\"key value\",\"database\",\"coreos\",\"open source\"],\"labels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"},\"links\":[{\"name\":\"Blog\",\"url\":\"https://coreos.com/etcd\"},{\"name\":\"Documentation\",\"url\":\"https://coreos.com/operators/etcd/docs/latest/\"},{\"name\":\"etcd Operator Source Code\",\"url\":\"https://github.com/coreos/etcd-operator\"}],\"maintainers\":[{\"email\":\"support@coreos.com\",\"name\":\"CoreOS, Inc\"}],\"maturity\":\"alpha\",\"provider\":{\"name\":\"CoreOS, Inc\"},\"replaces\":\"etcdoperator.v0.9.0\",\"selector\":{\"matchLabels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"}},\"version\":\"0.10.1\"}}" etcdWithLabelsCSVJSON = "{\"apiVersion\":\"operators.coreos.com/v1alpha1\",\"kind\":\"ClusterServiceVersion\",\"metadata\":{\"labels\": {\"test\": \"label\"},\"annotations\":{\"alm-examples\":\"[{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdCluster\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example\\\",\\\"namespace\\\":\\\"default\\\"},\\\"spec\\\":{\\\"size\\\":3,\\\"version\\\":\\\"3.2.13\\\"}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdRestore\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"spec\\\":{\\\"etcdCluster\\\":{\\\"name\\\":\\\"example-etcd-cluster\\\"},\\\"backupStorageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}},{\\\"apiVersion\\\":\\\"etcd.database.coreos.com/v1beta2\\\",\\\"kind\\\":\\\"EtcdBackup\\\",\\\"metadata\\\":{\\\"name\\\":\\\"example-etcd-cluster-backup\\\"},\\\"spec\\\":{\\\"etcdEndpoints\\\":[\\\"\\u003cetcd-cluster-endpoints\\u003e\\\"],\\\"storageType\\\":\\\"S3\\\",\\\"s3\\\":{\\\"path\\\":\\\"\\u003cfull-s3-path\\u003e\\\",\\\"awsSecret\\\":\\\"\\u003caws-secret\\u003e\\\"}}}]\",\"tectonic-visibility\":\"ocs\"},\"name\":\"etcdoperator.v0.9.2\",\"namespace\":\"placeholder\"},\"spec\":{\"customresourcedefinitions\":{\"owned\":[{\"description\":\"Represents a cluster of etcd nodes.\",\"displayName\":\"etcd Cluster\",\"kind\":\"EtcdCluster\",\"name\":\"etcdclusters.etcd.database.coreos.com\",\"resources\":[{\"kind\":\"Service\",\"version\":\"v1\"},{\"kind\":\"Pod\",\"version\":\"v1\"}],\"specDescriptors\":[{\"description\":\"The desired number of member Pods for the etcd cluster.\",\"displayName\":\"Size\",\"path\":\"size\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podCount\"]},{\"description\":\"Limits describes the minimum/maximum amount of compute resources required/allowed\",\"displayName\":\"Resource Requirements\",\"path\":\"pod.resources\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:resourceRequirements\"]}],\"statusDescriptors\":[{\"description\":\"The status of each of the member Pods for the etcd cluster.\",\"displayName\":\"Member Status\",\"path\":\"members\",\"x-descriptors\":[\"urn:alm:descriptor:com.tectonic.ui:podStatuses\"]},{\"description\":\"The service at which the running etcd cluster can be accessed.\",\"displayName\":\"Service\",\"path\":\"serviceName\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Service\"]},{\"description\":\"The current size of the etcd cluster.\",\"displayName\":\"Cluster Size\",\"path\":\"size\"},{\"description\":\"The current version of the etcd cluster.\",\"displayName\":\"Current Version\",\"path\":\"currentVersion\"},{\"description\":\"The target version of the etcd cluster, after upgrading.\",\"displayName\":\"Target Version\",\"path\":\"targetVersion\"},{\"description\":\"The current status of the etcd cluster.\",\"displayName\":\"Status\",\"path\":\"phase\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase\"]},{\"description\":\"Explanation for the current status of the cluster.\",\"displayName\":\"Status Details\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to backup an etcd cluster.\",\"displayName\":\"etcd Backup\",\"kind\":\"EtcdBackup\",\"name\":\"etcdbackups.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"Specifies the endpoints of an etcd cluster.\",\"displayName\":\"etcd Endpoint(s)\",\"path\":\"etcdEndpoints\",\"x-descriptors\":[\"urn:alm:descriptor:etcd:endpoint\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the backup was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any backup related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"},{\"description\":\"Represents the intent to restore an etcd cluster from a backup.\",\"displayName\":\"etcd Restore\",\"kind\":\"EtcdRestore\",\"name\":\"etcdrestores.etcd.database.coreos.com\",\"specDescriptors\":[{\"description\":\"References the EtcdCluster which should be restored,\",\"displayName\":\"etcd Cluster\",\"path\":\"etcdCluster.name\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:EtcdCluster\",\"urn:alm:descriptor:text\"]},{\"description\":\"The full AWS S3 path where the backup is saved.\",\"displayName\":\"S3 Path\",\"path\":\"s3.path\",\"x-descriptors\":[\"urn:alm:descriptor:aws:s3:path\"]},{\"description\":\"The name of the secret object that stores the AWS credential and config files.\",\"displayName\":\"AWS Secret\",\"path\":\"s3.awsSecret\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes:Secret\"]}],\"statusDescriptors\":[{\"description\":\"Indicates if the restore was successful.\",\"displayName\":\"Succeeded\",\"path\":\"succeeded\",\"x-descriptors\":[\"urn:alm:descriptor:text\"]},{\"description\":\"Indicates the reason for any restore related failures.\",\"displayName\":\"Reason\",\"path\":\"reason\",\"x-descriptors\":[\"urn:alm:descriptor:io.kubernetes.phase:reason\"]}],\"version\":\"v1beta2\"}]},\"description\":\"etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines. It’s open-source and available on GitHub. etcd gracefully handles leader elections during network partitions and will tolerate machine failure, including the leader. Your applications can read and write data into etcd.\\nA simple use-case is to store database connection details or feature flags within etcd as key value pairs. These values can be watched, allowing your app to reconfigure itself when they change. Advanced uses take advantage of the consistency guarantees to implement database leader elections or do distributed locking across a cluster of workers.\\n\\n_The etcd Open Cloud Service is Public Alpha. The goal before Beta is to fully implement backup features._\\n\\n### Reading and writing to etcd\\n\\nCommunicate with etcd though its command line utility `etcdctl` or with the API using the automatically generated Kubernetes Service.\\n\\n[Read the complete guide to using the etcd Open Cloud Service](https://coreos.com/tectonic/docs/latest/alm/etcd-ocs.html)\\n\\n### Supported Features\\n\\n\\n**High availability**\\n\\n\\nMultiple instances of etcd are networked together and secured. Individual failures or networking issues are transparently handled to keep your cluster up and running.\\n\\n\\n**Automated updates**\\n\\n\\nRolling out a new etcd version works like all Kubernetes rolling updates. Simply declare the desired version, and the etcd service starts a safe rolling update to the new version automatically.\\n\\n\\n**Backups included**\\n\\n\\nComing soon, the ability to schedule backups to happen on or off cluster.\\n\",\"displayName\":\"etcd\",\"icon\":[{\"base64data\":\"iVBORw0KGgoAAAANSUhEUgAAAOEAAADZCAYAAADWmle6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAEKlJREFUeNrsndt1GzkShmEev4sTgeiHfRYdgVqbgOgITEVgOgLTEQydwIiKwFQCayoCU6+7DyYjsBiBFyVVz7RkXvqCSxXw/+f04XjGQ6IL+FBVuL769euXgZ7r39f/G9iP0X+u/jWDNZzZdGI/Ftama1jjuV4BwmcNpbAf1Fgu+V/9YRvNAyzT2a59+/GT/3hnn5m16wKWedJrmOCxkYztx9Q+py/+E0GJxtJdReWfz+mxNt+QzS2Mc0AI+HbBBwj9QViKbH5t64DsP2fvmGXUkWU4WgO+Uve2YQzBUGd7r+zH2ZG/tiUQc4QxKwgbwFfVGwwmdLL5wH78aPC/ZBem9jJpCAX3xtcNASSNgJLzUPSQyjB1zQNl8IQJ9MIU4lx2+Jo72ysXYKl1HSzN02BMa/vbZ5xyNJIshJzwf3L0dQhJw4Sih/SFw9Tk8sVeghVPoefaIYCkMZCKbrcP9lnZuk0uPUjGE/KE8JQry7W2tgfuC3vXgvNV+qSQbyFtAtyWk7zWiYevvuUQ9QEQCvJ+5mmu6dTjz1zFHLFj8Eb87MtxaZh/IQFIHom+9vgTWwZxAQjT9X4vtbEVPojwjiV471s00mhAckpwGuCn1HtFtRDaSh6y9zsL+LNBvCG/24ThcxHObdlWc1v+VQJe8LcO0jwtuF8BwnAAUgP9M8JPU2Me+Oh12auPGT6fHuTePE3bLDy+x9pTLnhMn+07TQGh//Bz1iI0c6kvtqInjvPZcYR3KsPVmUsPYt9nFig9SCY8VQNhpPBzn952bbgcsk2EvM89wzh3UEffBbyPqvBUBYQ8ODGPFOLsa7RF096WJ69L+E4EmnpjWu5o4ChlKaRTKT39RMMaVPEQRsz/nIWlDN80chjdJlSd1l0pJCAMVZsniobQVuxceMM9OFoaMd9zqZtjMEYYDW38Drb8Y0DYPLShxn0pvIFuOSxd7YCPet9zk452wsh54FJoeN05hcgSQoG5RR0Qh9Q4E4VvL4wcZq8UACgaRFEQKgSwWrkr5WFnGxiHSutqJGlXjBgIOayhwYBTA0ER0oisIVSUV0AAMT0IASCUO4hRIQSAEECMCCEPwqyQA0JCQBzEGjWNAqHiUVAoXUWbvggOIQCEAOJzxTjoaQ4AIaE64/aZridUsBYUgkhB15oGg1DBIl8IqirYwV6hPSGBSFteMCUBSVXwfYixBmamRubeMyjzMJQBDDowE3OesDD+zwqFoDqiEwXoXJpljB+PvWJGy75BKF1FPxhKygJuqUdYQGlLxNEXkrYyjQ0GbaAwEnUIlLRNvVjQDYUAsJB0HKLE4y0AIpQNgCIhBIhQTgCKhZBBpAN/v6LtQI50JfUgYOnnjmLUFHKhjxbAmdTCaTiBm3ovLPqG2urWAij6im0Nd9aTN9ygLUEt9LgSRnohxUPIKxlGaE+/6Y7znFf0yX+GnkvFFWmarkab2o9PmTeq8sbd2a7DaysXz7i64VeznN4jCQhN9gdDbRiuWrfrsq0mHIrlaq+hlotCtd3Um9u0BYWY8y5D67wccJoZjFca7iUs9VqZcfsZwTd1sbWGG+OcYaTnPAP7rTQVVlM4Sg3oGvB1tmNh0t/HKXZ1jFoIMwCQjtqbhNxUmkGYqgZEDZP11HN/S3gAYRozf0l8C5kKEKUvW0t1IfeWG/5MwgheZTT1E0AEhDkAePQO+Ig2H3DncAkQM4cwUQCD530dU4B5Yvmi2LlDqXfWrxMCcMth51RToRMNUXFnfc2KJ0+Ryl0VNOUwlhh6NoxK5gnViTgQpUG4SqSyt5z3zRJpuKmt3Q1614QaCBPaN6je+2XiFcWAKOXcUfIYKRyL/1lb7pe5VxSxxjQ6hImshqGRt5GWZVKO6q2wHwujfwDtIvaIdexj8Cm8+a68EqMfox6x/voMouZF4dHnEGNeCDMwT6vdNfekH1MafMk4PI06YtqLVGl95aEM9Z5vAeCTOA++YLtoVJRrsqNCaJ6WRmkdYaNec5BT/lcTRMqrhmwfjbpkj55+OKp8IEbU/JLgPJE6Wa3TTe9sHS+ShVD5QIyqIxMEwKh12olC6mHIed5ewEop80CNlfIOADYOT2nd6ZXCop+Ebqchc0JqxKcKASxChycJgUh1rnHA5ow9eTrhqNI7JWiAYYwBGGdpyNLoGw0Pkh96h1BpHihyywtATDM/7Hk2fN9EnH8BgKJCU4ooBkbXFMZJiPbrOyecGl3zgQDQL4hk10IZiOe+5w99Q/gBAEIJgPhJM4QAEEoFREAIAAEiIASAkD8Qt4AQAEIAERAGFlX4CACKAXGVM4ivMwWwCLFAlyeoaa70QePKm5Dlp+/n+ye/5dYgva6YsUaVeMa+tzNFeJtWwc+udbJ0Fg399kLielQJ5Ze61c2+7ytA6EZetiPxZC6tj22yJCv6jUwOyj/zcbqAxOMyAKEbfeHtNa7DtYXptjsk2kJxR+eIeim/tHNofUKYy8DMrQcAKWz6brpvzyIAlpwPhQ49l6b7skJf5Z+YTOYQc4FwLDxvoTDwaygQK+U/kVr+ytSFBG01Q3gnJJR4cNiAhx4HDub8/b5DULXlj6SVZghFiE+LdvE9vo/o8Lp1RmH5hzm0T6wdbZ6n+D6i44zDRc3ln6CpAEJfXiRU45oqLz8gFAThWsh7ughrRibc0QynHgZpNJa/ENJ+loCwu/qOGnFIjYR/n7TfgycULhcQhu6VC+HfF+L3BoAQ4WiZTw1M+FPCnA2gKC6/FAhXgDC+ojQGh3NuWsvfF1L/D5ohlCKtl1j2ldu9a/nPAKFwN56Bst10zCG0CPleXN/zXPgHQZXaZaBgrbzyY5V/mUA+6F0hwtGN9rwu5DVZPuwWqfxdFz1LWbJ2lwKEa+0Qsm4Dl3fp+Pu0lV97PgwIPfSsS+UQhj5Oo+vvFULazRIQyvGEcxPuNLCth2MvFsrKn8UOilAQShkh7TTczYNMoS6OdP47msrPi82lXKGWhCdMZYS0bFy+vcnGAjP1CIfvgbKNA9glecEH9RD6Ol4wRuWyN/G9MHnksS6o/GPf5XcwNSUlHzQhDuAKtWJmkwKElU7lylP5rgIcsquh/FI8YZCDpkJBuE4FQm7Icw8N+SrUGaQKyi8FwiDt1ve5o+Vu7qYHy/psgK8cvh+FTYuO77bhEC7GuaPiys/L1X4IgXDL+e3M5+ovLxBy5VLuIebw1oqcHoPfoaMJUsHays878r8KbDc3xtPx/84gZPBG/JwaufrsY/SRG/OY3//8QMNdsvdZCFtbW6f8pFuf5bflILAlX7O+4fdfugKyFYS8T2zAsXthdG0VurPGKwI06oF5vkBgHWkNp6ry29+lsPZMU3vijnXFNmoclr+6+Ou/FIb8yb30sS8YGjmTqCLyQsi5N/6ZwKs0Yenj68pfPjF6N782Dp2FzV9CTyoSeY8mLK16qGxIkLI8oa1n8tz9juP40DlK0epxYEbojbq+9QfurBeVIlCO9D2396bxiV4lkYQ3hOAFw2pbhqMGISkkQOMcQ9EqhDmGZZdo92JC0YHRNTfoSg+5e0IT+opqCKHoIU+4ztQIgBD1EFNrQAgIpYSil9lDmPHqkROPt+JC6AgPquSuumJmg0YARVCuneDfvPVeJokZ6pIXDkNxQtGzTF9/BQjRG0tQznfb74RwCQghpALBtIQnfK4zhxdyQvVCUeknMIT3hLyY+T5jo0yABqKPQNpUNw/09tGZod5jgCaYFxyYvJcNPkv9eof+I3pnCFEHIETjSM8L9tHZHYCQT9PaZGycU6yg8S4akDnJ+P03L0+t23XGzCLzRgII/Wqa+fv/xlfvmKvMUOcOrlCDdoei1MGdZm6G5VEIfRzzjd4aQs69n699Rx7ewhvCGzr2gmTPs8zNsJOrXt24FbkhhOjCfT4ICA/rPbyhUy94Dks0gJCX1NzCZui9YUd3oei+c257TalFbgg19ILHrlrL2gvWgXAL26EX76gZTNASQnad8Ibwhl284NhgXpB0c+jKhWO3Ms1hP9ihJYB9eMF6qd1BCPk0qA1s+LimFIu7m4nsdQIzPK4VbQ8hYvrnuSH2G9b2ggP78QmWqBdF9Vx8SSY6QYdUW7BTA1schZATyhvY8lHvcRbNUS9YGFy2U+qmzh2YPVc0I7yAOFyHfRpyUwtCSzOdPXMHmz7qDIM0e0V2wZTEk+6Ym6N63eBLp/b5Bts+2cKCSJ/LuoZO3ANSiE5hKAZjnvNSS4931jcw9jpwT0feV/qSJ1pVtCyfHKDkvK8Ejx7pUxGh2xFNSwx8QTi2H9ceC0/nni64MS/5N5dG39pDqvRV+WgGk71c9VFXF9b+xYvOw/d61iv7m3MvEHryhvecwC52jSSx4VIIgwnMNT/UsTxIgpPt3K/ARj15CptwL3Zd/ceDSATj2DGQjbxgWwhdeMMte7zpy5On9vymRm/YxBYljGVjKWF9VJf7I1+sex3wY8w/V1QPTborW/72gkdsRDaZMJBdbdHIC7aCkAu9atlLbtnrzerMnyToDaGwelOnk3/hHSem/ZK7e/t7jeeR20LYBgqa8J80gS8jbwi5F02Uj1u2NYJxap8PLkJfLxA2hIJyvnHX/AfeEPLpBfe0uSFHbnXaea3Qd5d6HcpYZ8L6M7lnFwMQ3MNg+RxUR1+6AshtbsVgfXTEg1sIGax9UND2p7f270wdG3eK9gXVGHdw2k5sOyZv+Nbs39Z308XR9DqWb2J+PwKDhuKHPobfuXf7gnYGHdCs7bhDDadD4entDug7LWNsnRNW4mYqwJ9dk+GGSTPBiA2j0G8RWNM5upZtcG4/3vMfP7KnbK2egx6CCnDPhRn7NgD3cghLIad5WcM2SO38iqHvvMOosyeMpQ5zlVCaaj06GVs9xUbHdiKoqrHWgquFEFMWUEWfXUxJAML23hAHFOctmjZQffKD2pywkhtSGHKNtpitLroscAeE7kCkSsC60vxEl6yMtL9EL5HKGCMszU5bk8gdkklAyEn5FO0yK419rIxBOIqwFMooDE0tHEVYijAUECIshRCGIhxFWIowFJ5QkEYIS5PTJrUwNGlPyN6QQPyKtpuM1E/K5+YJDV/MiA3AaehzqgAm7QnZG9IGYKo8bHnSK7VblLL3hOwNHziPuEGOqE5brrdR6i+atCfckyeWD47HkAkepRGLY/e8A8J0gCwYSNypF08bBm+e6zVz2UL4AshhBUjML/rXLefqC82bcQFhGC9JDwZ1uuu+At0S5gCETYHsV4DUeD9fDN2Zfy5OXaW2zAwQygCzBLJ8cvaW5OXKC1FxfTggFAHmoAJnSiOw2wps9KwRWgJCLaEswaj5NqkLwAYIU4BxqTSXbHXpJdRMPZgAOiAMqABCNGYIEEJutEK5IUAIwYMDQgiCACEEAcJs1Vda7gGqDhCmoiEghAAhBAHCrKXVo2C1DCBMRlp37uMIEECoX7xrX3P5C9QiINSuIcoPAUI0YkAICLNWgfJDh4T9hH7zqYH9+JHAq7zBqWjwhPAicTVCVQJCNF50JghHocahKK0X/ZnQKyEkhSdUpzG8OgQI42qC94EQjsYLRSmH+pbgq73L6bYkeEJ4DYTYmeg1TOBFc/usTTp3V9DdEuXJ2xDCUbXhaXk0/kAYmBvuMB4qkC35E5e5AMKkwSQgyxufyuPy6fMMgAFCSI73LFXU/N8AmEL9X4ABACNSKMHAgb34AAAAAElFTkSuQmCC\",\"mediatype\":\"image/png\"}],\"install\":{\"spec\":{\"deployments\":[{\"name\":\"etcd-operator\",\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"name\":\"etcd-operator-alm-owned\"}},\"template\":{\"metadata\":{\"labels\":{\"name\":\"etcd-operator-alm-owned\"},\"name\":\"etcd-operator-alm-owned\"},\"spec\":{\"containers\":[{\"command\":[\"etcd-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-operator\"},{\"command\":[\"etcd-backup-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-backup-operator\"},{\"command\":[\"etcd-restore-operator\",\"--create-crd=false\"],\"env\":[{\"name\":\"MY_POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"MY_POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}}],\"image\":\"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2\",\"name\":\"etcd-restore-operator\"}],\"serviceAccountName\":\"etcd-operator\"}}}}],\"permissions\":[{\"rules\":[{\"apiGroups\":[\"etcd.database.coreos.com\"],\"resources\":[\"etcdclusters\",\"etcdbackups\",\"etcdrestores\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"pods\",\"services\",\"endpoints\",\"persistentvolumeclaims\",\"events\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"apps\"],\"resources\":[\"deployments\"],\"verbs\":[\"*\"]},{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\"]}],\"serviceAccountName\":\"etcd-operator\"}]},\"strategy\":\"deployment\"},\"keywords\":[\"etcd\",\"key value\",\"database\",\"coreos\",\"open source\"],\"labels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"},\"links\":[{\"name\":\"Blog\",\"url\":\"https://coreos.com/etcd\"},{\"name\":\"Documentation\",\"url\":\"https://coreos.com/operators/etcd/docs/latest/\"},{\"name\":\"etcd Operator Source Code\",\"url\":\"https://github.com/coreos/etcd-operator\"}],\"maintainers\":[{\"email\":\"support@coreos.com\",\"name\":\"CoreOS, Inc\"}],\"maturity\":\"alpha\",\"provider\":{\"name\":\"CoreOS, Inc\"},\"replaces\":\"etcdoperator.v0.9.0\",\"selector\":{\"matchLabels\":{\"alm-owner-etcd\":\"etcdoperator\",\"operated-by\":\"etcdoperator\"}},\"version\":\"0.9.2\"}}" etcdBackupsCRDJSON = "{\"apiVersion\":\"apiextensions.k8s.io/v1beta1\",\"kind\":\"CustomResourceDefinition\",\"metadata\":{\"name\":\"etcdbackups.etcd.database.coreos.com\"},\"spec\":{\"group\":\"etcd.database.coreos.com\",\"names\":{\"kind\":\"EtcdBackup\",\"listKind\":\"EtcdBackupList\",\"plural\":\"etcdbackups\",\"singular\":\"etcdbackup\"},\"scope\":\"Namespaced\",\"version\":\"v1beta2\"}}" etcdUpgradesCRDJSON = "{\"apiVersion\":\"apiextensions.k8s.io/v1beta1\",\"kind\":\"CustomResourceDefinition\",\"metadata\":{\"name\":\"etcdclusters.etcd.database.coreos.com\"},\"spec\":{\"group\":\"etcd.database.coreos.com\",\"names\":{\"kind\":\"EtcdCluster\",\"listKind\":\"EtcdClusterList\",\"plural\":\"etcdclusters\",\"shortNames\":[\"etcdclus\",\"etcd\"],\"singular\":\"etcdcluster\"},\"scope\":\"Namespaced\",\"version\":\"v1beta2\"}}" @@ -476,6 +477,99 @@ func TestToPackageManifest(t *testing.T) { } } +func TestPackageManifestChannelsDisplayOrder(t *testing.T) { + apiPkg := &api.Package{ + Name: "etcd", + Channels: []*api.Channel{ + { + Name: "beta", + CsvName: "etcdoperator.v0.10.1", + }, + { + Name: "alpha", + CsvName: "etcdoperator.v0.9.2", + }, + }, + DefaultChannelName: "alpha", + } + clientFake := &fakes.FakeRegistryClient{} + clientFake.GetBundleForChannelReturnsOnCall(0, &api.Bundle{ + CsvName: "etcdoperator.v0.9.2", + PackageName: "etcd", + ChannelName: "alpha", + CsvJson: etcdCSVJSON, + Object: []string{ + etcdCSVJSON, + etcdBackupsCRDJSON, + etcdUpgradesCRDJSON, + etcdRestoresCRDJSON, + }, + }, nil) + clientFake.GetBundleForChannelReturnsOnCall(1, &api.Bundle{ + CsvName: "etcdoperator.v0.10.1", + PackageName: "etcd", + ChannelName: "beta", + CsvJson: etcdCSVJSONv10, + Object: []string{ + etcdCSVJSON, + etcdBackupsCRDJSON, + etcdUpgradesCRDJSON, + etcdRestoresCRDJSON, + }, + }, nil) + + client := ®istryClient{ + RegistryClient: clientFake, + catsrc: catalogSource("cool-operators", "ns"), + } + + packageManifest, err := newPackageManifest(context.Background(), logrus.NewEntry(logrus.New()), apiPkg, client, nil) + require.NoError(t, err) + require.Equal(t, &operators.PackageManifest{ + ObjectMeta: metav1.ObjectMeta{ + Name: "etcd", + Namespace: "ns", + Labels: labels.Set{ + "catalog": "cool-operators", + "catalog-namespace": "ns", + "provider": "CoreOS, Inc", + "provider-url": "", + "operatorframework.io/arch.amd64": "supported", + "operatorframework.io/os.linux": "supported", + }, + }, + Status: operators.PackageManifestStatus{ + CatalogSource: "cool-operators", + CatalogSourceNamespace: "ns", + PackageName: "etcd", + Provider: operators.AppLink{ + Name: "CoreOS, Inc", + }, + DefaultChannel: "alpha", + Channels: []operators.PackageChannel{ + { + Name: "alpha", + CurrentCSV: "etcdoperator.v0.9.2", + CurrentCSVDesc: func() operators.CSVDescription { + csv := operatorsv1alpha1.ClusterServiceVersion{} + require.NoError(t, json.Unmarshal([]byte(etcdCSVJSON), &csv)) + return operators.CreateCSVDescription(&csv, etcdCSVJSON) + }(), + }, + { + Name: "beta", + CurrentCSV: "etcdoperator.v0.10.1", + CurrentCSVDesc: func() operators.CSVDescription { + csv := operatorsv1alpha1.ClusterServiceVersion{} + require.NoError(t, json.Unmarshal([]byte(etcdCSVJSONv10), &csv)) + return operators.CreateCSVDescription(&csv, etcdCSVJSONv10) + }(), + }, + }, + }, + }, packageManifest) +} + func TestRegistryProviderGet(t *testing.T) { type getRequest struct { packageNamespace string diff --git a/staging/operator-lifecycle-manager/pkg/package-server/storage/subresources.go b/staging/operator-lifecycle-manager/pkg/package-server/storage/subresources.go index a851ee215a..24bc799e69 100644 --- a/staging/operator-lifecycle-manager/pkg/package-server/storage/subresources.go +++ b/staging/operator-lifecycle-manager/pkg/package-server/storage/subresources.go @@ -3,7 +3,7 @@ package storage import ( "context" "encoding/base64" - "io/ioutil" + "io" "net/http" "strconv" "strings" @@ -72,7 +72,7 @@ func (s *LogoStorage) Connect(ctx context.Context, name string, options runtime. etag := `"` + strings.Join([]string{name, pkgChannel.Name, pkgChannel.CurrentCSV}, ".") + `"` reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data)) - imgBytes, _ := ioutil.ReadAll(reader) + imgBytes, _ := io.ReadAll(reader) return imgBytes, mimeType, etag } diff --git a/staging/operator-lifecycle-manager/test/e2e/ctx/installer_helm.go b/staging/operator-lifecycle-manager/test/e2e/ctx/installer_helm.go index 918995e2e5..3cc2a3d9fa 100644 --- a/staging/operator-lifecycle-manager/test/e2e/ctx/installer_helm.go +++ b/staging/operator-lifecycle-manager/test/e2e/ctx/installer_helm.go @@ -1,3 +1,4 @@ +//go:build helm // +build helm package ctx diff --git a/staging/operator-lifecycle-manager/test/e2e/ctx/installer_none.go b/staging/operator-lifecycle-manager/test/e2e/ctx/installer_none.go index e21484cd99..48375d6d1b 100644 --- a/staging/operator-lifecycle-manager/test/e2e/ctx/installer_none.go +++ b/staging/operator-lifecycle-manager/test/e2e/ctx/installer_none.go @@ -1,3 +1,4 @@ +//go:build !helm // +build !helm package ctx diff --git a/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kind.go b/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kind.go index 27f6d7c78c..6ac0ab976c 100644 --- a/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kind.go +++ b/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kind.go @@ -7,7 +7,6 @@ import ( "encoding/csv" "flag" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -78,7 +77,7 @@ func (kl kindLogAdapter) V(level log.Level) log.InfoLogger { } func Provision(ctx *TestContext) (func(), error) { - dir, err := ioutil.TempDir("", "kind.") + dir, err := os.MkdirTemp("", "kind.") if err != nil { return nil, fmt.Errorf("failed to create temporary directory: %s", err.Error()) } diff --git a/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kubeconfig.go b/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kubeconfig.go index fa3a6eec3a..1ce1980d71 100644 --- a/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kubeconfig.go +++ b/staging/operator-lifecycle-manager/test/e2e/ctx/provisioner_kubeconfig.go @@ -1,3 +1,4 @@ +//go:build !kind // +build !kind package ctx diff --git a/staging/operator-lifecycle-manager/test/e2e/setup_bare_test.go b/staging/operator-lifecycle-manager/test/e2e/setup_bare_test.go index 354e41cf68..f21ae71a98 100644 --- a/staging/operator-lifecycle-manager/test/e2e/setup_bare_test.go +++ b/staging/operator-lifecycle-manager/test/e2e/setup_bare_test.go @@ -7,7 +7,6 @@ import ( "context" "flag" "io" - "io/ioutil" "os" "strings" "testing" @@ -65,7 +64,7 @@ func TestMain(m *testing.M) { testNamespace = *namespace if testNamespace == "" { - testNamespaceBytes, err := ioutil.ReadFile("e2e.namespace") + testNamespaceBytes, err := os.ReadFile("e2e.namespace") if err != nil || testNamespaceBytes == nil { panic("no namespace set") } diff --git a/staging/operator-lifecycle-manager/test/e2e/split/main.go b/staging/operator-lifecycle-manager/test/e2e/split/main.go index 30745d0cab..1637fdb567 100644 --- a/staging/operator-lifecycle-manager/test/e2e/split/main.go +++ b/staging/operator-lifecycle-manager/test/e2e/split/main.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "math" "os" @@ -106,7 +105,7 @@ func findDescribes(logger logrus.FieldLogger, dir string) ([]string, error) { return nil, err } for _, match := range matches { - b, err := ioutil.ReadFile(match) + b, err := os.ReadFile(match) if err != nil { return nil, err } diff --git a/staging/operator-lifecycle-manager/test/e2e/util/resource_queue.go b/staging/operator-lifecycle-manager/test/e2e/util/resource_queue.go index eabe5db77a..03eca665f6 100644 --- a/staging/operator-lifecycle-manager/test/e2e/util/resource_queue.go +++ b/staging/operator-lifecycle-manager/test/e2e/util/resource_queue.go @@ -79,7 +79,7 @@ func (q *ResourceQueue) DequeueHead() (k8scontrollerclient.Object, bool) { func (q *ResourceQueue) DequeueTail() (k8scontrollerclient.Object, bool) { q.lock.Lock() defer q.lock.Unlock() - + if len(q.queue) == 0 { return nil, false } diff --git a/staging/operator-lifecycle-manager/util/cpb/main.go b/staging/operator-lifecycle-manager/util/cpb/main.go index ae9912bf97..5b1769bb37 100644 --- a/staging/operator-lifecycle-manager/util/cpb/main.go +++ b/staging/operator-lifecycle-manager/util/cpb/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -118,7 +117,7 @@ func getMetadata() (m *metadata, err error) { m.annotationsFile = path // Unmarshal metadata - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { return fmt.Errorf("couldn't get content of annotations.yaml file: %s", path) } diff --git a/staging/operator-registry/.github/workflows/build.yaml b/staging/operator-registry/.github/workflows/build.yaml index 80a591d3cd..456f5b4647 100644 --- a/staging/operator-registry/.github/workflows/build.yaml +++ b/staging/operator-registry/.github/workflows/build.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - run: make build diff --git a/staging/operator-registry/.github/workflows/go-apidiff.yaml b/staging/operator-registry/.github/workflows/go-apidiff.yaml index 4f1657eb16..3114b147aa 100644 --- a/staging/operator-registry/.github/workflows/go-apidiff.yaml +++ b/staging/operator-registry/.github/workflows/go-apidiff.yaml @@ -14,14 +14,14 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - name: Set up Go - uses: actions/setup-go@v2 - with: - go-version: '~1.18' - id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 with: fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + id: go - name: Run go-apidiff uses: joelanford/go-apidiff@main diff --git a/staging/operator-registry/.github/workflows/goreleaser.yaml b/staging/operator-registry/.github/workflows/goreleaser.yaml index 5779f83015..468c8beca4 100644 --- a/staging/operator-registry/.github/workflows/goreleaser.yaml +++ b/staging/operator-registry/.github/workflows/goreleaser.yaml @@ -53,9 +53,9 @@ jobs: # GoReleaser requires fetch-depth: 0 to correctly # run git describe fetch-depth: 0 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - name: "Run GoReleaser" run: make release @@ -78,9 +78,9 @@ jobs: # run git describe fetch-depth: 0 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - name: "Run GoReleaser" run: make release @@ -103,9 +103,9 @@ jobs: # run git describe fetch-depth: 0 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - name: "Install linux cross-compilers" run: | diff --git a/staging/operator-registry/.github/workflows/sanity.yaml b/staging/operator-registry/.github/workflows/sanity.yaml index 8008817f8c..b97c58e68a 100644 --- a/staging/operator-registry/.github/workflows/sanity.yaml +++ b/staging/operator-registry/.github/workflows/sanity.yaml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - name: Install goimports run: go install golang.org/x/tools/cmd/goimports@latest - name: Run sanity checks diff --git a/staging/operator-registry/.github/workflows/test.yml b/staging/operator-registry/.github/workflows/test.yml index 5d54944f0b..c9f653ce6e 100644 --- a/staging/operator-registry/.github/workflows/test.yml +++ b/staging/operator-registry/.github/workflows/test.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: 'go.mod' - name: Install podman run: | . /etc/os-release diff --git a/staging/operator-registry/.github/workflows/unit.yaml b/staging/operator-registry/.github/workflows/unit.yaml index 4d5bcbc382..92a3b1415d 100644 --- a/staging/operator-registry/.github/workflows/unit.yaml +++ b/staging/operator-registry/.github/workflows/unit.yaml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: '~1.18' + go-version-file: "go.mod" - run: make unit - run: sed -i'' "s:^github.com/$GITHUB_REPOSITORY/::" coverage.out - run: .github/workflows/codecov.sh -Z -f coverage.out diff --git a/staging/operator-registry/Dockerfile b/staging/operator-registry/Dockerfile index a4e7fb317e..f0fd8db02f 100644 --- a/staging/operator-registry/Dockerfile +++ b/staging/operator-registry/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.18-openshift-4.11 AS builder +FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.19-openshift-4.11 AS builder ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/staging/operator-registry/alpha/action/list_test.go b/staging/operator-registry/alpha/action/list_test.go index 87f53886e0..d4ca83977e 100644 --- a/staging/operator-registry/alpha/action/list_test.go +++ b/staging/operator-registry/alpha/action/list_test.go @@ -28,7 +28,7 @@ foo Foo Operator beta { name: "Error/UnknownIndex", list: ListPackages{IndexReference: "unknown-index"}, - expectedErr: `render reference "unknown-index": error resolving name : object required`, + expectedErr: `render reference "unknown-index": error resolving name for image ref unknown-index: object required`, }, } for _, s := range specs { @@ -79,7 +79,7 @@ foo stable foo.v0.2.0 { name: "Error/UnknownIndex", list: ListChannels{IndexReference: "unknown-index"}, - expectedErr: `render reference "unknown-index": error resolving name : object required`, + expectedErr: `render reference "unknown-index": error resolving name for image ref unknown-index: object required`, }, { name: "Error/UnknownPackage", @@ -138,7 +138,7 @@ foo stable foo.v0.2.0 foo.v0.1.0 foo.v0.1.1,foo.v0.1.2 <0.2.0 tes { name: "Error/UnknownIndex", list: ListBundles{IndexReference: "unknown-index"}, - expectedErr: `render reference "unknown-index": error resolving name : object required`, + expectedErr: `render reference "unknown-index": error resolving name for image ref unknown-index: object required`, }, { name: "Error/UnknownPackage", diff --git a/staging/operator-registry/alpha/declcfg/declcfg.go b/staging/operator-registry/alpha/declcfg/declcfg.go index a4169c28c5..d575987b10 100644 --- a/staging/operator-registry/alpha/declcfg/declcfg.go +++ b/staging/operator-registry/alpha/declcfg/declcfg.go @@ -52,11 +52,11 @@ type ChannelEntry struct { // Top-level fields are the source of truth, i.e. not CSV values. // // Notes: -// - Any field slice type field or type containing a slice somewhere -// where two types/fields are equal if their contents are equal regardless -// of order must have a `hash:"set"` field tag for bundle comparison. -// - Any fields that have a `json:"-"` tag must be included in the equality -// evaluation in bundlesEqual(). +// - Any field slice type field or type containing a slice somewhere +// where two types/fields are equal if their contents are equal regardless +// of order must have a `hash:"set"` field tag for bundle comparison. +// - Any fields that have a `json:"-"` tag must be included in the equality +// evaluation in bundlesEqual(). type Bundle struct { Schema string `json:"schema"` Name string `json:"name"` diff --git a/staging/operator-registry/alpha/declcfg/load.go b/staging/operator-registry/alpha/declcfg/load.go index 65c289780e..98b25da02a 100644 --- a/staging/operator-registry/alpha/declcfg/load.go +++ b/staging/operator-registry/alpha/declcfg/load.go @@ -1,6 +1,7 @@ package declcfg import ( + "bytes" "encoding/json" "errors" "fmt" @@ -135,7 +136,7 @@ func LoadReader(r io.Reader) (*DeclarativeConfig, error) { var in Meta if err := json.Unmarshal(doc, &in); err != nil { - return nil, err + return nil, fmt.Errorf("unmarshal error: %s", resolveUnmarshalErr(doc, err)) } switch in.Schema { @@ -186,3 +187,47 @@ func LoadFile(root fs.FS, path string) (*DeclarativeConfig, error) { return cfg, nil } + +func resolveUnmarshalErr(data []byte, err error) string { + var te *json.UnmarshalTypeError + if errors.As(err, &te) { + return formatUnmarshallErrorString(data, te.Error(), te.Offset) + } + var se *json.SyntaxError + if errors.As(err, &se) { + return formatUnmarshallErrorString(data, se.Error(), se.Offset) + } + return err.Error() +} + +func formatUnmarshallErrorString(data []byte, errmsg string, offset int64) string { + sb := new(strings.Builder) + _, _ = sb.WriteString(fmt.Sprintf("%s at offset %d (indicated by <==)\n ", errmsg, offset)) + // attempt to present the erroneous JSON in indented, human-readable format + // errors result in presenting the original, unformatted output + var pretty bytes.Buffer + err := json.Indent(&pretty, data, "", " ") + if err == nil { + pString := pretty.String() + // calc the prettified string offset which correlates to the original string offset + var pOffset, origOffset int64 + origOffset = 0 + for origOffset = 0; origOffset < offset; { + pOffset++ + if pString[pOffset] != '\n' && pString[pOffset] != ' ' { + origOffset++ + } + } + _, _ = sb.WriteString(pString[:pOffset]) + _, _ = sb.WriteString(" <== ") + _, _ = sb.WriteString(pString[pOffset:]) + } else { + for i := int64(0); i < offset; i++ { + _ = sb.WriteByte(data[i]) + } + _, _ = sb.WriteString(" <== ") + _, _ = sb.Write(data[offset:]) + } + + return sb.String() +} diff --git a/staging/operator-registry/alpha/declcfg/write.go b/staging/operator-registry/alpha/declcfg/write.go index 6eb616bf41..3a66829ef0 100644 --- a/staging/operator-registry/alpha/declcfg/write.go +++ b/staging/operator-registry/alpha/declcfg/write.go @@ -124,12 +124,12 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer) if len(ce.Replaces) > 0 { replacesId := fmt.Sprintf("%s-%s", channelID, ce.Replaces) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", entryId, ce.Name, "replaces", replacesId, ce.Replaces)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", replacesId, ce.Replaces, "replace", entryId, ce.Name)) } if len(ce.Skips) > 0 { for _, s := range ce.Skips { skipsId := fmt.Sprintf("%s-%s", channelID, s) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", entryId, ce.Name, "skips", skipsId, s)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", skipsId, s, "skip", entryId, ce.Name)) } } if len(ce.SkipRange) > 0 { @@ -138,7 +138,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer) for _, edgeName := range filteredChannel.Entries { if skipRange(versionMap[edgeName.Name]) { skipRangeId := fmt.Sprintf("%s-%s", channelID, edgeName.Name) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- \"%s(%s)\" --> %s[%q]\n", entryId, ce.Name, "skipRange", ce.SkipRange, skipRangeId, edgeName.Name)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- \"%s(%s)\" --> %s[%q]\n", skipRangeId, edgeName.Name, "skipRange", ce.SkipRange, entryId, ce.Name)) } } } else { diff --git a/staging/operator-registry/alpha/declcfg/write_test.go b/staging/operator-registry/alpha/declcfg/write_test.go index 46f6d68f8d..bbbd3482bf 100644 --- a/staging/operator-registry/alpha/declcfg/write_test.go +++ b/staging/operator-registry/alpha/declcfg/write_test.go @@ -491,16 +491,16 @@ func TestWriteMermaidChannels(t *testing.T) { subgraph anakin-dark["dark"] anakin-dark-anakin.v0.0.1["anakin.v0.0.1"] anakin-dark-anakin.v0.1.0["anakin.v0.1.0"] - anakin-dark-anakin.v0.1.0["anakin.v0.1.0"]-- replaces --> anakin-dark-anakin.v0.0.1["anakin.v0.0.1"] + anakin-dark-anakin.v0.0.1["anakin.v0.0.1"]-- replace --> anakin-dark-anakin.v0.1.0["anakin.v0.1.0"] anakin-dark-anakin.v0.1.1["anakin.v0.1.1"] - anakin-dark-anakin.v0.1.1["anakin.v0.1.1"]-- replaces --> anakin-dark-anakin.v0.0.1["anakin.v0.0.1"] - anakin-dark-anakin.v0.1.1["anakin.v0.1.1"]-- skips --> anakin-dark-anakin.v0.1.0["anakin.v0.1.0"] + anakin-dark-anakin.v0.0.1["anakin.v0.0.1"]-- replace --> anakin-dark-anakin.v0.1.1["anakin.v0.1.1"] + anakin-dark-anakin.v0.1.0["anakin.v0.1.0"]-- skip --> anakin-dark-anakin.v0.1.1["anakin.v0.1.1"] end %% channel "light" subgraph anakin-light["light"] anakin-light-anakin.v0.0.1["anakin.v0.0.1"] anakin-light-anakin.v0.1.0["anakin.v0.1.0"] - anakin-light-anakin.v0.1.0["anakin.v0.1.0"]-- replaces --> anakin-light-anakin.v0.0.1["anakin.v0.0.1"] + anakin-light-anakin.v0.0.1["anakin.v0.0.1"]-- replace --> anakin-light-anakin.v0.1.0["anakin.v0.1.0"] end end %% package "boba-fett" @@ -509,7 +509,7 @@ func TestWriteMermaidChannels(t *testing.T) { subgraph boba-fett-mando["mando"] boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"] boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"] - boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"]-- replaces --> boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"] + boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"]-- replace --> boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"] end end `, @@ -526,7 +526,7 @@ func TestWriteMermaidChannels(t *testing.T) { subgraph anakin-dark["dark"] anakin-dark-anakin.v0.1.0["anakin.v0.1.0"] anakin-dark-anakin.v0.1.1["anakin.v0.1.1"] - anakin-dark-anakin.v0.1.1["anakin.v0.1.1"]-- skips --> anakin-dark-anakin.v0.1.0["anakin.v0.1.0"] + anakin-dark-anakin.v0.1.0["anakin.v0.1.0"]-- skip --> anakin-dark-anakin.v0.1.1["anakin.v0.1.1"] end %% channel "light" subgraph anakin-light["light"] @@ -547,7 +547,7 @@ func TestWriteMermaidChannels(t *testing.T) { subgraph boba-fett-mando["mando"] boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"] boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"] - boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"]-- replaces --> boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"] + boba-fett-mando-boba-fett.v1.0.0["boba-fett.v1.0.0"]-- replace --> boba-fett-mando-boba-fett.v2.0.0["boba-fett.v2.0.0"] end end `, diff --git a/staging/operator-registry/alpha/model/model.go b/staging/operator-registry/alpha/model/model.go index a6ca060420..48861e49cd 100644 --- a/staging/operator-registry/alpha/model/model.go +++ b/staging/operator-registry/alpha/model/model.go @@ -141,8 +141,9 @@ type Channel struct { } // TODO(joelanford): This function determines the channel head by finding the bundle that has 0 -// incoming edges, based on replaces and skips. It also expects to find exactly one such bundle. -// Is this the correct algorithm? +// +// incoming edges, based on replaces and skips. It also expects to find exactly one such bundle. +// Is this the correct algorithm? func (c Channel) Head() (*Bundle, error) { incoming := map[string]int{} for _, b := range c.Bundles { @@ -210,11 +211,11 @@ func (c *Channel) Validate() error { // validateReplacesChain checks the replaces chain of a channel. // Specifically the following rules must be followed: -// 1. There must be exactly 1 channel head. -// 2. Beginning at the head, the replaces chain must reach all non-skipped entries. -// Non-skipped entries are defined as entries that are not skipped by any other entry in the channel. -// 3. There must be no cycles in the replaces chain. -// 4. The tail entry in the replaces chain is permitted to replace a non-existent entry. +// 1. There must be exactly 1 channel head. +// 2. Beginning at the head, the replaces chain must reach all non-skipped entries. +// Non-skipped entries are defined as entries that are not skipped by any other entry in the channel. +// 3. There must be no cycles in the replaces chain. +// 4. The tail entry in the replaces chain is permitted to replace a non-existent entry. func (c *Channel) validateReplacesChain() error { head, err := c.Head() if err != nil { diff --git a/staging/operator-registry/alpha/property/property.go b/staging/operator-registry/alpha/property/property.go index 695bfd6da8..9ccd0f14bc 100644 --- a/staging/operator-registry/alpha/property/property.go +++ b/staging/operator-registry/alpha/property/property.go @@ -40,8 +40,9 @@ type Package struct { } // NOTICE: The Channel properties are for internal use only. -// DO NOT use it for any public-facing functionalities. -// This API is in alpha stage and it is subject to change. +// +// DO NOT use it for any public-facing functionalities. +// This API is in alpha stage and it is subject to change. type Channel struct { ChannelName string `json:"channelName"` //Priority string `json:"priority"` @@ -287,8 +288,9 @@ func MustBuildBundleObjectData(data []byte) Property { } // NOTICE: The Channel properties are for internal use only. -// DO NOT use it for any public-facing functionalities. -// This API is in alpha stage and it is subject to change. +// +// DO NOT use it for any public-facing functionalities. +// This API is in alpha stage and it is subject to change. func MustBuildChannelPriority(name string, priority int) Property { return MustBuild(&Channel{ChannelName: name, Priority: priority}) } diff --git a/staging/operator-registry/alpha/template/basic/basic.go b/staging/operator-registry/alpha/template/basic/basic.go new file mode 100644 index 0000000000..18566fbcf2 --- /dev/null +++ b/staging/operator-registry/alpha/template/basic/basic.go @@ -0,0 +1,50 @@ +package basic + +import ( + "context" + "fmt" + "io" + + "github.com/operator-framework/operator-registry/alpha/action" + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/pkg/image" +) + +type Template struct { + Registry image.Registry +} + +func (t Template) Render(ctx context.Context, reader io.Reader) (*declcfg.DeclarativeConfig, error) { + cfg, err := declcfg.LoadReader(reader) + if err != nil { + return cfg, err + } + + outb := cfg.Bundles[:0] // allocate based on max size of input, but empty slice + // populate registry, incl any flags from CLI, and enforce only rendering bundle images + r := action.Render{ + Registry: t.Registry, + AllowedRefMask: action.RefBundleImage, + } + + for _, b := range cfg.Bundles { + if !isBundleTemplate(&b) { + return nil, fmt.Errorf("unexpected fields present in basic template bundle") + } + r.Refs = []string{b.Image} + contributor, err := r.Run(ctx) + if err != nil { + return nil, err + } + outb = append(outb, contributor.Bundles...) + } + + cfg.Bundles = outb + return cfg, nil +} + +// isBundleTemplate identifies a Bundle template source as having a Schema and Image defined +// but no Properties, RelatedImages or Package defined +func isBundleTemplate(b *declcfg.Bundle) bool { + return b.Schema != "" && b.Image != "" && b.Package == "" && len(b.Properties) == 0 && len(b.RelatedImages) == 0 +} diff --git a/staging/operator-registry/alpha/template/composite/builder.go b/staging/operator-registry/alpha/template/composite/builder.go new file mode 100644 index 0000000000..615cd09256 --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/builder.go @@ -0,0 +1,322 @@ +package composite + +import ( + "bytes" + "fmt" + "io" + "os" + "os/exec" + "path" + "strings" + + "sigs.k8s.io/yaml" + + "github.com/operator-framework/operator-registry/alpha/declcfg" +) + +const ( + BasicBuilderSchema = "olm.builder.basic" + SemverBuilderSchema = "olm.builder.semver" + RawBuilderSchema = "olm.builder.raw" + CustomBuilderSchema = "olm.builder.custom" +) + +type ContainerConfig struct { + ContainerTool string + BaseImage string + WorkingDir string +} + +type BuilderConfig struct { + ContainerCfg ContainerConfig + OutputType string + CurrentDirectory string +} + +type Builder interface { + Build(dir string, td TemplateDefinition) error + Validate(dir string) error +} + +type BasicBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &BasicBuilder{} + +func NewBasicBuilder(builderCfg BuilderConfig) *BasicBuilder { + return &BasicBuilder{ + builderCfg: builderCfg, + } +} + +func (bb *BasicBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != BasicBuilderSchema { + return fmt.Errorf("schema %q does not match the basic template builder schema %q", td.Schema, BasicBuilderSchema) + } + // Parse out the basic template configuration + basicConfig := &BasicConfig{} + err := yaml.UnmarshalStrict(td.Config, basicConfig) + if err != nil { + return fmt.Errorf("unmarshalling basic template config: %w", err) + } + + // validate the basic config fields + valid := true + validationErrs := []string{} + if basicConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "basic template config must have a non-empty input (templateDefinition.config.input)") + } + + if basicConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "basic template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("basic template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(bb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", bb.builderCfg.CurrentDirectory, bb.builderCfg.ContainerCfg.WorkingDir), + bb.builderCfg.ContainerCfg.BaseImage, + "alpha", + "render-template", + "basic", + path.Join(bb.builderCfg.ContainerCfg.WorkingDir, basicConfig.Input)) + + return build(containerCmd, path.Join(dir, basicConfig.Output), bb.builderCfg.OutputType) +} + +func (bb *BasicBuilder) Validate(dir string) error { + return validate(bb.builderCfg.ContainerCfg, path.Join(bb.builderCfg.CurrentDirectory, dir)) +} + +type SemverBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &SemverBuilder{} + +func NewSemverBuilder(builderCfg BuilderConfig) *SemverBuilder { + return &SemverBuilder{ + builderCfg: builderCfg, + } +} + +func (sb *SemverBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != SemverBuilderSchema { + return fmt.Errorf("schema %q does not match the semver template builder schema %q", td.Schema, SemverBuilderSchema) + } + // Parse out the semver template configuration + semverConfig := &SemverConfig{} + err := yaml.UnmarshalStrict(td.Config, semverConfig) + if err != nil { + return fmt.Errorf("unmarshalling semver template config: %w", err) + } + + // validate the semver config fields + valid := true + validationErrs := []string{} + if semverConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "semver template config must have a non-empty input (templateDefinition.config.input)") + } + + if semverConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "semver template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("semver template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(sb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", sb.builderCfg.CurrentDirectory, sb.builderCfg.ContainerCfg.WorkingDir), + sb.builderCfg.ContainerCfg.BaseImage, + "alpha", + "render-template", + "semver", + path.Join(sb.builderCfg.ContainerCfg.WorkingDir, semverConfig.Input)) + + return build(containerCmd, path.Join(dir, semverConfig.Output), sb.builderCfg.OutputType) +} + +func (sb *SemverBuilder) Validate(dir string) error { + return validate(sb.builderCfg.ContainerCfg, path.Join(sb.builderCfg.CurrentDirectory, dir)) +} + +type RawBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &RawBuilder{} + +func NewRawBuilder(builderCfg BuilderConfig) *RawBuilder { + return &RawBuilder{ + builderCfg: builderCfg, + } +} + +func (rb *RawBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != RawBuilderSchema { + return fmt.Errorf("schema %q does not match the raw template builder schema %q", td.Schema, RawBuilderSchema) + } + // Parse out the raw template configuration + rawConfig := &RawConfig{} + err := yaml.UnmarshalStrict(td.Config, rawConfig) + if err != nil { + return fmt.Errorf("unmarshalling raw template config: %w", err) + } + + // validate the raw config fields + valid := true + validationErrs := []string{} + if rawConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "raw template config must have a non-empty input (templateDefinition.config.input)") + } + + if rawConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "raw template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("raw template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(rb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", rb.builderCfg.CurrentDirectory, rb.builderCfg.ContainerCfg.WorkingDir), + "--entrypoint=cat", // This assumes that the `cat` command is available in the container -- Should we also build a `... render-template raw` command to ensure consistent operation? Does OPM already have a way to render a raw FBC? + rb.builderCfg.ContainerCfg.BaseImage, + path.Join(rb.builderCfg.ContainerCfg.WorkingDir, rawConfig.Input)) + + return build(containerCmd, path.Join(dir, rawConfig.Output), rb.builderCfg.OutputType) +} + +func (rb *RawBuilder) Validate(dir string) error { + return validate(rb.builderCfg.ContainerCfg, path.Join(rb.builderCfg.CurrentDirectory, dir)) +} + +type CustomBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &CustomBuilder{} + +func NewCustomBuilder(builderCfg BuilderConfig) *CustomBuilder { + return &CustomBuilder{ + builderCfg: builderCfg, + } +} + +func (cb *CustomBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != CustomBuilderSchema { + return fmt.Errorf("schema %q does not match the custom template builder schema %q", td.Schema, CustomBuilderSchema) + } + // Parse out the raw template configuration + customConfig := &CustomConfig{} + err := yaml.UnmarshalStrict(td.Config, customConfig) + if err != nil { + return fmt.Errorf("unmarshalling custom template config: %w", err) + } + + // validate the custom config fields + valid := true + validationErrs := []string{} + if customConfig.Command == "" { + valid = false + validationErrs = append(validationErrs, "custom template config must have a non-empty command (templateDefinition.config.command)") + } + + if customConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "custom template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("custom template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + // build the command to execute + cmd := exec.Command(customConfig.Command, customConfig.Args...) + cmd.Dir = cb.builderCfg.CurrentDirectory + + // custom template should output a valid FBC to STDOUT so we can + // build the FBC just like all the other templates. + return build(cmd, path.Join(dir, customConfig.Output), cb.builderCfg.OutputType) +} + +func (cb *CustomBuilder) Validate(dir string) error { + return validate(cb.builderCfg.ContainerCfg, path.Join(cb.builderCfg.CurrentDirectory, dir)) +} + +func writeDeclCfg(dcfg declcfg.DeclarativeConfig, w io.Writer, output string) error { + switch output { + case "yaml": + return declcfg.WriteYAML(dcfg, w) + case "json": + return declcfg.WriteJSON(dcfg, w) + default: + return fmt.Errorf("invalid --output value %q, expected (json|yaml)", output) + } +} + +func validate(containerCfg ContainerConfig, dir string) error { + // build the container command + containerCmd := exec.Command(containerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", dir, containerCfg.WorkingDir), + containerCfg.BaseImage, + "validate", + containerCfg.WorkingDir) + + _, err := containerCmd.Output() + if err != nil { + return fmt.Errorf("running command %q: %w", containerCmd.String(), err) + } + return nil +} + +func build(cmd *exec.Cmd, outPath string, outType string) error { + out, err := cmd.Output() + if err != nil { + return fmt.Errorf("running command %q: %w", cmd.String(), err) + } + + // parse out to dcfg + dcfg, err := declcfg.LoadReader(bytes.NewReader(out)) + if err != nil { + return fmt.Errorf("parsing builder output: %w", err) + } + + // write the dcfg + file, err := os.Create(outPath) + if err != nil { + return fmt.Errorf("creating output file %q: %w", outPath, err) + } + defer file.Close() + + err = writeDeclCfg(*dcfg, file, outType) + if err != nil { + return fmt.Errorf("writing to output file %q: %w", outPath, err) + } + + return nil +} diff --git a/staging/operator-registry/alpha/template/composite/builder_test.go b/staging/operator-registry/alpha/template/composite/builder_test.go new file mode 100644 index 0000000000..9c982d9208 --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/builder_test.go @@ -0,0 +1,1804 @@ +package composite + +import ( + "fmt" + "io" + "os" + "path" + "testing" + + "github.com/stretchr/testify/require" +) + +// TODO: Should we consolidate all these tests into a singular test function? +// It was intentional to keep them separate for now, but it would significantly reduce code replication to combine into one function +func TestBasicBuilder(t *testing.T) { + type testCase struct { + name string + validate bool + basicBuilder *BasicBuilder + templateDefinition TemplateDefinition + files map[string]string + buildAssertions func(t *testing.T, dir string, buildErr error) + validateAssertions func(t *testing.T, validateErr error) + } + + testCases := []testCase{ + { + name: "successful basic build yaml output", + validate: true, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "input": "components/basic.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/basic.yaml": basicYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.yaml") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), basicBuiltFbcYaml) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "successful basic build json output", + validate: true, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "json", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "input": "components/basic.yaml", + "output": "catalog.json" + }`), + }, + files: map[string]string{ + "components/basic.yaml": basicYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.json") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), basicBuiltFbcJson) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "invalid template configuration", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "invalid": "components/basic.yaml", + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "unmarshalling basic template config:") + }, + }, + { + name: "builder command failure", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "input": "components/basic.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "running command") + }, + }, + { + name: "invalid output type", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "invalid", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "input": "components/basic.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/basic.yaml": basicYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("invalid --output value %q, expected (json|yaml)", "invalid")) + }, + }, + { + name: "invalid schema", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: "olm.invalid", + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("schema %q does not match the basic template builder schema %q", "olm.invalid", BasicBuilderSchema)) + }, + }, + { + name: "template config has empty input", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "basic template configuration is invalid: basic template config must have a non-empty input (templateDefinition.config.input)") + }, + }, + { + name: "template config has empty output", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{ + "input": "components/basic.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "basic template configuration is invalid: basic template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + { + name: "template config has empty input & output", + validate: false, + basicBuilder: NewBasicBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/basic", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: BasicBuilderSchema, + Config: []byte(`{}`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "basic template configuration is invalid: basic template config must have a non-empty input (templateDefinition.config.input),basic template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + } + + testDir := t.TempDir() + + for i, tc := range testCases { + tc.basicBuilder.builderCfg.CurrentDirectory = testDir + t.Run(tc.name, func(t *testing.T) { + outDir := fmt.Sprintf("basic-%d", i) + outPath := path.Join(testDir, outDir) + err := os.MkdirAll(outPath, 0o777) + require.NoError(t, err) + + // create files in temp dir + for fileName, fileContents := range tc.files { + err := os.MkdirAll(path.Join(testDir, path.Dir(fileName)), 0o777) + require.NoError(t, err) + file, err := os.Create(path.Join(testDir, fileName)) + require.NoError(t, err) + _, err = file.WriteString(fileContents) + require.NoError(t, err) + } + + buildErr := tc.basicBuilder.Build(outPath, tc.templateDefinition) + tc.buildAssertions(t, outPath, buildErr) + + if tc.validate { + validateErr := tc.basicBuilder.Validate(outDir) + tc.validateAssertions(t, validateErr) + } + }) + } +} + +const basicYaml = `--- +defaultChannel: preview +name: webhook-operator +schema: olm.package +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +schema: olm.bundle +--- +schema: olm.channel +package: webhook-operator +name: preview +entries: + - name: webhook-operator.v0.0.1 +` + +const basicBuiltFbcYaml = `--- +defaultChannel: preview +name: webhook-operator +schema: olm.package +--- +entries: +- name: webhook-operator.v0.0.1 +name: preview +package: webhook-operator +schema: olm.channel +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +` + +const basicBuiltFbcJson = `{ + "schema": "olm.package", + "name": "webhook-operator", + "defaultChannel": "preview" +} +{ + "schema": "olm.channel", + "name": "preview", + "package": "webhook-operator", + "entries": [ + { + "name": "webhook-operator.v0.0.1" + } + ] +} +{ + "schema": "olm.bundle", + "name": "webhook-operator.v0.0.1", + "package": "webhook-operator", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3", + "properties": [ + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v1" + } + }, + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v2" + } + }, + { + "type": "olm.package", + "value": { + "packageName": "webhook-operator", + "version": "0.0.1" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0=" + } + } + ], + "relatedImages": [ + { + "name": "", + "image": "gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator:0.0.3" + } + ] +} +` + +func TestSemverBuilder(t *testing.T) { + type testCase struct { + name string + validate bool + semverBuilder *SemverBuilder + templateDefinition TemplateDefinition + files map[string]string + buildAssertions func(t *testing.T, dir string, buildErr error) + validateAssertions func(t *testing.T, validateErr error) + } + + testCases := []testCase{ + { + name: "successful semver build yaml output", + validate: true, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "input": "components/semver.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/semver.yaml": semverYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.yaml") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), semverBuiltFbcYaml) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "successful semver build json output", + validate: true, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "json", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "input": "components/semver.yaml", + "output": "catalog.json" + }`), + }, + files: map[string]string{ + "components/semver.yaml": semverYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.json") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), semverBuiltFbcJson) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "invalid template configuration", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "invalid": "components/semver.yaml", + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "unmarshalling semver template config:") + }, + }, + { + name: "builder command failure", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "input": "components/semver.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "running command") + }, + }, + { + name: "invalid output type", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "invalid", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "input": "components/semver.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/semver.yaml": semverYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("invalid --output value %q, expected (json|yaml)", "invalid")) + }, + }, + { + name: "invalid schema", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: "olm.invalid", + Config: []byte(`{ + "input": "components/semver.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("schema %q does not match the semver template builder schema %q", "olm.invalid", SemverBuilderSchema)) + }, + }, + { + name: "template config has empty input", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "semver template configuration is invalid: semver template config must have a non-empty input (templateDefinition.config.input)") + }, + }, + { + name: "template config has empty output", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{ + "input": "components/semver.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "semver template configuration is invalid: semver template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + { + name: "template config has empty input & output", + validate: false, + semverBuilder: NewSemverBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/semver", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: SemverBuilderSchema, + Config: []byte(`{}`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "semver template configuration is invalid: semver template config must have a non-empty input (templateDefinition.config.input),semver template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + } + + testDir := t.TempDir() + + for i, tc := range testCases { + tc.semverBuilder.builderCfg.CurrentDirectory = testDir + t.Run(tc.name, func(t *testing.T) { + outDir := fmt.Sprintf("semver-%d", i) + outPath := path.Join(testDir, outDir) + err := os.MkdirAll(outPath, 0o777) + require.NoError(t, err) + + // create files in temp dir + for fileName, fileContents := range tc.files { + err := os.MkdirAll(path.Join(testDir, path.Dir(fileName)), 0o777) + require.NoError(t, err) + file, err := os.Create(path.Join(testDir, fileName)) + require.NoError(t, err) + _, err = file.WriteString(fileContents) + require.NoError(t, err) + } + + buildErr := tc.semverBuilder.Build(outPath, tc.templateDefinition) + tc.buildAssertions(t, outPath, buildErr) + + if tc.validate { + validateErr := tc.semverBuilder.Validate(outDir) + tc.validateAssertions(t, validateErr) + } + }) + } +} + +const semverYaml = `--- +Schema: olm.semver +GenerateMajorChannels: true +GenerateMinorChannels: true +Stable: + Bundles: + - Image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +` + +const semverBuiltFbcYaml = `--- +defaultChannel: stable-v0 +name: webhook-operator +schema: olm.package +--- +entries: +- name: webhook-operator.v0.0.1 +name: stable-v0 +package: webhook-operator +schema: olm.channel +--- +entries: +- name: webhook-operator.v0.0.1 +name: stable-v0.0 +package: webhook-operator +schema: olm.channel +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +` + +const semverBuiltFbcJson = `{ + "schema": "olm.package", + "name": "webhook-operator", + "defaultChannel": "stable-v0" +} +{ + "schema": "olm.channel", + "name": "stable-v0", + "package": "webhook-operator", + "entries": [ + { + "name": "webhook-operator.v0.0.1" + } + ] +} +{ + "schema": "olm.channel", + "name": "stable-v0.0", + "package": "webhook-operator", + "entries": [ + { + "name": "webhook-operator.v0.0.1" + } + ] +} +{ + "schema": "olm.bundle", + "name": "webhook-operator.v0.0.1", + "package": "webhook-operator", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3", + "properties": [ + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v1" + } + }, + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v2" + } + }, + { + "type": "olm.package", + "value": { + "packageName": "webhook-operator", + "version": "0.0.1" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0=" + } + } + ], + "relatedImages": [ + { + "name": "", + "image": "gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator:0.0.3" + } + ] +} +` + +func TestRawBuilder(t *testing.T) { + type testCase struct { + name string + validate bool + rawBuilder *RawBuilder + templateDefinition TemplateDefinition + files map[string]string + buildAssertions func(t *testing.T, dir string, buildErr error) + validateAssertions func(t *testing.T, validateErr error) + } + + testCases := []testCase{ + { + name: "successful raw build yaml output", + validate: true, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "input": "components/raw.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/raw.yaml": rawYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.yaml") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), rawBuiltFbcYaml) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "successful raw build json output", + validate: true, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "json", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "input": "components/raw.yaml", + "output": "catalog.json" + }`), + }, + files: map[string]string{ + "components/raw.yaml": rawYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.json") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), rawBuiltFbcJson) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "invalid template configuration", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "invalid": "components/raw.yaml", + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "unmarshalling raw template config:") + }, + }, + { + name: "builder command failure", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "input": "components/raw.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "running command") + }, + }, + { + name: "invalid output type", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "invalid", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "input": "components/raw.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/raw.yaml": semverYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("invalid --output value %q, expected (json|yaml)", "invalid")) + }, + }, + { + name: "invalid schema", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: "olm.invalid", + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("schema %q does not match the raw template builder schema %q", "olm.invalid", RawBuilderSchema)) + }, + }, + { + name: "template config has empty input", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "raw template configuration is invalid: raw template config must have a non-empty input (templateDefinition.config.input)") + }, + }, + { + name: "template config has empty output", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{ + "input": "components/raw.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "raw template configuration is invalid: raw template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + { + name: "template config has empty input & output", + validate: false, + rawBuilder: NewRawBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/raw", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: RawBuilderSchema, + Config: []byte(`{}`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + buildErr.Error(), + "raw template configuration is invalid: raw template config must have a non-empty input (templateDefinition.config.input),raw template config must have a non-empty output (templateDefinition.config.output)") + }, + }, + } + + testDir := t.TempDir() + + for i, tc := range testCases { + tc.rawBuilder.builderCfg.CurrentDirectory = testDir + t.Run(tc.name, func(t *testing.T) { + outDir := fmt.Sprintf("raw-%d", i) + outPath := path.Join(testDir, outDir) + err := os.MkdirAll(outPath, 0o777) + require.NoError(t, err) + + // create files in temp dir + for fileName, fileContents := range tc.files { + err := os.MkdirAll(path.Join(testDir, path.Dir(fileName)), 0o777) + require.NoError(t, err) + file, err := os.Create(path.Join(testDir, fileName)) + require.NoError(t, err) + _, err = file.WriteString(fileContents) + require.NoError(t, err) + } + + buildErr := tc.rawBuilder.Build(outPath, tc.templateDefinition) + tc.buildAssertions(t, outPath, buildErr) + + if tc.validate { + validateErr := tc.rawBuilder.Validate(outDir) + tc.validateAssertions(t, validateErr) + } + }) + } +} + +const rawYaml = `--- +defaultChannel: preview +name: webhook-operator-412 +schema: olm.package +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator-412 +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator-412 + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +--- +schema: olm.channel +package: webhook-operator-412 +name: preview +entries: + - name: webhook-operator.v0.0.1 +` + +const rawBuiltFbcYaml = `--- +defaultChannel: preview +name: webhook-operator-412 +schema: olm.package +--- +entries: +- name: webhook-operator.v0.0.1 +name: preview +package: webhook-operator-412 +schema: olm.channel +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator-412 +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator-412 + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +` + +const rawBuiltFbcJson = `{ + "schema": "olm.package", + "name": "webhook-operator-412", + "defaultChannel": "preview" +} +{ + "schema": "olm.channel", + "name": "preview", + "package": "webhook-operator-412", + "entries": [ + { + "name": "webhook-operator.v0.0.1" + } + ] +} +{ + "schema": "olm.bundle", + "name": "webhook-operator.v0.0.1", + "package": "webhook-operator-412", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3", + "properties": [ + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v1" + } + }, + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v2" + } + }, + { + "type": "olm.package", + "value": { + "packageName": "webhook-operator-412", + "version": "0.0.1" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0=" + } + } + ], + "relatedImages": [ + { + "name": "", + "image": "gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator:0.0.3" + } + ] +} +` + +func TestCustomBuilder(t *testing.T) { + type testCase struct { + name string + validate bool + customBuilder *CustomBuilder + templateDefinition TemplateDefinition + files map[string]string + buildAssertions func(t *testing.T, dir string, buildErr error) + validateAssertions func(t *testing.T, validateErr error) + } + + testCases := []testCase{ + { + name: "successful custom build yaml output", + validate: true, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "command": "cat", + "args": ["components/custom.yaml"], + "output": "catalog.yaml" + }`), + }, + files: map[string]string{ + "components/custom.yaml": customYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.yaml") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), customBuiltFbcYaml) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "successful custom build json output", + validate: true, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "json", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "command": "cat", + "args": ["components/custom.yaml"], + "output": "catalog.json" + }`), + }, + files: map[string]string{ + "components/custom.yaml": customYaml, + }, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.NoError(t, buildErr) + // check if the catalog.yaml file exists in the correct place + filePath := path.Join(dir, "catalog.json") + _, err := os.Stat(filePath) + require.NoError(t, err) + file, err := os.Open(filePath) + require.NoError(t, err) + defer file.Close() + fileData, err := io.ReadAll(file) + require.NoError(t, err) + require.Equal(t, string(fileData), customBuiltFbcJson) + }, + validateAssertions: func(t *testing.T, validateErr error) { + require.NoError(t, validateErr) + }, + }, + { + name: "invalid template configuration", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "invalid": "components/custom.yaml", + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "unmarshalling custom template config:") + }, + }, + { + name: "builder command failure", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "command": "thiscommanddoesnotexist", + "args": [], + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), "running command") + }, + }, + { + name: "invalid schema", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: "olm.invalid", + Config: []byte(`{ + "input": "components/custom.yaml", + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Contains(t, buildErr.Error(), fmt.Sprintf("schema %q does not match the custom template builder schema %q", "olm.invalid", CustomBuilderSchema)) + }, + }, + { + name: "template config has empty command", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "output": "catalog.yaml" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + "custom template configuration is invalid: custom template config must have a non-empty command (templateDefinition.config.command)", + buildErr.Error(), + ) + }, + }, + { + name: "template config has empty output", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{ + "command": "ls" + }`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + "custom template configuration is invalid: custom template config must have a non-empty output (templateDefinition.config.output)", + buildErr.Error(), + ) + }, + }, + { + name: "template config has empty command & output", + validate: false, + customBuilder: NewCustomBuilder(BuilderConfig{ + ContainerCfg: ContainerConfig{ + ContainerTool: "docker", + BaseImage: "quay.io/operator-framework/opm:latest", + WorkingDir: "/custom", + }, + OutputType: "yaml", + }), + templateDefinition: TemplateDefinition{ + Schema: CustomBuilderSchema, + Config: []byte(`{}`), + }, + files: map[string]string{}, + buildAssertions: func(t *testing.T, dir string, buildErr error) { + require.Error(t, buildErr) + require.Equal(t, + "custom template configuration is invalid: custom template config must have a non-empty command (templateDefinition.config.command),custom template config must have a non-empty output (templateDefinition.config.output)", + buildErr.Error(), + ) + }, + }, + } + + testDir := t.TempDir() + + for i, tc := range testCases { + tc.customBuilder.builderCfg.CurrentDirectory = testDir + t.Run(tc.name, func(t *testing.T) { + outDir := fmt.Sprintf("custom-%d", i) + outPath := path.Join(testDir, outDir) + err := os.MkdirAll(outPath, 0o777) + require.NoError(t, err) + + // create files in temp dir + for fileName, fileContents := range tc.files { + err := os.MkdirAll(path.Join(testDir, path.Dir(fileName)), 0o777) + require.NoError(t, err) + file, err := os.Create(path.Join(testDir, fileName)) + require.NoError(t, err) + _, err = file.WriteString(fileContents) + require.NoError(t, err) + } + + buildErr := tc.customBuilder.Build(outPath, tc.templateDefinition) + tc.buildAssertions(t, outPath, buildErr) + + if tc.validate { + validateErr := tc.customBuilder.Validate(outDir) + tc.validateAssertions(t, validateErr) + } + }) + } +} + +const customYaml = `--- +defaultChannel: preview +name: webhook-operator-413 +schema: olm.package +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator-413 +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator-413 + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +--- +schema: olm.channel +package: webhook-operator-413 +name: preview +entries: + - name: webhook-operator.v0.0.1 +` + +const customBuiltFbcYaml = `--- +defaultChannel: preview +name: webhook-operator-413 +schema: olm.package +--- +entries: +- name: webhook-operator.v0.0.1 +name: preview +package: webhook-operator-413 +schema: olm.channel +--- +image: quay.io/olmtest/webhook-operator-bundle:0.0.3 +name: webhook-operator.v0.0.1 +package: webhook-operator-413 +properties: +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v1 +- type: olm.gvk + value: + group: webhook.operators.coreos.io + kind: WebhookTest + version: v2 +- type: olm.package + value: + packageName: webhook-operator-413 + version: 0.0.1 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0= +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0= +relatedImages: +- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: "" +- image: quay.io/olmtest/webhook-operator-bundle:0.0.3 + name: "" +- image: quay.io/olmtest/webhook-operator:0.0.3 + name: "" +schema: olm.bundle +` + +const customBuiltFbcJson = `{ + "schema": "olm.package", + "name": "webhook-operator-413", + "defaultChannel": "preview" +} +{ + "schema": "olm.channel", + "name": "preview", + "package": "webhook-operator-413", + "entries": [ + { + "name": "webhook-operator.v0.0.1" + } + ] +} +{ + "schema": "olm.bundle", + "name": "webhook-operator.v0.0.1", + "package": "webhook-operator-413", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3", + "properties": [ + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v1" + } + }, + { + "type": "olm.gvk", + "value": { + "group": "webhook.operators.coreos.io", + "kind": "WebhookTest", + "version": "v2" + } + }, + { + "type": "olm.package", + "value": { + "packageName": "webhook-operator-413", + "version": "0.0.1" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MWJldGExIiwia2luZCI6IkNsdXN0ZXJSb2xlIiwibWV0YWRhdGEiOnsiY3JlYXRpb25UaW1lc3RhbXAiOm51bGwsIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLW1ldHJpY3MtcmVhZGVyIn0sInJ1bGVzIjpbeyJub25SZXNvdXJjZVVSTHMiOlsiL21ldHJpY3MiXSwidmVyYnMiOlsiZ2V0Il19XX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiV2ViaG9va1Rlc3RcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIndlYmhvb2t0ZXN0LXNhbXBsZVwiLFxuICAgICAgXCJuYW1lc3BhY2VcIjogXCJ3ZWJob29rLW9wZXJhdG9yLXN5c3RlbVwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJ2YWxpZFwiOiB0cnVlXG4gICAgfVxuICB9XG5dIiwiY2FwYWJpbGl0aWVzIjoiQmFzaWMgSW5zdGFsbCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjAuMCIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9wcm9qZWN0X2xheW91dCI6ImdvIn0sIm5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLnYwLjAuMSIsIm5hbWVzcGFjZSI6InBsYWNlaG9sZGVyIn0sInNwZWMiOnsiYXBpc2VydmljZWRlZmluaXRpb25zIjp7fSwiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3sia2luZCI6IldlYmhvb2tUZXN0IiwibmFtZSI6IndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IldlYmhvb2sgT3BlcmF0b3IgZGVzY3JpcHRpb24uIFRPRE8uIiwiZGlzcGxheU5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IiIsIm1lZGlhdHlwZSI6IiJ9XSwiaW5zdGFsbCI6eyJzcGVjIjp7ImNsdXN0ZXJQZXJtaXNzaW9ucyI6W3sicnVsZXMiOlt7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cyJdLCJ2ZXJicyI6WyJjcmVhdGUiLCJkZWxldGUiLCJnZXQiLCJsaXN0IiwicGF0Y2giLCJ1cGRhdGUiLCJ3YXRjaCJdfSx7ImFwaUdyb3VwcyI6WyJ3ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwicmVzb3VyY2VzIjpbIndlYmhvb2t0ZXN0cy9zdGF0dXMiXSwidmVyYnMiOlsiZ2V0IiwicGF0Y2giLCJ1cGRhdGUiXX0seyJhcGlHcm91cHMiOlsiYXV0aGVudGljYXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJ0b2tlbnJldmlld3MiXSwidmVyYnMiOlsiY3JlYXRlIl19LHsiYXBpR3JvdXBzIjpbImF1dGhvcml6YXRpb24uazhzLmlvIl0sInJlc291cmNlcyI6WyJzdWJqZWN0YWNjZXNzcmV2aWV3cyJdLCJ2ZXJicyI6WyJjcmVhdGUiXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJkZWZhdWx0In1dLCJkZXBsb3ltZW50cyI6W3sibmFtZSI6IndlYmhvb2stb3BlcmF0b3Itd2ViaG9vayIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImNvbnRyb2wtcGxhbmUiOiJjb250cm9sbGVyLW1hbmFnZXIifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLXNlY3VyZS1saXN0ZW4tYWRkcmVzcz0wLjAuMC4wOjg0NDMiLCItLXVwc3RyZWFtPWh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8iLCItLWxvZ3Rvc3RkZXJyPXRydWUiLCItLXY9MTAiXSwiaW1hZ2UiOiJnY3IuaW8va3ViZWJ1aWxkZXIva3ViZS1yYmFjLXByb3h5OnYwLjUuMCIsIm5hbWUiOiJrdWJlLXJiYWMtcHJveHkiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODQ0MywibmFtZSI6Imh0dHBzIn1dLCJyZXNvdXJjZXMiOnt9fSx7ImFyZ3MiOlsiLS1tZXRyaWNzLWFkZHI9MTI3LjAuMC4xOjgwODAiLCItLWVuYWJsZS1sZWFkZXItZWxlY3Rpb24iXSwiY29tbWFuZCI6WyIvbWFuYWdlciJdLCJpbWFnZSI6InF1YXkuaW8vb2xtdGVzdC93ZWJob29rLW9wZXJhdG9yOjAuMC4zIiwibmFtZSI6Im1hbmFnZXIiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6OTQ0MywibmFtZSI6IndlYmhvb2stc2VydmVyIiwicHJvdG9jb2wiOiJUQ1AifV0sInJlc291cmNlcyI6eyJsaW1pdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjMwTWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjIwTWkifX19XSwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiY29uZmlnbWFwcyJdLCJ2ZXJicyI6WyJnZXQiLCJsaXN0Iiwid2F0Y2giLCJjcmVhdGUiLCJ1cGRhdGUiLCJwYXRjaCIsImRlbGV0ZSJdfSx7ImFwaUdyb3VwcyI6WyIiXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInVwZGF0ZSIsInBhdGNoIl19LHsiYXBpR3JvdXBzIjpbIiJdLCJyZXNvdXJjZXMiOlsiZXZlbnRzIl0sInZlcmJzIjpbImNyZWF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6ImRlZmF1bHQifV19LCJzdHJhdGVneSI6ImRlcGxveW1lbnQifSwiaW5zdGFsbE1vZGVzIjpbeyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiU2luZ2xlTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOmZhbHNlLCJ0eXBlIjoiTXVsdGlOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImtleXdvcmRzIjpbIndlYmhvb2stb3BlcmF0b3IiXSwibGlua3MiOlt7Im5hbWUiOiJXZWJob29rIE9wZXJhdG9yIiwidXJsIjoiaHR0cHM6Ly93ZWJob29rLW9wZXJhdG9yLmRvbWFpbiJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoieW91ckBlbWFpbC5jb20iLCJuYW1lIjoiTWFpbnRhaW5lciBOYW1lIn1dLCJtYXR1cml0eSI6ImFscGhhIiwicHJvdmlkZXIiOnsibmFtZSI6IlByb3ZpZGVyIE5hbWUiLCJ1cmwiOiJodHRwczovL3lvdXIuZG9tYWluIn0sInZlcnNpb24iOiIwLjAuMSIsIndlYmhvb2tkZWZpbml0aW9ucyI6W3siYWRtaXNzaW9uUmV2aWV3VmVyc2lvbnMiOlsidjFiZXRhMSIsInYxIl0sImNvbnRhaW5lclBvcnQiOjQ0MywiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6InZ3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiVmFsaWRhdGluZ0FkbWlzc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii92YWxpZGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImRlcGxveW1lbnROYW1lIjoid2ViaG9vay1vcGVyYXRvci13ZWJob29rIiwiZmFpbHVyZVBvbGljeSI6IkZhaWwiLCJnZW5lcmF0ZU5hbWUiOiJtd2ViaG9va3Rlc3Qua2IuaW8iLCJydWxlcyI6W3siYXBpR3JvdXBzIjpbIndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJdLCJhcGlWZXJzaW9ucyI6WyJ2MSJdLCJvcGVyYXRpb25zIjpbIkNSRUFURSIsIlVQREFURSJdLCJyZXNvdXJjZXMiOlsid2ViaG9va3Rlc3RzIl19XSwic2lkZUVmZmVjdHMiOiJOb25lIiwidGFyZ2V0UG9ydCI6NDM0MywidHlwZSI6Ik11dGF0aW5nQWRtaXNzaW9uV2ViaG9vayIsIndlYmhvb2tQYXRoIjoiL211dGF0ZS13ZWJob29rLW9wZXJhdG9ycy1jb3Jlb3MtaW8tdjEtd2ViaG9va3Rlc3QifSx7ImFkbWlzc2lvblJldmlld1ZlcnNpb25zIjpbInYxYmV0YTEiLCJ2MSJdLCJjb250YWluZXJQb3J0Ijo0NDMsImNvbnZlcnNpb25DUkRzIjpbIndlYmhvb2t0ZXN0cy53ZWJob29rLm9wZXJhdG9ycy5jb3Jlb3MuaW8iXSwiZGVwbG95bWVudE5hbWUiOiJ3ZWJob29rLW9wZXJhdG9yLXdlYmhvb2siLCJmYWlsdXJlUG9saWN5IjoiRmFpbCIsImdlbmVyYXRlTmFtZSI6ImN3ZWJob29rdGVzdC5rYi5pbyIsInJ1bGVzIjpbeyJhcGlHcm91cHMiOlsid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIl0sImFwaVZlcnNpb25zIjpbInYxIl0sIm9wZXJhdGlvbnMiOlsiQ1JFQVRFIiwiVVBEQVRFIl0sInJlc291cmNlcyI6WyJ3ZWJob29rdGVzdHMiXX1dLCJzaWRlRWZmZWN0cyI6Ik5vbmUiLCJ0YXJnZXRQb3J0Ijo0MzQzLCJ0eXBlIjoiQ29udmVyc2lvbldlYmhvb2siLCJ3ZWJob29rUGF0aCI6Ii9jb252ZXJ0In1dfX0=" + } + }, + { + "type": "olm.bundle.object", + "value": { + "data": "eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjFiZXRhMSIsImtpbmQiOiJDdXN0b21SZXNvdXJjZURlZmluaXRpb24iLCJtZXRhZGF0YSI6eyJhbm5vdGF0aW9ucyI6eyJjb250cm9sbGVyLWdlbi5rdWJlYnVpbGRlci5pby92ZXJzaW9uIjoidjAuMy4wIn0sImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoid2ViaG9va3Rlc3RzLndlYmhvb2sub3BlcmF0b3JzLmNvcmVvcy5pbyJ9LCJzcGVjIjp7Imdyb3VwIjoid2ViaG9vay5vcGVyYXRvcnMuY29yZW9zLmlvIiwibmFtZXMiOnsia2luZCI6IldlYmhvb2tUZXN0IiwibGlzdEtpbmQiOiJXZWJob29rVGVzdExpc3QiLCJwbHVyYWwiOiJ3ZWJob29rdGVzdHMiLCJzaW5ndWxhciI6IndlYmhvb2t0ZXN0In0sInByZXNlcnZlVW5rbm93bkZpZWxkcyI6ZmFsc2UsInNjb3BlIjoiTmFtZXNwYWNlZCIsInZlcnNpb24iOiJ2MSIsInZlcnNpb25zIjpbeyJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIHdlYmhvb2t0ZXN0cyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3BlYyBkZWZpbmVzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwicHJvcGVydGllcyI6eyJtdXRhdGUiOnsiZGVzY3JpcHRpb24iOiJNdXRhdGUgaXMgYSBmaWVsZCB0aGF0IHdpbGwgYmUgc2V0IHRvIHRydWUgYnkgdGhlIG11dGF0aW5nIHdlYmhvb2suIiwidHlwZSI6ImJvb2xlYW4ifSwidmFsaWQiOnsiZGVzY3JpcHRpb24iOiJWYWxpZCBtdXN0IGJlIHNldCB0byB0cnVlIG9yIHRoZSB2YWxpZGF0aW9uIHdlYmhvb2sgd2lsbCByZWplY3QgdGhlIHJlc291cmNlLiIsInR5cGUiOiJib29sZWFuIn19LCJyZXF1aXJlZCI6WyJ2YWxpZCJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfSx7Im5hbWUiOiJ2MiIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJXZWJob29rVGVzdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgd2ViaG9va3Rlc3RzIEFQSSIsInByb3BlcnRpZXMiOnsiYXBpVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IkFQSVZlcnNpb24gZGVmaW5lcyB0aGUgdmVyc2lvbmVkIHNjaGVtYSBvZiB0aGlzIHJlcHJlc2VudGF0aW9uIG9mIGFuIG9iamVjdC4gU2VydmVycyBzaG91bGQgY29udmVydCByZWNvZ25pemVkIHNjaGVtYXMgdG8gdGhlIGxhdGVzdCBpbnRlcm5hbCB2YWx1ZSwgYW5kIG1heSByZWplY3QgdW5yZWNvZ25pemVkIHZhbHVlcy4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCNyZXNvdXJjZXMiLCJ0eXBlIjoic3RyaW5nIn0sImtpbmQiOnsiZGVzY3JpcHRpb24iOiJLaW5kIGlzIGEgc3RyaW5nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgUkVTVCByZXNvdXJjZSB0aGlzIG9iamVjdCByZXByZXNlbnRzLiBTZXJ2ZXJzIG1heSBpbmZlciB0aGlzIGZyb20gdGhlIGVuZHBvaW50IHRoZSBjbGllbnQgc3VibWl0cyByZXF1ZXN0cyB0by4gQ2Fubm90IGJlIHVwZGF0ZWQuIEluIENhbWVsQ2FzZS4gTW9yZSBpbmZvOiBodHRwczovL2dpdC5rOHMuaW8vY29tbXVuaXR5L2NvbnRyaWJ1dG9ycy9kZXZlbC9zaWctYXJjaGl0ZWN0dXJlL2FwaS1jb252ZW50aW9ucy5tZCN0eXBlcy1raW5kcyIsInR5cGUiOiJzdHJpbmcifSwibWV0YWRhdGEiOnsidHlwZSI6Im9iamVjdCJ9LCJzcGVjIjp7ImRlc2NyaXB0aW9uIjoiV2ViaG9va1Rlc3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgV2ViaG9va1Rlc3QiLCJwcm9wZXJ0aWVzIjp7ImNvbnZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJDb252ZXJzaW9uIGlzIGFuIGV4YW1wbGUgZmllbGQgb2YgV2ViaG9va1Rlc3QuIEVkaXQgV2ViaG9va1Rlc3RfdHlwZXMuZ28gdG8gcmVtb3ZlL3VwZGF0ZSIsInByb3BlcnRpZXMiOnsibXV0YXRlIjp7ImRlc2NyaXB0aW9uIjoiTXV0YXRlIGlzIGEgZmllbGQgdGhhdCB3aWxsIGJlIHNldCB0byB0cnVlIGJ5IHRoZSBtdXRhdGluZyB3ZWJob29rLiIsInR5cGUiOiJib29sZWFuIn0sInZhbGlkIjp7ImRlc2NyaXB0aW9uIjoiVmFsaWQgbXVzdCBiZSBzZXQgdG8gdHJ1ZSBvciB0aGUgdmFsaWRhdGlvbiB3ZWJob29rIHdpbGwgcmVqZWN0IHRoZSByZXNvdXJjZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwicmVxdWlyZWQiOlsidmFsaWQiXSwidHlwZSI6Im9iamVjdCJ9fSwicmVxdWlyZWQiOlsiY29udmVyc2lvbiJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IldlYmhvb2tUZXN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIFdlYmhvb2tUZXN0IiwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjpmYWxzZX1dfSwic3RhdHVzIjp7ImFjY2VwdGVkTmFtZXMiOnsia2luZCI6IiIsInBsdXJhbCI6IiJ9LCJjb25kaXRpb25zIjpbXSwic3RvcmVkVmVyc2lvbnMiOltdfX0=" + } + } + ], + "relatedImages": [ + { + "name": "", + "image": "gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator-bundle:0.0.3" + }, + { + "name": "", + "image": "quay.io/olmtest/webhook-operator:0.0.3" + } + ] +} +` + +func TestValidateFailure(t *testing.T) { + err := validate(ContainerConfig{}, "") + require.Error(t, err) + require.Contains(t, err.Error(), "running command") +} diff --git a/staging/operator-registry/alpha/template/composite/composite.go b/staging/operator-registry/alpha/template/composite/composite.go new file mode 100644 index 0000000000..537db48afe --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/composite.go @@ -0,0 +1,47 @@ +package composite + +import ( + "context" + "fmt" +) + +type BuilderMap map[string]Builder + +type CatalogBuilderMap map[string]BuilderMap + +type Template struct { + CatalogBuilders CatalogBuilderMap +} + +// TODO(everettraven): do we need the context here? If so, how should it be used? +func (t *Template) Render(ctx context.Context, config *CompositeConfig, validate bool) error { + // TODO(everettraven): should we return aggregated errors? + for _, component := range config.Components { + if builderMap, ok := t.CatalogBuilders[component.Name]; ok { + if builder, ok := builderMap[component.Strategy.Template.Schema]; ok { + // run the builder corresponding to the schema + err := builder.Build(component.Destination.Path, component.Strategy.Template) + if err != nil { + return fmt.Errorf("building component %q: %w", component.Name, err) + } + + if validate { + // run the validation for the builder + err = builder.Validate(component.Destination.Path) + if err != nil { + return fmt.Errorf("validating component %q: %w", component.Name, err) + } + } + } else { + return fmt.Errorf("building component %q: no builder found for template schema %q", component.Name, component.Strategy.Template.Schema) + } + } else { + allowedComponents := []string{} + for k := range t.CatalogBuilders { + allowedComponents = append(allowedComponents, k) + } + return fmt.Errorf("building component %q: component does not exist in the catalog configuration. Available components are: %s", component.Name, allowedComponents) + } + } + return nil +} diff --git a/staging/operator-registry/alpha/template/composite/composite_test.go b/staging/operator-registry/alpha/template/composite/composite_test.go new file mode 100644 index 0000000000..35bc754713 --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/composite_test.go @@ -0,0 +1,257 @@ +package composite + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +type TestBuilder struct { + buildError bool + validateError bool +} + +const buildErr = "TestBuilder Build() error" +const validateErr = "TestBuilder Validate() error" + +var _ Builder = &TestBuilder{} + +func (tb *TestBuilder) Build(dir string, vd TemplateDefinition) error { + if tb.buildError { + return errors.New(buildErr) + } + return nil +} + +func (tb *TestBuilder) Validate(dir string) error { + if tb.validateError { + return errors.New(validateErr) + } + return nil +} + +func TestCompositeRender(t *testing.T) { + type testCase struct { + name string + compositeTemplate Template + compositeCfg CompositeConfig + validate bool + assertions func(t *testing.T, err error) + } + + testCases := []testCase{ + { + name: "successful render", + validate: true, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "testcatalog", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.test", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + { + name: "component not in catalog config", + validate: true, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "invalid", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.test", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + require.Error(t, err) + expectedErr := fmt.Sprintf("building component %q: component does not exist in the catalog configuration. Available components are: %s", "invalid", []string{"testcatalog"}) + require.Equal(t, expectedErr, err.Error()) + }, + }, + { + name: "builder not in catalog config", + validate: true, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "testcatalog", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.invalid", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + require.Error(t, err) + expectedErr := fmt.Sprintf("building component %q: no builder found for template schema %q", "testcatalog", "olm.builder.invalid") + require.Equal(t, expectedErr, err.Error()) + }, + }, + { + name: "build step error", + validate: true, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{buildError: true}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "testcatalog", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.test", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + require.Error(t, err) + expectedErr := fmt.Sprintf("building component %q: %s", "testcatalog", buildErr) + require.Equal(t, expectedErr, err.Error()) + }, + }, + { + name: "validate step error", + validate: true, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{validateError: true}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "testcatalog", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.test", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + require.Error(t, err) + expectedErr := fmt.Sprintf("validating component %q: %s", "testcatalog", validateErr) + require.Equal(t, expectedErr, err.Error()) + }, + }, + { + name: "validation step skipped", + validate: false, + compositeTemplate: Template{ + CatalogBuilders: CatalogBuilderMap{ + "testcatalog": BuilderMap{ + "olm.builder.test": &TestBuilder{validateError: true}, + }, + }, + }, + compositeCfg: CompositeConfig{ + Schema: CompositeSchema, + Components: []Component{ + { + Name: "testcatalog", + Destination: ComponentDestination{ + Path: "testcatalog/mypackage", + }, + Strategy: BuildStrategy{ + Name: "testbuild", + Template: TemplateDefinition{ + Schema: "olm.builder.test", + Config: json.RawMessage{}, + }, + }, + }, + }, + }, + assertions: func(t *testing.T, err error) { + // the validate step would error but since + // we are skipping it we expect no error to occur + require.NoError(t, err) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.compositeTemplate.Render(context.Background(), &tc.compositeCfg, tc.validate) + tc.assertions(t, err) + }) + } +} diff --git a/staging/operator-registry/alpha/template/composite/config.go b/staging/operator-registry/alpha/template/composite/config.go new file mode 100644 index 0000000000..70a480d4e8 --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/config.go @@ -0,0 +1,42 @@ +package composite + +const ( + CompositeSchema = "olm.composite" + CatalogSchema = "olm.composite.catalogs" +) + +type CompositeConfig struct { + Schema string + Components []Component +} + +type Component struct { + Name string + Destination ComponentDestination + Strategy BuildStrategy +} + +type ComponentDestination struct { + Path string +} + +type BuildStrategy struct { + Name string + Template TemplateDefinition +} + +type CatalogConfig struct { + Schema string + Catalogs []Catalog +} + +type Catalog struct { + Name string + Destination CatalogDestination + Builders []string +} + +type CatalogDestination struct { + BaseImage string + WorkingDir string +} diff --git a/staging/operator-registry/alpha/template/composite/types.go b/staging/operator-registry/alpha/template/composite/types.go new file mode 100644 index 0000000000..5295a5ddfd --- /dev/null +++ b/staging/operator-registry/alpha/template/composite/types.go @@ -0,0 +1,29 @@ +package composite + +import "encoding/json" + +type TemplateDefinition struct { + Schema string + Config json.RawMessage +} + +type BasicConfig struct { + Input string + Output string +} + +type SemverConfig struct { + Input string + Output string +} + +type RawConfig struct { + Input string + Output string +} + +type CustomConfig struct { + Command string + Args []string + Output string +} diff --git a/staging/operator-registry/alpha/template/semver/README.md b/staging/operator-registry/alpha/template/semver/README.md new file mode 100644 index 0000000000..2bab90c1c0 --- /dev/null +++ b/staging/operator-registry/alpha/template/semver/README.md @@ -0,0 +1,259 @@ +## Semver Template: + +Since a `catalog template` is identified as an input schema which may be processed to generate a valid FBC, we can define a `semver template` as a schema which uses channel conventions to facilitate the auto-generation of channels along `semver` delimiters. + +[**DISCLAIMER:** since version build metadata [MUST be ignored when determining version precedence](https://semver.org) when using semver, it cannot be used in any bundle included in the `semver template` and will result in a fatal error.] + +### Schema Goals +The `semver template` must have: +- terse grammar to minimize creation/maintenance effort +- deterministic output +- simple channel promotion for maturing bundles +- demonstration of a common type of channel maturity model +- minor-version (Y-stream), major-version (X-stream) versioning optionality + +The resulting FBC must clearly indicate how generated channels relate to template entities + +### Schema Anatomy +For convenience and simplicity, this template currently supports hard-coded channel names `Candidate`, `Fast`, and `Stable`, in order of increasing channel stability. We leverage this relationship to calculate the default channel for the package. + +`GenerateMajorChannels` and `GenerateMinorChannels` dictate whether this template will generate X-stream or Y-stream channels (attributes can be set independently). If omitted, only minor (Y-stream) channels will be generated. + +Under each channel are a list of bundle image references which contribute to that channel. + +With the following (hypothetical) example we define a mock bundle which has 11 versions, represented across each of the channel types: +```yaml +Schema: olm.semver +GenerateMajorChannels: true +GenerateMinorChannels: true +Candidate: + Bundles: + - Image: quay.io/foo/olm:testoperator.v0.1.0 + - Image: quay.io/foo/olm:testoperator.v0.1.1 + - Image: quay.io/foo/olm:testoperator.v0.1.2 + - Image: quay.io/foo/olm:testoperator.v0.1.3 + - Image: quay.io/foo/olm:testoperator.v0.2.0 + - Image: quay.io/foo/olm:testoperator.v0.2.1 + - Image: quay.io/foo/olm:testoperator.v0.2.2 + - Image: quay.io/foo/olm:testoperator.v0.3.0 + - Image: quay.io/foo/olm:testoperator.v1.0.0 + - Image: quay.io/foo/olm:testoperator.v1.0.1 + - Image: quay.io/foo/olm:testoperator.v1.1.0 +Fast: + Bundles: + - Image: quay.io/foo/olm:testoperator.v0.2.1 + - Image: quay.io/foo/olm:testoperator.v0.2.2 + - Image: quay.io/foo/olm:testoperator.v0.3.0 + - Image: quay.io/foo/olm:testoperator.v1.0.1 + - Image: quay.io/foo/olm:testoperator.v1.1.0 +Stable: + Bundles: + - Image: quay.io/foo/olm:testoperator.v1.0.1 +``` +In this example, `Candidate` has the entire version range of bundles, `Fast` has a mix of older and more-recent versions, and `Stable` channel only has a single published entry. + +### CLI Tool Usage +``` +% ./bin/opm alpha render-template semver -h +Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input + +Usage: + opm alpha render-template semver [FILE] [flags] + +Flags: + -h, --help help for semver + -o, --output string Output format (json|yaml|mermaid) (default "json") + +Global Flags: + --skip-tls-verify skip TLS certificate verification for container image registries while pulling bundles + --use-http use plain HTTP for container image registries while pulling bundles +``` + +Example command usage: +``` +# Example with file argument passed in +opm alpha render-template semver infile.semver.template.yaml + +# Example with no file argument passed in +opm alpha render-template semver -o yaml < infile.semver.template.yaml > outfile.yaml + +# Example with "-" as the file argument passed in +cat infile.semver.template.yaml | opm alpha render-template semver -o mermaid - +``` +Note that if the command is called without a file argument and nothing passed in on standard input, +the command will hang indefinitely. Either a file argument or file information passed +in on standard input is required by the command. + +With the template attribute `GenerateMajorChannels: true` resulting major channels from the command are (skipping the rendered bundle image output): +```yaml +--- +defaultChannel: stable-v1 +name: testoperator +schema: olm.package +--- +entries: +- name: testoperator.v0.1.0 +- name: testoperator.v0.1.1 +- name: testoperator.v0.1.2 +- name: testoperator.v0.1.3 + skips: + - testoperator.v0.1.0 + - testoperator.v0.1.1 + - testoperator.v0.1.2 +- name: testoperator.v0.2.0 +- name: testoperator.v0.2.1 +- name: testoperator.v0.2.2 + replaces: testoperator.v0.1.3 + skips: + - testoperator.v0.2.0 + - testoperator.v0.2.1 +- name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: candidate-v0 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.0 +- name: testoperator.v1.0.1 + skips: + - testoperator.v1.0.0 +- name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: candidate-v1 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v0.2.1 +- name: testoperator.v0.2.2 + skips: + - testoperator.v0.2.1 +- name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: fast-v0 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.1 +- name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: fast-v1 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.1 +name: stable-v1 +package: testoperator +schema: olm.channel +``` + +We generated a channel for each template channel entity corresponding to each of the 0.\#.\#, 1.\#.\# major version ranges with skips to the head of the highest semver in a channel. We also generated a replaces edge to traverse across minor version transitions within each major channel. Finally, we generated an `olm.package` object, setting as default the most-stable channel head we created. This process will prefer `Stable` channel over `Fast`, over `Candidate` and then a higher bundle version over a lower version. +(Please note that the naming of the generated channels indicates the digits of significance for that channel. For example, `fast-v1` is a decomposed channel of the `fast` type which contains only major versions of contributing bundles matching `v1`.) + +For contrast, with the template attribute `GenerateMinorChannels: true` and running the command again (again skipping rendered bundle image output) we get a bunch more channels: +```yaml +--- +defaultChannel: stable-v1.0 +name: testoperator +schema: olm.package +--- +entries: + - name: testoperator.v0.1.0 + - name: testoperator.v0.1.1 + - name: testoperator.v0.1.2 + - name: testoperator.v0.1.3 + skips: + - testoperator.v0.1.0 + - testoperator.v0.1.1 + - testoperator.v0.1.2 +name: candidate-v0.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.2.0 + - name: testoperator.v0.2.1 + - name: testoperator.v0.2.2 + replaces: testoperator.v0.1.3 + skips: + - testoperator.v0.2.0 + - testoperator.v0.2.1 +name: candidate-v0.2 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: candidate-v0.3 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.0 + - name: testoperator.v1.0.1 + skips: + - testoperator.v1.0.0 +name: candidate-v1.0 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: candidate-v1.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.2.1 + - name: testoperator.v0.2.2 + skips: + - testoperator.v0.2.1 +name: fast-v0.2 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: fast-v0.3 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.1 +name: fast-v1.0 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: fast-v1.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.1 +name: stable-v1.0 +package: testoperator +schema: olm.channel + +``` +Here, a channel is generated for each template channel which differs by minor version, and each channel has a `replaces` edge from the predecessor channel to the next-lesser minor bundle version. Please note that at no time do we transgress across major-version boundaries with the channels, to be consistent with [the semver convention](https://semver.org/) for major versions, where the purpose is to make incompatible API changes. + + +### DEMOS + +#### Major Channel Generation +![`GenerateMajorChannels`](./major-version-demo.gif) + +#### Minor Channel Generation +![`GenerateMinorChannels`](./minor-version-demo.gif) + + diff --git a/staging/operator-registry/alpha/template/semver/major-version-demo.gif b/staging/operator-registry/alpha/template/semver/major-version-demo.gif new file mode 100755 index 0000000000..244ecd6dbb Binary files /dev/null and b/staging/operator-registry/alpha/template/semver/major-version-demo.gif differ diff --git a/staging/operator-registry/alpha/template/semver/minor-version-demo.gif b/staging/operator-registry/alpha/template/semver/minor-version-demo.gif new file mode 100755 index 0000000000..af0fea0b36 Binary files /dev/null and b/staging/operator-registry/alpha/template/semver/minor-version-demo.gif differ diff --git a/staging/operator-registry/alpha/template/semver/semver.go b/staging/operator-registry/alpha/template/semver/semver.go new file mode 100644 index 0000000000..601047d261 --- /dev/null +++ b/staging/operator-registry/alpha/template/semver/semver.go @@ -0,0 +1,477 @@ +package semver + +import ( + "context" + "encoding/json" + "fmt" + "io" + "sort" + + "github.com/blang/semver/v4" + "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "sigs.k8s.io/yaml" + + "github.com/operator-framework/operator-registry/alpha/action" + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/property" + "github.com/operator-framework/operator-registry/pkg/image" +) + +// data passed into this module externally +type Template struct { + Data io.Reader + Registry image.Registry +} + +// IO structs -- BEGIN +type semverTemplateBundleEntry struct { + Image string `json:"image,omitempty"` +} + +type candidateBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} +type fastBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} +type stableBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} + +type semverTemplate struct { + Schema string `json:"schema"` + GenerateMajorChannels bool `json:"generateMajorChannels,omitempty"` + GenerateMinorChannels bool `json:"generateMinorChannels,omitempty"` + AvoidSkipPatch bool `json:"avoidSkipPatch,omitempty"` + Candidate candidateBundles `json:"candidate,omitempty"` + Fast fastBundles `json:"fast,omitempty"` + Stable stableBundles `json:"stable,omitempty"` + + pkg string `json:"-"` // the derived package name + defaultChannel string `json:"-"` // detected "most stable" channel head +} + +// IO structs -- END + +// channel "kinds", restricted in this iteration to just these +const ( + candidateChannelName string = "candidate" + fastChannelName string = "fast" + stableChannelName string = "stable" +) + +// mapping channel name --> stability, where higher values indicate greater stability +var channelPriorities = map[string]int{candidateChannelName: 0, fastChannelName: 1, stableChannelName: 2} + +// sorting capability for a slice according to the assigned channelPriorities +type byChannelPriority []string + +func (b byChannelPriority) Len() int { return len(b) } +func (b byChannelPriority) Less(i, j int) bool { + return channelPriorities[b[i]] < channelPriorities[b[j]] +} +func (b byChannelPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] } + +// map of channels : bundles : bundle-version +// channels --> bundles --> version +type semverRenderedChannelVersions map[string]map[string]semver.Version // e.g. d["stable-v1"]["example-operator/v1.0.0"] = 1.0.0 + +func (t Template) Render(ctx context.Context) (*declcfg.DeclarativeConfig, error) { + var out declcfg.DeclarativeConfig + + sv, err := readFile(t.Data) + if err != nil { + return nil, fmt.Errorf("semver-render: unable to read file: %v", err) + } + + var cfgs []declcfg.DeclarativeConfig + + bundleDict := make(map[string]struct{}) + buildBundleList(&sv.Candidate.Bundles, &bundleDict) + buildBundleList(&sv.Fast.Bundles, &bundleDict) + buildBundleList(&sv.Stable.Bundles, &bundleDict) + + for b, _ := range bundleDict { + r := action.Render{ + AllowedRefMask: action.RefBundleImage, + Refs: []string{b}, + Registry: t.Registry, + } + c, err := r.Run(ctx) + if err != nil { + return nil, err + } + cfgs = append(cfgs, *c) + } + out = *combineConfigs(cfgs) + + if len(out.Bundles) == 0 { + return nil, fmt.Errorf("semver-render: no bundles specified or no bundles could be rendered") + } + + channelBundleVersions, err := sv.getVersionsFromStandardChannels(&out) + if err != nil { + return nil, fmt.Errorf("semver-render: unable to post-process bundle info: %v", err) + } + + channels := sv.generateChannels(channelBundleVersions) + out.Channels = channels + out.Packages[0].DefaultChannel = sv.defaultChannel + + return &out, nil +} + +func buildBundleList(bundles *[]semverTemplateBundleEntry, dict *map[string]struct{}) { + for _, b := range *bundles { + if _, ok := (*dict)[b.Image]; !ok { + (*dict)[b.Image] = struct{}{} + } + } +} + +func readFile(reader io.Reader) (*semverTemplate, error) { + data, err := io.ReadAll(reader) + if err != nil { + return nil, err + } + + // default behavior is to generate only minor channels and to use skips over replaces + sv := semverTemplate{ + GenerateMajorChannels: false, + GenerateMinorChannels: true, + AvoidSkipPatch: false, + } + if err := yaml.Unmarshal(data, &sv, func(decoder *json.Decoder) *json.Decoder { + decoder.DisallowUnknownFields() + return decoder + }); err != nil { + return nil, err + } + return &sv, nil +} + +func (sv *semverTemplate) getVersionsFromStandardChannels(cfg *declcfg.DeclarativeConfig) (*semverRenderedChannelVersions, error) { + versions := semverRenderedChannelVersions{} + + bdm, err := sv.getVersionsFromChannel(sv.Candidate.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[candidateChannelName] = bdm + + bdm, err = sv.getVersionsFromChannel(sv.Fast.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[fastChannelName] = bdm + + bdm, err = sv.getVersionsFromChannel(sv.Stable.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[stableChannelName] = bdm + + return &versions, nil +} + +func (sv *semverTemplate) getVersionsFromChannel(semverBundles []semverTemplateBundleEntry, cfg *declcfg.DeclarativeConfig) (map[string]semver.Version, error) { + entries := make(map[string]semver.Version) + + // we iterate over the channel bundles from the template, to: + // - identify if any required bundles for the channel are missing/not rendered/otherwise unavailable + // - maintain the channel-bundle relationship as we map from un-rendered semver template bundles to rendered bundles in `entries` which is accumulated by the caller + // in a per-channel structure to which we can safely refer when generating/linking channels + for _, semverBundle := range semverBundles { + // test if the bundle specified in the template is present in the successfully-rendered bundles + index := 0 + for index < len(cfg.Bundles) { + if cfg.Bundles[index].Image == semverBundle.Image { + break + } + index++ + } + if index == len(cfg.Bundles) { + return nil, fmt.Errorf("supplied bundle image name %q not found in rendered bundle images", semverBundle.Image) + } + b := cfg.Bundles[index] + + props, err := property.Parse(b.Properties) + if err != nil { + return nil, fmt.Errorf("parse properties for bundle %q: %v", b.Name, err) + } + if len(props.Packages) != 1 { + return nil, fmt.Errorf("bundle %q has multiple %q properties, expected exactly 1", b.Name, property.TypePackage) + } + v, err := semver.Parse(props.Packages[0].Version) + if err != nil { + return nil, fmt.Errorf("bundle %q has invalid version %q: %v", b.Name, props.Packages[0].Version, err) + } + + // package name detection + if sv.pkg != "" { + // if we have a known package name, then ensure all subsequent packages match + if props.Packages[0].PackageName != sv.pkg { + return nil, fmt.Errorf("bundle %q does not belong to this package: %q", props.Packages[0].PackageName, sv.pkg) + } + } else { + // else cache the first + p := newPackage(props.Packages[0].PackageName) + cfg.Packages = append(cfg.Packages, *p) + sv.pkg = props.Packages[0].PackageName + } + + if _, ok := entries[b.Name]; ok { + return nil, fmt.Errorf("duplicate bundle name %q", b.Name) + } + + entries[b.Name] = v + } + + return entries, nil +} + +// the "high-water channel" struct functions as a freely-rising indicator of the "most stable" channel head, so we can use that +// later as the package's defaultChannel attribute +type highwaterChannel struct { + kind string + version semver.Version + name string +} + +func (h *highwaterChannel) gt(ih *highwaterChannel) bool { + return (channelPriorities[h.kind] > channelPriorities[ih.kind]) || (h.version.GT(ih.version)) +} + +// generates an unlinked channel for each channel as per the input template config (major || minor), then link up the edges of the set of channels so that: +// - (for major channels) iterating to a new minor version channel (traversing between Y-streams) creates a 'replaces' edge between the predecessor and successor bundles +// - within the same minor version (Y-stream), the head of the channel should have a 'skips' encompassing all lesser minor versions of the bundle enumerated in the template. +// along the way, uses a highwaterChannel marker to identify the "most stable" channel head to be used as the default channel for the generated package +func (sv *semverTemplate) generateChannels(semverChannels *semverRenderedChannelVersions) []declcfg.Channel { + outChannels := []declcfg.Channel{} + + // sort the channelkinds in ascending order so we can traverse the bundles in order of + // their source channel's priority + var keysByPriority []string + for k, _ := range channelPriorities { + keysByPriority = append(keysByPriority, k) + } + sort.Sort(byChannelPriority(keysByPriority)) + + // set to the least-priority channel + hwc := highwaterChannel{kind: keysByPriority[0], version: semver.Version{Major: 0, Minor: 0}} + + // mapping the generated channel name to the original semver name (i.e. channel kind), so we can do generated-channel-name --> original-semver-name --> version mapping, later + channelMapping := map[string]string{} + + for _, k := range keysByPriority { + bundles := (*semverChannels)[k] + + // skip channel if empty + if len(bundles) == 0 { + continue + } + + // sort the bundle names according to their semver, so we can walk in ascending order + bundleNamesByVersion := []string{} + for b := range bundles { + bundleNamesByVersion = append(bundleNamesByVersion, b) + } + sort.Slice(bundleNamesByVersion, func(i, j int) bool { + return bundles[bundleNamesByVersion[i]].LT(bundles[bundleNamesByVersion[j]]) + }) + + majors := map[string]*declcfg.Channel{} + minors := map[string]*declcfg.Channel{} + + for _, b := range bundleNamesByVersion { + if sv.GenerateMajorChannels { + testChannelName := channelNameFromMajor(k, bundles[b]) + ch, ok := majors[testChannelName] + if !ok { + ch = newChannel(sv.pkg, testChannelName) + majors[testChannelName] = ch + } + ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) + + channelMapping[testChannelName] = k + + hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} + if hwcCandidate.gt(&hwc) { + hwc = hwcCandidate + } + } + if sv.GenerateMinorChannels { + testChannelName := channelNameFromMinor(k, bundles[b]) + ch, ok := minors[testChannelName] + if !ok { + ch = newChannel(sv.pkg, testChannelName) + minors[testChannelName] = ch + } + ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) + + channelMapping[testChannelName] = k + + hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} + if hwcCandidate.gt(&hwc) { + hwc = hwcCandidate + } + } + } + + outChannels = append(outChannels, sv.linkChannels(majors, sv.pkg, semverChannels, &channelMapping)...) + outChannels = append(outChannels, sv.linkChannels(minors, sv.pkg, semverChannels, &channelMapping)...) + } + + // save off the name of the high-water-mark channel for the default for this package + sv.defaultChannel = hwc.name + + return outChannels +} + +// all channels that come to linkChannels MUST have the same prefix. This adds replaces edges of minor versions of the largest major version. +func (sv *semverTemplate) linkChannels(unlinkedChannels map[string]*declcfg.Channel, pkg string, semverChannels *semverRenderedChannelVersions, channelMapping *map[string]string) []declcfg.Channel { + channels := []declcfg.Channel{} + + for channelName, channel := range unlinkedChannels { + // sort the channel entries in ascending order, according to the corresponding bundle versions for the channelName stored in the semverRenderedChannelVersions + // convenience function, to make this more clear + versionLookup := func(generatedChannelName string, channelEdgeIndex int) semver.Version { + channelKind := (*channelMapping)[generatedChannelName] + bundleVersions := (*semverChannels)[channelKind] + bundleName := channel.Entries[channelEdgeIndex].Name + return bundleVersions[bundleName] + } + + sort.Slice(channel.Entries, func(i, j int) bool { + return versionLookup(channelName, i).LT(versionLookup(channelName, j)) + }) + + // link up the edges according to config + if sv.AvoidSkipPatch { + for i := 1; i < len(channel.Entries); i++ { + channel.Entries[i] = declcfg.ChannelEntry{ + Name: channel.Entries[i].Name, + Replaces: channel.Entries[i-1].Name, + } + } + } else { + curIndex := len(channel.Entries) - 1 + curMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][channel.Entries[curIndex].Name]) + curSkips := sets.NewString() + for i := len(channel.Entries) - 2; i >= 0; i-- { + thisName := channel.Entries[i].Name + thisMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][thisName]) + if thisMinor.EQ(curMinor) { + channel.Entries[i] = declcfg.ChannelEntry{Name: thisName} + curSkips = curSkips.Insert(thisName) + } else { + channel.Entries[curIndex] = declcfg.ChannelEntry{ + Name: channel.Entries[curIndex].Name, + Replaces: thisName, + Skips: curSkips.List(), + } + curSkips = sets.NewString() + curIndex = i + curMinor = thisMinor + } + } + channel.Entries[curIndex] = declcfg.ChannelEntry{ + Name: channel.Entries[curIndex].Name, + Skips: curSkips.List(), + } + } + channels = append(channels, *channel) + } + return channels +} + +func channelNameFromMinor(prefix string, version semver.Version) string { + return fmt.Sprintf("%s-v%d.%d", prefix, version.Major, version.Minor) +} + +func channelNameFromMajor(prefix string, version semver.Version) string { + return fmt.Sprintf("%s-v%d", prefix, version.Major) +} + +func newPackage(name string) *declcfg.Package { + return &declcfg.Package{ + Schema: "olm.package", + Name: name, + DefaultChannel: "", + } +} + +func newChannel(pkgName string, chName string) *declcfg.Channel { + return &declcfg.Channel{ + Schema: "olm.channel", + Name: string(chName), + Package: pkgName, + Entries: []declcfg.ChannelEntry{}, + } +} + +func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig { + out := &declcfg.DeclarativeConfig{} + for _, in := range cfgs { + out.Packages = append(out.Packages, in.Packages...) + out.Channels = append(out.Channels, in.Channels...) + out.Bundles = append(out.Bundles, in.Bundles...) + out.Others = append(out.Others, in.Others...) + } + return out +} + +func getMinorVersion(v semver.Version) semver.Version { + return semver.Version{ + Major: v.Major, + Minor: v.Minor, + } +} + +func withoutBuildMetadataConflict(versions *map[string]semver.Version) error { + errs := []error{} + + // using the stringified semver because the semver package generates deterministic representations, + // and because the semver.Version contains slice fields which make it unsuitable as a map key + // stringified-semver.Version ==> incidence count + seen := make(map[string]int) + for b := range *versions { + stripped := stripBuildMetadata((*versions)[b]) + if _, ok := seen[stripped]; !ok { + seen[stripped] = 1 + } else { + seen[stripped] = seen[stripped] + 1 + errs = append(errs, fmt.Errorf("bundle version %q cannot be compared to %q", (*versions)[b].String(), stripped)) + } + } + + if len(errs) != 0 { + return fmt.Errorf("encountered bundle versions which differ only by build metadata, which cannot be ordered: %v", errors.NewAggregate(errs)) + } + + return nil +} + +func validateVersions(versions *map[string]semver.Version) error { + // short-circuit if empty, since that is not an error + if len(*versions) == 0 { + return nil + } + return withoutBuildMetadataConflict(versions) +} + +// strips out the build metadata from a semver.Version and then stringifies it to make it suitable for collision detection +func stripBuildMetadata(v semver.Version) string { + v.Build = nil + return v.String() +} diff --git a/staging/operator-registry/alpha/veneer/semver/semver_test.go b/staging/operator-registry/alpha/template/semver/semver_test.go similarity index 84% rename from staging/operator-registry/alpha/veneer/semver/semver_test.go rename to staging/operator-registry/alpha/template/semver/semver_test.go index 68b2b29884..d712578c09 100644 --- a/staging/operator-registry/alpha/veneer/semver/semver_test.go +++ b/staging/operator-registry/alpha/template/semver/semver_test.go @@ -1,12 +1,14 @@ package semver import ( + "strings" "testing" "github.com/blang/semver/v4" + "github.com/stretchr/testify/require" + "github.com/operator-framework/operator-registry/alpha/declcfg" "github.com/operator-framework/operator-registry/alpha/property" - "github.com/stretchr/testify/require" ) func TestLinkChannels(t *testing.T) { @@ -366,7 +368,7 @@ func TestLinkChannels(t *testing.T) { for c, e := range tt.unlinkedChannels { unlinkedChannels[c] = e } - sv := &semverVeneer{AvoidSkipPatch: tt.avoidSkipPatch, GenerateMajorChannels: tt.generateMajorChannels, GenerateMinorChannels: tt.generateMinorChannels} + sv := &semverTemplate{AvoidSkipPatch: tt.avoidSkipPatch, GenerateMajorChannels: tt.generateMajorChannels, GenerateMinorChannels: tt.generateMinorChannels} require.ElementsMatch(t, tt.out, sv.linkChannels(unlinkedChannels, "a", &channelOperatorVersions, &channelNameToKind)) }) } @@ -486,7 +488,7 @@ func TestGenerateChannels(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - sv := &semverVeneer{AvoidSkipPatch: tt.avoidSkipPatch, GenerateMajorChannels: tt.generateMajorChannels, GenerateMinorChannels: tt.generateMinorChannels, pkg: "a"} + sv := &semverTemplate{AvoidSkipPatch: tt.avoidSkipPatch, GenerateMajorChannels: tt.generateMajorChannels, GenerateMinorChannels: tt.generateMinorChannels, pkg: "a"} require.ElementsMatch(t, tt.out, sv.generateChannels(&channelOperatorVersions)) }) } @@ -495,15 +497,15 @@ func TestGenerateChannels(t *testing.T) { func TestGetVersionsFromStandardChannel(t *testing.T) { tests := []struct { name string - sv semverVeneer + sv semverTemplate outVersions semverRenderedChannelVersions dc declcfg.DeclarativeConfig }{ { name: "sunny day case", - sv: semverVeneer{ + sv: semverTemplate{ Stable: stableBundles{ - []semverVeneerBundleEntry{ + []semverTemplateBundleEntry{ {Image: "repo/origin/a-v0.1.0"}, {Image: "repo/origin/a-v0.1.1"}, {Image: "repo/origin/a-v1.1.0"}, @@ -568,9 +570,9 @@ func TestGetVersionsFromStandardChannel(t *testing.T) { } func TestBailOnVersionBuildMetadata(t *testing.T) { - sv := semverVeneer{ + sv := semverTemplate{ Stable: stableBundles{ - []semverVeneerBundleEntry{ + []semverTemplateBundleEntry{ {Image: "repo/origin/a-v0.1.0"}, {Image: "repo/origin/a-v0.1.1"}, {Image: "repo/origin/a-v1.1.0"}, @@ -615,3 +617,93 @@ func TestBailOnVersionBuildMetadata(t *testing.T) { require.Error(t, err) }) } + +func TestReadFile(t *testing.T) { + type testCase struct { + name string + input string + assertions func(*testing.T, *semverTemplate, error) + } + testCases := []testCase{ + { + name: "valid", + input: `--- +schema: olm.semver +generateMajorChannels: true +generateMinorChannels: true +candidate: + bundles: + - image: quay.io/foo/olm:testoperator.v0.1.0 + - image: quay.io/foo/olm:testoperator.v0.1.1 + - image: quay.io/foo/olm:testoperator.v0.1.2 + - image: quay.io/foo/olm:testoperator.v0.1.3 + - image: quay.io/foo/olm:testoperator.v0.2.0 + - image: quay.io/foo/olm:testoperator.v0.2.1 + - image: quay.io/foo/olm:testoperator.v0.2.2 + - image: quay.io/foo/olm:testoperator.v0.3.0 + - image: quay.io/foo/olm:testoperator.v1.0.0 + - image: quay.io/foo/olm:testoperator.v1.0.1 + - image: quay.io/foo/olm:testoperator.v1.1.0 +fast: + bundles: + - image: quay.io/foo/olm:testoperator.v0.2.1 + - image: quay.io/foo/olm:testoperator.v0.2.2 + - image: quay.io/foo/olm:testoperator.v0.3.0 + - image: quay.io/foo/olm:testoperator.v1.0.1 + - image: quay.io/foo/olm:testoperator.v1.1.0 +stable: + bundles: + - image: quay.io/foo/olm:testoperator.v1.0.1 +`, + assertions: func(t *testing.T, template *semverTemplate, err error) { + require.NotNil(t, template) + require.NoError(t, err) + }, + }, + { + name: "unknown channel prefix", + input: `--- +schema: olm.semver +generateMajorChannels: true +generateMinorChannels: true +candidate: + bundles: + - image: quay.io/foo/olm:testoperator.v0.1.0 + - image: quay.io/foo/olm:testoperator.v0.1.1 + - image: quay.io/foo/olm:testoperator.v0.1.2 + - image: quay.io/foo/olm:testoperator.v0.1.3 + - image: quay.io/foo/olm:testoperator.v0.2.0 + - image: quay.io/foo/olm:testoperator.v0.2.1 + - image: quay.io/foo/olm:testoperator.v0.2.2 + - image: quay.io/foo/olm:testoperator.v0.3.0 + - image: quay.io/foo/olm:testoperator.v1.0.0 + - image: quay.io/foo/olm:testoperator.v1.0.1 + - image: quay.io/foo/olm:testoperator.v1.1.0 +fast: + bundles: + - image: quay.io/foo/olm:testoperator.v0.2.1 + - image: quay.io/foo/olm:testoperator.v0.2.2 + - image: quay.io/foo/olm:testoperator.v0.3.0 + - image: quay.io/foo/olm:testoperator.v1.0.1 + - image: quay.io/foo/olm:testoperator.v1.1.0 +stable: + bundles: + - image: quay.io/foo/olm:testoperator.v1.0.1 +invalid: + bundles: + - image: quay.io/foo/olm:testoperator.v1.0.1 +`, + assertions: func(t *testing.T, template *semverTemplate, err error) { + require.Nil(t, template) + require.EqualError(t, err, `error unmarshaling JSON: while decoding JSON: json: unknown field "invalid"`) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sv, err := readFile(strings.NewReader(tc.input)) + tc.assertions(t, sv, err) + }) + } +} diff --git a/staging/operator-registry/alpha/veneer/basic/basic.go b/staging/operator-registry/alpha/veneer/basic/basic.go deleted file mode 100644 index 26c2788b57..0000000000 --- a/staging/operator-registry/alpha/veneer/basic/basic.go +++ /dev/null @@ -1,50 +0,0 @@ -package basic - -import ( - "context" - "fmt" - "io" - - "github.com/operator-framework/operator-registry/alpha/action" - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/pkg/image" -) - -type Veneer struct { - Registry image.Registry -} - -func (v Veneer) Render(ctx context.Context, reader io.Reader) (*declcfg.DeclarativeConfig, error) { - cfg, err := declcfg.LoadReader(reader) - if err != nil { - return cfg, err - } - - outb := cfg.Bundles[:0] // allocate based on max size of input, but empty slice - // populate registry, incl any flags from CLI, and enforce only rendering bundle images - r := action.Render{ - Registry: v.Registry, - AllowedRefMask: action.RefBundleImage, - } - - for _, b := range cfg.Bundles { - if !isBundleVeneer(&b) { - return nil, fmt.Errorf("unexpected fields present in basic veneer bundle") - } - r.Refs = []string{b.Image} - contributor, err := r.Run(ctx) - if err != nil { - return nil, err - } - outb = append(outb, contributor.Bundles...) - } - - cfg.Bundles = outb - return cfg, nil -} - -// isBundleVeneer identifies a Bundle veneer source as having a Schema and Image defined -// but no Properties, RelatedImages or Package defined -func isBundleVeneer(b *declcfg.Bundle) bool { - return b.Schema != "" && b.Image != "" && b.Package == "" && len(b.Properties) == 0 && len(b.RelatedImages) == 0 -} diff --git a/staging/operator-registry/alpha/veneer/semver/README.md b/staging/operator-registry/alpha/veneer/semver/README.md deleted file mode 100644 index e69726c487..0000000000 --- a/staging/operator-registry/alpha/veneer/semver/README.md +++ /dev/null @@ -1,259 +0,0 @@ -## Semver Veneer: - -Since a `veneer` is identified as an input schema which may be processed to generate a valid FBC, we can define a `semver veneer` as a schema which uses channel conventions to facilitate the auto-generation of channels along `semver` delimiters. - -[**DISCLAIMER:** since version build metadata [MUST be ignored when determining version precedence](https://semver.org) when using semver, it cannot be used in any bundle included in the `semver veneer` and will result in a fatal error.] - -### Schema Goals -The `semver veneer` must have: -- terse grammar to minimize creation/maintenance effort -- deterministic output -- simple channel promotion for maturing bundles -- demonstration of a common type of channel maturity model -- minor-version (Y-stream), major-version (X-stream) versioning optionality - -The resulting FBC must clearly indicate how generated channels relate to veneer entities - -### Schema Anatomy -For convenience and simplicity, this veneer currently supports hard-coded channel names `Candidate`, `Fast`, and `Stable`, in order of increasing channel stability. We leverage this relationship to calculate the default channel for the package. - -`GenerateMajorChannels` and `GenerateMinorChannels` dictate whether this veneer will generate X-stream or Y-stream channels (attributes can be set independently). If omitted, only minor (Y-stream) channels will be generated. - -Under each channel are a list of bundle image references which contribute to that channel. - -With the following (hypothetical) example we define a mock bundle which has 11 versions, represented across each of the channel types: -```yaml -Schema: olm.semver -GenerateMajorChannels: true -GenerateMinorChannels: true -Candidate: - Bundles: - - Image: quay.io/foo/olm:testoperator.v0.1.0 - - Image: quay.io/foo/olm:testoperator.v0.1.1 - - Image: quay.io/foo/olm:testoperator.v0.1.2 - - Image: quay.io/foo/olm:testoperator.v0.1.3 - - Image: quay.io/foo/olm:testoperator.v0.2.0 - - Image: quay.io/foo/olm:testoperator.v0.2.1 - - Image: quay.io/foo/olm:testoperator.v0.2.2 - - Image: quay.io/foo/olm:testoperator.v0.3.0 - - Image: quay.io/foo/olm:testoperator.v1.0.0 - - Image: quay.io/foo/olm:testoperator.v1.0.1 - - Image: quay.io/foo/olm:testoperator.v1.1.0 -Fast: - Bundles: - - Image: quay.io/foo/olm:testoperator.v0.2.1 - - Image: quay.io/foo/olm:testoperator.v0.2.2 - - Image: quay.io/foo/olm:testoperator.v0.3.0 - - Image: quay.io/foo/olm:testoperator.v1.0.1 - - Image: quay.io/foo/olm:testoperator.v1.1.0 -Stable: - Bundles: - - Image: quay.io/foo/olm:testoperator.v1.0.1 -``` -In this example, `Candidate` has the entire version range of bundles, `Fast` has a mix of older and more-recent versions, and `Stable` channel only has a single published entry. - -### CLI Tool Usage -``` -% ./bin/opm alpha render-veneer semver -h -Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input - -Usage: - opm alpha render-veneer semver [FILE] [flags] - -Flags: - -h, --help help for semver - -o, --output string Output format (json|yaml|mermaid) (default "json") - -Global Flags: - --skip-tls-verify skip TLS certificate verification for container image registries while pulling bundles - --use-http use plain HTTP for container image registries while pulling bundles -``` - -Example command usage: -``` -# Example with file argument passed in -opm alpha render-veneer semver infile.semver.veneer.yaml - -# Example with no file argument passed in -opm alpha render-veneer semver -o yaml < infile.semver.veneer.yaml > outfile.yaml - -# Example with "-" as the file argument passed in -cat infile.semver.veneer.yaml | opm alpha render-veneer semver -o mermaid - -``` -Note that if the command is called without a file argument and nothing passed in on standard input, -the command will hang indefinitely. Either a file argument or file information passed -in on standard input is required by the command. - -With the veneer attribute `GenerateMajorChannels: true` resulting major channels from the command are (skipping the rendered bundle image output): -```yaml ---- -defaultChannel: stable-v1 -name: testoperator -schema: olm.package ---- -entries: -- name: testoperator.v0.1.0 -- name: testoperator.v0.1.1 -- name: testoperator.v0.1.2 -- name: testoperator.v0.1.3 - skips: - - testoperator.v0.1.0 - - testoperator.v0.1.1 - - testoperator.v0.1.2 -- name: testoperator.v0.2.0 -- name: testoperator.v0.2.1 -- name: testoperator.v0.2.2 - replaces: testoperator.v0.1.3 - skips: - - testoperator.v0.2.0 - - testoperator.v0.2.1 -- name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: candidate-v0 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.0 -- name: testoperator.v1.0.1 - skips: - - testoperator.v1.0.0 -- name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: candidate-v1 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v0.2.1 -- name: testoperator.v0.2.2 - skips: - - testoperator.v0.2.1 -- name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: fast-v0 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.1 -- name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: fast-v1 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.1 -name: stable-v1 -package: testoperator -schema: olm.channel -``` - -We generated a channel for each veneer channel entity corresponding to each of the 0.\#.\#, 1.\#.\# major version ranges with skips to the head of the highest semver in a channel. We also generated a replaces edge to traverse across minor version transitions within each major channel. Finally, we generated an `olm.package` object, setting as default the most-stable channel head we created. This process will prefer `Stable` channel over `Fast`, over `Candidate` and then a higher bundle version over a lower version. -(Please note that the naming of the generated channels indicates the digits of significance for that channel. For example, `fast-v1` is a decomposed channel of the `fast` type which contains only major versions of contributing bundles matching `v1`.) - -For contrast, with the veneer attribute `GenerateMinorChannels: true` and running the command again (again skipping rendered bundle image output) we get a bunch more channels: -```yaml ---- -defaultChannel: stable-v1.0 -name: testoperator -schema: olm.package ---- -entries: - - name: testoperator.v0.1.0 - - name: testoperator.v0.1.1 - - name: testoperator.v0.1.2 - - name: testoperator.v0.1.3 - skips: - - testoperator.v0.1.0 - - testoperator.v0.1.1 - - testoperator.v0.1.2 -name: candidate-v0.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.2.0 - - name: testoperator.v0.2.1 - - name: testoperator.v0.2.2 - replaces: testoperator.v0.1.3 - skips: - - testoperator.v0.2.0 - - testoperator.v0.2.1 -name: candidate-v0.2 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: candidate-v0.3 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.0 - - name: testoperator.v1.0.1 - skips: - - testoperator.v1.0.0 -name: candidate-v1.0 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: candidate-v1.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.2.1 - - name: testoperator.v0.2.2 - skips: - - testoperator.v0.2.1 -name: fast-v0.2 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: fast-v0.3 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.1 -name: fast-v1.0 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: fast-v1.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.1 -name: stable-v1.0 -package: testoperator -schema: olm.channel - -``` -Here, a channel is generated for each veneer channel which differs by minor version, and each channel has a `replaces` edge from the predecessor channel to the next-lesser minor bundle version. Please note that at no time do we transgress across major-version boundaries with the channels, to be consistent with [the semver convention](https://semver.org/) for major versions, where the purpose is to make incompatible API changes. - - -### DEMOS - -#### Major Channel Generation -![`GenerateMajorChannels`](./major-version-demo.gif) - -#### Minor Channel Generation -![`GenerateMinorChannels`](./minor-version-demo.gif) - - diff --git a/staging/operator-registry/alpha/veneer/semver/major-version-demo.gif b/staging/operator-registry/alpha/veneer/semver/major-version-demo.gif deleted file mode 100644 index bf2faa3795..0000000000 Binary files a/staging/operator-registry/alpha/veneer/semver/major-version-demo.gif and /dev/null differ diff --git a/staging/operator-registry/alpha/veneer/semver/minor-version-demo.gif b/staging/operator-registry/alpha/veneer/semver/minor-version-demo.gif deleted file mode 100644 index 3644292b92..0000000000 Binary files a/staging/operator-registry/alpha/veneer/semver/minor-version-demo.gif and /dev/null differ diff --git a/staging/operator-registry/alpha/veneer/semver/semver.go b/staging/operator-registry/alpha/veneer/semver/semver.go deleted file mode 100644 index 00edcc64f4..0000000000 --- a/staging/operator-registry/alpha/veneer/semver/semver.go +++ /dev/null @@ -1,472 +0,0 @@ -package semver - -import ( - "context" - "fmt" - "io" - "sort" - - "github.com/blang/semver/v4" - "github.com/operator-framework/operator-registry/alpha/action" - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/property" - "github.com/operator-framework/operator-registry/pkg/image" - "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/yaml" -) - -// data passed into this module externally -type Veneer struct { - Data io.Reader - Registry image.Registry -} - -// IO structs -- BEGIN -type semverVeneerBundleEntry struct { - Image string `json:"image,omitempty"` -} - -type candidateBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} -type fastBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} -type stableBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} - -type semverVeneer struct { - Schema string `json:"schema"` - GenerateMajorChannels bool `json:"generateMajorChannels,omitempty"` - GenerateMinorChannels bool `json:"generateMinorChannels,omitempty"` - AvoidSkipPatch bool `json:"avoidSkipPatch,omitempty"` - Candidate candidateBundles `json:"candidate,omitempty"` - Fast fastBundles `json:"fast,omitempty"` - Stable stableBundles `json:"stable,omitempty"` - - pkg string `json:"-"` // the derived package name - defaultChannel string `json:"-"` // detected "most stable" channel head -} - -// IO structs -- END - -// channel "kinds", restricted in this iteration to just these -const ( - candidateChannelName string = "candidate" - fastChannelName string = "fast" - stableChannelName string = "stable" -) - -// mapping channel name --> stability, where higher values indicate greater stability -var channelPriorities = map[string]int{candidateChannelName: 0, fastChannelName: 1, stableChannelName: 2} - -// sorting capability for a slice according to the assigned channelPriorities -type byChannelPriority []string - -func (b byChannelPriority) Len() int { return len(b) } -func (b byChannelPriority) Less(i, j int) bool { - return channelPriorities[b[i]] < channelPriorities[b[j]] -} -func (b byChannelPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] } - -// map of channels : bundles : bundle-version -// channels --> bundles --> version -type semverRenderedChannelVersions map[string]map[string]semver.Version // e.g. d["stable-v1"]["example-operator/v1.0.0"] = 1.0.0 - -func (v Veneer) Render(ctx context.Context) (*declcfg.DeclarativeConfig, error) { - var out declcfg.DeclarativeConfig - - sv, err := readFile(v.Data) - if err != nil { - return nil, fmt.Errorf("semver-render: unable to read file: %v", err) - } - - var cfgs []declcfg.DeclarativeConfig - - bundleDict := make(map[string]struct{}) - buildBundleList(&sv.Candidate.Bundles, &bundleDict) - buildBundleList(&sv.Fast.Bundles, &bundleDict) - buildBundleList(&sv.Stable.Bundles, &bundleDict) - - for b, _ := range bundleDict { - r := action.Render{ - AllowedRefMask: action.RefBundleImage, - Refs: []string{b}, - Registry: v.Registry, - } - c, err := r.Run(ctx) - if err != nil { - return nil, err - } - cfgs = append(cfgs, *c) - } - out = *combineConfigs(cfgs) - - if len(out.Bundles) == 0 { - return nil, fmt.Errorf("semver-render: no bundles specified or no bundles could be rendered") - } - - channelBundleVersions, err := sv.getVersionsFromStandardChannels(&out) - if err != nil { - return nil, fmt.Errorf("semver-render: unable to post-process bundle info: %v", err) - } - - channels := sv.generateChannels(channelBundleVersions) - out.Channels = channels - out.Packages[0].DefaultChannel = sv.defaultChannel - - return &out, nil -} - -func buildBundleList(bundles *[]semverVeneerBundleEntry, dict *map[string]struct{}) { - for _, b := range *bundles { - if _, ok := (*dict)[b.Image]; !ok { - (*dict)[b.Image] = struct{}{} - } - } -} - -func readFile(data io.Reader) (*semverVeneer, error) { - fileData, err := io.ReadAll(data) - if err != nil { - return nil, err - } - - // default behavior is to generate only minor channels and to use skips over replaces - sv := semverVeneer{ - GenerateMajorChannels: false, - GenerateMinorChannels: true, - AvoidSkipPatch: false, - } - if err := yaml.Unmarshal(fileData, &sv); err != nil { - return nil, err - } - return &sv, nil -} - -func (sv *semverVeneer) getVersionsFromStandardChannels(cfg *declcfg.DeclarativeConfig) (*semverRenderedChannelVersions, error) { - versions := semverRenderedChannelVersions{} - - bdm, err := sv.getVersionsFromChannel(sv.Candidate.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[candidateChannelName] = bdm - - bdm, err = sv.getVersionsFromChannel(sv.Fast.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[fastChannelName] = bdm - - bdm, err = sv.getVersionsFromChannel(sv.Stable.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[stableChannelName] = bdm - - return &versions, nil -} - -func (sv *semverVeneer) getVersionsFromChannel(semverBundles []semverVeneerBundleEntry, cfg *declcfg.DeclarativeConfig) (map[string]semver.Version, error) { - entries := make(map[string]semver.Version) - - // we iterate over the channel bundles from the veneer, to: - // - identify if any required bundles for the channel are missing/not rendered/otherwise unavailable - // - maintain the channel-bundle relationship as we map from un-rendered semver veneer bundles to rendered bundles in `entries` which is accumulated by the caller - // in a per-channel structure to which we can safely refer when generating/linking channels - for _, semverBundle := range semverBundles { - // test if the bundle specified in the veneer is present in the successfully-rendered bundles - index := 0 - for index < len(cfg.Bundles) { - if cfg.Bundles[index].Image == semverBundle.Image { - break - } - index++ - } - if index == len(cfg.Bundles) { - return nil, fmt.Errorf("supplied bundle image name %q not found in rendered bundle images", semverBundle.Image) - } - b := cfg.Bundles[index] - - props, err := property.Parse(b.Properties) - if err != nil { - return nil, fmt.Errorf("parse properties for bundle %q: %v", b.Name, err) - } - if len(props.Packages) != 1 { - return nil, fmt.Errorf("bundle %q has multiple %q properties, expected exactly 1", b.Name, property.TypePackage) - } - v, err := semver.Parse(props.Packages[0].Version) - if err != nil { - return nil, fmt.Errorf("bundle %q has invalid version %q: %v", b.Name, props.Packages[0].Version, err) - } - - // package name detection - if sv.pkg != "" { - // if we have a known package name, then ensure all subsequent packages match - if props.Packages[0].PackageName != sv.pkg { - return nil, fmt.Errorf("bundle %q does not belong to this package: %q", props.Packages[0].PackageName, sv.pkg) - } - } else { - // else cache the first - p := newPackage(props.Packages[0].PackageName) - cfg.Packages = append(cfg.Packages, *p) - sv.pkg = props.Packages[0].PackageName - } - - if _, ok := entries[b.Name]; ok { - return nil, fmt.Errorf("duplicate bundle name %q", b.Name) - } - - entries[b.Name] = v - } - - return entries, nil -} - -// the "high-water channel" struct functions as a freely-rising indicator of the "most stable" channel head, so we can use that -// later as the package's defaultChannel attribute -type highwaterChannel struct { - kind string - version semver.Version - name string -} - -func (h *highwaterChannel) gt(ih *highwaterChannel) bool { - return (channelPriorities[h.kind] > channelPriorities[ih.kind]) || (h.version.GT(ih.version)) -} - -// generates an unlinked channel for each channel as per the input veneer config (major || minor), then link up the edges of the set of channels so that: -// - (for major channels) iterating to a new minor version channel (traversing between Y-streams) creates a 'replaces' edge between the predecessor and successor bundles -// - within the same minor version (Y-stream), the head of the channel should have a 'skips' encompassing all lesser minor versions of the bundle enumerated in the veneer. -// along the way, uses a highwaterChannel marker to identify the "most stable" channel head to be used as the default channel for the generated package -func (sv *semverVeneer) generateChannels(semverChannels *semverRenderedChannelVersions) []declcfg.Channel { - outChannels := []declcfg.Channel{} - - // sort the channelkinds in ascending order so we can traverse the bundles in order of - // their source channel's priority - var keysByPriority []string - for k, _ := range channelPriorities { - keysByPriority = append(keysByPriority, k) - } - sort.Sort(byChannelPriority(keysByPriority)) - - // set to the least-priority channel - hwc := highwaterChannel{kind: keysByPriority[0], version: semver.Version{Major: 0, Minor: 0}} - - // mapping the generated channel name to the original semver name (i.e. channel kind), so we can do generated-channel-name --> original-semver-name --> version mapping, later - channelMapping := map[string]string{} - - for _, k := range keysByPriority { - bundles := (*semverChannels)[k] - - // skip channel if empty - if len(bundles) == 0 { - continue - } - - // sort the bundle names according to their semver, so we can walk in ascending order - bundleNamesByVersion := []string{} - for b := range bundles { - bundleNamesByVersion = append(bundleNamesByVersion, b) - } - sort.Slice(bundleNamesByVersion, func(i, j int) bool { - return bundles[bundleNamesByVersion[i]].LT(bundles[bundleNamesByVersion[j]]) - }) - - majors := map[string]*declcfg.Channel{} - minors := map[string]*declcfg.Channel{} - - for _, b := range bundleNamesByVersion { - if sv.GenerateMajorChannels { - testChannelName := channelNameFromMajor(k, bundles[b]) - ch, ok := majors[testChannelName] - if !ok { - ch = newChannel(sv.pkg, testChannelName) - majors[testChannelName] = ch - } - ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) - - channelMapping[testChannelName] = k - - hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} - if hwcCandidate.gt(&hwc) { - hwc = hwcCandidate - } - } - if sv.GenerateMinorChannels { - testChannelName := channelNameFromMinor(k, bundles[b]) - ch, ok := minors[testChannelName] - if !ok { - ch = newChannel(sv.pkg, testChannelName) - minors[testChannelName] = ch - } - ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) - - channelMapping[testChannelName] = k - - hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} - if hwcCandidate.gt(&hwc) { - hwc = hwcCandidate - } - } - } - - outChannels = append(outChannels, sv.linkChannels(majors, sv.pkg, semverChannels, &channelMapping)...) - outChannels = append(outChannels, sv.linkChannels(minors, sv.pkg, semverChannels, &channelMapping)...) - } - - // save off the name of the high-water-mark channel for the default for this package - sv.defaultChannel = hwc.name - - return outChannels -} - -// all channels that come to linkChannels MUST have the same prefix. This adds replaces edges of minor versions of the largest major version. -func (sv *semverVeneer) linkChannels(unlinkedChannels map[string]*declcfg.Channel, pkg string, semverChannels *semverRenderedChannelVersions, channelMapping *map[string]string) []declcfg.Channel { - channels := []declcfg.Channel{} - - for channelName, channel := range unlinkedChannels { - // sort the channel entries in ascending order, according to the corresponding bundle versions for the channelName stored in the semverRenderedChannelVersions - // convenience function, to make this more clear - versionLookup := func(generatedChannelName string, channelEdgeIndex int) semver.Version { - channelKind := (*channelMapping)[generatedChannelName] - bundleVersions := (*semverChannels)[channelKind] - bundleName := channel.Entries[channelEdgeIndex].Name - return bundleVersions[bundleName] - } - - sort.Slice(channel.Entries, func(i, j int) bool { - return versionLookup(channelName, i).LT(versionLookup(channelName, j)) - }) - - // link up the edges according to config - if sv.AvoidSkipPatch { - for i := 1; i < len(channel.Entries); i++ { - channel.Entries[i] = declcfg.ChannelEntry{ - Name: channel.Entries[i].Name, - Replaces: channel.Entries[i-1].Name, - } - } - } else { - curIndex := len(channel.Entries) - 1 - curMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][channel.Entries[curIndex].Name]) - curSkips := sets.NewString() - for i := len(channel.Entries) - 2; i >= 0; i-- { - thisName := channel.Entries[i].Name - thisMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][thisName]) - if thisMinor.EQ(curMinor) { - channel.Entries[i] = declcfg.ChannelEntry{Name: thisName} - curSkips = curSkips.Insert(thisName) - } else { - channel.Entries[curIndex] = declcfg.ChannelEntry{ - Name: channel.Entries[curIndex].Name, - Replaces: thisName, - Skips: curSkips.List(), - } - curSkips = sets.NewString() - curIndex = i - curMinor = thisMinor - } - } - channel.Entries[curIndex] = declcfg.ChannelEntry{ - Name: channel.Entries[curIndex].Name, - Skips: curSkips.List(), - } - } - channels = append(channels, *channel) - } - return channels -} - -func channelNameFromMinor(prefix string, version semver.Version) string { - return fmt.Sprintf("%s-v%d.%d", prefix, version.Major, version.Minor) -} - -func channelNameFromMajor(prefix string, version semver.Version) string { - return fmt.Sprintf("%s-v%d", prefix, version.Major) -} - -func newPackage(name string) *declcfg.Package { - return &declcfg.Package{ - Schema: "olm.package", - Name: name, - DefaultChannel: "", - } -} - -func newChannel(pkgName string, chName string) *declcfg.Channel { - return &declcfg.Channel{ - Schema: "olm.channel", - Name: string(chName), - Package: pkgName, - Entries: []declcfg.ChannelEntry{}, - } -} - -func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig { - out := &declcfg.DeclarativeConfig{} - for _, in := range cfgs { - out.Packages = append(out.Packages, in.Packages...) - out.Channels = append(out.Channels, in.Channels...) - out.Bundles = append(out.Bundles, in.Bundles...) - out.Others = append(out.Others, in.Others...) - } - return out -} - -func getMinorVersion(v semver.Version) semver.Version { - return semver.Version{ - Major: v.Major, - Minor: v.Minor, - } -} - -func withoutBuildMetadataConflict(versions *map[string]semver.Version) error { - errs := []error{} - - // using the stringified semver because the semver package generates deterministic representations, - // and because the semver.Version contains slice fields which make it unsuitable as a map key - // stringified-semver.Version ==> incidence count - seen := make(map[string]int) - for b := range *versions { - stripped := stripBuildMetadata((*versions)[b]) - if _, ok := seen[stripped]; !ok { - seen[stripped] = 1 - } else { - seen[stripped] = seen[stripped] + 1 - errs = append(errs, fmt.Errorf("bundle version %q cannot be compared to %q", (*versions)[b].String(), stripped)) - } - } - - if len(errs) != 0 { - return fmt.Errorf("encountered bundle versions which differ only by build metadata, which cannot be ordered: %v", errors.NewAggregate(errs)) - } - - return nil -} - -func validateVersions(versions *map[string]semver.Version) error { - // short-circuit if empty, since that is not an error - if len(*versions) == 0 { - return nil - } - return withoutBuildMetadataConflict(versions) -} - -// strips out the build metadata from a semver.Version and then stringifies it to make it suitable for collision detection -func stripBuildMetadata(v semver.Version) string { - v.Build = nil - return v.String() -} diff --git a/staging/operator-registry/cmd/opm/alpha/cmd.go b/staging/operator-registry/cmd/opm/alpha/cmd.go index 74e88edbe7..55511cb2ea 100644 --- a/staging/operator-registry/cmd/opm/alpha/cmd.go +++ b/staging/operator-registry/cmd/opm/alpha/cmd.go @@ -6,7 +6,7 @@ import ( "github.com/operator-framework/operator-registry/cmd/opm/alpha/bundle" "github.com/operator-framework/operator-registry/cmd/opm/alpha/list" rendergraph "github.com/operator-framework/operator-registry/cmd/opm/alpha/render-graph" - "github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer" + "github.com/operator-framework/operator-registry/cmd/opm/alpha/template" ) func NewCmd() *cobra.Command { @@ -15,13 +15,14 @@ func NewCmd() *cobra.Command { Use: "alpha", Short: "Run an alpha subcommand", Args: cobra.NoArgs, + Run: func(_ *cobra.Command, _ []string) {}, // adding an empty function here to preserve non-zero exit status for misstated subcommands/flags for the command hierarchy } runCmd.AddCommand( bundle.NewCmd(), list.NewCmd(), rendergraph.NewCmd(), - veneer.NewCmd(), + template.NewCmd(), ) return runCmd } diff --git a/staging/operator-registry/cmd/opm/alpha/template/basic.go b/staging/operator-registry/cmd/opm/alpha/template/basic.go new file mode 100644 index 0000000000..2510a4fa74 --- /dev/null +++ b/staging/operator-registry/cmd/opm/alpha/template/basic.go @@ -0,0 +1,76 @@ +package template + +import ( + "io" + "io/ioutil" + "log" + "os" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/template/basic" + "github.com/operator-framework/operator-registry/cmd/opm/internal/util" +) + +func newBasicTemplateCmd() *cobra.Command { + var ( + template basic.Template + output string + ) + cmd := &cobra.Command{ + Use: "basic basic-template-file", + Short: `Generate a file-based catalog from a single 'basic template' file +When FILE is '-' or not provided, the template is read from standard input`, + Long: `Generate a file-based catalog from a single 'basic template' file +When FILE is '-' or not provided, the template is read from standard input`, + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + // Handle different input argument types + // When no arguments or "-" is passed to the command, + // assume input is coming from stdin + // Otherwise open the file passed to the command + data, source, err := openFileOrStdin(cmd, args) + if err != nil { + log.Fatalf("unable to open %q: %v", source, err) + } + defer data.Close() + + var write func(declcfg.DeclarativeConfig, io.Writer) error + switch output { + case "yaml": + write = declcfg.WriteYAML + case "json": + write = declcfg.WriteJSON + default: + log.Fatalf("invalid --output value %q, expected (json|yaml)", output) + } + + // The bundle loading impl is somewhat verbose, even on the happy path, + // so discard all logrus default logger logs. Any important failures will be + // returned from template.Render and logged as fatal errors. + logrus.SetOutput(ioutil.Discard) + + reg, err := util.CreateCLIRegistry(cmd) + if err != nil { + log.Fatalf("creating containerd registry: %v", err) + } + defer reg.Destroy() + + template.Registry = reg + + // only taking first file argument + cfg, err := template.Render(cmd.Context(), data) + if err != nil { + log.Fatal(err) + } + + if err := write(*cfg, os.Stdout); err != nil { + log.Fatal(err) + } + }, + } + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") + return cmd +} diff --git a/staging/operator-registry/cmd/opm/alpha/template/cmd.go b/staging/operator-registry/cmd/opm/alpha/template/cmd.go new file mode 100644 index 0000000000..1c435e6fa2 --- /dev/null +++ b/staging/operator-registry/cmd/opm/alpha/template/cmd.go @@ -0,0 +1,30 @@ +package template + +import ( + "io" + "os" + + "github.com/spf13/cobra" +) + +func NewCmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "render-template", + Short: "Render a catalog template type", + Args: cobra.NoArgs, + } + + runCmd.AddCommand(newBasicTemplateCmd()) + runCmd.AddCommand(newSemverTemplateCmd()) + runCmd.AddCommand(newCompositeTemplateCmd()) + + return runCmd +} + +func openFileOrStdin(cmd *cobra.Command, args []string) (io.ReadCloser, string, error) { + if len(args) == 0 || args[0] == "-" { + return io.NopCloser(cmd.InOrStdin()), "stdin", nil + } + reader, err := os.Open(args[0]) + return reader, args[0], err +} diff --git a/staging/operator-registry/cmd/opm/alpha/template/composite.go b/staging/operator-registry/cmd/opm/alpha/template/composite.go new file mode 100644 index 0000000000..9cac25c6cf --- /dev/null +++ b/staging/operator-registry/cmd/opm/alpha/template/composite.go @@ -0,0 +1,173 @@ +package template + +import ( + "encoding/json" + "fmt" + "log" + "os" + + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/util/yaml" + + "github.com/operator-framework/operator-registry/alpha/template/composite" +) + +func newCompositeTemplateCmd() *cobra.Command { + var ( + template composite.Template + output string + containerTool string + validate bool + compositeFile string + catalogFile string + ) + cmd := &cobra.Command{ + Use: "composite", + Short: `Generate file-based catalogs from a catalog configuration file +and a 'composite template' file`, + Long: `Generate file-based catalogs from a catalog configuration file +and a 'composite template' file`, + Args: cobra.MaximumNArgs(0), + Run: func(cmd *cobra.Command, args []string) { + containerTool = "docker" + catalogData, err := os.Open(catalogFile) + if err != nil { + log.Fatalf("opening catalog config file %q: %s", catalogFile, err) + } + defer catalogData.Close() + + // get catalog configurations + catalogConfig := &composite.CatalogConfig{} + catalogDoc := json.RawMessage{} + catalogDecoder := yaml.NewYAMLOrJSONDecoder(catalogData, 4096) + err = catalogDecoder.Decode(&catalogDoc) + if err != nil { + log.Fatalf("decoding catalog config: %s", err) + } + err = json.Unmarshal(catalogDoc, catalogConfig) + if err != nil { + log.Fatalf("unmarshalling catalog config: %s", err) + } + + if catalogConfig.Schema != composite.CatalogSchema { + log.Fatalf("catalog configuration file has unknown schema, should be %q", composite.CatalogSchema) + } + + catalogBuilderMap := make(composite.CatalogBuilderMap) + + wd, err := os.Getwd() + if err != nil { + log.Fatalf("getting current working directory: %s", err) + } + + // setup the builders for each catalog + setupFailed := false + setupErrors := map[string][]string{} + for _, catalog := range catalogConfig.Catalogs { + errs := []string{} + if catalog.Destination.BaseImage == "" { + errs = append(errs, "destination.baseImage must not be an empty string") + } + + if catalog.Destination.WorkingDir == "" { + errs = append(errs, "destination.workingDir must not be an empty string") + } + + // check for validation errors and skip builder creation if there are any errors + if len(errs) > 0 { + setupFailed = true + setupErrors[catalog.Name] = errs + continue + } + + if _, ok := catalogBuilderMap[catalog.Name]; !ok { + builderMap := make(composite.BuilderMap) + for _, schema := range catalog.Builders { + builder, err := builderForSchema(schema, composite.BuilderConfig{ + ContainerCfg: composite.ContainerConfig{ + ContainerTool: containerTool, + BaseImage: catalog.Destination.BaseImage, + WorkingDir: catalog.Destination.WorkingDir, + }, + OutputType: output, + CurrentDirectory: wd, + }) + if err != nil { + log.Fatalf("getting builder %q for catalog %q: %s", schema, catalog.Name, err) + } + builderMap[schema] = builder + } + catalogBuilderMap[catalog.Name] = builderMap + } + } + + // if there were errors validating the catalog configuration then exit + if setupFailed { + //build the error message + var errMsg string + for cat, errs := range setupErrors { + errMsg += fmt.Sprintf("\nCatalog %s:\n", cat) + for _, err := range errs { + errMsg += fmt.Sprintf(" - %s\n", err) + } + } + log.Fatalf("catalog configuration file field validation failed: %s", errMsg) + } + + template.CatalogBuilders = catalogBuilderMap + + compositeData, err := os.Open(compositeFile) + if err != nil { + log.Fatalf("opening composite config file %q: %s", compositeFile, err) + } + defer compositeData.Close() + + // parse data to composite config + compositeConfig := &composite.CompositeConfig{} + compositeDoc := json.RawMessage{} + compositeDecoder := yaml.NewYAMLOrJSONDecoder(compositeData, 4096) + err = compositeDecoder.Decode(&compositeDoc) + if err != nil { + log.Fatalf("decoding composite config: %s", err) + } + err = json.Unmarshal(compositeDoc, compositeConfig) + if err != nil { + log.Fatalf("unmarshalling composite config: %s", err) + } + + if compositeConfig.Schema != composite.CompositeSchema { + log.Fatalf("%q has unknown schema, should be %q", compositeFile, composite.CompositeSchema) + } + + err = template.Render(cmd.Context(), compositeConfig, validate) + if err != nil { + log.Fatalf("rendering the composite template: %s", err) + } + }, + } + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") + // TODO: Investigate ways to do this without using a cli tool like docker/podman + // cmd.Flags().StringVar(&containerTool, "container-tool", "docker", "container tool to be used when rendering templates (should be an equivalent replacement to docker - similar to podman)") + cmd.Flags().BoolVar(&validate, "validate", true, "whether or not the created FBC should be validated (i.e 'opm validate')") + cmd.Flags().StringVarP(&compositeFile, "composite-config", "c", "catalog/config.yaml", "File to use as the composite configuration file") + cmd.Flags().StringVarP(&catalogFile, "catalog-config", "f", "catalogs.yaml", "File to use as the catalog configuration file") + return cmd +} + +func builderForSchema(schema string, builderCfg composite.BuilderConfig) (composite.Builder, error) { + var builder composite.Builder + switch schema { + case composite.BasicBuilderSchema: + builder = composite.NewBasicBuilder(builderCfg) + case composite.SemverBuilderSchema: + builder = composite.NewSemverBuilder(builderCfg) + case composite.RawBuilderSchema: + builder = composite.NewRawBuilder(builderCfg) + case composite.CustomBuilderSchema: + builder = composite.NewCustomBuilder(builderCfg) + default: + return nil, fmt.Errorf("unknown schema %q", schema) + } + + return builder, nil +} diff --git a/staging/operator-registry/cmd/opm/alpha/template/semver.go b/staging/operator-registry/cmd/opm/alpha/template/semver.go new file mode 100644 index 0000000000..dd27fda074 --- /dev/null +++ b/staging/operator-registry/cmd/opm/alpha/template/semver.go @@ -0,0 +1,85 @@ +package template + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "os" + + "github.com/sirupsen/logrus" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/template/semver" + "github.com/operator-framework/operator-registry/cmd/opm/internal/util" + "github.com/spf13/cobra" +) + +func newSemverTemplateCmd() *cobra.Command { + output := "" + cmd := &cobra.Command{ + Use: "semver [FILE]", + Short: `Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input`, + Long: `Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + // Handle different input argument types + // When no arguments or "-" is passed to the command, + // assume input is coming from stdin + // Otherwise open the file passed to the command + data, source, err := openFileOrStdin(cmd, args) + if err != nil { + return err + } + defer data.Close() + + var write func(declcfg.DeclarativeConfig, io.Writer) error + switch output { + case "json": + write = declcfg.WriteJSON + case "yaml": + write = declcfg.WriteYAML + case "mermaid": + write = func(cfg declcfg.DeclarativeConfig, writer io.Writer) error { + mermaidWriter := declcfg.NewMermaidWriter() + return mermaidWriter.WriteChannels(cfg, writer) + } + default: + return fmt.Errorf("invalid output format %q", output) + } + + // The bundle loading impl is somewhat verbose, even on the happy path, + // so discard all logrus default logger logs. Any important failures will be + // returned from template.Render and logged as fatal errors. + logrus.SetOutput(ioutil.Discard) + + reg, err := util.CreateCLIRegistry(cmd) + if err != nil { + log.Fatalf("creating containerd registry: %v", err) + } + defer reg.Destroy() + + template := semver.Template{ + Data: data, + Registry: reg, + } + out, err := template.Render(cmd.Context()) + if err != nil { + log.Fatalf("semver %q: %v", source, err) + } + + if out != nil { + if err := write(*out, os.Stdout); err != nil { + log.Fatal(err) + } + } + + return nil + }, + } + + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml|mermaid)") + return cmd +} diff --git a/staging/operator-registry/cmd/opm/alpha/veneer/basic.go b/staging/operator-registry/cmd/opm/alpha/veneer/basic.go deleted file mode 100644 index 40311c0eb2..0000000000 --- a/staging/operator-registry/cmd/opm/alpha/veneer/basic.go +++ /dev/null @@ -1,76 +0,0 @@ -package veneer - -import ( - "io" - "io/ioutil" - "log" - "os" - - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/veneer/basic" - "github.com/operator-framework/operator-registry/cmd/opm/internal/util" -) - -func newBasicVeneerRenderCmd() *cobra.Command { - var ( - veneer basic.Veneer - output string - ) - cmd := &cobra.Command{ - Use: "basic basic-veneer-file", - Short: `Generate a file-based catalog from a single 'basic veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Long: `Generate a file-based catalog from a single 'basic veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { - // Handle different input argument types - // When no arguments or "-" is passed to the command, - // assume input is coming from stdin - // Otherwise open the file passed to the command - data, source, err := openFileOrStdin(cmd, args) - if err != nil { - log.Fatalf("unable to open %q: %v", source, err) - } - defer data.Close() - - var write func(declcfg.DeclarativeConfig, io.Writer) error - switch output { - case "yaml": - write = declcfg.WriteYAML - case "json": - write = declcfg.WriteJSON - default: - log.Fatalf("invalid --output value %q, expected (json|yaml)", output) - } - - // The bundle loading impl is somewhat verbose, even on the happy path, - // so discard all logrus default logger logs. Any important failures will be - // returned from veneer.Render and logged as fatal errors. - logrus.SetOutput(ioutil.Discard) - - reg, err := util.CreateCLIRegistry(cmd) - if err != nil { - log.Fatalf("creating containerd registry: %v", err) - } - defer reg.Destroy() - - veneer.Registry = reg - - // only taking first file argument - cfg, err := veneer.Render(cmd.Context(), data) - if err != nil { - log.Fatal(err) - } - - if err := write(*cfg, os.Stdout); err != nil { - log.Fatal(err) - } - }, - } - cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") - return cmd -} diff --git a/staging/operator-registry/cmd/opm/alpha/veneer/cmd.go b/staging/operator-registry/cmd/opm/alpha/veneer/cmd.go deleted file mode 100644 index 2bdec4e1f7..0000000000 --- a/staging/operator-registry/cmd/opm/alpha/veneer/cmd.go +++ /dev/null @@ -1,29 +0,0 @@ -package veneer - -import ( - "io" - "os" - - "github.com/spf13/cobra" -) - -func NewCmd() *cobra.Command { - runCmd := &cobra.Command{ - Use: "render-veneer", - Short: "Render a veneer type", - Args: cobra.NoArgs, - } - - runCmd.AddCommand(newBasicVeneerRenderCmd()) - runCmd.AddCommand(newSemverCmd()) - - return runCmd -} - -func openFileOrStdin(cmd *cobra.Command, args []string) (io.ReadCloser, string, error) { - if len(args) == 0 || args[0] == "-" { - return io.NopCloser(cmd.InOrStdin()), "stdin", nil - } - reader, err := os.Open(args[0]) - return reader, args[0], err -} diff --git a/staging/operator-registry/cmd/opm/alpha/veneer/semver.go b/staging/operator-registry/cmd/opm/alpha/veneer/semver.go deleted file mode 100644 index 0dd4bd122d..0000000000 --- a/staging/operator-registry/cmd/opm/alpha/veneer/semver.go +++ /dev/null @@ -1,85 +0,0 @@ -package veneer - -import ( - "fmt" - "io" - "io/ioutil" - "log" - "os" - - "github.com/sirupsen/logrus" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/veneer/semver" - "github.com/operator-framework/operator-registry/cmd/opm/internal/util" - "github.com/spf13/cobra" -) - -func newSemverCmd() *cobra.Command { - output := "" - cmd := &cobra.Command{ - Use: "semver [FILE]", - Short: `Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Long: `Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Args: cobra.MaximumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - // Handle different input argument types - // When no arguments or "-" is passed to the command, - // assume input is coming from stdin - // Otherwise open the file passed to the command - data, source, err := openFileOrStdin(cmd, args) - if err != nil { - return err - } - defer data.Close() - - var write func(declcfg.DeclarativeConfig, io.Writer) error - switch output { - case "json": - write = declcfg.WriteJSON - case "yaml": - write = declcfg.WriteYAML - case "mermaid": - write = func(cfg declcfg.DeclarativeConfig, writer io.Writer) error { - mermaidWriter := declcfg.NewMermaidWriter() - return mermaidWriter.WriteChannels(cfg, writer) - } - default: - return fmt.Errorf("invalid output format %q", output) - } - - // The bundle loading impl is somewhat verbose, even on the happy path, - // so discard all logrus default logger logs. Any important failures will be - // returned from veneer.Render and logged as fatal errors. - logrus.SetOutput(ioutil.Discard) - - reg, err := util.CreateCLIRegistry(cmd) - if err != nil { - log.Fatalf("creating containerd registry: %v", err) - } - defer reg.Destroy() - - veneer := semver.Veneer{ - Data: data, - Registry: reg, - } - out, err := veneer.Render(cmd.Context()) - if err != nil { - log.Fatalf("semver %q: %v", source, err) - } - - if out != nil { - if err := write(*out, os.Stdout); err != nil { - log.Fatal(err) - } - } - - return nil - }, - } - - cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml|mermaid)") - return cmd -} diff --git a/staging/operator-registry/cmd/opm/migrate/cmd.go b/staging/operator-registry/cmd/opm/migrate/cmd.go index 6405060b0a..36c73abc7a 100644 --- a/staging/operator-registry/cmd/opm/migrate/cmd.go +++ b/staging/operator-registry/cmd/opm/migrate/cmd.go @@ -21,6 +21,10 @@ func NewCmd() *cobra.Command { Short: "Migrate a sqlite-based index image or database file to a file-based catalog", Long: `Migrate a sqlite-based index image or database file to a file-based catalog. +NOTE: the --output=json format produces streamable, concatenated JSON files. +These are suitable to opm and jq, but may not be supported by arbitrary JSON +parsers that assume that a file contains exactly one valid JSON object. + ` + sqlite.DeprecationMessage, Args: cobra.ExactArgs(2), PersistentPreRun: func(_ *cobra.Command, _ []string) { diff --git a/staging/operator-registry/cmd/opm/root/cmd.go b/staging/operator-registry/cmd/opm/root/cmd.go index 9a551f1457..71631c6129 100644 --- a/staging/operator-registry/cmd/opm/root/cmd.go +++ b/staging/operator-registry/cmd/opm/root/cmd.go @@ -28,6 +28,7 @@ func NewCmd() *cobra.Command { return nil }, Args: cobra.NoArgs, + Run: func(_ *cobra.Command, _ []string) {}, // adding an empty function here to preserve non-zero exit status for misstated subcommands/flags for the command hierarchy } cmd.PersistentFlags().Bool("skip-tls", false, "skip TLS certificate verification for container image registries while pulling bundles or index") diff --git a/staging/operator-registry/cmd/opm/serve/serve.go b/staging/operator-registry/cmd/opm/serve/serve.go index 8b7d280764..633ad9ef3f 100644 --- a/staging/operator-registry/cmd/opm/serve/serve.go +++ b/staging/operator-registry/cmd/opm/serve/serve.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "io" "net" "net/http" endpoint "net/http/pprof" @@ -20,18 +19,17 @@ import ( "github.com/operator-framework/operator-registry/pkg/api" health "github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1" - "github.com/operator-framework/operator-registry/pkg/cache" "github.com/operator-framework/operator-registry/pkg/lib/dns" "github.com/operator-framework/operator-registry/pkg/lib/graceful" "github.com/operator-framework/operator-registry/pkg/lib/log" + "github.com/operator-framework/operator-registry/pkg/registry" "github.com/operator-framework/operator-registry/pkg/server" ) type serve struct { - configDir string - cacheDir string - cacheOnly bool - cacheEnforceIntegrity bool + configDir string + cacheDir string + cacheOnly bool port string terminationLog string @@ -61,19 +59,15 @@ startup. Changes made to the declarative config after the this command starts will not be reflected in the served content. `, Args: cobra.ExactArgs(1), - PreRun: func(_ *cobra.Command, args []string) { + PreRunE: func(_ *cobra.Command, args []string) error { s.configDir = args[0] if s.debug { logger.SetLevel(logrus.DebugLevel) } + return nil }, - Run: func(cmd *cobra.Command, _ []string) { - if !cmd.Flags().Changed("cache-enforce-integrity") { - s.cacheEnforceIntegrity = s.cacheDir != "" && !s.cacheOnly - } - if err := s.run(cmd.Context()); err != nil { - logger.Fatal(err) - } + RunE: func(cmd *cobra.Command, _ []string) error { + return s.run(cmd.Context()) }, } @@ -83,7 +77,6 @@ will not be reflected in the served content. cmd.Flags().StringVar(&s.pprofAddr, "pprof-addr", "", "address of startup profiling endpoint (addr:port format)") cmd.Flags().StringVar(&s.cacheDir, "cache-dir", "", "if set, sync and persist server cache directory") cmd.Flags().BoolVar(&s.cacheOnly, "cache-only", false, "sync the serve cache and exit without serving") - cmd.Flags().BoolVar(&s.cacheEnforceIntegrity, "cache-enforce-integrity", false, "exit with error if cache is not present or has been invalidated. (default: true when --cache-dir is set and --cache-only is false, false otherwise), ") return cmd } @@ -109,38 +102,11 @@ func (s *serve) run(ctx context.Context) error { s.logger = s.logger.WithFields(logrus.Fields{"configs": s.configDir, "port": s.port}) - if s.cacheDir == "" && s.cacheEnforceIntegrity { - return fmt.Errorf("--cache-dir must be specified with --cache-enforce-integrity") - } - - if s.cacheDir == "" { - s.cacheDir, err = os.MkdirTemp("", "opm-serve-cache-") - if err != nil { - return err - } - defer os.RemoveAll(s.cacheDir) - } - - store, err := cache.New(s.cacheDir) + store, err := registry.NewQuerierFromFS(os.DirFS(s.configDir), s.cacheDir) + defer store.Close() if err != nil { return err } - if storeCloser, ok := store.(io.Closer); ok { - defer storeCloser.Close() - } - if s.cacheEnforceIntegrity { - if err := store.CheckIntegrity(os.DirFS(s.configDir)); err != nil { - return err - } - if err := store.Load(); err != nil { - return err - } - } else { - if err := cache.LoadOrRebuild(store, os.DirFS(s.configDir)); err != nil { - return err - } - } - if s.cacheOnly { return nil } diff --git a/staging/operator-registry/codegen.Dockerfile b/staging/operator-registry/codegen.Dockerfile index 38bbfb429c..a85ff0ce76 100644 --- a/staging/operator-registry/codegen.Dockerfile +++ b/staging/operator-registry/codegen.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine +FROM golang:1.19-alpine RUN apk update && \ apk add make git protobuf diff --git a/staging/operator-registry/go.mod b/staging/operator-registry/go.mod index c6f9412fe9..b52cd8f46e 100644 --- a/staging/operator-registry/go.mod +++ b/staging/operator-registry/go.mod @@ -1,6 +1,6 @@ module github.com/operator-framework/operator-registry -go 1.18 +go 1.19 require ( github.com/adrg/xdg v0.4.0 @@ -12,18 +12,18 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/golang-migrate/migrate/v4 v4.6.2 github.com/golang/mock v1.5.0 - github.com/google/go-cmp v0.5.6 + github.com/google/go-cmp v0.5.8 github.com/grpc-ecosystem/grpc-health-probe v0.4.11 github.com/h2non/filetype v1.1.1 github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d github.com/mattn/go-sqlite3 v1.14.10 github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 - github.com/onsi/ginkgo/v2 v2.1.3 - github.com/onsi/gomega v1.18.1 + github.com/onsi/ginkgo/v2 v2.1.4 + github.com/onsi/gomega v1.19.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.0.2 - github.com/operator-framework/api v0.15.0 + github.com/operator-framework/api v0.17.2-0.20220915200120-ff2dbc53d381 github.com/otiai10/copy v1.2.0 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/errors v0.9.1 @@ -32,19 +32,19 @@ require ( github.com/stretchr/testify v1.7.0 go.etcd.io/bbolt v1.3.6 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 - golang.org/x/net v0.4.0 + golang.org/x/net v0.0.0-20220722155237-a158d28d115b golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 - golang.org/x/sys v0.3.0 + golang.org/x/sys v0.0.0-20220907062415-87db552b00fd google.golang.org/grpc v1.47.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200709232328-d8193ee9cc3e google.golang.org/protobuf v1.28.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.24.0 - k8s.io/apiextensions-apiserver v0.24.0 - k8s.io/apimachinery v0.24.0 - k8s.io/client-go v0.24.0 - k8s.io/kubectl v0.24.0 - sigs.k8s.io/controller-runtime v0.12.1 + k8s.io/api v0.25.0 + k8s.io/apiextensions-apiserver v0.25.0 + k8s.io/apimachinery v0.25.0 + k8s.io/client-go v0.25.0 + k8s.io/kubectl v0.25.0 + sigs.k8s.io/controller-runtime v0.13.0 sigs.k8s.io/kind v0.11.1 sigs.k8s.io/yaml v1.3.0 ) @@ -52,7 +52,7 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v0.3.1 // indirect - github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Microsoft/go-winio v0.4.17 // indirect github.com/Microsoft/hcsshim v0.8.24 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -61,6 +61,7 @@ require ( github.com/alessio/shellescape v1.4.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect + github.com/benbjohnson/clock v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/bshuster-repo/logrus-logstash-hook v0.4.1 // indirect @@ -76,15 +77,15 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect - github.com/emicklei/go-restful v2.9.5+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.2.0 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect github.com/garyburd/redigo v1.6.0 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.1.0 // indirect github.com/go-git/go-git/v5 v5.3.0 // indirect - github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect @@ -93,7 +94,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.3 // indirect github.com/google/cel-go v0.12.4 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gofuzz v1.1.0 // indirect @@ -108,7 +108,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect - github.com/klauspost/compress v1.12.3 // indirect + github.com/klauspost/compress v1.11.13 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect @@ -124,7 +124,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml v1.9.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect @@ -149,25 +149,24 @@ require ( go.opentelemetry.io/proto/otlp v0.7.0 // indirect golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/tools v0.1.12 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - k8s.io/apiserver v0.24.0 // indirect - k8s.io/component-base v0.24.0 // indirect - k8s.io/klog/v2 v2.60.1 // indirect - k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 // indirect - sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiserver v0.25.0 // indirect + k8s.io/component-base v0.25.0 // indirect + k8s.io/klog/v2 v2.70.1 // indirect + k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect + k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) // latest tag resolves to a very old version. this is only used for spinning up local test registries diff --git a/staging/operator-registry/go.sum b/staging/operator-registry/go.sum index 938204fd83..492f5a6b26 100644 --- a/staging/operator-registry/go.sum +++ b/staging/operator-registry/go.sum @@ -15,11 +15,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -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/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 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= @@ -44,18 +39,11 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 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/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= @@ -64,7 +52,6 @@ github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOp github.com/Microsoft/hcsshim v0.8.24 h1:jP+GMeRXIR1sH1kG4lJr9ShmSjVrua5jmFZDtfYGkn4= github.com/Microsoft/hcsshim v0.8.24/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= @@ -87,7 +74,6 @@ github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVK github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed h1:ue9pVfIcP+QMEjfgo/Ez4ZjNZfonGgR6NgjMaJMu1Cg= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -114,7 +100,6 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= 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.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -131,31 +116,23 @@ github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABF github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= 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= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= 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-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/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= @@ -176,7 +153,6 @@ github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcD 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/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -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/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -202,7 +178,6 @@ github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKX github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -241,48 +216,38 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt 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 h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 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.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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.2.0 h1:8ozOH5xxoMYDt5/u+yMTsVXydVCbTORFnOOoq2lumco= github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +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/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= -github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= 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/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -303,10 +268,10 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V 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 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-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= @@ -338,7 +303,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -369,22 +333,15 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -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.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= github.com/google/cel-go v0.12.4 h1:YINKfuHZ8n72tPOqSPZBwGiDpew2CJS48mdM5W8LZQU= github.com/google/cel-go v0.12.4/go.mod h1:Av7CU6r6X3YmcHR9GXqVDaEJYfEtSxl6wvIjUQTriCw= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -398,8 +355,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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/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/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -407,7 +365,6 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.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/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= @@ -415,14 +372,9 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -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-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= @@ -430,7 +382,6 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= 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= @@ -443,9 +394,7 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= 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/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -480,7 +429,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -499,7 +447,6 @@ github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52Cu github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d h1:A2/B900ip/Z20TzkLeGRNy1s6J2HmH9AmGt+dHyqb4I= github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d/go.mod h1:7HQupe4vyNxMKXmM5DFuwXHsqwMyglcYmZBtlDPIcZ8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= 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= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -521,12 +468,11 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 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/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -539,14 +485,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= 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/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -554,7 +496,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -592,7 +533,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -604,32 +544,22 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -641,10 +571,9 @@ github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= 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/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/api v0.15.0 h1:4f9i0drtqHj7ykLoHxv92GR43S7MmQHhmFQkfm5YaGI= -github.com/operator-framework/api v0.15.0/go.mod h1:scnY9xqSeCsOdtJtNoHIXd7OtHZ14gj1hkDA4+DlgLY= +github.com/operator-framework/api v0.17.2-0.20220915200120-ff2dbc53d381 h1:/XHgTzfI0O/RP3I6WF0BiPLVuVkfgVyiw04b0MyCJ2M= +github.com/operator-framework/api v0.17.2-0.20220915200120-ff2dbc53d381/go.mod h1:wof6IrBhVAufc+ZiQo/BB68fKctXiuSEAMbOO29kZdI= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -657,7 +586,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= 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/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 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -665,11 +593,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.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/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -678,8 +604,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -735,30 +661,23 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= 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/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 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/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= 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= -github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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/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.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spiffe/go-spiffe/v2 v2.0.0 h1:y6N7BZAxgaFZYELyrIdxSMm2e2tWpzgQewUts9h1hfM= github.com/spiffe/go-spiffe/v2 v2.0.0/go.mod h1:TEfgrEcyFhuSuvqohJt6IxENUNeHfndWCCV1EX7UaVk= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= @@ -776,7 +695,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= @@ -784,14 +702,12 @@ github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6e github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= @@ -808,16 +724,6 @@ gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -825,12 +731,10 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= @@ -851,20 +755,14 @@ go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52l go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -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.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -874,13 +772,9 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U 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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 h1:iU7T1X1J6yxDr0rda54sWGkHgOp5XJrqm79gcNlC2VM= golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -905,8 +799,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 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/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= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -915,10 +807,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -955,29 +844,18 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -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-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -985,13 +863,6 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -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/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-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1031,13 +902,10 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/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-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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1053,47 +921,32 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/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-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-20210603081109-ebe580a85c40/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-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= 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= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1102,14 +955,11 @@ 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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 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= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1135,7 +985,6 @@ golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDq golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/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-20191108193012-7d206e10da11/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= @@ -1156,7 +1005,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -1164,23 +1012,13 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -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/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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= -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= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -1202,12 +1040,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -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/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1240,7 +1072,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1251,21 +1082,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1283,16 +1100,10 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= @@ -1327,10 +1138,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy 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.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1350,8 +1158,9 @@ 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-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= @@ -1365,58 +1174,45 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.24.0 h1:J0hann2hfxWr1hinZIDefw7Q96wmCBx6SSB8IY0MdDg= -k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I= -k8s.io/apiextensions-apiserver v0.24.0 h1:JfgFqbA8gKJ/uDT++feAqk9jBIwNnL9YGdQvaI9DLtY= -k8s.io/apiextensions-apiserver v0.24.0/go.mod h1:iuVe4aEpe6827lvO6yWQVxiPSpPoSKVjkq+MIdg84cM= +k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= +k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= +k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= +k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.24.0 h1:ydFCyC/DjCvFCHK5OPMKBlxayQytB8pxy8YQInd5UyQ= -k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apiserver v0.24.0 h1:GR7kGsjOMfilRvlG3Stxv/3uz/ryvJ/aZXc5pqdsNV0= -k8s.io/apiserver v0.24.0/go.mod h1:WFx2yiOMawnogNToVvUYT9nn1jaIkMKj41ZYCVycsBA= -k8s.io/cli-runtime v0.24.0/go.mod h1:9XxoZDsEkRFUThnwqNviqzljtT/LdHtNWvcNFrAXl0A= -k8s.io/client-go v0.24.0 h1:lbE4aB1gTHvYFSwm6eD3OF14NhFDKCejlnsGYlSJe5U= -k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw= -k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/component-base v0.24.0 h1:h5jieHZQoHrY/lHG+HyrSbJeyfuitheBvqvKwKHVC0g= -k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA= -k8s.io/component-helpers v0.24.0/go.mod h1:Q2SlLm4h6g6lPTC9GMMfzdywfLSvJT2f1hOnnjaWD8c= +k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= +k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= +k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= +k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= +k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= +k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= +k8s.io/component-base v0.25.0 h1:haVKlLkPCFZhkcqB6WCvpVxftrg6+FK5x1ZuaIDaQ5Y= +k8s.io/component-base v0.25.0/go.mod h1:F2Sumv9CnbBlqrpdf7rKZTmmd2meJq0HizeyY/yAFxk= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 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.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kubectl v0.24.0 h1:nA+WtMLVdXUs4wLogGd1mPTAesnLdBpCVgCmz3I7dXo= -k8s.io/kubectl v0.24.0/go.mod h1:pdXkmCyHiRTqjYfyUJiXtbVNURhv0/Q1TyRhy2d5ic0= -k8s.io/metrics v0.24.0/go.mod h1:jrLlFGdKl3X+szubOXPG0Lf2aVxuV3QJcbsgVRAM6fI= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/kubectl v0.25.0 h1:/Wn1cFqo8ik3iee1EvpxYre3bkWsGLXzLQI6uCCAkQc= +k8s.io/kubectl v0.25.0/go.mod h1:n16ULWsOl2jmQpzt2o7Dud1t4o0+Y186ICb4O+GwKAU= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 h1:dUk62HQ3ZFhD48Qr8MIXCiKA8wInBQCtuE4QGfFW7yA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= -sigs.k8s.io/controller-runtime v0.12.1 h1:4BJY01xe9zKQti8oRjj/NeHKRXthf1YkYJAgLONFFoI= -sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXez/vp1Y8dxTU0= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.11.1 h1:pVzOkhUwMBrCB0Q/WllQDO3v14Y+o2V0tFgjTqIUjwA= sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= -sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI= -sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= -sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVYCA4BzxeAaLI05Bg= -sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/staging/operator-registry/opm-example.Dockerfile b/staging/operator-registry/opm-example.Dockerfile index a59dfb1af5..3e368fbc03 100644 --- a/staging/operator-registry/opm-example.Dockerfile +++ b/staging/operator-registry/opm-example.Dockerfile @@ -4,10 +4,11 @@ FROM quay.io/operator-framework/opm:latest # Configure the entrypoint and command ENTRYPOINT ["/bin/opm"] -CMD ["serve", "/configs"] +CMD ["serve", "/configs", "--cache-dir=/tmp/cache"] -# Copy declarative config root into image at /configs +# Copy declarative config root into image at /configs and pre-populate serve cache ADD index /configs +RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"] # Set DC-specific label for the location of the DC root directory # in the image diff --git a/staging/operator-registry/pkg/image/containerdregistry/registry.go b/staging/operator-registry/pkg/image/containerdregistry/registry.go index 6519539e5b..a5bacb4fab 100644 --- a/staging/operator-registry/pkg/image/containerdregistry/registry.go +++ b/staging/operator-registry/pkg/image/containerdregistry/registry.go @@ -47,7 +47,7 @@ func (r *Registry) Pull(ctx context.Context, ref image.Reference) error { name, root, err := r.resolver.Resolve(ctx, ref.String()) if err != nil { - return fmt.Errorf("error resolving name %s: %v", name, err) + return fmt.Errorf("error resolving name for image ref %s: %v", ref.String(), err) } r.log.Debugf("resolved name: %s", name) diff --git a/staging/operator-registry/pkg/lib/indexer/interfaces.go b/staging/operator-registry/pkg/lib/indexer/interfaces.go index df9e6e47a2..5ebefdd1e3 100644 --- a/staging/operator-registry/pkg/lib/indexer/interfaces.go +++ b/staging/operator-registry/pkg/lib/indexer/interfaces.go @@ -9,6 +9,7 @@ import ( // IndexAdder allows the creation of index container images from scratch or // based on previous index images +// //counterfeiter:generate . IndexAdder type IndexAdder interface { AddToIndex(AddToIndexRequest) error @@ -29,6 +30,7 @@ func NewIndexAdder(buildTool, pullTool containertools.ContainerTool, logger *log // IndexDeleter takes indexes and deletes all references to an operator // from them +// //counterfeiter:generate . IndexDeleter type IndexDeleter interface { DeleteFromIndex(DeleteFromIndexRequest) error diff --git a/staging/operator-registry/pkg/registry/query.go b/staging/operator-registry/pkg/registry/query.go new file mode 100644 index 0000000000..3da8b16f45 --- /dev/null +++ b/staging/operator-registry/pkg/registry/query.go @@ -0,0 +1,653 @@ +package registry + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "hash/fnv" + "io/fs" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/model" + "github.com/operator-framework/operator-registry/pkg/api" +) + +type Querier struct { + *cache +} + +func (q Querier) Close() error { + return q.cache.close() +} + +type apiBundleKey struct { + pkgName string + chName string + name string +} + +type SliceBundleSender []*api.Bundle + +func (s *SliceBundleSender) Send(b *api.Bundle) error { + + *s = append(*s, b) + return nil +} + +var _ GRPCQuery = &Querier{} + +func NewQuerierFromFS(fbcFS fs.FS, cacheDir string) (*Querier, error) { + q := &Querier{} + var err error + q.cache, err = newCache(cacheDir, &fbcCacheModel{ + FBC: fbcFS, + Cache: os.DirFS(cacheDir), + }) + if err != nil { + return q, err + } + return q, nil +} + +func NewQuerier(m model.Model) (*Querier, error) { + q := &Querier{} + var err error + q.cache, err = newCache("", &nonDigestableModel{Model: m}) + if err != nil { + return q, err + } + return q, nil +} + +func (q Querier) loadAPIBundle(k apiBundleKey) (*api.Bundle, error) { + filename, ok := q.apiBundles[k] + if !ok { + return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", k.pkgName, k.chName, k.name) + } + d, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + var b api.Bundle + if err := json.Unmarshal(d, &b); err != nil { + return nil, err + } + return &b, nil +} + +func (q Querier) ListPackages(_ context.Context) ([]string, error) { + var packages []string + for pkgName := range q.pkgs { + packages = append(packages, pkgName) + } + return packages, nil +} + +func (q Querier) ListBundles(ctx context.Context) ([]*api.Bundle, error) { + var bundleSender SliceBundleSender + + err := q.SendBundles(ctx, &bundleSender) + if err != nil { + return nil, err + } + + return bundleSender, nil +} + +func (q Querier) SendBundles(_ context.Context, s BundleSender) error { + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + if apiBundle.BundlePath != "" { + // The SQLite-based server + // configures its querier to + // omit these fields when + // bundle path is set. + apiBundle.CsvJson = "" + apiBundle.Object = nil + } + if err := s.Send(apiBundle); err != nil { + return err + } + } + } + } + return nil +} + +func (q Querier) GetPackage(_ context.Context, name string) (*PackageManifest, error) { + pkg, ok := q.pkgs[name] + if !ok { + return nil, fmt.Errorf("package %q not found", name) + } + + var channels []PackageChannel + for _, ch := range pkg.Channels { + channels = append(channels, PackageChannel{ + Name: ch.Name, + CurrentCSVName: ch.Head, + }) + } + return &PackageManifest{ + PackageName: pkg.Name, + Channels: channels, + DefaultChannelName: pkg.DefaultChannel, + }, nil +} + +func (q Querier) GetBundle(_ context.Context, pkgName, channelName, csvName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %q not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + b, ok := ch.Bundles[csvName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", pkgName, channelName, csvName) + } + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil +} + +func (q Querier) GetBundleForChannel(_ context.Context, pkgName string, channelName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %q not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, ch.Head}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", ch.Head, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil +} + +func (q Querier) GetChannelEntriesThatReplace(_ context.Context, name string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + entries = append(entries, channelEntriesThatReplace(b, name)...) + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that replace %s", name) + } + return entries, nil +} + +func (q Querier) GetBundleThatReplaces(_ context.Context, name, pkgName, channelName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %s not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + + // NOTE: iterating over a map is non-deterministic in Go, so if multiple bundles replace this one, + // the bundle returned by this function is also non-deterministic. The sqlite implementation + // is ALSO non-deterministic because it doesn't use ORDER BY, so its probably okay for this + // implementation to be non-deterministic as well. + for _, b := range ch.Bundles { + if bundleReplaces(b, name) { + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil + } + } + return nil, fmt.Errorf("no entry found for package %q, channel %q", pkgName, channelName) +} + +func (q Querier) GetChannelEntriesThatProvide(_ context.Context, group, version, kind string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + provides, err := q.doesModelBundleProvide(b, group, version, kind) + if err != nil { + return nil, err + } + if provides { + // TODO(joelanford): It seems like the SQLite query returns + // invalid entries (i.e. where bundle `Replaces` isn't actually + // in channel `ChannelName`). Is that a bug? For now, this mimics + // the sqlite server and returns seemingly invalid channel entries. + // Don't worry about this. Not used anymore. + + entries = append(entries, q.channelEntriesForBundle(b, true)...) + } + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) + } + return entries, nil +} + +// TODO(joelanford): Need to review the expected functionality of this function. I ran +// +// some experiments with the sqlite version of this function and it seems to only return +// channel heads that provide the GVK (rather than searching down the graph if parent bundles +// don't provide the API). Based on that, this function currently looks at channel heads only. +// --- +// Separate, but possibly related, I noticed there are several channels in the channel entry +// table who's minimum depth is 1. What causes 1 to be minimum depth in some cases and 0 in others? +func (q Querier) GetLatestChannelEntriesThatProvide(_ context.Context, group, version, kind string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + b := ch.Bundles[ch.Head] + provides, err := q.doesModelBundleProvide(b, group, version, kind) + if err != nil { + return nil, err + } + if provides { + entries = append(entries, q.channelEntriesForBundle(b, false)...) + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) + } + return entries, nil +} + +func (q Querier) GetBundleThatProvides(ctx context.Context, group, version, kind string) (*api.Bundle, error) { + latestEntries, err := q.GetLatestChannelEntriesThatProvide(ctx, group, version, kind) + if err != nil { + return nil, err + } + + // It's possible for multiple packages to provide an API, but this function is forced to choose one. + // To do that deterministically, we'll pick the the bundle based on a lexicographical sort of its + // package name. + sort.Slice(latestEntries, func(i, j int) bool { + return latestEntries[i].PackageName < latestEntries[j].PackageName + }) + + for _, entry := range latestEntries { + pkg, ok := q.pkgs[entry.PackageName] + if !ok { + // This should never happen because the latest entries were + // collected based on iterating over the packages in q.pkgs. + continue + } + if entry.ChannelName == pkg.DefaultChannel { + return q.GetBundle(ctx, entry.PackageName, entry.ChannelName, entry.BundleName) + } + } + return nil, fmt.Errorf("no entry found that provides group:%q version:%q kind:%q", group, version, kind) +} + +func (q Querier) doesModelBundleProvide(b cBundle, group, version, kind string) (bool, error) { + apiBundle, err := q.loadAPIBundle(apiBundleKey{b.Package, b.Channel, b.Name}) + if err != nil { + return false, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + for _, gvk := range apiBundle.ProvidedApis { + if gvk.Group == group && gvk.Version == version && gvk.Kind == kind { + return true, nil + } + } + return false, nil +} + +func bundleReplaces(b cBundle, name string) bool { + if b.Replaces == name { + return true + } + for _, s := range b.Skips { + if s == name { + return true + } + } + return false +} + +func channelEntriesThatReplace(b cBundle, name string) []*ChannelEntry { + var entries []*ChannelEntry + if b.Replaces == name { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }) + } + for _, s := range b.Skips { + if s == name && s != b.Replaces { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }) + } + } + return entries +} + +func (q Querier) channelEntriesForBundle(b cBundle, ignoreChannel bool) []*ChannelEntry { + entries := []*ChannelEntry{{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }} + for _, s := range b.Skips { + // Ignore skips that duplicate b.Replaces. Also, only add it if its + // in the same channel as b (or we're ignoring channel presence). + if _, inChannel := q.pkgs[b.Package].Channels[b.Channel].Bundles[s]; s != b.Replaces && (ignoreChannel || inChannel) { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: s, + }) + } + } + return entries +} + +type cache struct { + digest string + baseDir string + persist bool + pkgs map[string]cPkg + apiBundles map[apiBundleKey]string +} + +func newCache(baseDir string, model digestableModel) (*cache, error) { + var ( + qc *cache + err error + ) + if baseDir == "" { + qc, err = newEphemeralCache() + } else { + qc, err = newPersistentCache(baseDir) + } + if err != nil { + return nil, err + } + return qc, qc.load(model) +} + +func (qc cache) close() error { + if qc.persist { + return nil + } + return os.RemoveAll(qc.baseDir) +} + +func newEphemeralCache() (*cache, error) { + baseDir, err := os.MkdirTemp("", "opm-serve-cache-") + if err != nil { + return nil, err + } + if err := os.MkdirAll(filepath.Join(baseDir, "cache"), 0700); err != nil { + return nil, err + } + return &cache{ + digest: "", + baseDir: baseDir, + persist: false, + }, nil +} + +func newPersistentCache(baseDir string) (*cache, error) { + if err := os.MkdirAll(baseDir, 0700); err != nil { + return nil, err + } + qc := &cache{baseDir: baseDir, persist: true} + if digest, err := os.ReadFile(filepath.Join(baseDir, "digest")); err == nil { + qc.digest = strings.TrimSpace(string(digest)) + } + return qc, nil +} + +func (qc *cache) load(model digestableModel) error { + computedDigest, err := model.GetDigest() + if err != nil && !errors.Is(err, errNonDigestable) { + return fmt.Errorf("compute digest: %v", err) + } + if err == nil && computedDigest == qc.digest { + err = qc.loadFromCache() + if err == nil { + return nil + } + // if there _was_ an error loading from the cache, + // we'll drop down and repopulate from scratch. + } + return qc.repopulateCache(model) +} + +func (qc *cache) loadFromCache() error { + packagesData, err := os.ReadFile(filepath.Join(qc.baseDir, "cache", "packages.json")) + if err != nil { + return err + } + if err := json.Unmarshal(packagesData, &qc.pkgs); err != nil { + return err + } + qc.apiBundles = map[apiBundleKey]string{} + for _, p := range qc.pkgs { + for _, ch := range p.Channels { + for _, b := range ch.Bundles { + filename := filepath.Join(qc.baseDir, "cache", fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) + qc.apiBundles[apiBundleKey{pkgName: p.Name, chName: ch.Name, name: b.Name}] = filename + } + } + } + return nil +} + +func (qc *cache) repopulateCache(model digestableModel) error { + m, err := model.GetModel() + if err != nil { + return err + } + cacheDirEntries, err := os.ReadDir(qc.baseDir) + if err != nil { + return err + } + for _, e := range cacheDirEntries { + if err := os.RemoveAll(filepath.Join(qc.baseDir, e.Name())); err != nil { + return err + } + } + if err := os.MkdirAll(filepath.Join(qc.baseDir, "cache"), 0700); err != nil { + return err + } + + qc.pkgs, err = packagesFromModel(m) + if err != nil { + return err + } + + packageJson, err := json.Marshal(qc.pkgs) + if err != nil { + return err + } + if err := os.WriteFile(filepath.Join(qc.baseDir, "cache", "packages.json"), packageJson, 0600); err != nil { + return err + } + + qc.apiBundles = map[apiBundleKey]string{} + for _, p := range m { + for _, ch := range p.Channels { + for _, b := range ch.Bundles { + apiBundle, err := api.ConvertModelBundleToAPIBundle(*b) + if err != nil { + return err + } + jsonBundle, err := json.Marshal(apiBundle) + if err != nil { + return err + } + filename := filepath.Join(qc.baseDir, "cache", fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) + if err := os.WriteFile(filename, jsonBundle, 0666); err != nil { + return err + } + qc.apiBundles[apiBundleKey{p.Name, ch.Name, b.Name}] = filename + } + } + } + computedHash, err := model.GetDigest() + if err == nil { + if err := os.WriteFile(filepath.Join(qc.baseDir, "digest"), []byte(computedHash), 0600); err != nil { + return err + } + } else if !errors.Is(err, errNonDigestable) { + return fmt.Errorf("compute digest: %v", err) + } + return nil +} + +func packagesFromModel(m model.Model) (map[string]cPkg, error) { + pkgs := map[string]cPkg{} + for _, p := range m { + newP := cPkg{ + Name: p.Name, + Description: p.Description, + DefaultChannel: p.DefaultChannel.Name, + Channels: map[string]cChannel{}, + } + if p.Icon != nil { + newP.Icon = &declcfg.Icon{ + Data: p.Icon.Data, + MediaType: p.Icon.MediaType, + } + } + for _, ch := range p.Channels { + head, err := ch.Head() + if err != nil { + return nil, err + } + newCh := cChannel{ + Name: ch.Name, + Head: head.Name, + Bundles: map[string]cBundle{}, + } + for _, b := range ch.Bundles { + newB := cBundle{ + Package: b.Package.Name, + Channel: b.Channel.Name, + Name: b.Name, + Replaces: b.Replaces, + Skips: b.Skips, + } + newCh.Bundles[b.Name] = newB + } + newP.Channels[ch.Name] = newCh + } + pkgs[p.Name] = newP + } + return pkgs, nil +} + +type cPkg struct { + Name string `json:"name"` + Description string `json:"description"` + Icon *declcfg.Icon `json:"icon"` + DefaultChannel string `json:"defaultChannel"` + Channels map[string]cChannel +} + +type cChannel struct { + Name string + Head string + Bundles map[string]cBundle +} + +type cBundle struct { + Package string `json:"package"` + Channel string `json:"channel"` + Name string `json:"name"` + Replaces string `json:"replaces"` + Skips []string `json:"skips"` +} + +type digestableModel interface { + GetModel() (model.Model, error) + GetDigest() (string, error) +} + +type fbcCacheModel struct { + FBC fs.FS + Cache fs.FS +} + +func (m *fbcCacheModel) GetModel() (model.Model, error) { + fbc, err := declcfg.LoadFS(m.FBC) + if err != nil { + return nil, err + } + return declcfg.ConvertToModel(*fbc) +} + +func (m *fbcCacheModel) GetDigest() (string, error) { + computedHasher := fnv.New64a() + if err := fsToTar(computedHasher, m.FBC); err != nil { + return "", err + } + if cacheFS, err := fs.Sub(m.Cache, "cache"); err == nil { + if err := fsToTar(computedHasher, cacheFS); err != nil && !errors.Is(err, os.ErrNotExist) { + return "", fmt.Errorf("compute hash: %v", err) + } + } + return fmt.Sprintf("%x", computedHasher.Sum(nil)), nil +} + +var errNonDigestable = errors.New("cannot generate digest") + +type nonDigestableModel struct { + model.Model +} + +func (m *nonDigestableModel) GetModel() (model.Model, error) { + return m.Model, nil +} + +func (m *nonDigestableModel) GetDigest() (string, error) { + return "", errNonDigestable +} diff --git a/staging/operator-registry/pkg/registry/tar.go b/staging/operator-registry/pkg/registry/tar.go new file mode 100644 index 0000000000..f62a15da85 --- /dev/null +++ b/staging/operator-registry/pkg/registry/tar.go @@ -0,0 +1,66 @@ +package registry + +import ( + "archive/tar" + "fmt" + "io" + "io/fs" + "os" + "time" +) + +// fsToTar writes the filesystem represented by fsys to w as a tar archive. +// This function unsets user and group information in the tar archive so that readers +// of archives produced by this function do not need to account for differences in +// permissions between source and destination filesystems. +func fsToTar(w io.Writer, fsys fs.FS) error { + tw := tar.NewWriter(w) + if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.Type()&os.ModeSymlink != 0 { + return nil + } + info, err := d.Info() + if err != nil { + return fmt.Errorf("get file info for %q: %v", path, err) + } + + h, err := tar.FileInfoHeader(info, "") + if err != nil { + return fmt.Errorf("build tar file info header for %q: %v", path, err) + } + h.Uid = 0 + h.Gid = 0 + h.Uname = "" + h.Gname = "" + h.AccessTime = time.Time{} + h.ChangeTime = time.Time{} + h.ModTime = time.Time{} + h.Name = path + + if err := tw.WriteHeader(h); err != nil { + return fmt.Errorf("write tar header for %q: %v", path, err) + } + if d.IsDir() { + return nil + } + f, err := fsys.Open(path) + if err != nil { + return fmt.Errorf("open file %q: %v", path, err) + } + defer f.Close() + if _, err := io.Copy(tw, f); err != nil { + return fmt.Errorf("write tar data for %q: %v", path, err) + } + return nil + }); err != nil { + return fmt.Errorf("write tar: %w", err) + } + if err := tw.Close(); err != nil { + return err + } + return nil +} diff --git a/staging/operator-registry/registry.Dockerfile b/staging/operator-registry/registry.Dockerfile index e87459c1af..f87672614b 100644 --- a/staging/operator-registry/registry.Dockerfile +++ b/staging/operator-registry/registry.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine as builder +FROM golang:1.19-alpine as builder RUN apk update && apk add sqlite build-base git mercurial bash WORKDIR /build diff --git a/staging/operator-registry/upstream-builder.Dockerfile b/staging/operator-registry/upstream-builder.Dockerfile index 20fc9b9d50..687ab3520c 100644 --- a/staging/operator-registry/upstream-builder.Dockerfile +++ b/staging/operator-registry/upstream-builder.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18-alpine as builder +FROM golang:1.19-alpine as builder RUN apk update && apk add sqlite build-base git mercurial bash WORKDIR /build diff --git a/staging/operator-registry/upstream-opm-builder.Dockerfile b/staging/operator-registry/upstream-opm-builder.Dockerfile index 9951433bdd..9d7ad9b4fe 100644 --- a/staging/operator-registry/upstream-opm-builder.Dockerfile +++ b/staging/operator-registry/upstream-opm-builder.Dockerfile @@ -3,7 +3,7 @@ ## GoReleaser to build and push multi-arch images for opm ## -FROM golang:1.18-alpine AS builder +FROM golang:1.19-alpine AS builder RUN apk update && apk add ca-certificates COPY ["nsswitch.conf", "/etc/nsswitch.conf"] diff --git a/vendor/cloud.google.com/go/LICENSE b/vendor/cloud.google.com/go/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/vendor/cloud.google.com/go/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - 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/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go deleted file mode 100644 index 5dbe77cc79..0000000000 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ /dev/null @@ -1,536 +0,0 @@ -// Copyright 2014 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 provides access to Google Compute Engine (GCE) -// metadata and API service accounts. -// -// This package is a wrapper around the GCE metadata service, -// as documented at https://developers.google.com/compute/docs/metadata. -package metadata // import "cloud.google.com/go/compute/metadata" - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "runtime" - "strings" - "sync" - "time" -) - -const ( - // metadataIP is the documented metadata server IP address. - metadataIP = "169.254.169.254" - - // metadataHostEnv is the environment variable specifying the - // GCE metadata hostname. If empty, the default value of - // metadataIP ("169.254.169.254") is used instead. - // This is variable name is not defined by any spec, as far as - // I know; it was made up for the Go package. - metadataHostEnv = "GCE_METADATA_HOST" - - userAgent = "gcloud-golang/0.1" -) - -type cachedValue struct { - k string - trim bool - mu sync.Mutex - v string -} - -var ( - projID = &cachedValue{k: "project/project-id", trim: true} - projNum = &cachedValue{k: "project/numeric-project-id", trim: true} - instID = &cachedValue{k: "instance/id", trim: true} -) - -var defaultClient = &Client{hc: &http.Client{ - Transport: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 2 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - }, -}} - -// NotDefinedError is returned when requested metadata is not defined. -// -// The underlying string is the suffix after "/computeMetadata/v1/". -// -// This error is not returned if the value is defined to be the empty -// string. -type NotDefinedError string - -func (suffix NotDefinedError) Error() string { - return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) -} - -func (c *cachedValue) get(cl *Client) (v string, err error) { - defer c.mu.Unlock() - c.mu.Lock() - if c.v != "" { - return c.v, nil - } - if c.trim { - v, err = cl.getTrimmed(c.k) - } else { - v, err = cl.Get(c.k) - } - if err == nil { - c.v = v - } - return -} - -var ( - onGCEOnce sync.Once - onGCE bool -) - -// OnGCE reports whether this process is running on Google Compute Engine. -func OnGCE() bool { - onGCEOnce.Do(initOnGCE) - return onGCE -} - -func initOnGCE() { - onGCE = testOnGCE() -} - -func testOnGCE() bool { - // The user explicitly said they're on GCE, so trust them. - if os.Getenv(metadataHostEnv) != "" { - return true - } - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - resc := make(chan bool, 2) - - // Try two strategies in parallel. - // See https://github.com/googleapis/google-cloud-go/issues/194 - go func() { - req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) - req.Header.Set("User-Agent", userAgent) - res, err := defaultClient.hc.Do(req.WithContext(ctx)) - if err != nil { - resc <- false - return - } - defer res.Body.Close() - resc <- res.Header.Get("Metadata-Flavor") == "Google" - }() - - go func() { - addrs, err := net.DefaultResolver.LookupHost(ctx, "metadata.google.internal") - if err != nil || len(addrs) == 0 { - resc <- false - return - } - resc <- strsContains(addrs, metadataIP) - }() - - tryHarder := systemInfoSuggestsGCE() - if tryHarder { - res := <-resc - if res { - // The first strategy succeeded, so let's use it. - return true - } - // Wait for either the DNS or metadata server probe to - // contradict the other one and say we are running on - // GCE. Give it a lot of time to do so, since the system - // info already suggests we're running on a GCE BIOS. - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case res = <-resc: - return res - case <-timer.C: - // Too slow. Who knows what this system is. - return false - } - } - - // There's no hint from the system info that we're running on - // GCE, so use the first probe's result as truth, whether it's - // true or false. The goal here is to optimize for speed for - // users who are NOT running on GCE. We can't assume that - // either a DNS lookup or an HTTP request to a blackholed IP - // address is fast. Worst case this should return when the - // metaClient's Transport.ResponseHeaderTimeout or - // Transport.Dial.Timeout fires (in two seconds). - return <-resc -} - -// systemInfoSuggestsGCE reports whether the local system (without -// doing network requests) suggests that we're running on GCE. If this -// returns true, testOnGCE tries a bit harder to reach its metadata -// server. -func systemInfoSuggestsGCE() bool { - if runtime.GOOS != "linux" { - // We don't have any non-Linux clues available, at least yet. - return false - } - slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name") - name := strings.TrimSpace(string(slurp)) - return name == "Google" || name == "Google Compute Engine" -} - -// Subscribe calls Client.Subscribe on the default client. -func Subscribe(suffix string, fn func(v string, ok bool) error) error { - return defaultClient.Subscribe(suffix, fn) -} - -// Get calls Client.Get on the default client. -func Get(suffix string) (string, error) { return defaultClient.Get(suffix) } - -// ProjectID returns the current instance's project ID string. -func ProjectID() (string, error) { return defaultClient.ProjectID() } - -// NumericProjectID returns the current instance's numeric project ID. -func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() } - -// InternalIP returns the instance's primary internal IP address. -func InternalIP() (string, error) { return defaultClient.InternalIP() } - -// ExternalIP returns the instance's primary external (public) IP address. -func ExternalIP() (string, error) { return defaultClient.ExternalIP() } - -// Email calls Client.Email on the default client. -func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) } - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -func Hostname() (string, error) { return defaultClient.Hostname() } - -// InstanceTags returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() } - -// InstanceID returns the current VM's numeric instance ID. -func InstanceID() (string, error) { return defaultClient.InstanceID() } - -// InstanceName returns the current VM's instance ID string. -func InstanceName() (string, error) { return defaultClient.InstanceName() } - -// Zone returns the current VM's zone, such as "us-central1-b". -func Zone() (string, error) { return defaultClient.Zone() } - -// InstanceAttributes calls Client.InstanceAttributes on the default client. -func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() } - -// ProjectAttributes calls Client.ProjectAttributes on the default client. -func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() } - -// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client. -func InstanceAttributeValue(attr string) (string, error) { - return defaultClient.InstanceAttributeValue(attr) -} - -// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client. -func ProjectAttributeValue(attr string) (string, error) { - return defaultClient.ProjectAttributeValue(attr) -} - -// Scopes calls Client.Scopes on the default client. -func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) } - -func strsContains(ss []string, s string) bool { - for _, v := range ss { - if v == s { - return true - } - } - return false -} - -// A Client provides metadata. -type Client struct { - hc *http.Client -} - -// NewClient returns a Client that can be used to fetch metadata. -// Returns the client that uses the specified http.Client for HTTP requests. -// If nil is specified, returns the default client. -func NewClient(c *http.Client) *Client { - if c == nil { - return defaultClient - } - - return &Client{hc: c} -} - -// 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 - // variable GCE_METADATA_HOST is first inspected to decide where metadata - // requests shall go. - host := os.Getenv(metadataHostEnv) - if host == "" { - // Using 169.254.169.254 instead of "metadata" here because Go - // binaries built with the "netgo" tag and without cgo won't - // know the search suffix for "metadata" is - // ".google.internal", and this IP address is documented as - // being stable anyway. - host = metadataIP - } - suffix = strings.TrimLeft(suffix, "/") - u := "http://" + host + "/computeMetadata/v1/" + suffix - req, err := http.NewRequest("GET", u, nil) - if err != nil { - return "", "", err - } - req.Header.Set("Metadata-Flavor", "Google") - req.Header.Set("User-Agent", userAgent) - 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 "", "", reqErr - } - defer res.Body.Close() - if res.StatusCode == http.StatusNotFound { - return "", "", NotDefinedError(suffix) - } - all, err := ioutil.ReadAll(res.Body) - if err != nil { - return "", "", err - } - if res.StatusCode != 200 { - return "", "", &Error{Code: res.StatusCode, Message: string(all)} - } - return string(all), res.Header.Get("Etag"), nil -} - -// Get returns a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// -// If the GCE_METADATA_HOST environment variable is not defined, a default of -// 169.254.169.254 will be used instead. -// -// If the requested metadata is not defined, the returned error will -// be of type NotDefinedError. -func (c *Client) Get(suffix string) (string, error) { - val, _, err := c.getETag(suffix) - return val, err -} - -func (c *Client) getTrimmed(suffix string) (s string, err error) { - s, err = c.Get(suffix) - s = strings.TrimSpace(s) - return -} - -func (c *Client) lines(suffix string) ([]string, error) { - j, err := c.Get(suffix) - if err != nil { - return nil, err - } - s := strings.Split(strings.TrimSpace(j), "\n") - for i := range s { - s[i] = strings.TrimSpace(s[i]) - } - return s, nil -} - -// ProjectID returns the current instance's project ID string. -func (c *Client) ProjectID() (string, error) { return projID.get(c) } - -// NumericProjectID returns the current instance's numeric project ID. -func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) } - -// InstanceID returns the current VM's numeric instance ID. -func (c *Client) InstanceID() (string, error) { return instID.get(c) } - -// InternalIP returns the instance's primary internal IP address. -func (c *Client) InternalIP() (string, error) { - return c.getTrimmed("instance/network-interfaces/0/ip") -} - -// Email returns the email address associated with the service account. -// The account may be empty or the string "default" to use the instance's -// main account. -func (c *Client) Email(serviceAccount string) (string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email") -} - -// ExternalIP returns the instance's primary external (public) IP address. -func (c *Client) ExternalIP() (string, error) { - return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") -} - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -func (c *Client) Hostname() (string, error) { - return c.getTrimmed("instance/hostname") -} - -// InstanceTags returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func (c *Client) InstanceTags() ([]string, error) { - var s []string - j, err := c.Get("instance/tags") - if err != nil { - return nil, err - } - if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { - return nil, err - } - return s, nil -} - -// InstanceName returns the current VM's instance ID string. -func (c *Client) InstanceName() (string, error) { - return c.getTrimmed("instance/name") -} - -// Zone returns the current VM's zone, such as "us-central1-b". -func (c *Client) Zone() (string, error) { - zone, err := c.getTrimmed("instance/zone") - // zone is of the form "projects//zones/". - if err != nil { - return "", err - } - return zone[strings.LastIndex(zone, "/")+1:], nil -} - -// InstanceAttributes returns the list of user-defined attributes, -// assigned when initially creating a GCE VM instance. The value of an -// attribute can be obtained with InstanceAttributeValue. -func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") } - -// ProjectAttributes returns the list of user-defined attributes -// applying to the project as a whole, not just this VM. The value of -// an attribute can be obtained with ProjectAttributeValue. -func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") } - -// InstanceAttributeValue returns the value of the provided VM -// instance attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// InstanceAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func (c *Client) InstanceAttributeValue(attr string) (string, error) { - return c.Get("instance/attributes/" + attr) -} - -// ProjectAttributeValue returns the value of the provided -// project attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// ProjectAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func (c *Client) ProjectAttributeValue(attr string) (string, error) { - return c.Get("project/attributes/" + attr) -} - -// Scopes returns the service account scopes for the given account. -// The account may be empty or the string "default" to use the instance's -// main account. -func (c *Client) Scopes(serviceAccount string) ([]string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return c.lines("instance/service-accounts/" + serviceAccount + "/scopes") -} - -// Subscribe subscribes to a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// The suffix may contain query parameters. -// -// Subscribe calls fn with the latest metadata value indicated by the provided -// suffix. If the metadata value is deleted, fn is called with the empty string -// and ok false. Subscribe blocks until fn returns a non-nil error or the value -// is deleted. Subscribe returns the error value returned from the last call to -// fn, which may be nil when ok == false. -func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { - const failedSubscribeSleep = time.Second * 5 - - // First check to see if the metadata value exists at all. - val, lastETag, err := c.getETag(suffix) - if err != nil { - return err - } - - if err := fn(val, true); err != nil { - return err - } - - ok := true - if strings.ContainsRune(suffix, '?') { - suffix += "&wait_for_change=true&last_etag=" - } else { - suffix += "?wait_for_change=true&last_etag=" - } - for { - val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag)) - if err != nil { - if _, deleted := err.(NotDefinedError); !deleted { - time.Sleep(failedSubscribeSleep) - continue // Retry on other errors. - } - ok = false - } - lastETag = etag - - if err := fn(val, ok); err != nil || !ok { - return err - } - } -} - -// Error contains an error response from the server. -type Error struct { - // Code is the HTTP response status code. - Code int - // Message is the server response message. - Message string -} - -func (e *Error) Error() string { - return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) -} diff --git a/vendor/cloud.google.com/go/compute/metadata/retry.go b/vendor/cloud.google.com/go/compute/metadata/retry.go deleted file mode 100644 index 0f18f3cda1..0000000000 --- a/vendor/cloud.google.com/go/compute/metadata/retry.go +++ /dev/null @@ -1,114 +0,0 @@ -// 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 deleted file mode 100644 index bb412f8917..0000000000 --- a/vendor/cloud.google.com/go/compute/metadata/retry_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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/Azure/go-autorest/.gitignore b/vendor/github.com/Azure/go-autorest/.gitignore deleted file mode 100644 index 3350aaf706..0000000000 --- a/vendor/github.com/Azure/go-autorest/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# The standard Go .gitignore file follows. (Sourced from: github.com/github/gitignore/master/Go.gitignore) -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -.DS_Store -.idea/ -.vscode/ - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -# go-autorest specific -vendor/ -autorest/azure/example/example diff --git a/vendor/github.com/Azure/go-autorest/CHANGELOG.md b/vendor/github.com/Azure/go-autorest/CHANGELOG.md deleted file mode 100644 index d1f596bfc9..0000000000 --- a/vendor/github.com/Azure/go-autorest/CHANGELOG.md +++ /dev/null @@ -1,1004 +0,0 @@ -# CHANGELOG - -## v14.2.0 - -- Added package comment to make `github.com/Azure/go-autorest` importable. - -## v14.1.1 - -### Bug Fixes - -- Change `x-ms-authorization-auxiliary` header value separator to comma. - -## v14.1.0 - -### New Features - -- Added `azure.SetEnvironment()` that will update the global environments map with the specified values. - -## v14.0.1 - -### Bug Fixes - -- Fix race condition when refreshing token. -- Fixed some tests to work with Go 1.14. - -## v14.0.0 - -## Breaking Changes - -- By default, the `DoRetryForStatusCodes` functions will no longer infinitely retry a request when the response returns an HTTP status code of 429 (StatusTooManyRequests). To opt in to the old behavior set `autorest.Count429AsRetry` to `false`. - -## New Features - -- Variable `autorest.Max429Delay` can be used to control the maximum delay between retries when a 429 is received with no `Retry-After` header. The default is zero which means there is no cap. - -## v13.4.0 - -## New Features - -- Added field `SendDecorators` to the `Client` type. This can be used to specify a custom chain of SendDecorators per client. -- Added method `Client.Send()` which includes logic for selecting the preferred chain of SendDecorators. - -## v13.3.3 - -### Bug Fixes - -- Fixed connection leak when retrying requests. -- Enabled exponential back-off with a 2-minute cap when retrying on 429. -- Fixed some cases where errors were inadvertently dropped. - -## v13.3.2 - -### Bug Fixes - -- Updated `autorest.AsStringSlice()` to convert slice elements to their string representation. - -## v13.3.1 - -- Updated external dependencies. - -### Bug Fixes - -## v13.3.0 - -### New Features - -- Added support for shared key and shared access signature token authorization. - - `autorest.NewSharedKeyAuthorizer()` and dependent types. - - `autorest.NewSASTokenAuthorizer()` and dependent types. -- Added `ServicePrincipalToken.SetCustomRefresh()` so a custom refresh function can be invoked when a token has expired. - -### Bug Fixes - -- Fixed `cli.AccessTokensPath()` to respect `AZURE_CONFIG_DIR` when set. -- Support parsing error messages in XML responses. - -## v13.2.0 - -### New Features - -- Added the following functions to replace their versions that don't take a context. - - `adal.InitiateDeviceAuthWithContext()` - - `adal.CheckForUserCompletionWithContext()` - - `adal.WaitForUserCompletionWithContext()` - -## v13.1.0 - -### New Features - -- Added support for MSI authentication on Azure App Service and Azure Functions. - -## v13.0.2 - -### Bug Fixes - -- Always retry a request even if the sender returns a non-nil error. - -## v13.0.1 - -## Bug Fixes - -- Fixed `autorest.WithQueryParameters()` so that it properly encodes multi-value query parameters. - -## v13.0.0 - -## Breaking Changes - -The `tracing` package has been rewritten to provide a common interface for consumers to wire in the tracing package of their choice. -What this means is that by default no tracing provider will be compiled into your program and setting the `AZURE_SDK_TRACING_ENABLED` -environment variable will have no effect. To enable this previous behavior you must now add the following import to your source file. -```go - import _ "github.com/Azure/go-autorest/tracing/opencensus" -``` -The APIs required by autorest-generated code have remained but some APIs have been removed and new ones added. -The following APIs and variables have been removed (the majority of them were moved to the `opencensus` package). -- tracing.Transport -- tracing.Enable() -- tracing.EnableWithAIForwarding() -- tracing.Disable() - -The following APIs and types have been added -- tracing.Tracer -- tracing.Register() - -To hook up a tracer simply call `tracing.Register()` passing in a type that satisfies the `tracing.Tracer` interface. - -## v12.4.3 - -### Bug Fixes - -- `autorest.MultiTenantServicePrincipalTokenAuthorizer` will now properly add its auxiliary bearer tokens. - -## v12.4.2 - -### Bug Fixes - -- Improvements to the fixes made in v12.4.1. - - Remove `override` stanza from Gopkg.toml and `replace` directive from go.mod as they don't apply when being consumed as a dependency. - - Switched to latest version of `ocagent` that still depends on protobuf v1.2. - - Add indirect dependencies to the `required` clause with matching `constraint` stanzas so that `dep` dependencies match go.sum. - -## v12.4.1 - -### Bug Fixes - -- Updated OpenCensus and OCAgent versions to versions that don't depend on v1.3+ of protobuf as it was breaking kubernetes. -- Pinned opencensus-proto to a version that's compatible with our versions of OpenCensus and OCAgent. - -## v12.4.0 - -### New Features - -- Added `autorest.WithPrepareDecorators` and `autorest.GetPrepareDecorators` for adding and retrieving a custom chain of PrepareDecorators to the provided context. - -## v12.3.0 - -### New Features - -- Support for multi-tenant via x-ms-authorization-auxiliary header has been added for client credentials with - secret scenario; this basically bundles multiple OAuthConfig and ServicePrincipalToken types into corresponding - MultiTenant* types along with a new authorizer that adds the primary and auxiliary token headers to the reqest. - The authenticaion helpers have been updated to support this scenario; if environment var AZURE_AUXILIARY_TENANT_IDS - is set with a semicolon delimited list of tenants the multi-tenant codepath will kick in to create the appropriate authorizer. - See `adal.NewMultiTenantOAuthConfig`, `adal.NewMultiTenantServicePrincipalToken` and `autorest.NewMultiTenantServicePrincipalTokenAuthorizer` - along with their supporting types and methods. -- Added `autorest.WithSendDecorators` and `autorest.GetSendDecorators` for adding and retrieving a custom chain of SendDecorators to the provided context. -- Added `autorest.DoRetryForStatusCodesWithCap` and `autorest.DelayForBackoffWithCap` to enforce an upper bound on the duration between retries. - -## v12.2.0 - -### New Features - -- Added `autorest.WithXML`, `autorest.AsMerge`, `autorest.WithBytes` preparer decorators. -- Added `autorest.ByUnmarshallingBytes` response decorator. -- Added `Response.IsHTTPStatus` and `Response.HasHTTPStatus` helper methods for inspecting HTTP status code in `autorest.Response` types. - -### Bug Fixes - -- `autorest.DelayWithRetryAfter` now supports HTTP-Dates in the `Retry-After` header and is not limited to just 429 status codes. - -## v12.1.0 - -### New Features - -- Added `to.ByteSlicePtr()`. -- Added blob/queue storage resource ID to `azure.ResourceIdentifier`. - -## v12.0.0 - -### Breaking Changes - -In preparation for modules the following deprecated content has been removed. - - - async.NewFuture() - - async.Future.Done() - - async.Future.WaitForCompletion() - - async.DoPollForAsynchronous() - - The `utils` package - - validation.NewErrorWithValidationError() - - The `version` package - -## v11.9.0 - -### New Features - -- Add `ResourceIdentifiers` field to `azure.Environment` containing resource IDs for public and sovereign clouds. - -## v11.8.0 - -### New Features - -- Added `autorest.NewClientWithOptions()` to support endpoints that require free renegotiation. - -## v11.7.1 - -### Bug Fixes - -- Fix missing support for http(s) proxy when using the default sender. - -## v11.7.0 - -### New Features - -- Added methods to obtain a ServicePrincipalToken on the various credential configuration types in the `auth` package. - -## v11.6.1 - -### Bug Fixes - -- Fix ACR DNS endpoint for government clouds. -- Add Cosmos DB DNS endpoints. -- Update dependencies to resolve build breaks in OpenCensus. - -## v11.6.0 - -### New Features - -- Added type `autorest.BasicAuthorizer` to support Basic authentication. - -## v11.5.2 - -### Bug Fixes - -- Fixed `GetTokenFromCLI` did not work with zsh. - -## v11.5.1 - -### Bug Fixes - -- In `Client.sender()` set the minimum TLS version on HTTP clients to 1.2. - -## v11.5.0 - -### New Features - -- The `auth` package has been refactored so that the environment and file settings are now available. -- The methods used in `auth.NewAuthorizerFromEnvironment()` are now exported so that custom authorization chains can be created. -- Added support for certificate authorization for file-based config. - -## v11.4.0 - -### New Features - -- Added `adal.AddToUserAgent()` so callers can append custom data to the user-agent header used for ADAL requests. -- Exported `adal.UserAgent()` for parity with `autorest.Client`. - -## v11.3.2 - -### Bug Fixes - -- In `Future.WaitForCompletionRef()` if the provided context has a deadline don't add the default deadline. - -## v11.3.1 - -### Bug Fixes - -- For an LRO PUT operation the final GET URL was incorrectly set to the Location polling header in some cases. - -## v11.3.0 - -### New Features - -- Added method `ServicePrincipalToken()` to `DeviceFlowConfig` type. - -## v11.2.8 - -### Bug Fixes - -- Deprecate content in the `version` package. The functionality has been superseded by content in the `autorest` package. - -## v11.2.7 - -### Bug Fixes - -- Fix environment variable name for enabling tracing from `AZURE_SDK_TRACING_ENABELD` to `AZURE_SDK_TRACING_ENABLED`. - Note that for backward compatibility reasons, both will work until the next major version release of the package. - -## v11.2.6 - -### Bug Fixes - -- If zero bytes are read from a polling response body don't attempt to unmarshal them. - -## v11.2.5 - -### Bug Fixes - -- Removed race condition in `autorest.DoRetryForStatusCodes`. - -## v11.2.4 - -### Bug Fixes - -- Function `cli.ProfilePath` now respects environment `AZURE_CONFIG_DIR` if available. - -## v11.2.1 - -NOTE: Versions of Go prior to 1.10 have been removed from CI as they no -longer work with golint. - -### Bug Fixes - -- Method `MSIConfig.Authorizer` now supports user-assigned identities. -- The adal package now reports its own user-agent string. - -## v11.2.0 - -### New Features - -- Added `tracing` package that enables instrumentation of HTTP and API calls. - Setting the env variable `AZURE_SDK_TRACING_ENABLED` or calling `tracing.Enable` - will start instrumenting the code for metrics and traces. - Additionally, setting the env variable `OCAGENT_TRACE_EXPORTER_ENDPOINT` or - calling `tracing.EnableWithAIForwarding` will start the instrumentation and connect to an - App Insights Local Forwarder that is needs to be running. Note that if the - AI Local Forwarder is not running tracking will still be enabled. - By default, instrumentation is disabled. Once enabled, instrumentation can also - be programatically disabled by calling `Disable`. -- Added `DoneWithContext` call for checking LRO status. `Done` has been deprecated. - -### Bug Fixes - -- Don't use the initial request's context for LRO polling. -- Don't override the `refreshLock` and the `http.Client` when unmarshalling `ServicePrincipalToken` if - it is already set. - -## v11.1.1 - -### Bug Fixes - -- When creating a future always include the polling tracker even if there's a failure; this allows the underlying response to be obtained by the caller. - -## v11.1.0 - -### New Features - -- Added `auth.NewAuthorizerFromCLI` to create an authorizer configured from the Azure 2.0 CLI. -- Added `adal.NewOAuthConfigWithAPIVersion` to create an OAuthConfig with the specified API version. - -## v11.0.1 - -### New Features - -- Added `x5c` header to client assertion for certificate Issuer+Subject Name authentication. - -## v11.0.0 - -### Breaking Changes - -- To handle differences between ADFS and AAD the following fields have had their types changed from `string` to `json.Number` - - ExpiresIn - - ExpiresOn - - NotBefore - -### New Features - -- Added `auth.NewAuthorizerFromFileWithResource` to create an authorizer from the config file with the specified resource. -- Setting a client's `PollingDuration` to zero will use the provided context to control a LRO's polling duration. - -## v10.15.5 - -### Bug Fixes - -- In `DoRetryForStatusCodes`, if a request's context is cancelled return the last response. - -## v10.15.4 - -### Bug Fixes - -- If a polling operation returns a failure status code return the associated error. - -## v10.15.3 - -### Bug Fixes - -- Initialize the polling URL and method for an LRO tracker on each iteration, favoring the Azure-AsyncOperation header. - -## v10.15.2 - -### Bug Fixes - -- Use fmt.Fprint when printing request/response so that any escape sequences aren't treated as format specifiers. - -## v10.15.1 - -### Bug Fixes - -- If an LRO API returns a `Failed` provisioning state in the initial response return an error at that point so the caller doesn't have to poll. -- For failed LROs without an OData v4 error include the response body in the error's `AdditionalInfo` field to aid in diagnosing the failure. - -## v10.15.0 - -### New Features - -- Add initial support for request/response logging via setting environment variables. - Setting `AZURE_GO_SDK_LOG_LEVEL` to `LogInfo` will log request/response - without their bodies. To include the bodies set the log level to `LogDebug`. - By default the logger writes to strerr, however it can also write to stdout or a file - if specified in `AZURE_GO_SDK_LOG_FILE`. Note that if the specified file - already exists it will be truncated. - IMPORTANT: by default the logger will redact the Authorization and Ocp-Apim-Subscription-Key - headers. Any other secrets will _not_ be redacted. - -## v10.14.0 - -### New Features - -- Added package version that contains version constants and user-agent data. - -### Bug Fixes - -- Add the user-agent to token requests. - -## v10.13.0 - -- Added support for additionalInfo in ServiceError type. - -## v10.12.0 - -### New Features - -- Added field ServicePrincipalToken.MaxMSIRefreshAttempts to configure the maximun number of attempts to refresh an MSI token. - -## v10.11.4 - -### Bug Fixes - -- If an LRO returns http.StatusOK on the initial response with no async headers return the response body from Future.GetResult(). -- If there is no "final GET URL" return an error from Future.GetResult(). - -## v10.11.3 - -### Bug Fixes - -- In IMDS retry logic, if we don't receive a response don't retry. - - Renamed the retry function so it's clear it's meant for IMDS only. -- For error response bodies that aren't OData-v4 compliant stick the raw JSON in the ServiceError.Details field so the information isn't lost. - - Also add the raw HTTP response to the DetailedResponse. -- Removed superfluous wrapping of response error in azure.DoRetryWithRegistration(). - -## v10.11.2 - -### Bug Fixes - -- Validation for integers handles int and int64 types. - -## v10.11.1 - -### Bug Fixes - -- Adding User information to authorization config as parsed from CLI cache. - -## v10.11.0 - -### New Features - -- Added NewServicePrincipalTokenFromManualTokenSecret for creating a new SPT using a manual token and secret -- Added method ServicePrincipalToken.MarshalTokenJSON() to marshall the inner Token - -## v10.10.0 - -### New Features - -- Most ServicePrincipalTokens can now be marshalled/unmarshall to/from JSON (ServicePrincipalCertificateSecret and ServicePrincipalMSISecret are not supported). -- Added method ServicePrincipalToken.SetRefreshCallbacks(). - -## v10.9.2 - -### Bug Fixes - -- Refreshing a refresh token obtained from a web app authorization code now works. - -## v10.9.1 - -### Bug Fixes - -- The retry logic for MSI token requests now uses exponential backoff per the guidelines. -- IsTemporaryNetworkError() will return true for errors that don't implement the net.Error interface. - -## v10.9.0 - -### Deprecated Methods - -| Old Method | New Method | -| -------------------------: | :---------------------------: | -| azure.NewFuture() | azure.NewFutureFromResponse() | -| Future.WaitForCompletion() | Future.WaitForCompletionRef() | - -### New Features - -- Added azure.NewFutureFromResponse() for creating a Future from the initial response from an async operation. -- Added Future.GetResult() for making the final GET call to retrieve the result from an async operation. - -### Bug Fixes - -- Some futures failed to return their results, this should now be fixed. - -## v10.8.2 - -### Bug Fixes - -- Add nil-gaurd to token retry logic. - -## v10.8.1 - -### Bug Fixes - -- Return a TokenRefreshError if the sender fails on the initial request. -- Don't retry on non-temporary network errors. - -## v10.8.0 - -- Added NewAuthorizerFromEnvironmentWithResource() helper function. - -## v10.7.0 - -### New Features - -- Added \*WithContext() methods to ADAL token refresh operations. - -## v10.6.2 - -- Fixed a bug on device authentication. - -## v10.6.1 - -- Added retries to MSI token get request. - -## v10.6.0 - -- Changed MSI token implementation. Now, the token endpoint is the IMDS endpoint. - -## v10.5.1 - -### Bug Fixes - -- `DeviceFlowConfig.Authorizer()` now prints the device code message when running `go test`. `-v` flag is required. - -## v10.5.0 - -### New Features - -- Added NewPollingRequestWithContext() for use with polling asynchronous operations. - -### Bug Fixes - -- Make retry logic use the request's context instead of the deprecated Cancel object. - -## v10.4.0 - -### New Features - -- Added helper for parsing Azure Resource ID's. -- Added deprecation message to utils.GetEnvVarOrExit() - -## v10.3.0 - -### New Features - -- Added EnvironmentFromURL method to load an Environment from a given URL. This function is particularly useful in the private and hybrid Cloud model, where one may define their own endpoints -- Added TokenAudience endpoint to Environment structure. This is useful in private and hybrid cloud models where TokenAudience endpoint can be different from ResourceManagerEndpoint - -## v10.2.0 - -### New Features - -- Added endpoints for batch management. - -## v10.1.3 - -### Bug Fixes - -- In Client.Do() invoke WithInspection() last so that it will inspect WithAuthorization(). -- Fixed authorization methods to invoke p.Prepare() first, aligning them with the other preparers. - -## v10.1.2 - -- Corrected comment for auth.NewAuthorizerFromFile() function. - -## v10.1.1 - -- Updated version number to match current release. - -## v10.1.0 - -### New Features - -- Expose the polling URL for futures. - -### Bug Fixes - -- Add validation.NewErrorWithValidationError back to prevent breaking changes (it is deprecated). - -## v10.0.0 - -### New Features - -- Added target and innererror fields to ServiceError to comply with OData v4 spec. -- The Done() method on futures will now return a ServiceError object when available (it used to return a partial value of such errors). -- Added helper methods for obtaining authorizers. -- Expose the polling URL for futures. - -### Bug Fixes - -- Switched from glide to dep for dependency management. -- Fixed unmarshaling of ServiceError for JSON bodies that don't conform to the OData spec. -- Fixed a race condition in token refresh. - -### Breaking Changes - -- The ServiceError.Details field type has been changed to match the OData v4 spec. -- Go v1.7 has been dropped from CI. -- API parameter validation failures will now return a unique error type validation.Error. -- The adal.Token type has been decomposed from adal.ServicePrincipalToken (this was necessary in order to fix the token refresh race). - -## v9.10.0 - -- Fix the Service Bus suffix in Azure public env -- Add Service Bus Endpoint (AAD ResourceURI) for use in [Azure Service Bus RBAC Preview](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-role-based-access-control) - -## v9.9.0 - -### New Features - -- Added EventGridKeyAuthorizer for key authorization with event grid topics. - -### Bug Fixes - -- Fixed race condition when auto-refreshing service principal tokens. - -## v9.8.1 - -### Bug Fixes - -- Added http.StatusNoContent (204) to the list of expected status codes for long-running operations. -- Updated runtime version info so it's current. - -## v9.8.0 - -### New Features - -- Added type azure.AsyncOpIncompleteError to be returned from a future's Result() method when the operation has not completed. - -## v9.7.1 - -### Bug Fixes - -- Use correct AAD and Graph endpoints for US Gov environment. - -## v9.7.0 - -### New Features - -- Added support for application/octet-stream MIME types. - -## v9.6.1 - -### Bug Fixes - -- Ensure Authorization header is added to request when polling for registration status. - -## v9.6.0 - -### New Features - -- Added support for acquiring tokens via MSI with a user assigned identity. - -## v9.5.3 - -### Bug Fixes - -- Don't remove encoding of existing URL Query parameters when calling autorest.WithQueryParameters. -- Set correct Content Type when using autorest.WithFormData. - -## v9.5.2 - -### Bug Fixes - -- Check for nil \*http.Response before dereferencing it. - -## v9.5.1 - -### Bug Fixes - -- Don't count http.StatusTooManyRequests (429) against the retry cap. -- Use retry logic when SkipResourceProviderRegistration is set to true. - -## v9.5.0 - -### New Features - -- Added support for username + password, API key, authoriazation code and cognitive services authentication. -- Added field SkipResourceProviderRegistration to clients to provide a way to skip auto-registration of RPs. -- Added utility function AsStringSlice() to convert its parameters to a string slice. - -### Bug Fixes - -- When checking for authentication failures look at the error type not the status code as it could vary. - -## v9.4.2 - -### Bug Fixes - -- Validate parameters when creating credentials. -- Don't retry requests if the returned status is a 401 (http.StatusUnauthorized) as it will never succeed. - -## v9.4.1 - -### Bug Fixes - -- Update the AccessTokensPath() to read access tokens path through AZURE_ACCESS_TOKEN_FILE. If this - environment variable is not set, it will fall back to use default path set by Azure CLI. -- Use case-insensitive string comparison for polling states. - -## v9.4.0 - -### New Features - -- Added WaitForCompletion() to Future as a default polling implementation. - -### Bug Fixes - -- Method Future.Done() shouldn't update polling status for unexpected HTTP status codes. - -## v9.3.1 - -### Bug Fixes - -- DoRetryForStatusCodes will retry if sender.Do returns a non-nil error. - -## v9.3.0 - -### New Features - -- Added PollingMethod() to Future so callers know what kind of polling mechanism is used. -- Added azure.ChangeToGet() which transforms an http.Request into a GET (to be used with LROs). - -## v9.2.0 - -### New Features - -- Added support for custom Azure Stack endpoints. -- Added type azure.Future used to track the status of long-running operations. - -### Bug Fixes - -- Preserve the original error in DoRetryWithRegistration when registration fails. - -## v9.1.1 - -- Fixes a bug regarding the cookie jar on `autorest.Client.Sender`. - -## v9.1.0 - -### New Features - -- In cases where there is a non-empty error from the service, attempt to unmarshal it instead of uniformly calling it an "Unknown" error. -- Support for loading Azure CLI Authentication files. -- Automatically register your subscription with the Azure Resource Provider if it hadn't been previously. - -### Bug Fixes - -- RetriableRequest can now tolerate a ReadSeekable body being read but not reset. -- Adding missing Apache Headers - -## v9.0.0 - -> **IMPORTANT:** This release was intially labeled incorrectly as `v8.4.0`. From the time it was released, it should have been marked `v9.0.0` because it contains breaking changes to the MSI packages. We appologize for any inconvenience this causes. - -Adding MSI Endpoint Support and CLI token rehydration. - -## v8.3.1 - -Pick up bug fix in adal for MSI support. - -## v8.3.0 - -Updates to Error string formats for clarity. Also, adding a copy of the http.Response to errors for an improved debugging experience. - -## v8.2.0 - -### New Features - -- Add support for bearer authentication callbacks -- Support 429 response codes that include "Retry-After" header -- Support validation constraint "Pattern" for map keys - -### Bug Fixes - -- Make RetriableRequest work with multiple versions of Go - -## v8.1.1 - -Updates the RetriableRequest to take advantage of GetBody() added in Go 1.8. - -## v8.1.0 - -Adds RetriableRequest type for more efficient handling of retrying HTTP requests. - -## v8.0.0 - -ADAL refactored into its own package. -Support for UNIX time. - -## v7.3.1 - -- Version Testing now removed from production bits that are shipped with the library. - -## v7.3.0 - -- Exposing new `RespondDecorator`, `ByDiscardingBody`. This allows operations - to acknowledge that they do not need either the entire or a trailing portion - of accepts response body. In doing so, Go's http library can reuse HTTP - connections more readily. -- Adding `PrepareDecorator` to target custom BaseURLs. -- Adding ACR suffix to public cloud environment. -- Updating Glide dependencies. - -## v7.2.5 - -- Fixed the Active Directory endpoint for the China cloud. -- Removes UTF-8 BOM if present in response payload. -- Added telemetry. - -## v7.2.3 - -- Fixing bug in calls to `DelayForBackoff` that caused doubling of delay - duration. - -## v7.2.2 - -- autorest/azure: added ASM and ARM VM DNS suffixes. - -## v7.2.1 - -- fixed parsing of UTC times that are not RFC3339 conformant. - -## v7.2.0 - -- autorest/validation: Reformat validation error for better error message. - -## v7.1.0 - -- preparer: Added support for multipart formdata - WithMultiPartFormdata() -- preparer: Added support for sending file in request body - WithFile -- client: Added RetryDuration parameter. -- autorest/validation: new package for validation code for Azure Go SDK. - -## v7.0.7 - -- Add trailing / to endpoint -- azure: add EnvironmentFromName - -## v7.0.6 - -- Add retry logic for 408, 500, 502, 503 and 504 status codes. -- Change url path and query encoding logic. -- Fix DelayForBackoff for proper exponential delay. -- Add CookieJar in Client. - -## v7.0.5 - -- Add check to start polling only when status is in [200,201,202]. -- Refactoring for unchecked errors. -- azure/persist changes. -- Fix 'file in use' issue in renewing token in deviceflow. -- Store header RetryAfter for subsequent requests in polling. -- Add attribute details in service error. - -## v7.0.4 - -- Better error messages for long running operation failures - -## v7.0.3 - -- Corrected DoPollForAsynchronous to properly handle the initial response - -## v7.0.2 - -- Corrected DoPollForAsynchronous to continue using the polling method first discovered - -## v7.0.1 - -- Fixed empty JSON input error in ByUnmarshallingJSON -- Fixed polling support for GET calls -- Changed format name from TimeRfc1123 to TimeRFC1123 - -## v7.0.0 - -- Added ByCopying responder with supporting TeeReadCloser -- Rewrote Azure asynchronous handling -- Reverted to only unmarshalling JSON -- Corrected handling of RFC3339 time strings and added support for Rfc1123 time format - -The `json.Decoder` does not catch bad data as thoroughly as `json.Unmarshal`. Since -`encoding/json` successfully deserializes all core types, and extended types normally provide -their custom JSON serialization handlers, the code has been reverted back to using -`json.Unmarshal`. The original change to use `json.Decode` was made to reduce duplicate -code; there is no loss of function, and there is a gain in accuracy, by reverting. - -Additionally, Azure services indicate requests to be polled by multiple means. The existing code -only checked for one of those (that is, the presence of the `Azure-AsyncOperation` header). -The new code correctly covers all cases and aligns with the other Azure SDKs. - -## v6.1.0 - -- Introduced `date.ByUnmarshallingJSONDate` and `date.ByUnmarshallingJSONTime` to enable JSON encoded values. - -## v6.0.0 - -- Completely reworked the handling of polled and asynchronous requests -- Removed unnecessary routines -- Reworked `mocks.Sender` to replay a series of `http.Response` objects -- Added `PrepareDecorators` for primitive types (e.g., bool, int32) - -Handling polled and asynchronous requests is no longer part of `Client#Send`. Instead new -`SendDecorators` implement different styles of polled behavior. See`autorest.DoPollForStatusCodes` -and `azure.DoPollForAsynchronous` for examples. - -## v5.0.0 - -- Added new RespondDecorators unmarshalling primitive types -- Corrected application of inspection and authorization PrependDecorators - -## v4.0.0 - -- Added support for Azure long-running operations. -- Added cancelation support to all decorators and functions that may delay. -- Breaking: `DelayForBackoff` now accepts a channel, which may be nil. - -## v3.1.0 - -- Add support for OAuth Device Flow authorization. -- Add support for ServicePrincipalTokens that are backed by an existing token, rather than other secret material. -- Add helpers for persisting and restoring Tokens. -- Increased code coverage in the github.com/Azure/autorest/azure package - -## v3.0.0 - -- Breaking: `NewErrorWithError` no longer takes `statusCode int`. -- Breaking: `NewErrorWithStatusCode` is replaced with `NewErrorWithResponse`. -- Breaking: `Client#Send()` no longer takes `codes ...int` argument. -- Add: XML unmarshaling support with `ByUnmarshallingXML()` -- Stopped vending dependencies locally and switched to [Glide](https://github.com/Masterminds/glide). - Applications using this library should either use Glide or vendor dependencies locally some other way. -- Add: `azure.WithErrorUnlessStatusCode()` decorator to handle Azure errors. -- Fix: use `net/http.DefaultClient` as base client. -- Fix: Missing inspection for polling responses added. -- Add: CopyAndDecode helpers. -- Improved `./autorest/to` with `[]string` helpers. -- Removed golint suppressions in .travis.yml. - -## v2.1.0 - -- Added `StatusCode` to `Error` for more easily obtaining the HTTP Reponse StatusCode (if any) - -## v2.0.0 - -- Changed `to.StringMapPtr` method signature to return a pointer -- Changed `ServicePrincipalCertificateSecret` and `NewServicePrincipalTokenFromCertificate` to support generic certificate and private keys - -## v1.0.0 - -- Added Logging inspectors to trace http.Request / Response -- Added support for User-Agent header -- Changed WithHeader PrepareDecorator to use set vs. add -- Added JSON to error when unmarshalling fails -- Added Client#Send method -- Corrected case of "Azure" in package paths -- Added "to" helpers, Azure helpers, and improved ease-of-use -- Corrected golint issues - -## v1.0.1 - -- Added CHANGELOG.md - -## v1.1.0 - -- Added mechanism to retrieve a ServicePrincipalToken using a certificate-signed JWT -- Added an example of creating a certificate-based ServicePrincipal and retrieving an OAuth token using the certificate - -## v1.1.1 - -- Introduce godeps and vendor dependencies introduced in v1.1.1 diff --git a/vendor/github.com/Azure/go-autorest/GNUmakefile b/vendor/github.com/Azure/go-autorest/GNUmakefile deleted file mode 100644 index a434e73ac4..0000000000 --- a/vendor/github.com/Azure/go-autorest/GNUmakefile +++ /dev/null @@ -1,23 +0,0 @@ -DIR?=./autorest/ - -default: build - -build: fmt - go install $(DIR) - -test: - go test $(DIR) || exit 1 - -vet: - @echo "go vet ." - @go vet $(DIR)... ; if [ $$? -eq 1 ]; then \ - echo ""; \ - echo "Vet found suspicious constructs. Please check the reported constructs"; \ - echo "and fix them if necessary before submitting the code for review."; \ - exit 1; \ - fi - -fmt: - gofmt -w $(DIR) - -.PHONY: build test vet fmt diff --git a/vendor/github.com/Azure/go-autorest/Gopkg.lock b/vendor/github.com/Azure/go-autorest/Gopkg.lock deleted file mode 100644 index dc6e3e633e..0000000000 --- a/vendor/github.com/Azure/go-autorest/Gopkg.lock +++ /dev/null @@ -1,324 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:892e39e5c083d0943f1e80ab8351690f183c6a5ab24e1d280adcad424c26255e" - name = "contrib.go.opencensus.io/exporter/ocagent" - packages = ["."] - pruneopts = "UT" - revision = "a8a6f458bbc1d5042322ad1f9b65eeb0b69be9ea" - version = "v0.6.0" - -[[projects]] - digest = "1:8f5acd4d4462b5136af644d25101f0968a7a94ee90fcb2059cec5b7cc42e0b20" - name = "github.com/census-instrumentation/opencensus-proto" - packages = [ - "gen-go/agent/common/v1", - "gen-go/agent/metrics/v1", - "gen-go/agent/trace/v1", - "gen-go/metrics/v1", - "gen-go/resource/v1", - "gen-go/trace/v1", - ] - pruneopts = "UT" - revision = "d89fa54de508111353cb0b06403c00569be780d8" - version = "v0.2.1" - -[[projects]] - digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "UT" - revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" - version = "v1.1.1" - -[[projects]] - digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55" - name = "github.com/dgrijalva/jwt-go" - packages = ["."] - pruneopts = "UT" - revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" - version = "v3.2.0" - -[[projects]] - digest = "1:cf0d2e435fd4ce45b789e93ef24b5f08e86be0e9807a16beb3694e2d8c9af965" - name = "github.com/dimchansky/utfbom" - packages = ["."] - pruneopts = "UT" - revision = "d2133a1ce379ef6fa992b0514a77146c60db9d1c" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:b7cb6054d3dff43b38ad2e92492f220f57ae6087ee797dca298139776749ace8" - name = "github.com/golang/groupcache" - packages = ["lru"] - pruneopts = "UT" - revision = "611e8accdfc92c4187d399e95ce826046d4c8d73" - -[[projects]] - digest = "1:e3839df32927e8d3403cd5aa7253d966e8ff80fc8f10e2e35d146461cd83fcfa" - name = "github.com/golang/protobuf" - packages = [ - "descriptor", - "jsonpb", - "proto", - "protoc-gen-go/descriptor", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/struct", - "ptypes/timestamp", - "ptypes/wrappers", - ] - pruneopts = "UT" - revision = "6c65a5562fc06764971b7c5d05c76c75e84bdbf7" - version = "v1.3.2" - -[[projects]] - digest = "1:c560cd79300fac84f124b96225181a637a70b60155919a3c36db50b7cca6b806" - name = "github.com/grpc-ecosystem/grpc-gateway" - packages = [ - "internal", - "runtime", - "utilities", - ] - pruneopts = "UT" - revision = "f7120437bb4f6c71f7f5076ad65a45310de2c009" - version = "v1.12.1" - -[[projects]] - digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" - name = "github.com/mitchellh/go-homedir" - packages = ["."] - pruneopts = "UT" - revision = "af06845cf3004701891bf4fdb884bfe4920b3727" - version = "v1.1.0" - -[[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "UT" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - digest = "1:99d32780e5238c2621fff621123997c3e3cca96db8be13179013aea77dfab551" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - ] - pruneopts = "UT" - revision = "221dbe5ed46703ee255b1da0dec05086f5035f62" - version = "v1.4.0" - -[[projects]] - digest = "1:7c5e00383399fe13de0b4b65c9fdde16275407ce8ac02d867eafeaa916edcc71" - name = "go.opencensus.io" - packages = [ - ".", - "internal", - "internal/tagencoding", - "metric/metricdata", - "metric/metricproducer", - "plugin/ocgrpc", - "plugin/ochttp", - "plugin/ochttp/propagation/b3", - "plugin/ochttp/propagation/tracecontext", - "resource", - "stats", - "stats/internal", - "stats/view", - "tag", - "trace", - "trace/internal", - "trace/propagation", - "trace/tracestate", - ] - pruneopts = "UT" - revision = "aad2c527c5defcf89b5afab7f37274304195a6b2" - version = "v0.22.2" - -[[projects]] - branch = "master" - digest = "1:f604f5e2ee721b6757d962dfe7bab4f28aae50c456e39cfb2f3819762a44a6ae" - name = "golang.org/x/crypto" - packages = [ - "pkcs12", - "pkcs12/internal/rc2", - ] - pruneopts = "UT" - revision = "e9b2fee46413994441b28dfca259d911d963dfed" - -[[projects]] - branch = "master" - digest = "1:334b27eac455cb6567ea28cd424230b07b1a64334a2f861a8075ac26ce10af43" - name = "golang.org/x/lint" - packages = [ - ".", - "golint", - ] - pruneopts = "UT" - revision = "fdd1cda4f05fd1fd86124f0ef9ce31a0b72c8448" - -[[projects]] - branch = "master" - digest = "1:257a75d024975428ab9192bfc334c3490882f8cb21322ea5784ca8eca000a910" - name = "golang.org/x/net" - packages = [ - "http/httpguts", - "http2", - "http2/hpack", - "idna", - "internal/timeseries", - "trace", - ] - pruneopts = "UT" - revision = "1ddd1de85cb0337b623b740a609d35817d516a8d" - -[[projects]] - branch = "master" - digest = "1:382bb5a7fb4034db3b6a2d19e5a4a6bcf52f4750530603c01ca18a172fa3089b" - name = "golang.org/x/sync" - packages = ["semaphore"] - pruneopts = "UT" - revision = "cd5d95a43a6e21273425c7ae415d3df9ea832eeb" - -[[projects]] - branch = "master" - digest = "1:4da420ceda5f68e8d748aa2169d0ed44ffadb1bbd6537cf778a49563104189b8" - name = "golang.org/x/sys" - packages = ["unix"] - pruneopts = "UT" - revision = "ce4227a45e2eb77e5c847278dcc6a626742e2945" - -[[projects]] - digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/language", - "internal/language/compact", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - ] - pruneopts = "UT" - revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475" - version = "v0.3.2" - -[[projects]] - branch = "master" - digest = "1:4eb5ea8395fb60212dd58b92c9db80bab59d5e99c7435f9a6a0a528c373b60e7" - name = "golang.org/x/tools" - packages = [ - "go/ast/astutil", - "go/gcexportdata", - "go/internal/gcimporter", - "go/types/typeutil", - ] - pruneopts = "UT" - revision = "259af5ff87bdcd4abf2ecda8edc3f13f04f26a42" - -[[projects]] - digest = "1:964bb30febc27fabfbec4759fa530c6ec35e77a7c85fed90b9317ea39a054877" - name = "google.golang.org/api" - packages = ["support/bundler"] - pruneopts = "UT" - revision = "8a410c21381766a810817fd6200fce8838ecb277" - version = "v0.14.0" - -[[projects]] - branch = "master" - digest = "1:a8d5c2c6e746b3485e36908ab2a9e3d77b86b81f8156d88403c7d2b462431dfd" - name = "google.golang.org/genproto" - packages = [ - "googleapis/api/httpbody", - "googleapis/rpc/status", - "protobuf/field_mask", - ] - pruneopts = "UT" - revision = "51378566eb590fa106d1025ea12835a4416dda84" - -[[projects]] - digest = "1:b59ce3ddb11daeeccccc9cb3183b58ebf8e9a779f1c853308cd91612e817a301" - name = "google.golang.org/grpc" - packages = [ - ".", - "backoff", - "balancer", - "balancer/base", - "balancer/roundrobin", - "binarylog/grpc_binarylog_v1", - "codes", - "connectivity", - "credentials", - "credentials/internal", - "encoding", - "encoding/proto", - "grpclog", - "internal", - "internal/backoff", - "internal/balancerload", - "internal/binarylog", - "internal/buffer", - "internal/channelz", - "internal/envconfig", - "internal/grpcrand", - "internal/grpcsync", - "internal/resolver/dns", - "internal/resolver/passthrough", - "internal/syscall", - "internal/transport", - "keepalive", - "metadata", - "naming", - "peer", - "resolver", - "serviceconfig", - "stats", - "status", - "tap", - ] - pruneopts = "UT" - revision = "1a3960e4bd028ac0cec0a2afd27d7d8e67c11514" - version = "v1.25.1" - -[[projects]] - digest = "1:b75b3deb2bce8bc079e16bb2aecfe01eb80098f5650f9e93e5643ca8b7b73737" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "UT" - revision = "1f64d6156d11335c3f22d9330b0ad14fc1e789ce" - version = "v2.2.7" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "contrib.go.opencensus.io/exporter/ocagent", - "github.com/dgrijalva/jwt-go", - "github.com/dimchansky/utfbom", - "github.com/mitchellh/go-homedir", - "github.com/stretchr/testify/require", - "go.opencensus.io/plugin/ochttp", - "go.opencensus.io/plugin/ochttp/propagation/tracecontext", - "go.opencensus.io/stats/view", - "go.opencensus.io/trace", - "golang.org/x/crypto/pkcs12", - "golang.org/x/lint/golint", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/Azure/go-autorest/Gopkg.toml b/vendor/github.com/Azure/go-autorest/Gopkg.toml deleted file mode 100644 index 1fc2865969..0000000000 --- a/vendor/github.com/Azure/go-autorest/Gopkg.toml +++ /dev/null @@ -1,59 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - -required = ["golang.org/x/lint/golint"] - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "contrib.go.opencensus.io/exporter/ocagent" - version = "0.6.0" - -[[constraint]] - name = "github.com/dgrijalva/jwt-go" - version = "3.2.0" - -[[constraint]] - name = "github.com/dimchansky/utfbom" - version = "1.1.0" - -[[constraint]] - name = "github.com/mitchellh/go-homedir" - version = "1.1.0" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.3.0" - -[[constraint]] - name = "go.opencensus.io" - version = "0.22.0" - -[[constraint]] - branch = "master" - name = "golang.org/x/crypto" diff --git a/vendor/github.com/Azure/go-autorest/LICENSE b/vendor/github.com/Azure/go-autorest/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/README.md b/vendor/github.com/Azure/go-autorest/README.md deleted file mode 100644 index de1e19a44d..0000000000 --- a/vendor/github.com/Azure/go-autorest/README.md +++ /dev/null @@ -1,165 +0,0 @@ -# go-autorest - -[![GoDoc](https://godoc.org/github.com/Azure/go-autorest/autorest?status.png)](https://godoc.org/github.com/Azure/go-autorest/autorest) -[![Build Status](https://dev.azure.com/azure-sdk/public/_apis/build/status/go/Azure.go-autorest?branchName=master)](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=625&branchName=master) -[![Go Report Card](https://goreportcard.com/badge/Azure/go-autorest)](https://goreportcard.com/report/Azure/go-autorest) - -Package go-autorest provides an HTTP request client for use with [Autorest](https://github.com/Azure/autorest.go)-generated API client packages. - -An authentication client tested with Azure Active Directory (AAD) is also -provided in this repo in the package -`github.com/Azure/go-autorest/autorest/adal`. Despite its name, this package -is maintained only as part of the Azure Go SDK and is not related to other -"ADAL" libraries in [github.com/AzureAD](https://github.com/AzureAD). - -## Overview - -Package go-autorest implements an HTTP request pipeline suitable for use across -multiple goroutines and provides the shared routines used by packages generated -by [Autorest](https://github.com/Azure/autorest.go). - -The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, -and Responding. A typical pattern is: - -```go - req, err := Prepare(&http.Request{}, - token.WithAuthorization()) - - resp, err := Send(req, - WithLogging(logger), - DoErrorIfStatusCode(http.StatusInternalServerError), - DoCloseIfError(), - DoRetryForAttempts(5, time.Second)) - - err = Respond(resp, - ByDiscardingBody(), - ByClosing()) -``` - -Each phase relies on decorators to modify and / or manage processing. Decorators may first modify -and then pass the data along, pass the data first and then modify the result, or wrap themselves -around passing the data (such as a logger might do). Decorators run in the order provided. For -example, the following: - -```go - req, err := Prepare(&http.Request{}, - WithBaseURL("https://microsoft.com/"), - WithPath("a"), - WithPath("b"), - WithPath("c")) -``` - -will set the URL to: - -``` - https://microsoft.com/a/b/c -``` - -Preparers and Responders may be shared and re-used (assuming the underlying decorators support -sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders -shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, -all bound together by means of input / output channels. - -Decorators hold their passed state within a closure (such as the path components in the example -above). Be careful to share Preparers and Responders only in a context where such held state -applies. For example, it may not make sense to share a Preparer that applies a query string from a -fixed set of values. Similarly, sharing a Responder that reads the response body into a passed -struct (e.g., `ByUnmarshallingJson`) is likely incorrect. - -Errors raised by autorest objects and methods will conform to the `autorest.Error` interface. - -See the included examples for more detail. For details on the suggested use of this package by -generated clients, see the Client described below. - -## Helpers - -### Handling Swagger Dates - -The Swagger specification (https://swagger.io) that drives AutoRest -(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The -github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure correct -parsing and formatting. - -### Handling Empty Values - -In JSON, missing values have different semantics than empty values. This is especially true for -services using the HTTP PATCH verb. The JSON submitted with a PATCH request generally contains -only those values to modify. Missing values are to be left unchanged. Developers, then, require a -means to both specify an empty value and to leave the value out of the submitted JSON. - -The Go JSON package (`encoding/json`) supports the `omitempty` tag. When specified, it omits -empty values from the rendered JSON. Since Go defines default values for all base types (such as "" -for string and 0 for int) and provides no means to mark a value as actually empty, the JSON package -treats default values as meaning empty, omitting them from the rendered JSON. This means that, using -the Go base types encoded through the default JSON package, it is not possible to create JSON to -clear a value at the server. - -The workaround within the Go community is to use pointers to base types in lieu of base types within -structures that map to JSON. For example, instead of a value of type `string`, the workaround uses -`*string`. While this enables distinguishing empty values from those to be unchanged, creating -pointers to a base type (notably constant, in-line values) requires additional variables. This, for -example, - -```go - s := struct { - S *string - }{ S: &"foo" } -``` -fails, while, this - -```go - v := "foo" - s := struct { - S *string - }{ S: &v } -``` -succeeds. - -To ease using pointers, the subpackage `to` contains helpers that convert to and from pointers for -Go base types which have Swagger analogs. It also provides a helper that converts between -`map[string]string` and `map[string]*string`, enabling the JSON to specify that the value -associated with a key should be cleared. With the helpers, the previous example becomes - -```go - s := struct { - S *string - }{ S: to.StringPtr("foo") } -``` - -## Install - -```bash -go get github.com/Azure/go-autorest/autorest -go get github.com/Azure/go-autorest/autorest/azure -go get github.com/Azure/go-autorest/autorest/date -go get github.com/Azure/go-autorest/autorest/to -``` - -### Using with Go Modules -In [v12.0.1](https://github.com/Azure/go-autorest/pull/386), this repository introduced the following modules. - -- autorest/adal -- autorest/azure/auth -- autorest/azure/cli -- autorest/date -- autorest/mocks -- autorest/to -- autorest/validation -- autorest -- logger -- tracing - -Tagging cumulative SDK releases as a whole (e.g. `v12.3.0`) is still enabled to support consumers of this repo that have not yet migrated to modules. - -## License - -See LICENSE file. - ------ - -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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/autorest/adal/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/autorest/adal/README.md b/vendor/github.com/Azure/go-autorest/autorest/adal/README.md deleted file mode 100644 index b11eb07884..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/README.md +++ /dev/null @@ -1,294 +0,0 @@ -# NOTE: This module will go out of support by March 31, 2023. For authenticating with Azure AD, use module [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) instead. For help migrating from `adal` to `azidentiy` please consult the [migration guide](https://aka.ms/azsdk/go/identity/migration). General information about the retirement of this and other legacy modules can be found [here](https://azure.microsoft.com/updates/support-for-azure-sdk-libraries-that-do-not-conform-to-our-current-azure-sdk-guidelines-will-be-retired-as-of-31-march-2023/). - -# Azure Active Directory authentication for Go - -This is a standalone package for authenticating with Azure Active -Directory from other Go libraries and applications, in particular the [Azure SDK -for Go](https://github.com/Azure/azure-sdk-for-go). - -Note: Despite the package's name it is not related to other "ADAL" libraries -maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues -should be opened in [this repo's](https://github.com/Azure/go-autorest/issues) -or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue -trackers. - -## Install - -```bash -go get -u github.com/Azure/go-autorest/autorest/adal -``` - -## Usage - -An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli). - -### Register an Azure AD Application with secret - - -1. Register a new application with a `secret` credential - - ``` - az ad app create \ - --display-name example-app \ - --homepage https://example-app/home \ - --identifier-uris https://example-app/app \ - --password secret - ``` - -2. Create a service principal using the `Application ID` from previous step - - ``` - az ad sp create --id "Application ID" - ``` - - * Replace `Application ID` with `appId` from step 1. - -### Register an Azure AD Application with certificate - -1. Create a private key - - ``` - openssl genrsa -out "example-app.key" 2048 - ``` - -2. Create the certificate - - ``` - openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr" - openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000 - ``` - -3. Create the PKCS12 version of the certificate containing also the private key - - ``` - openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass: - - ``` - -4. Register a new application with the certificate content form `example-app.crt` - - ``` - certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)" - - az ad app create \ - --display-name example-app \ - --homepage https://example-app/home \ - --identifier-uris https://example-app/app \ - --key-usage Verify --end-date 2018-01-01 \ - --key-value "${certificateContents}" - ``` - -5. Create a service principal using the `Application ID` from previous step - - ``` - az ad sp create --id "APPLICATION_ID" - ``` - - * Replace `APPLICATION_ID` with `appId` from step 4. - - -### Grant the necessary permissions - -Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained -level. There is a set of [pre-defined roles](https://docs.microsoft.com/azure/active-directory/role-based-access-built-in-roles) -which can be assigned to a service principal of an Azure AD application depending of your needs. - -``` -az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME" -``` - -* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step. -* Replace the `ROLE_NAME` with a role name of your choice. - -It is also possible to define custom role definitions. - -``` -az role definition create --role-definition role-definition.json -``` - -* Check [custom roles](https://docs.microsoft.com/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file. - - -### Acquire Access Token - -The common configuration used by all flows: - -```Go -const activeDirectoryEndpoint = "https://login.microsoftonline.com/" -tenantID := "TENANT_ID" -oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID) - -applicationID := "APPLICATION_ID" - -callback := func(token adal.Token) error { - // This is called after the token is acquired -} - -// The resource for which the token is acquired -resource := "https://management.core.windows.net/" -``` - -* Replace the `TENANT_ID` with your tenant ID. -* Replace the `APPLICATION_ID` with the value from previous section. - -#### Client Credentials - -```Go -applicationSecret := "APPLICATION_SECRET" - -spt, err := adal.NewServicePrincipalToken( - *oauthConfig, - appliationID, - applicationSecret, - resource, - callbacks...) -if err != nil { - return nil, err -} - -// Acquire a new access token -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -* Replace the `APPLICATION_SECRET` with the `password` value from previous section. - -#### Client Certificate - -```Go -certificatePath := "./example-app.pfx" - -certData, err := ioutil.ReadFile(certificatePath) -if err != nil { - return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err) -} - -// Get the certificate and private key from pfx file -certificate, rsaPrivateKey, err := decodePkcs12(certData, "") -if err != nil { - return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) -} - -spt, err := adal.NewServicePrincipalTokenFromCertificate( - *oauthConfig, - applicationID, - certificate, - rsaPrivateKey, - resource, - callbacks...) - -// Acquire a new access token -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -* Update the certificate path to point to the example-app.pfx file which was created in previous section. - - -#### Device Code - -```Go -oauthClient := &http.Client{} - -// Acquire the device code -deviceCode, err := adal.InitiateDeviceAuth( - oauthClient, - *oauthConfig, - applicationID, - resource) -if err != nil { - return nil, fmt.Errorf("Failed to start device auth flow: %s", err) -} - -// Display the authentication message -fmt.Println(*deviceCode.Message) - -// Wait here until the user is authenticated -token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) -if err != nil { - return nil, fmt.Errorf("Failed to finish device auth flow: %s", err) -} - -spt, err := adal.NewServicePrincipalTokenFromManualToken( - *oauthConfig, - applicationID, - resource, - *token, - callbacks...) - -if (err == nil) { - token := spt.Token -} -``` - -#### Username password authenticate - -```Go -spt, err := adal.NewServicePrincipalTokenFromUsernamePassword( - *oauthConfig, - applicationID, - username, - password, - resource, - callbacks...) - -if (err == nil) { - token := spt.Token -} -``` - -#### Authorization code authenticate - -``` Go -spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode( - *oauthConfig, - applicationID, - clientSecret, - authorizationCode, - redirectURI, - resource, - callbacks...) - -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -### Command Line Tool - -A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above. - -``` -adal -h - -Usage of ./adal: - -applicationId string - application id - -certificatePath string - path to pk12/PFC application certificate - -mode string - authentication mode (device, secret, cert, refresh) (default "device") - -resource string - resource for which the token is requested - -secret string - application secret - -tenantId string - tenant id - -tokenCachePath string - location of oath token cache (default "/home/cgc/.adal/accessToken.json") -``` - -Example acquire a token for `https://management.core.windows.net/` using device code flow: - -``` -adal -mode device \ - -applicationId "APPLICATION_ID" \ - -tenantId "TENANT_ID" \ - -resource https://management.core.windows.net/ - -``` diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go deleted file mode 100644 index fa5964742f..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go +++ /dev/null @@ -1,151 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "errors" - "fmt" - "net/url" -) - -const ( - activeDirectoryEndpointTemplate = "%s/oauth2/%s%s" -) - -// OAuthConfig represents the endpoints needed -// in OAuth operations -type OAuthConfig struct { - AuthorityEndpoint url.URL `json:"authorityEndpoint"` - AuthorizeEndpoint url.URL `json:"authorizeEndpoint"` - TokenEndpoint url.URL `json:"tokenEndpoint"` - DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"` -} - -// IsZero returns true if the OAuthConfig object is zero-initialized. -func (oac OAuthConfig) IsZero() bool { - return oac == OAuthConfig{} -} - -func validateStringParam(param, name string) error { - if len(param) == 0 { - return fmt.Errorf("parameter '" + name + "' cannot be empty") - } - return nil -} - -// NewOAuthConfig returns an OAuthConfig with tenant specific urls -func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { - apiVer := "1.0" - return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer) -} - -// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls. -// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value. -func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) { - if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil { - return nil, err - } - api := "" - // it's legal for tenantID to be empty so don't validate it - if apiVersion != nil { - if err := validateStringParam(*apiVersion, "apiVersion"); err != nil { - return nil, err - } - api = fmt.Sprintf("?api-version=%s", *apiVersion) - } - u, err := url.Parse(activeDirectoryEndpoint) - if err != nil { - return nil, err - } - authorityURL, err := u.Parse(tenantID) - if err != nil { - return nil, err - } - authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api)) - if err != nil { - return nil, err - } - tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api)) - if err != nil { - return nil, err - } - deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api)) - if err != nil { - return nil, err - } - - return &OAuthConfig{ - AuthorityEndpoint: *authorityURL, - AuthorizeEndpoint: *authorizeURL, - TokenEndpoint: *tokenURL, - DeviceCodeEndpoint: *deviceCodeURL, - }, nil -} - -// MultiTenantOAuthConfig provides endpoints for primary and aulixiary tenant IDs. -type MultiTenantOAuthConfig interface { - PrimaryTenant() *OAuthConfig - AuxiliaryTenants() []*OAuthConfig -} - -// OAuthOptions contains optional OAuthConfig creation arguments. -type OAuthOptions struct { - APIVersion string -} - -func (c OAuthOptions) apiVersion() string { - if c.APIVersion != "" { - return fmt.Sprintf("?api-version=%s", c.APIVersion) - } - return "1.0" -} - -// NewMultiTenantOAuthConfig creates an object that support multitenant OAuth configuration. -// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/authenticate-multi-tenant for more information. -func NewMultiTenantOAuthConfig(activeDirectoryEndpoint, primaryTenantID string, auxiliaryTenantIDs []string, options OAuthOptions) (MultiTenantOAuthConfig, error) { - if len(auxiliaryTenantIDs) == 0 || len(auxiliaryTenantIDs) > 3 { - return nil, errors.New("must specify one to three auxiliary tenants") - } - mtCfg := multiTenantOAuthConfig{ - cfgs: make([]*OAuthConfig, len(auxiliaryTenantIDs)+1), - } - apiVer := options.apiVersion() - pri, err := NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, primaryTenantID, &apiVer) - if err != nil { - return nil, fmt.Errorf("failed to create OAuthConfig for primary tenant: %v", err) - } - mtCfg.cfgs[0] = pri - for i := range auxiliaryTenantIDs { - aux, err := NewOAuthConfig(activeDirectoryEndpoint, auxiliaryTenantIDs[i]) - if err != nil { - return nil, fmt.Errorf("failed to create OAuthConfig for tenant '%s': %v", auxiliaryTenantIDs[i], err) - } - mtCfg.cfgs[i+1] = aux - } - return mtCfg, nil -} - -type multiTenantOAuthConfig struct { - // first config in the slice is the primary tenant - cfgs []*OAuthConfig -} - -func (m multiTenantOAuthConfig) PrimaryTenant() *OAuthConfig { - return m.cfgs[0] -} - -func (m multiTenantOAuthConfig) AuxiliaryTenants() []*OAuthConfig { - return m.cfgs[1:] -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go deleted file mode 100644 index 9daa4b58b8..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go +++ /dev/null @@ -1,273 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -/* - This file is largely based on rjw57/oauth2device's code, with the follow differences: - * scope -> resource, and only allow a single one - * receive "Message" in the DeviceCode struct and show it to users as the prompt - * azure-xplat-cli has the following behavior that this emulates: - - does not send client_secret during the token exchange - - sends resource again in the token exchange request -*/ - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "strings" - "time" -) - -const ( - logPrefix = "autorest/adal/devicetoken:" -) - -var ( - // ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow - ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix) - - // ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow - ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix) - - // ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow - ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix) - - // ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow - ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix) - - // ErrDeviceSlowDown represents the service telling us we're polling too often during device flow - ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix) - - // ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow - ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix) - - // ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow - ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix) - - errCodeSendingFails = "Error occurred while sending request for Device Authorization Code" - errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint" - errTokenSendingFails = "Error occurred while sending request with device code for a token" - errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)" - errStatusNotOK = "Error HTTP status != 200" -) - -// DeviceCode is the object returned by the device auth endpoint -// It contains information to instruct the user to complete the auth flow -type DeviceCode struct { - DeviceCode *string `json:"device_code,omitempty"` - UserCode *string `json:"user_code,omitempty"` - VerificationURL *string `json:"verification_url,omitempty"` - ExpiresIn *int64 `json:"expires_in,string,omitempty"` - Interval *int64 `json:"interval,string,omitempty"` - - Message *string `json:"message"` // Azure specific - Resource string // store the following, stored when initiating, used when exchanging - OAuthConfig OAuthConfig - ClientID string -} - -// TokenError is the object returned by the token exchange endpoint -// when something is amiss -type TokenError struct { - Error *string `json:"error,omitempty"` - ErrorCodes []int `json:"error_codes,omitempty"` - ErrorDescription *string `json:"error_description,omitempty"` - Timestamp *string `json:"timestamp,omitempty"` - TraceID *string `json:"trace_id,omitempty"` -} - -// DeviceToken is the object return by the token exchange endpoint -// It can either look like a Token or an ErrorToken, so put both here -// and check for presence of "Error" to know if we are in error state -type deviceToken struct { - Token - TokenError -} - -// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode -// that can be used with CheckForUserCompletion or WaitForUserCompletion. -// Deprecated: use InitiateDeviceAuthWithContext() instead. -func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { - return InitiateDeviceAuthWithContext(context.Background(), sender, oauthConfig, clientID, resource) -} - -// InitiateDeviceAuthWithContext initiates a device auth flow. It returns a DeviceCode -// that can be used with CheckForUserCompletion or WaitForUserCompletion. -func InitiateDeviceAuthWithContext(ctx context.Context, sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { - v := url.Values{ - "client_id": []string{clientID}, - "resource": []string{resource}, - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - - req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) - } - - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - resp, err := sender.Do(req.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) - } - defer resp.Body.Close() - - rb, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) - } - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK) - } - - if len(strings.Trim(string(rb), " ")) == 0 { - return nil, ErrDeviceCodeEmpty - } - - var code DeviceCode - err = json.Unmarshal(rb, &code) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) - } - - code.ClientID = clientID - code.Resource = resource - code.OAuthConfig = oauthConfig - - return &code, nil -} - -// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint -// to see if the device flow has: been completed, timed out, or otherwise failed -// Deprecated: use CheckForUserCompletionWithContext() instead. -func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { - return CheckForUserCompletionWithContext(context.Background(), sender, code) -} - -// CheckForUserCompletionWithContext takes a DeviceCode and checks with the Azure AD OAuth endpoint -// to see if the device flow has: been completed, timed out, or otherwise failed -func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) { - v := url.Values{ - "client_id": []string{code.ClientID}, - "code": []string{*code.DeviceCode}, - "grant_type": []string{OAuthGrantTypeDeviceCode}, - "resource": []string{code.Resource}, - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - - req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) - } - - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - resp, err := sender.Do(req.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) - } - defer resp.Body.Close() - - rb, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) - } - - if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK) - } - if len(strings.Trim(string(rb), " ")) == 0 { - return nil, ErrOAuthTokenEmpty - } - - var token deviceToken - err = json.Unmarshal(rb, &token) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) - } - - if token.Error == nil { - return &token.Token, nil - } - - switch *token.Error { - case "authorization_pending": - return nil, ErrDeviceAuthorizationPending - case "slow_down": - return nil, ErrDeviceSlowDown - case "access_denied": - return nil, ErrDeviceAccessDenied - case "code_expired": - return nil, ErrDeviceCodeExpired - default: - // return a more meaningful error message if available - if token.ErrorDescription != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, *token.Error, *token.ErrorDescription) - } - return nil, ErrDeviceGeneric - } -} - -// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs. -// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. -// Deprecated: use WaitForUserCompletionWithContext() instead. -func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { - return WaitForUserCompletionWithContext(context.Background(), sender, code) -} - -// WaitForUserCompletionWithContext calls CheckForUserCompletion repeatedly until a token is granted or an error -// state occurs. This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. -func WaitForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) { - intervalDuration := time.Duration(*code.Interval) * time.Second - waitDuration := intervalDuration - - for { - token, err := CheckForUserCompletionWithContext(ctx, sender, code) - - if err == nil { - return token, nil - } - - switch err { - case ErrDeviceSlowDown: - waitDuration += waitDuration - case ErrDeviceAuthorizationPending: - // noop - default: // everything else is "fatal" to us - return nil, err - } - - if waitDuration > (intervalDuration * 3) { - return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix) - } - - select { - case <-time.After(waitDuration): - // noop - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go deleted file mode 100644 index 647a61bb8c..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go deleted file mode 100644 index 2a974a39b3..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go +++ /dev/null @@ -1,135 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "crypto/rsa" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - - "golang.org/x/crypto/pkcs12" -) - -var ( - // ErrMissingCertificate is returned when no local certificate is found in the provided PFX data. - ErrMissingCertificate = errors.New("adal: certificate missing") - - // ErrMissingPrivateKey is returned when no private key is found in the provided PFX data. - ErrMissingPrivateKey = errors.New("adal: private key missing") -) - -// LoadToken restores a Token object from a file located at 'path'. -func LoadToken(path string) (*Token, error) { - file, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) - } - defer file.Close() - - var token Token - - dec := json.NewDecoder(file) - if err = dec.Decode(&token); err != nil { - return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err) - } - return &token, nil -} - -// SaveToken persists an oauth token at the given location on disk. -// It moves the new file into place so it can safely be used to replace an existing file -// that maybe accessed by multiple processes. -func SaveToken(path string, mode os.FileMode, token Token) error { - dir := filepath.Dir(path) - err := os.MkdirAll(dir, os.ModePerm) - if err != nil { - return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err) - } - - newFile, err := ioutil.TempFile(dir, "token") - if err != nil { - return fmt.Errorf("failed to create the temp file to write the token: %v", err) - } - tempPath := newFile.Name() - - if err := json.NewEncoder(newFile).Encode(token); err != nil { - return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err) - } - if err := newFile.Close(); err != nil { - return fmt.Errorf("failed to close temp file %s: %v", tempPath, err) - } - - // Atomic replace to avoid multi-writer file corruptions - if err := os.Rename(tempPath, path); err != nil { - return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err) - } - if err := os.Chmod(path, mode); err != nil { - return fmt.Errorf("failed to chmod the token file %s: %v", path, err) - } - return nil -} - -// DecodePfxCertificateData extracts the x509 certificate and RSA private key from the provided PFX data. -// The PFX data must contain a private key along with a certificate whose public key matches that of the -// private key or an error is returned. -// If the private key is not password protected pass the empty string for password. -func DecodePfxCertificateData(pfxData []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) { - blocks, err := pkcs12.ToPEM(pfxData, password) - if err != nil { - return nil, nil, err - } - // first extract the private key - var priv *rsa.PrivateKey - for _, block := range blocks { - if block.Type == "PRIVATE KEY" { - priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - return nil, nil, err - } - break - } - } - if priv == nil { - return nil, nil, ErrMissingPrivateKey - } - // now find the certificate with the matching public key of our private key - var cert *x509.Certificate - for _, block := range blocks { - if block.Type == "CERTIFICATE" { - pcert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, nil, err - } - certKey, ok := pcert.PublicKey.(*rsa.PublicKey) - if !ok { - // keep looking - continue - } - if priv.E == certKey.E && priv.N.Cmp(certKey.N) == 0 { - // found a match - cert = pcert - break - } - } - } - if cert == nil { - return nil, nil, ErrMissingCertificate - } - return cert, priv, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go deleted file mode 100644 index eb649bce9f..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go +++ /dev/null @@ -1,101 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "crypto/tls" - "net" - "net/http" - "net/http/cookiejar" - "sync" - "time" - - "github.com/Azure/go-autorest/tracing" -) - -const ( - contentType = "Content-Type" - mimeTypeFormPost = "application/x-www-form-urlencoded" -) - -// DO NOT ACCESS THIS DIRECTLY. go through sender() -var defaultSender Sender -var defaultSenderInit = &sync.Once{} - -// Sender is the interface that wraps the Do method to send HTTP requests. -// -// The standard http.Client conforms to this interface. -type Sender interface { - Do(*http.Request) (*http.Response, error) -} - -// SenderFunc is a method that implements the Sender interface. -type SenderFunc func(*http.Request) (*http.Response, error) - -// Do implements the Sender interface on SenderFunc. -func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { - return sf(r) -} - -// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then react to the -// http.Response result. -type SendDecorator func(Sender) Sender - -// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. -func CreateSender(decorators ...SendDecorator) Sender { - return DecorateSender(sender(), decorators...) -} - -// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to -// the Sender. Decorators are applied in the order received, but their affect upon the request -// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a -// post-decorator (pass the http.Request along and react to the results in http.Response). -func DecorateSender(s Sender, decorators ...SendDecorator) Sender { - for _, decorate := range decorators { - s = decorate(s) - } - return s -} - -func sender() Sender { - // note that we can't init defaultSender in init() since it will - // execute before calling code has had a chance to enable tracing - defaultSenderInit.Do(func() { - // copied from http.DefaultTransport with a TLS minimum version. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - }, - } - var roundTripper http.RoundTripper = transport - if tracing.IsEnabled() { - roundTripper = tracing.NewTransport(transport) - } - j, _ := cookiejar.New(nil) - defaultSender = &http.Client{Jar: j, Transport: roundTripper} - }) - return defaultSender -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go deleted file mode 100644 index 1a9c8ab537..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ /dev/null @@ -1,1396 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "context" - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/Azure/go-autorest/autorest/date" - "github.com/Azure/go-autorest/logger" - "github.com/golang-jwt/jwt/v4" -) - -const ( - defaultRefresh = 5 * time.Minute - - // OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow - OAuthGrantTypeDeviceCode = "device_code" - - // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows - OAuthGrantTypeClientCredentials = "client_credentials" - - // OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows - OAuthGrantTypeUserPass = "password" - - // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows - OAuthGrantTypeRefreshToken = "refresh_token" - - // OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows - OAuthGrantTypeAuthorizationCode = "authorization_code" - - // metadataHeader is the header required by MSI extension - metadataHeader = "Metadata" - - // msiEndpoint is the well known endpoint for getting MSI authentications tokens - msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" - - // the API version to use for the MSI endpoint - msiAPIVersion = "2018-02-01" - - // the default number of attempts to refresh an MSI authentication token - defaultMaxMSIRefreshAttempts = 5 - - // asMSIEndpointEnv is the environment variable used to store the endpoint on App Service and Functions - msiEndpointEnv = "MSI_ENDPOINT" - - // asMSISecretEnv is the environment variable used to store the request secret on App Service and Functions - msiSecretEnv = "MSI_SECRET" - - // the API version to use for the legacy App Service MSI endpoint - appServiceAPIVersion2017 = "2017-09-01" - - // secret header used when authenticating against app service MSI endpoint - secretHeader = "Secret" - - // the format for expires_on in UTC with AM/PM - expiresOnDateFormatPM = "1/2/2006 15:04:05 PM +00:00" - - // the format for expires_on in UTC without AM/PM - expiresOnDateFormat = "1/2/2006 15:04:05 +00:00" -) - -// OAuthTokenProvider is an interface which should be implemented by an access token retriever -type OAuthTokenProvider interface { - OAuthToken() string -} - -// MultitenantOAuthTokenProvider provides tokens used for multi-tenant authorization. -type MultitenantOAuthTokenProvider interface { - PrimaryOAuthToken() string - AuxiliaryOAuthTokens() []string -} - -// TokenRefreshError is an interface used by errors returned during token refresh. -type TokenRefreshError interface { - error - Response() *http.Response -} - -// Refresher is an interface for token refresh functionality -type Refresher interface { - Refresh() error - RefreshExchange(resource string) error - EnsureFresh() error -} - -// RefresherWithContext is an interface for token refresh functionality -type RefresherWithContext interface { - RefreshWithContext(ctx context.Context) error - RefreshExchangeWithContext(ctx context.Context, resource string) error - EnsureFreshWithContext(ctx context.Context) error -} - -// TokenRefreshCallback is the type representing callbacks that will be called after -// a successful token refresh -type TokenRefreshCallback func(Token) error - -// TokenRefresh is a type representing a custom callback to refresh a token -type TokenRefresh func(ctx context.Context, resource string) (*Token, error) - -// Token encapsulates the access token used to authorize Azure requests. -// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response -type Token struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - - ExpiresIn json.Number `json:"expires_in"` - ExpiresOn json.Number `json:"expires_on"` - NotBefore json.Number `json:"not_before"` - - Resource string `json:"resource"` - Type string `json:"token_type"` -} - -func newToken() Token { - return Token{ - ExpiresIn: "0", - ExpiresOn: "0", - NotBefore: "0", - } -} - -// IsZero returns true if the token object is zero-initialized. -func (t Token) IsZero() bool { - return t == Token{} -} - -// Expires returns the time.Time when the Token expires. -func (t Token) Expires() time.Time { - s, err := t.ExpiresOn.Float64() - if err != nil { - s = -3600 - } - - expiration := date.NewUnixTimeFromSeconds(s) - - return time.Time(expiration).UTC() -} - -// IsExpired returns true if the Token is expired, false otherwise. -func (t Token) IsExpired() bool { - return t.WillExpireIn(0) -} - -// WillExpireIn returns true if the Token will expire after the passed time.Duration interval -// from now, false otherwise. -func (t Token) WillExpireIn(d time.Duration) bool { - return !t.Expires().After(time.Now().Add(d)) -} - -//OAuthToken return the current access token -func (t *Token) OAuthToken() string { - return t.AccessToken -} - -// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form -// that is submitted when acquiring an oAuth token. -type ServicePrincipalSecret interface { - SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error -} - -// ServicePrincipalNoSecret represents a secret type that contains no secret -// meaning it is not valid for fetching a fresh token. This is used by Manual -type ServicePrincipalNoSecret struct { -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret -// It only returns an error for the ServicePrincipalNoSecret type -func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token") -} - -// MarshalJSON implements the json.Marshaler interface. -func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalNoSecret", - }) -} - -// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. -type ServicePrincipalTokenSecret struct { - ClientSecret string `json:"value"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using the client_secret. -func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("client_secret", tokenSecret.ClientSecret) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Value string `json:"value"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalTokenSecret", - Value: tokenSecret.ClientSecret, - }) -} - -// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. -type ServicePrincipalCertificateSecret struct { - Certificate *x509.Certificate - PrivateKey *rsa.PrivateKey -} - -// SignJwt returns the JWT signed with the certificate's private key. -func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { - hasher := sha1.New() - _, err := hasher.Write(secret.Certificate.Raw) - if err != nil { - return "", err - } - - thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) - - // The jti (JWT ID) claim provides a unique identifier for the JWT. - jti := make([]byte, 20) - _, err = rand.Read(jti) - if err != nil { - return "", err - } - - token := jwt.New(jwt.SigningMethodRS256) - token.Header["x5t"] = thumbprint - x5c := []string{base64.StdEncoding.EncodeToString(secret.Certificate.Raw)} - token.Header["x5c"] = x5c - token.Claims = jwt.MapClaims{ - "aud": spt.inner.OauthConfig.TokenEndpoint.String(), - "iss": spt.inner.ClientID, - "sub": spt.inner.ClientID, - "jti": base64.URLEncoding.EncodeToString(jti), - "nbf": time.Now().Unix(), - "exp": time.Now().Add(24 * time.Hour).Unix(), - } - - signedString, err := token.SignedString(secret.PrivateKey) - return signedString, err -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate. -func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - jwt, err := secret.SignJwt(spt) - if err != nil { - return err - } - - v.Set("client_assertion", jwt) - v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported") -} - -// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension. -type ServicePrincipalMSISecret struct { - msiType msiType - clientResourceID string -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported") -} - -// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. -type ServicePrincipalUsernamePasswordSecret struct { - Username string `json:"username"` - Password string `json:"password"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("username", secret.Username) - v.Set("password", secret.Password) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Username string `json:"username"` - Password string `json:"password"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalUsernamePasswordSecret", - Username: secret.Username, - Password: secret.Password, - }) -} - -// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. -type ServicePrincipalAuthorizationCodeSecret struct { - ClientSecret string `json:"value"` - AuthorizationCode string `json:"authCode"` - RedirectURI string `json:"redirect"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("code", secret.AuthorizationCode) - v.Set("client_secret", secret.ClientSecret) - v.Set("redirect_uri", secret.RedirectURI) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Value string `json:"value"` - AuthCode string `json:"authCode"` - Redirect string `json:"redirect"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalAuthorizationCodeSecret", - Value: secret.ClientSecret, - AuthCode: secret.AuthorizationCode, - Redirect: secret.RedirectURI, - }) -} - -// ServicePrincipalFederatedSecret implements ServicePrincipalSecret for Federated JWTs. -type ServicePrincipalFederatedSecret struct { - jwt string -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during OAuth Token Acquisition using a JWT signed by an OIDC issuer. -func (secret *ServicePrincipalFederatedSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - - v.Set("client_assertion", secret.jwt) - v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalFederatedSecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalFederatedSecret is not supported") -} - -// ServicePrincipalToken encapsulates a Token created for a Service Principal. -type ServicePrincipalToken struct { - inner servicePrincipalToken - refreshLock *sync.RWMutex - sender Sender - customRefreshFunc TokenRefresh - refreshCallbacks []TokenRefreshCallback - // MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token. - // Settings this to a value less than 1 will use the default value. - MaxMSIRefreshAttempts int -} - -// MarshalTokenJSON returns the marshalled inner token. -func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) { - return json.Marshal(spt.inner.Token) -} - -// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks. -func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) { - spt.refreshCallbacks = callbacks -} - -// SetCustomRefreshFunc sets a custom refresh function used to refresh the token. -func (spt *ServicePrincipalToken) SetCustomRefreshFunc(customRefreshFunc TokenRefresh) { - spt.customRefreshFunc = customRefreshFunc -} - -// MarshalJSON implements the json.Marshaler interface. -func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) { - return json.Marshal(spt.inner) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error { - // need to determine the token type - raw := map[string]interface{}{} - err := json.Unmarshal(data, &raw) - if err != nil { - return err - } - secret := raw["secret"].(map[string]interface{}) - switch secret["type"] { - case "ServicePrincipalNoSecret": - spt.inner.Secret = &ServicePrincipalNoSecret{} - case "ServicePrincipalTokenSecret": - spt.inner.Secret = &ServicePrincipalTokenSecret{} - case "ServicePrincipalCertificateSecret": - return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported") - case "ServicePrincipalMSISecret": - return errors.New("unmarshalling ServicePrincipalMSISecret is not supported") - case "ServicePrincipalUsernamePasswordSecret": - spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{} - case "ServicePrincipalAuthorizationCodeSecret": - spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{} - case "ServicePrincipalFederatedSecret": - return errors.New("unmarshalling ServicePrincipalFederatedSecret is not supported") - default: - return fmt.Errorf("unrecognized token type '%s'", secret["type"]) - } - err = json.Unmarshal(data, &spt.inner) - if err != nil { - return err - } - // Don't override the refreshLock or the sender if those have been already set. - if spt.refreshLock == nil { - spt.refreshLock = &sync.RWMutex{} - } - if spt.sender == nil { - spt.sender = sender() - } - return nil -} - -// internal type used for marshalling/unmarshalling -type servicePrincipalToken struct { - Token Token `json:"token"` - Secret ServicePrincipalSecret `json:"secret"` - OauthConfig OAuthConfig `json:"oauth"` - ClientID string `json:"clientID"` - Resource string `json:"resource"` - AutoRefresh bool `json:"autoRefresh"` - RefreshWithin time.Duration `json:"refreshWithin"` -} - -func validateOAuthConfig(oac OAuthConfig) error { - if oac.IsZero() { - return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized") - } - return nil -} - -// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. -func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(id, "id"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if secret == nil { - return nil, fmt.Errorf("parameter 'secret' cannot be nil") - } - spt := &ServicePrincipalToken{ - inner: servicePrincipalToken{ - Token: newToken(), - OauthConfig: oauthConfig, - Secret: secret, - ClientID: id, - Resource: resource, - AutoRefresh: true, - RefreshWithin: defaultRefresh, - }, - refreshLock: &sync.RWMutex{}, - sender: sender(), - refreshCallbacks: callbacks, - } - return spt, nil -} - -// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token -func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if token.IsZero() { - return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") - } - spt, err := NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalNoSecret{}, - callbacks...) - if err != nil { - return nil, err - } - - spt.inner.Token = token - - return spt, nil -} - -// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret -func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if secret == nil { - return nil, fmt.Errorf("parameter 'secret' cannot be nil") - } - if token.IsZero() { - return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") - } - spt, err := NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - secret, - callbacks...) - if err != nil { - return nil, err - } - - spt.inner.Token = token - - return spt, nil -} - -// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal -// credentials scoped to the named resource. -func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(secret, "secret"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalTokenSecret{ - ClientSecret: secret, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes. -func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if certificate == nil { - return nil, fmt.Errorf("parameter 'certificate' cannot be nil") - } - if privateKey == nil { - return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password. -func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(username, "username"); err != nil { - return nil, err - } - if err := validateStringParam(password, "password"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalUsernamePasswordSecret{ - Username: username, - Password: password, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the -func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(clientSecret, "clientSecret"); err != nil { - return nil, err - } - if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil { - return nil, err - } - if err := validateStringParam(redirectURI, "redirectURI"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalAuthorizationCodeSecret{ - ClientSecret: clientSecret, - AuthorizationCode: authorizationCode, - RedirectURI: redirectURI, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromFederatedToken creates a ServicePrincipalToken from the supplied federated OIDC JWT. -func NewServicePrincipalTokenFromFederatedToken(oauthConfig OAuthConfig, clientID string, jwt string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if jwt == "" { - return nil, fmt.Errorf("parameter 'jwt' cannot be empty") - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalFederatedSecret{ - jwt: jwt, - }, - callbacks..., - ) -} - -type msiType int - -const ( - msiTypeUnavailable msiType = iota - msiTypeAppServiceV20170901 - msiTypeCloudShell - msiTypeIMDS -) - -func (m msiType) String() string { - switch m { - case msiTypeAppServiceV20170901: - return "AppServiceV20170901" - case msiTypeCloudShell: - return "CloudShell" - case msiTypeIMDS: - return "IMDS" - default: - return fmt.Sprintf("unhandled MSI type %d", m) - } -} - -// returns the MSI type and endpoint, or an error -func getMSIType() (msiType, string, error) { - if endpointEnvVar := os.Getenv(msiEndpointEnv); endpointEnvVar != "" { - // if the env var MSI_ENDPOINT is set - if secretEnvVar := os.Getenv(msiSecretEnv); secretEnvVar != "" { - // if BOTH the env vars MSI_ENDPOINT and MSI_SECRET are set the msiType is AppService - return msiTypeAppServiceV20170901, endpointEnvVar, nil - } - // if ONLY the env var MSI_ENDPOINT is set the msiType is CloudShell - return msiTypeCloudShell, endpointEnvVar, nil - } - // if MSI_ENDPOINT is NOT set assume the msiType is IMDS - return msiTypeIMDS, msiEndpoint, nil -} - -// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. -// NOTE: this always returns the IMDS endpoint, it does not work for app services or cloud shell. -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIVMEndpoint() (string, error) { - return msiEndpoint, nil -} - -// GetMSIAppServiceEndpoint get the MSI endpoint for App Service and Functions. -// It will return an error when not running in an app service/functions environment. -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIAppServiceEndpoint() (string, error) { - msiType, endpoint, err := getMSIType() - if err != nil { - return "", err - } - switch msiType { - case msiTypeAppServiceV20170901: - return endpoint, nil - default: - return "", fmt.Errorf("%s is not app service environment", msiType) - } -} - -// GetMSIEndpoint get the appropriate MSI endpoint depending on the runtime environment -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIEndpoint() (string, error) { - _, endpoint, err := getMSIType() - return endpoint, err -} - -// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the system assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", "", callbacks...) -} - -// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the clientID of specified user assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(userAssignedID, "userAssignedID"); err != nil { - return nil, err - } - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, "", callbacks...) -} - -// NewServicePrincipalTokenFromMSIWithIdentityResourceID creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the azure resource id of user assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSIWithIdentityResourceID(msiEndpoint, resource string, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(identityResourceID, "identityResourceID"); err != nil { - return nil, err - } - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", identityResourceID, callbacks...) -} - -// ManagedIdentityOptions contains optional values for configuring managed identity authentication. -type ManagedIdentityOptions struct { - // ClientID is the user-assigned identity to use during authentication. - // It is mutually exclusive with IdentityResourceID. - ClientID string - - // IdentityResourceID is the resource ID of the user-assigned identity to use during authentication. - // It is mutually exclusive with ClientID. - IdentityResourceID string -} - -// NewServicePrincipalTokenFromManagedIdentity creates a ServicePrincipalToken using a managed identity. -// It supports the following managed identity environments. -// - App Service Environment (API version 2017-09-01 only) -// - Cloud shell -// - IMDS with a system or user assigned identity -func NewServicePrincipalTokenFromManagedIdentity(resource string, options *ManagedIdentityOptions, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if options == nil { - options = &ManagedIdentityOptions{} - } - return newServicePrincipalTokenFromMSI("", resource, options.ClientID, options.IdentityResourceID, callbacks...) -} - -func newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if userAssignedID != "" && identityResourceID != "" { - return nil, errors.New("cannot specify userAssignedID and identityResourceID") - } - msiType, endpoint, err := getMSIType() - if err != nil { - logger.Instance.Writef(logger.LogError, "Error determining managed identity environment: %v\n", err) - return nil, err - } - logger.Instance.Writef(logger.LogInfo, "Managed identity environment is %s, endpoint is %s\n", msiType, endpoint) - if msiEndpoint != "" { - endpoint = msiEndpoint - logger.Instance.Writef(logger.LogInfo, "Managed identity custom endpoint is %s\n", endpoint) - } - msiEndpointURL, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - // cloud shell sends its data in the request body - if msiType != msiTypeCloudShell { - v := url.Values{} - v.Set("resource", resource) - clientIDParam := "client_id" - switch msiType { - case msiTypeAppServiceV20170901: - clientIDParam = "clientid" - v.Set("api-version", appServiceAPIVersion2017) - break - case msiTypeIMDS: - v.Set("api-version", msiAPIVersion) - } - if userAssignedID != "" { - v.Set(clientIDParam, userAssignedID) - } else if identityResourceID != "" { - v.Set("mi_res_id", identityResourceID) - } - msiEndpointURL.RawQuery = v.Encode() - } - - spt := &ServicePrincipalToken{ - inner: servicePrincipalToken{ - Token: newToken(), - OauthConfig: OAuthConfig{ - TokenEndpoint: *msiEndpointURL, - }, - Secret: &ServicePrincipalMSISecret{ - msiType: msiType, - clientResourceID: identityResourceID, - }, - Resource: resource, - AutoRefresh: true, - RefreshWithin: defaultRefresh, - ClientID: userAssignedID, - }, - refreshLock: &sync.RWMutex{}, - sender: sender(), - refreshCallbacks: callbacks, - MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts, - } - - return spt, nil -} - -// internal type that implements TokenRefreshError -type tokenRefreshError struct { - message string - resp *http.Response -} - -// Error implements the error interface which is part of the TokenRefreshError interface. -func (tre tokenRefreshError) Error() string { - return tre.message -} - -// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation. -func (tre tokenRefreshError) Response() *http.Response { - return tre.resp -} - -func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError { - return tokenRefreshError{message: message, resp: resp} -} - -// EnsureFresh will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (spt *ServicePrincipalToken) EnsureFresh() error { - return spt.EnsureFreshWithContext(context.Background()) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - // must take the read lock when initially checking the token's expiration - if spt.inner.AutoRefresh && spt.Token().WillExpireIn(spt.inner.RefreshWithin) { - // take the write lock then check again to see if the token was already refreshed - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { - return spt.refreshInternal(ctx, spt.inner.Resource) - } - } - return nil -} - -// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization -func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { - if spt.refreshCallbacks != nil { - for _, callback := range spt.refreshCallbacks { - err := callback(spt.inner.Token) - if err != nil { - return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err) - } - } - } - return nil -} - -// Refresh obtains a fresh token for the Service Principal. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) Refresh() error { - return spt.RefreshWithContext(context.Background()) -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - return spt.refreshInternal(ctx, spt.inner.Resource) -} - -// RefreshExchange refreshes the token, but for a different resource. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { - return spt.RefreshExchangeWithContext(context.Background(), resource) -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - return spt.refreshInternal(ctx, resource) -} - -func (spt *ServicePrincipalToken) getGrantType() string { - switch spt.inner.Secret.(type) { - case *ServicePrincipalUsernamePasswordSecret: - return OAuthGrantTypeUserPass - case *ServicePrincipalAuthorizationCodeSecret: - return OAuthGrantTypeAuthorizationCode - default: - return OAuthGrantTypeClientCredentials - } -} - -func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error { - if spt.customRefreshFunc != nil { - token, err := spt.customRefreshFunc(ctx, resource) - if err != nil { - return err - } - spt.inner.Token = *token - return spt.InvokeRefreshCallbacks(spt.inner.Token) - } - req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil) - if err != nil { - return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err) - } - req.Header.Add("User-Agent", UserAgent()) - req = req.WithContext(ctx) - var resp *http.Response - authBodyFilter := func(b []byte) []byte { - if logger.Level() != logger.LogAuth { - return []byte("**REDACTED** authentication body") - } - return b - } - if msiSecret, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok { - switch msiSecret.msiType { - case msiTypeAppServiceV20170901: - req.Method = http.MethodGet - req.Header.Set("secret", os.Getenv(msiSecretEnv)) - break - case msiTypeCloudShell: - req.Header.Set("Metadata", "true") - data := url.Values{} - data.Set("resource", spt.inner.Resource) - if spt.inner.ClientID != "" { - data.Set("client_id", spt.inner.ClientID) - } else if msiSecret.clientResourceID != "" { - data.Set("msi_res_id", msiSecret.clientResourceID) - } - req.Body = ioutil.NopCloser(strings.NewReader(data.Encode())) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - break - case msiTypeIMDS: - req.Method = http.MethodGet - req.Header.Set("Metadata", "true") - break - } - logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter}) - resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts) - } else { - v := url.Values{} - v.Set("client_id", spt.inner.ClientID) - v.Set("resource", resource) - - if spt.inner.Token.RefreshToken != "" { - v.Set("grant_type", OAuthGrantTypeRefreshToken) - v.Set("refresh_token", spt.inner.Token.RefreshToken) - // web apps must specify client_secret when refreshing tokens - // see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens - if spt.getGrantType() == OAuthGrantTypeAuthorizationCode { - err := spt.inner.Secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } - } - } else { - v.Set("grant_type", spt.getGrantType()) - err := spt.inner.Secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - req.Body = body - logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter}) - resp, err = spt.sender.Do(req) - } - - // don't return a TokenRefreshError here; this will allow retry logic to apply - if err != nil { - return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err) - } else if resp == nil { - return fmt.Errorf("adal: received nil response and error") - } - - logger.Instance.WriteResponse(resp, logger.Filter{Body: authBodyFilter}) - defer resp.Body.Close() - rb, err := ioutil.ReadAll(resp.Body) - - if resp.StatusCode != http.StatusOK { - if err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v Endpoint %s", resp.StatusCode, err, req.URL.String()), resp) - } - return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s Endpoint %s", resp.StatusCode, string(rb), req.URL.String()), resp) - } - - // for the following error cases don't return a TokenRefreshError. the operation succeeded - // but some transient failure happened during deserialization. by returning a generic error - // the retry logic will kick in (we don't retry on TokenRefreshError). - - if err != nil { - return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err) - } - if len(strings.Trim(string(rb), " ")) == 0 { - return fmt.Errorf("adal: Empty service principal token received during refresh") - } - token := struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - - // AAD returns expires_in as a string, ADFS returns it as an int - ExpiresIn json.Number `json:"expires_in"` - // expires_on can be in three formats, a UTC time stamp, or the number of seconds as a string *or* int. - ExpiresOn interface{} `json:"expires_on"` - NotBefore json.Number `json:"not_before"` - - Resource string `json:"resource"` - Type string `json:"token_type"` - }{} - // return a TokenRefreshError in the follow error cases as the token is in an unexpected format - err = json.Unmarshal(rb, &token) - if err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)), resp) - } - expiresOn := json.Number("") - // ADFS doesn't include the expires_on field - if token.ExpiresOn != nil { - if expiresOn, err = parseExpiresOn(token.ExpiresOn); err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: failed to parse expires_on: %v value '%s'", err, token.ExpiresOn), resp) - } - } - spt.inner.Token.AccessToken = token.AccessToken - spt.inner.Token.RefreshToken = token.RefreshToken - spt.inner.Token.ExpiresIn = token.ExpiresIn - spt.inner.Token.ExpiresOn = expiresOn - spt.inner.Token.NotBefore = token.NotBefore - spt.inner.Token.Resource = token.Resource - spt.inner.Token.Type = token.Type - - return spt.InvokeRefreshCallbacks(spt.inner.Token) -} - -// converts expires_on to the number of seconds -func parseExpiresOn(s interface{}) (json.Number, error) { - // the JSON unmarshaler treats JSON numbers unmarshaled into an interface{} as float64 - asFloat64, ok := s.(float64) - if ok { - // this is the number of seconds as int case - return json.Number(strconv.FormatInt(int64(asFloat64), 10)), nil - } - asStr, ok := s.(string) - if !ok { - return "", fmt.Errorf("unexpected expires_on type %T", s) - } - // convert the expiration date to the number of seconds from the unix epoch - timeToDuration := func(t time.Time) json.Number { - return json.Number(strconv.FormatInt(t.UTC().Unix(), 10)) - } - if _, err := json.Number(asStr).Int64(); err == nil { - // this is the number of seconds case, no conversion required - return json.Number(asStr), nil - } else if eo, err := time.Parse(expiresOnDateFormatPM, asStr); err == nil { - return timeToDuration(eo), nil - } else if eo, err := time.Parse(expiresOnDateFormat, asStr); err == nil { - return timeToDuration(eo), nil - } else { - // unknown format - return json.Number(""), err - } -} - -// retry logic specific to retrieving a token from the IMDS endpoint -func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) { - // copied from client.go due to circular dependency - retries := []int{ - http.StatusRequestTimeout, // 408 - http.StatusTooManyRequests, // 429 - http.StatusInternalServerError, // 500 - http.StatusBadGateway, // 502 - http.StatusServiceUnavailable, // 503 - http.StatusGatewayTimeout, // 504 - } - // extra retry status codes specific to IMDS - retries = append(retries, - http.StatusNotFound, - http.StatusGone, - // all remaining 5xx - http.StatusNotImplemented, - http.StatusHTTPVersionNotSupported, - http.StatusVariantAlsoNegotiates, - http.StatusInsufficientStorage, - http.StatusLoopDetected, - http.StatusNotExtended, - http.StatusNetworkAuthenticationRequired) - - // see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance - - const maxDelay time.Duration = 60 * time.Second - - attempt := 0 - delay := time.Duration(0) - - // maxAttempts is user-specified, ensure that its value is greater than zero else no request will be made - if maxAttempts < 1 { - maxAttempts = defaultMaxMSIRefreshAttempts - } - - for attempt < maxAttempts { - if resp != nil && resp.Body != nil { - io.Copy(ioutil.Discard, resp.Body) - resp.Body.Close() - } - resp, err = sender.Do(req) - // we want to retry if err is not nil or the status code is in the list of retry codes - if err == nil && !responseHasStatusCode(resp, retries...) { - return - } - - // perform exponential backoff with a cap. - // must increment attempt before calculating delay. - attempt++ - // the base value of 2 is the "delta backoff" as specified in the guidance doc - delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second) - if delay > maxDelay { - delay = maxDelay - } - - select { - case <-time.After(delay): - // intentionally left blank - case <-req.Context().Done(): - err = req.Context().Err() - return - } - } - return -} - -func responseHasStatusCode(resp *http.Response, codes ...int) bool { - if resp != nil { - for _, i := range codes { - if i == resp.StatusCode { - return true - } - } - } - return false -} - -// SetAutoRefresh enables or disables automatic refreshing of stale tokens. -func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { - spt.inner.AutoRefresh = autoRefresh -} - -// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will -// refresh the token. -func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { - spt.inner.RefreshWithin = d - return -} - -// SetSender sets the http.Client used when obtaining the Service Principal token. An -// undecorated http.Client is used by default. -func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s } - -// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token. -func (spt *ServicePrincipalToken) OAuthToken() string { - spt.refreshLock.RLock() - defer spt.refreshLock.RUnlock() - return spt.inner.Token.OAuthToken() -} - -// Token returns a copy of the current token. -func (spt *ServicePrincipalToken) Token() Token { - spt.refreshLock.RLock() - defer spt.refreshLock.RUnlock() - return spt.inner.Token -} - -// MultiTenantServicePrincipalToken contains tokens for multi-tenant authorization. -type MultiTenantServicePrincipalToken struct { - PrimaryToken *ServicePrincipalToken - AuxiliaryTokens []*ServicePrincipalToken -} - -// PrimaryOAuthToken returns the primary authorization token. -func (mt *MultiTenantServicePrincipalToken) PrimaryOAuthToken() string { - return mt.PrimaryToken.OAuthToken() -} - -// AuxiliaryOAuthTokens returns one to three auxiliary authorization tokens. -func (mt *MultiTenantServicePrincipalToken) AuxiliaryOAuthTokens() []string { - tokens := make([]string, len(mt.AuxiliaryTokens)) - for i := range mt.AuxiliaryTokens { - tokens[i] = mt.AuxiliaryTokens[i].OAuthToken() - } - return tokens -} - -// NewMultiTenantServicePrincipalToken creates a new MultiTenantServicePrincipalToken with the specified credentials and resource. -func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig, clientID string, secret string, resource string) (*MultiTenantServicePrincipalToken, error) { - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(secret, "secret"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - auxTenants := multiTenantCfg.AuxiliaryTenants() - m := MultiTenantServicePrincipalToken{ - AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)), - } - primary, err := NewServicePrincipalToken(*multiTenantCfg.PrimaryTenant(), clientID, secret, resource) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err) - } - m.PrimaryToken = primary - for i := range auxTenants { - aux, err := NewServicePrincipalToken(*auxTenants[i], clientID, secret, resource) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err) - } - m.AuxiliaryTokens[i] = aux - } - return &m, nil -} - -// NewMultiTenantServicePrincipalTokenFromCertificate creates a new MultiTenantServicePrincipalToken with the specified certificate credentials and resource. -func NewMultiTenantServicePrincipalTokenFromCertificate(multiTenantCfg MultiTenantOAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string) (*MultiTenantServicePrincipalToken, error) { - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if certificate == nil { - return nil, fmt.Errorf("parameter 'certificate' cannot be nil") - } - if privateKey == nil { - return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") - } - auxTenants := multiTenantCfg.AuxiliaryTenants() - m := MultiTenantServicePrincipalToken{ - AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)), - } - primary, err := NewServicePrincipalTokenWithSecret( - *multiTenantCfg.PrimaryTenant(), - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err) - } - m.PrimaryToken = primary - for i := range auxTenants { - aux, err := NewServicePrincipalTokenWithSecret( - *auxTenants[i], - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err) - } - m.AuxiliaryTokens[i] = aux - } - return &m, nil -} - -// MSIAvailable returns true if the MSI endpoint is available for authentication. -func MSIAvailable(ctx context.Context, s Sender) bool { - msiType, _, err := getMSIType() - - if err != nil { - return false - } - - if msiType != msiTypeIMDS { - return true - } - - if s == nil { - s = sender() - } - - resp, err := getMSIEndpoint(ctx, s) - - if err == nil { - resp.Body.Close() - } - - return err == nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go deleted file mode 100644 index 89190a4213..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build go1.13 -// +build go1.13 - -// Copyright 2017 Microsoft Corporation -// -// 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 adal - -import ( - "context" - "fmt" - "net/http" - "time" -) - -func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { - tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - // http.NewRequestWithContext() was added in Go 1.13 - req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil) - q := req.URL.Query() - q.Add("api-version", msiAPIVersion) - req.URL.RawQuery = q.Encode() - return sender.Do(req) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.EnsureFreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go deleted file mode 100644 index 27ec4efad7..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build !go1.13 -// +build !go1.13 - -// Copyright 2017 Microsoft Corporation -// -// 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 adal - -import ( - "context" - "net/http" - "time" -) - -func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { - tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil) - req = req.WithContext(tempCtx) - q := req.URL.Query() - q.Add("api-version", msiAPIVersion) - req.URL.RawQuery = q.Encode() - return sender.Do(req) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.EnsureFreshWithContext(ctx); err != nil { - return err - } - } - return nil -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshWithContext(ctx); err != nil { - return err - } - } - return nil -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/version.go b/vendor/github.com/Azure/go-autorest/autorest/adal/version.go deleted file mode 100644 index c867b34843..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/version.go +++ /dev/null @@ -1,45 +0,0 @@ -package adal - -import ( - "fmt" - "runtime" -) - -// Copyright 2017 Microsoft Corporation -// -// 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. - -const number = "v1.0.0" - -var ( - ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - number, - ) -) - -// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version. -func UserAgent() string { - return ua -} - -// AddToUserAgent adds an extension to the current user agent -func AddToUserAgent(extension string) error { - if extension != "" { - ua = fmt.Sprintf("%s %s", ua, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go deleted file mode 100644 index 1226c41115..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization.go +++ /dev/null @@ -1,353 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "crypto/tls" - "encoding/base64" - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/Azure/go-autorest/autorest/adal" -) - -const ( - bearerChallengeHeader = "Www-Authenticate" - bearer = "Bearer" - tenantID = "tenantID" - apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key" - bingAPISdkHeader = "X-BingApis-SDK-Client" - golangBingAPISdkHeaderValue = "Go-SDK" - authorization = "Authorization" - basic = "Basic" -) - -// Authorizer is the interface that provides a PrepareDecorator used to supply request -// authorization. Most often, the Authorizer decorator runs last so it has access to the full -// state of the formed HTTP request. -type Authorizer interface { - WithAuthorization() PrepareDecorator -} - -// NullAuthorizer implements a default, "do nothing" Authorizer. -type NullAuthorizer struct{} - -// WithAuthorization returns a PrepareDecorator that does nothing. -func (na NullAuthorizer) WithAuthorization() PrepareDecorator { - return WithNothing() -} - -// APIKeyAuthorizer implements API Key authorization. -type APIKeyAuthorizer struct { - headers map[string]interface{} - queryParameters map[string]interface{} -} - -// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers. -func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer { - return NewAPIKeyAuthorizer(headers, nil) -} - -// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters. -func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer { - return NewAPIKeyAuthorizer(nil, queryParameters) -} - -// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers. -func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer { - return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Parameters. -func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters)) - } -} - -// CognitiveServicesAuthorizer implements authorization for Cognitive Services. -type CognitiveServicesAuthorizer struct { - subscriptionKey string -} - -// NewCognitiveServicesAuthorizer is -func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer { - return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey} -} - -// WithAuthorization is -func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator { - headers := make(map[string]interface{}) - headers[apiKeyAuthorizerHeader] = csa.subscriptionKey - headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue - - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// BearerAuthorizer implements the bearer authorization -type BearerAuthorizer struct { - tokenProvider adal.OAuthTokenProvider -} - -// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider -func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer { - return &BearerAuthorizer{tokenProvider: tp} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the token. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - // the ordering is important here, prefer RefresherWithContext if available - if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok { - err = refresher.EnsureFreshWithContext(r.Context()) - } else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok { - err = refresher.EnsureFresh() - } - if err != nil { - var resp *http.Response - if tokError, ok := err.(adal.TokenRefreshError); ok { - resp = tokError.Response() - } - return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, - "Failed to refresh the Token for request to %s", r.URL) - } - return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))) - } - return r, err - }) - } -} - -// TokenProvider returns OAuthTokenProvider so that it can be used for authorization outside the REST. -func (ba *BearerAuthorizer) TokenProvider() adal.OAuthTokenProvider { - return ba.tokenProvider -} - -// BearerAuthorizerCallbackFunc is the authentication callback signature. -type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error) - -// BearerAuthorizerCallback implements bearer authorization via a callback. -type BearerAuthorizerCallback struct { - sender Sender - callback BearerAuthorizerCallbackFunc -} - -// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback -// is invoked when the HTTP request is submitted. -func NewBearerAuthorizerCallback(s Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback { - if s == nil { - s = sender(tls.RenegotiateNever) - } - return &BearerAuthorizerCallback{sender: s, callback: callback} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value -// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - // make a copy of the request and remove the body as it's not - // required and avoids us having to create a copy of it. - rCopy := *r - removeRequestBody(&rCopy) - - resp, err := bacb.sender.Do(&rCopy) - if err != nil { - return r, err - } - DrainResponseBody(resp) - if resp.StatusCode == 401 && hasBearerChallenge(resp.Header) { - bc, err := newBearerChallenge(resp.Header) - if err != nil { - return r, err - } - if bacb.callback != nil { - ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"]) - if err != nil { - return r, err - } - return Prepare(r, ba.WithAuthorization()) - } - } - } - return r, err - }) - } -} - -// returns true if the HTTP response contains a bearer challenge -func hasBearerChallenge(header http.Header) bool { - authHeader := header.Get(bearerChallengeHeader) - if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 { - return false - } - return true -} - -type bearerChallenge struct { - values map[string]string -} - -func newBearerChallenge(header http.Header) (bc bearerChallenge, err error) { - challenge := strings.TrimSpace(header.Get(bearerChallengeHeader)) - trimmedChallenge := challenge[len(bearer)+1:] - - // challenge is a set of key=value pairs that are comma delimited - pairs := strings.Split(trimmedChallenge, ",") - if len(pairs) < 1 { - err = fmt.Errorf("challenge '%s' contains no pairs", challenge) - return bc, err - } - - bc.values = make(map[string]string) - for i := range pairs { - trimmedPair := strings.TrimSpace(pairs[i]) - pair := strings.Split(trimmedPair, "=") - if len(pair) == 2 { - // remove the enclosing quotes - key := strings.Trim(pair[0], "\"") - value := strings.Trim(pair[1], "\"") - - switch key { - case "authorization", "authorization_uri": - // strip the tenant ID from the authorization URL - asURL, err := url.Parse(value) - if err != nil { - return bc, err - } - bc.values[tenantID] = asURL.Path[1:] - default: - bc.values[key] = value - } - } - } - - return bc, err -} - -// EventGridKeyAuthorizer implements authorization for event grid using key authentication. -type EventGridKeyAuthorizer struct { - topicKey string -} - -// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer -// with the specified topic key. -func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer { - return EventGridKeyAuthorizer{topicKey: topicKey} -} - -// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header. -func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator { - headers := map[string]interface{}{ - "aeg-sas-key": egta.topicKey, - } - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header -// with the value "Basic " where is a base64-encoded username:password tuple. -type BasicAuthorizer struct { - userName string - password string -} - -// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password. -func NewBasicAuthorizer(userName, password string) *BasicAuthorizer { - return &BasicAuthorizer{ - userName: userName, - password: password, - } -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Basic " followed by the base64-encoded username:password tuple. -func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator { - headers := make(map[string]interface{}) - headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password))) - - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// MultiTenantServicePrincipalTokenAuthorizer provides authentication across tenants. -type MultiTenantServicePrincipalTokenAuthorizer interface { - WithAuthorization() PrepareDecorator -} - -// NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider -func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer { - return NewMultiTenantBearerAuthorizer(tp) -} - -// MultiTenantBearerAuthorizer implements bearer authorization across multiple tenants. -type MultiTenantBearerAuthorizer struct { - tp adal.MultitenantOAuthTokenProvider -} - -// NewMultiTenantBearerAuthorizer creates a MultiTenantBearerAuthorizer using the given token provider. -func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer { - return &MultiTenantBearerAuthorizer{tp: tp} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the -// primary token along with the auxiliary authorization header using the auxiliary tokens. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - if refresher, ok := mt.tp.(adal.RefresherWithContext); ok { - err = refresher.EnsureFreshWithContext(r.Context()) - if err != nil { - var resp *http.Response - if tokError, ok := err.(adal.TokenRefreshError); ok { - resp = tokError.Response() - } - return r, NewErrorWithError(err, "azure.multiTenantSPTAuthorizer", "WithAuthorization", resp, - "Failed to refresh one or more Tokens for request to %s", r.URL) - } - } - r, err = Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", mt.tp.PrimaryOAuthToken()))) - if err != nil { - return r, err - } - auxTokens := mt.tp.AuxiliaryOAuthTokens() - for i := range auxTokens { - auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i]) - } - return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, ", "))) - }) - } -} - -// TokenProvider returns the underlying MultitenantOAuthTokenProvider for this authorizer. -func (mt *MultiTenantBearerAuthorizer) TokenProvider() adal.MultitenantOAuthTokenProvider { - return mt.tp -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go b/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go deleted file mode 100644 index 66501493bd..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go +++ /dev/null @@ -1,66 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "fmt" - "net/http" - "strings" -) - -// SASTokenAuthorizer implements an authorization for SAS Token Authentication -// this can be used for interaction with Blob Storage Endpoints -type SASTokenAuthorizer struct { - sasToken string -} - -// NewSASTokenAuthorizer creates a SASTokenAuthorizer using the given credentials -func NewSASTokenAuthorizer(sasToken string) (*SASTokenAuthorizer, error) { - if strings.TrimSpace(sasToken) == "" { - return nil, fmt.Errorf("sasToken cannot be empty") - } - - token := sasToken - if strings.HasPrefix(sasToken, "?") { - token = strings.TrimPrefix(sasToken, "?") - } - - return &SASTokenAuthorizer{ - sasToken: token, - }, nil -} - -// WithAuthorization returns a PrepareDecorator that adds a shared access signature token to the -// URI's query parameters. This can be used for the Blob, Queue, and File Services. -// -// See https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature -func (sas *SASTokenAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - - if r.URL.RawQuery == "" { - r.URL.RawQuery = sas.sasToken - } else if !strings.Contains(r.URL.RawQuery, sas.sasToken) { - r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken) - } - - return Prepare(r) - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go b/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go deleted file mode 100644 index 2af5030a1c..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go +++ /dev/null @@ -1,307 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "fmt" - "net/http" - "net/url" - "sort" - "strings" - "time" -) - -// SharedKeyType defines the enumeration for the various shared key types. -// See https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key for details on the shared key types. -type SharedKeyType string - -const ( - // SharedKey is used to authorize against blobs, files and queues services. - SharedKey SharedKeyType = "sharedKey" - - // SharedKeyForTable is used to authorize against the table service. - SharedKeyForTable SharedKeyType = "sharedKeyTable" - - // SharedKeyLite is used to authorize against blobs, files and queues services. It's provided for - // backwards compatibility with API versions before 2009-09-19. Prefer SharedKey instead. - SharedKeyLite SharedKeyType = "sharedKeyLite" - - // SharedKeyLiteForTable is used to authorize against the table service. It's provided for - // backwards compatibility with older table API versions. Prefer SharedKeyForTable instead. - SharedKeyLiteForTable SharedKeyType = "sharedKeyLiteTable" -) - -const ( - headerAccept = "Accept" - headerAcceptCharset = "Accept-Charset" - headerContentEncoding = "Content-Encoding" - headerContentLength = "Content-Length" - headerContentMD5 = "Content-MD5" - headerContentLanguage = "Content-Language" - headerIfModifiedSince = "If-Modified-Since" - headerIfMatch = "If-Match" - headerIfNoneMatch = "If-None-Match" - headerIfUnmodifiedSince = "If-Unmodified-Since" - headerDate = "Date" - headerXMSDate = "X-Ms-Date" - headerXMSVersion = "x-ms-version" - headerRange = "Range" -) - -const storageEmulatorAccountName = "devstoreaccount1" - -// SharedKeyAuthorizer implements an authorization for Shared Key -// this can be used for interaction with Blob, File and Queue Storage Endpoints -type SharedKeyAuthorizer struct { - accountName string - accountKey []byte - keyType SharedKeyType -} - -// NewSharedKeyAuthorizer creates a SharedKeyAuthorizer using the provided credentials and shared key type. -func NewSharedKeyAuthorizer(accountName, accountKey string, keyType SharedKeyType) (*SharedKeyAuthorizer, error) { - key, err := base64.StdEncoding.DecodeString(accountKey) - if err != nil { - return nil, fmt.Errorf("malformed storage account key: %v", err) - } - return &SharedKeyAuthorizer{ - accountName: accountName, - accountKey: key, - keyType: keyType, - }, nil -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is " " followed by the computed key. -// This can be used for the Blob, Queue, and File Services -// -// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key -// You may use Shared Key authorization to authorize a request made against the -// 2009-09-19 version and later of the Blob and Queue services, -// and version 2014-02-14 and later of the File services. -func (sk *SharedKeyAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - - sk, err := buildSharedKey(sk.accountName, sk.accountKey, r, sk.keyType) - if err != nil { - return r, err - } - return Prepare(r, WithHeader(headerAuthorization, sk)) - }) - } -} - -func buildSharedKey(accName string, accKey []byte, req *http.Request, keyType SharedKeyType) (string, error) { - canRes, err := buildCanonicalizedResource(accName, req.URL.String(), keyType) - if err != nil { - return "", err - } - - if req.Header == nil { - req.Header = http.Header{} - } - - // ensure date is set - if req.Header.Get(headerDate) == "" && req.Header.Get(headerXMSDate) == "" { - date := time.Now().UTC().Format(http.TimeFormat) - req.Header.Set(headerXMSDate, date) - } - canString, err := buildCanonicalizedString(req.Method, req.Header, canRes, keyType) - if err != nil { - return "", err - } - return createAuthorizationHeader(accName, accKey, canString, keyType), nil -} - -func buildCanonicalizedResource(accountName, uri string, keyType SharedKeyType) (string, error) { - errMsg := "buildCanonicalizedResource error: %s" - u, err := url.Parse(uri) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - cr := bytes.NewBufferString("") - if accountName != storageEmulatorAccountName { - cr.WriteString("/") - cr.WriteString(getCanonicalizedAccountName(accountName)) - } - - if len(u.Path) > 0 { - // Any portion of the CanonicalizedResource string that is derived from - // the resource's URI should be encoded exactly as it is in the URI. - // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx - cr.WriteString(u.EscapedPath()) - } else { - // a slash is required to indicate the root path - cr.WriteString("/") - } - - params, err := url.ParseQuery(u.RawQuery) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - // See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277 - if keyType == SharedKey { - if len(params) > 0 { - cr.WriteString("\n") - - keys := []string{} - for key := range params { - keys = append(keys, key) - } - sort.Strings(keys) - - completeParams := []string{} - for _, key := range keys { - if len(params[key]) > 1 { - sort.Strings(params[key]) - } - - completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ","))) - } - cr.WriteString(strings.Join(completeParams, "\n")) - } - } else { - // search for "comp" parameter, if exists then add it to canonicalizedresource - if v, ok := params["comp"]; ok { - cr.WriteString("?comp=" + v[0]) - } - } - - return string(cr.Bytes()), nil -} - -func getCanonicalizedAccountName(accountName string) string { - // since we may be trying to access a secondary storage account, we need to - // remove the -secondary part of the storage name - return strings.TrimSuffix(accountName, "-secondary") -} - -func buildCanonicalizedString(verb string, headers http.Header, canonicalizedResource string, keyType SharedKeyType) (string, error) { - contentLength := headers.Get(headerContentLength) - if contentLength == "0" { - contentLength = "" - } - date := headers.Get(headerDate) - if v := headers.Get(headerXMSDate); v != "" { - if keyType == SharedKey || keyType == SharedKeyLite { - date = "" - } else { - date = v - } - } - var canString string - switch keyType { - case SharedKey: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentEncoding), - headers.Get(headerContentLanguage), - contentLength, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - headers.Get(headerIfModifiedSince), - headers.Get(headerIfMatch), - headers.Get(headerIfNoneMatch), - headers.Get(headerIfUnmodifiedSince), - headers.Get(headerRange), - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case SharedKeyForTable: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - canonicalizedResource, - }, "\n") - case SharedKeyLite: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case SharedKeyLiteForTable: - canString = strings.Join([]string{ - date, - canonicalizedResource, - }, "\n") - default: - return "", fmt.Errorf("key type '%s' is not supported", keyType) - } - return canString, nil -} - -func buildCanonicalizedHeader(headers http.Header) string { - cm := make(map[string]string) - - for k := range headers { - headerName := strings.TrimSpace(strings.ToLower(k)) - if strings.HasPrefix(headerName, "x-ms-") { - cm[headerName] = headers.Get(k) - } - } - - if len(cm) == 0 { - return "" - } - - keys := []string{} - for key := range cm { - keys = append(keys, key) - } - - sort.Strings(keys) - - ch := bytes.NewBufferString("") - - for _, key := range keys { - ch.WriteString(key) - ch.WriteRune(':') - ch.WriteString(cm[key]) - ch.WriteRune('\n') - } - - return strings.TrimSuffix(string(ch.Bytes()), "\n") -} - -func createAuthorizationHeader(accountName string, accountKey []byte, canonicalizedString string, keyType SharedKeyType) string { - h := hmac.New(sha256.New, accountKey) - h.Write([]byte(canonicalizedString)) - signature := base64.StdEncoding.EncodeToString(h.Sum(nil)) - var key string - switch keyType { - case SharedKey, SharedKeyForTable: - key = "SharedKey" - case SharedKeyLite, SharedKeyLiteForTable: - key = "SharedKeyLite" - } - return fmt.Sprintf("%s %s:%s", key, getCanonicalizedAccountName(accountName), signature) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go deleted file mode 100644 index aafdf021fd..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/autorest.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines -and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) -generated Go code. - -The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, -and Responding. A typical pattern is: - - req, err := Prepare(&http.Request{}, - token.WithAuthorization()) - - resp, err := Send(req, - WithLogging(logger), - DoErrorIfStatusCode(http.StatusInternalServerError), - DoCloseIfError(), - DoRetryForAttempts(5, time.Second)) - - err = Respond(resp, - ByDiscardingBody(), - ByClosing()) - -Each phase relies on decorators to modify and / or manage processing. Decorators may first modify -and then pass the data along, pass the data first and then modify the result, or wrap themselves -around passing the data (such as a logger might do). Decorators run in the order provided. For -example, the following: - - req, err := Prepare(&http.Request{}, - WithBaseURL("https://microsoft.com/"), - WithPath("a"), - WithPath("b"), - WithPath("c")) - -will set the URL to: - - https://microsoft.com/a/b/c - -Preparers and Responders may be shared and re-used (assuming the underlying decorators support -sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders -shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, -all bound together by means of input / output channels. - -Decorators hold their passed state within a closure (such as the path components in the example -above). Be careful to share Preparers and Responders only in a context where such held state -applies. For example, it may not make sense to share a Preparer that applies a query string from a -fixed set of values. Similarly, sharing a Responder that reads the response body into a passed -struct (e.g., ByUnmarshallingJson) is likely incorrect. - -Lastly, the Swagger specification (https://swagger.io) that drives AutoRest -(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The -github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure -correct parsing and formatting. - -Errors raised by autorest objects and methods will conform to the autorest.Error interface. - -See the included examples for more detail. For details on the suggested use of this package by -generated clients, see the Client described below. -*/ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "context" - "net/http" - "time" -) - -const ( - // HeaderLocation specifies the HTTP Location header. - HeaderLocation = "Location" - - // HeaderRetryAfter specifies the HTTP Retry-After header. - HeaderRetryAfter = "Retry-After" -) - -// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set -// and false otherwise. -func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { - if resp == nil { - return false - } - return containsInt(codes, resp.StatusCode) -} - -// GetLocation retrieves the URL from the Location header of the passed response. -func GetLocation(resp *http.Response) string { - return resp.Header.Get(HeaderLocation) -} - -// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If -// the header is absent or is malformed, it will return the supplied default delay time.Duration. -func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration { - retry := resp.Header.Get(HeaderRetryAfter) - if retry == "" { - return defaultDelay - } - - d, err := time.ParseDuration(retry + "s") - if err != nil { - return defaultDelay - } - - return d -} - -// NewPollingRequest allocates and returns a new http.Request to poll for the passed response. -func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) { - location := GetLocation(resp) - if location == "" { - return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling") - } - - req, err := Prepare(&http.Request{Cancel: cancel}, - AsGet(), - WithBaseURL(location)) - if err != nil { - return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location) - } - - return req, nil -} - -// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response. -func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) { - location := GetLocation(resp) - if location == "" { - return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling") - } - - req, err := Prepare((&http.Request{}).WithContext(ctx), - AsGet(), - WithBaseURL(location)) - if err != nil { - return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location) - } - - return req, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go deleted file mode 100644 index 45575eedbf..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ /dev/null @@ -1,995 +0,0 @@ -package azure - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "strings" - "time" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/logger" - "github.com/Azure/go-autorest/tracing" -) - -const ( - headerAsyncOperation = "Azure-AsyncOperation" -) - -const ( - operationInProgress string = "InProgress" - operationCanceled string = "Canceled" - operationFailed string = "Failed" - operationSucceeded string = "Succeeded" -) - -var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK} - -// FutureAPI contains the set of methods on the Future type. -type FutureAPI interface { - // Response returns the last HTTP response. - Response() *http.Response - - // Status returns the last status message of the operation. - Status() string - - // PollingMethod returns the method used to monitor the status of the asynchronous operation. - PollingMethod() PollingMethodType - - // DoneWithContext queries the service to see if the operation has completed. - DoneWithContext(context.Context, autorest.Sender) (bool, error) - - // GetPollingDelay returns a duration the application should wait before checking - // the status of the asynchronous request and true; this value is returned from - // the service via the Retry-After response header. If the header wasn't returned - // then the function returns the zero-value time.Duration and false. - GetPollingDelay() (time.Duration, bool) - - // WaitForCompletionRef will return when one of the following conditions is met: the long - // running operation has completed, the provided context is cancelled, or the client's - // polling duration has been exceeded. It will retry failed polling attempts based on - // the retry value defined in the client up to the maximum retry attempts. - // If no deadline is specified in the context then the client.PollingDuration will be - // used to determine if a default deadline should be used. - // If PollingDuration is greater than zero the value will be used as the context's timeout. - // If PollingDuration is zero then no default deadline will be used. - WaitForCompletionRef(context.Context, autorest.Client) error - - // MarshalJSON implements the json.Marshaler interface. - MarshalJSON() ([]byte, error) - - // MarshalJSON implements the json.Unmarshaler interface. - UnmarshalJSON([]byte) error - - // PollingURL returns the URL used for retrieving the status of the long-running operation. - PollingURL() string - - // GetResult should be called once polling has completed successfully. - // It makes the final GET call to retrieve the resultant payload. - GetResult(autorest.Sender) (*http.Response, error) -} - -var _ FutureAPI = (*Future)(nil) - -// Future provides a mechanism to access the status and results of an asynchronous request. -// Since futures are stateful they should be passed by value to avoid race conditions. -type Future struct { - pt pollingTracker -} - -// NewFutureFromResponse returns a new Future object initialized -// with the initial response from an asynchronous operation. -func NewFutureFromResponse(resp *http.Response) (Future, error) { - pt, err := createPollingTracker(resp) - return Future{pt: pt}, err -} - -// Response returns the last HTTP response. -func (f Future) Response() *http.Response { - if f.pt == nil { - return nil - } - return f.pt.latestResponse() -} - -// Status returns the last status message of the operation. -func (f Future) Status() string { - if f.pt == nil { - return "" - } - return f.pt.pollingStatus() -} - -// PollingMethod returns the method used to monitor the status of the asynchronous operation. -func (f Future) PollingMethod() PollingMethodType { - if f.pt == nil { - return PollingUnknown - } - return f.pt.pollingMethod() -} - -// DoneWithContext queries the service to see if the operation has completed. -func (f *Future) DoneWithContext(ctx context.Context, sender autorest.Sender) (done bool, err error) { - ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.DoneWithContext") - defer func() { - sc := -1 - resp := f.Response() - if resp != nil { - sc = resp.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - - if f.pt == nil { - return false, autorest.NewError("Future", "Done", "future is not initialized") - } - if f.pt.hasTerminated() { - return true, f.pt.pollingError() - } - if err := f.pt.pollForStatus(ctx, sender); err != nil { - return false, err - } - if err := f.pt.checkForErrors(); err != nil { - return f.pt.hasTerminated(), err - } - if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil { - return false, err - } - if err := f.pt.initPollingMethod(); err != nil { - return false, err - } - if err := f.pt.updatePollingMethod(); err != nil { - return false, err - } - return f.pt.hasTerminated(), f.pt.pollingError() -} - -// GetPollingDelay returns a duration the application should wait before checking -// the status of the asynchronous request and true; this value is returned from -// the service via the Retry-After response header. If the header wasn't returned -// then the function returns the zero-value time.Duration and false. -func (f Future) GetPollingDelay() (time.Duration, bool) { - if f.pt == nil { - return 0, false - } - resp := f.pt.latestResponse() - if resp == nil { - return 0, false - } - - retry := resp.Header.Get(autorest.HeaderRetryAfter) - if retry == "" { - return 0, false - } - - d, err := time.ParseDuration(retry + "s") - if err != nil { - panic(err) - } - - return d, true -} - -// WaitForCompletionRef will return when one of the following conditions is met: the long -// running operation has completed, the provided context is cancelled, or the client's -// polling duration has been exceeded. It will retry failed polling attempts based on -// the retry value defined in the client up to the maximum retry attempts. -// If no deadline is specified in the context then the client.PollingDuration will be -// used to determine if a default deadline should be used. -// If PollingDuration is greater than zero the value will be used as the context's timeout. -// If PollingDuration is zero then no default deadline will be used. -func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) (err error) { - ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.WaitForCompletionRef") - defer func() { - sc := -1 - resp := f.Response() - if resp != nil { - sc = resp.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - cancelCtx := ctx - // if the provided context already has a deadline don't override it - _, hasDeadline := ctx.Deadline() - if d := client.PollingDuration; !hasDeadline && d != 0 { - var cancel context.CancelFunc - cancelCtx, cancel = context.WithTimeout(ctx, d) - defer cancel() - } - // if the initial response has a Retry-After, sleep for the specified amount of time before starting to poll - if delay, ok := f.GetPollingDelay(); ok { - logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: initial polling delay") - if delayElapsed := autorest.DelayForBackoff(delay, 0, cancelCtx.Done()); !delayElapsed { - err = cancelCtx.Err() - return - } - } - done, err := f.DoneWithContext(ctx, client) - for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) { - if attempts >= client.RetryAttempts { - return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded") - } - // we want delayAttempt to be zero in the non-error case so - // that DelayForBackoff doesn't perform exponential back-off - var delayAttempt int - var delay time.Duration - if err == nil { - // check for Retry-After delay, if not present use the client's polling delay - var ok bool - delay, ok = f.GetPollingDelay() - if !ok { - logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: Using client polling delay") - delay = client.PollingDelay - } - } else { - // there was an error polling for status so perform exponential - // back-off based on the number of attempts using the client's retry - // duration. update attempts after delayAttempt to avoid off-by-one. - logger.Instance.Writef(logger.LogError, "WaitForCompletionRef: %s\n", err) - delayAttempt = attempts - delay = client.RetryDuration - attempts++ - } - // wait until the delay elapses or the context is cancelled - delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done()) - if !delayElapsed { - return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled") - } - } - return -} - -// MarshalJSON implements the json.Marshaler interface. -func (f Future) MarshalJSON() ([]byte, error) { - return json.Marshal(f.pt) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (f *Future) UnmarshalJSON(data []byte) error { - // unmarshal into JSON object to determine the tracker type - obj := map[string]interface{}{} - err := json.Unmarshal(data, &obj) - if err != nil { - return err - } - if obj["method"] == nil { - return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property") - } - method := obj["method"].(string) - switch strings.ToUpper(method) { - case http.MethodDelete: - f.pt = &pollingTrackerDelete{} - case http.MethodPatch: - f.pt = &pollingTrackerPatch{} - case http.MethodPost: - f.pt = &pollingTrackerPost{} - case http.MethodPut: - f.pt = &pollingTrackerPut{} - default: - return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method) - } - // now unmarshal into the tracker - return json.Unmarshal(data, &f.pt) -} - -// PollingURL returns the URL used for retrieving the status of the long-running operation. -func (f Future) PollingURL() string { - if f.pt == nil { - return "" - } - return f.pt.pollingURL() -} - -// GetResult should be called once polling has completed successfully. -// It makes the final GET call to retrieve the resultant payload. -func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) { - if f.pt.finalGetURL() == "" { - // we can end up in this situation if the async operation returns a 200 - // with no polling URLs. in that case return the response which should - // contain the JSON payload (only do this for successful terminal cases). - if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() { - return lr, nil - } - return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result") - } - req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil) - if err != nil { - return nil, err - } - resp, err := sender.Do(req) - if err == nil && resp.Body != nil { - // copy the body and close it so callers don't have to - defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - return resp, err - } - resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - return resp, err -} - -type pollingTracker interface { - // these methods can differ per tracker - - // checks the response headers and status code to determine the polling mechanism - updatePollingMethod() error - - // checks the response for tracker-specific error conditions - checkForErrors() error - - // returns true if provisioning state should be checked - provisioningStateApplicable() bool - - // methods common to all trackers - - // initializes a tracker's polling URL and method, called for each iteration. - // these values can be overridden by each polling tracker as required. - initPollingMethod() error - - // initializes the tracker's internal state, call this when the tracker is created - initializeState() error - - // makes an HTTP request to check the status of the LRO - pollForStatus(ctx context.Context, sender autorest.Sender) error - - // updates internal tracker state, call this after each call to pollForStatus - updatePollingState(provStateApl bool) error - - // returns the error response from the service, can be nil - pollingError() error - - // returns the polling method being used - pollingMethod() PollingMethodType - - // returns the state of the LRO as returned from the service - pollingStatus() string - - // returns the URL used for polling status - pollingURL() string - - // returns the URL used for the final GET to retrieve the resource - finalGetURL() string - - // returns true if the LRO is in a terminal state - hasTerminated() bool - - // returns true if the LRO is in a failed terminal state - hasFailed() bool - - // returns true if the LRO is in a successful terminal state - hasSucceeded() bool - - // returns the cached HTTP response after a call to pollForStatus(), can be nil - latestResponse() *http.Response -} - -type pollingTrackerBase struct { - // resp is the last response, either from the submission of the LRO or from polling - resp *http.Response - - // method is the HTTP verb, this is needed for deserialization - Method string `json:"method"` - - // rawBody is the raw JSON response body - rawBody map[string]interface{} - - // denotes if polling is using async-operation or location header - Pm PollingMethodType `json:"pollingMethod"` - - // the URL to poll for status - URI string `json:"pollingURI"` - - // the state of the LRO as returned from the service - State string `json:"lroState"` - - // the URL to GET for the final result - FinalGetURI string `json:"resultURI"` - - // used to hold an error object returned from the service - Err *ServiceError `json:"error,omitempty"` -} - -func (pt *pollingTrackerBase) initializeState() error { - // determine the initial polling state based on response body and/or HTTP status - // code. this is applicable to the initial LRO response, not polling responses! - pt.Method = pt.resp.Request.Method - if err := pt.updateRawBody(); err != nil { - return err - } - switch pt.resp.StatusCode { - case http.StatusOK: - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - if pt.hasFailed() { - pt.updateErrorFromResponse() - return pt.pollingError() - } - } else { - pt.State = operationSucceeded - } - case http.StatusCreated: - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - } else { - pt.State = operationInProgress - } - case http.StatusAccepted: - pt.State = operationInProgress - case http.StatusNoContent: - pt.State = operationSucceeded - default: - pt.State = operationFailed - pt.updateErrorFromResponse() - return pt.pollingError() - } - return pt.initPollingMethod() -} - -func (pt pollingTrackerBase) getProvisioningState() *string { - if pt.rawBody != nil && pt.rawBody["properties"] != nil { - p := pt.rawBody["properties"].(map[string]interface{}) - if ps := p["provisioningState"]; ps != nil { - s := ps.(string) - return &s - } - } - return nil -} - -func (pt *pollingTrackerBase) updateRawBody() error { - pt.rawBody = map[string]interface{}{} - if pt.resp.ContentLength != 0 { - defer pt.resp.Body.Close() - b, err := ioutil.ReadAll(pt.resp.Body) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body") - } - // put the body back so it's available to other callers - pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - // observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty - if len(b) == 0 { - return nil - } - if err = json.Unmarshal(b, &pt.rawBody); err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body") - } - } - return nil -} - -func (pt *pollingTrackerBase) pollForStatus(ctx context.Context, sender autorest.Sender) error { - req, err := http.NewRequest(http.MethodGet, pt.URI, nil) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request") - } - - req = req.WithContext(ctx) - preparer := autorest.CreatePreparer(autorest.GetPrepareDecorators(ctx)...) - req, err = preparer.Prepare(req) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed preparing HTTP request") - } - pt.resp, err = sender.Do(req) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request") - } - if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) { - // reset the service error on success case - pt.Err = nil - err = pt.updateRawBody() - } else { - // check response body for error content - pt.updateErrorFromResponse() - err = pt.pollingError() - } - return err -} - -// attempts to unmarshal a ServiceError type from the response body. -// if that fails then make a best attempt at creating something meaningful. -// NOTE: this assumes that the async operation has failed. -func (pt *pollingTrackerBase) updateErrorFromResponse() { - var err error - if pt.resp.ContentLength != 0 { - type respErr struct { - ServiceError *ServiceError `json:"error"` - } - re := respErr{} - defer pt.resp.Body.Close() - var b []byte - if b, err = ioutil.ReadAll(pt.resp.Body); err != nil { - goto Default - } - // put the body back so it's available to other callers - pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - if len(b) == 0 { - goto Default - } - if err = json.Unmarshal(b, &re); err != nil { - goto Default - } - // unmarshalling the error didn't yield anything, try unwrapped error - if re.ServiceError == nil { - err = json.Unmarshal(b, &re.ServiceError) - if err != nil { - goto Default - } - } - // the unmarshaller will ensure re.ServiceError is non-nil - // even if there was no content unmarshalled so check the code. - if re.ServiceError.Code != "" { - pt.Err = re.ServiceError - return - } - } -Default: - se := &ServiceError{ - Code: pt.pollingStatus(), - Message: "The async operation failed.", - } - if err != nil { - se.InnerError = make(map[string]interface{}) - se.InnerError["unmarshalError"] = err.Error() - } - // stick the response body into the error object in hopes - // it contains something useful to help diagnose the failure. - if len(pt.rawBody) > 0 { - se.AdditionalInfo = []map[string]interface{}{ - pt.rawBody, - } - } - pt.Err = se -} - -func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error { - if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil { - pt.State = pt.rawBody["status"].(string) - } else { - if pt.resp.StatusCode == http.StatusAccepted { - pt.State = operationInProgress - } else if provStateApl { - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - } else { - pt.State = operationSucceeded - } - } else { - return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code") - } - } - // if the operation has failed update the error state - if pt.hasFailed() { - pt.updateErrorFromResponse() - } - return nil -} - -func (pt pollingTrackerBase) pollingError() error { - if pt.Err == nil { - return nil - } - return pt.Err -} - -func (pt pollingTrackerBase) pollingMethod() PollingMethodType { - return pt.Pm -} - -func (pt pollingTrackerBase) pollingStatus() string { - return pt.State -} - -func (pt pollingTrackerBase) pollingURL() string { - return pt.URI -} - -func (pt pollingTrackerBase) finalGetURL() string { - return pt.FinalGetURI -} - -func (pt pollingTrackerBase) hasTerminated() bool { - return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded) -} - -func (pt pollingTrackerBase) hasFailed() bool { - return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) -} - -func (pt pollingTrackerBase) hasSucceeded() bool { - return strings.EqualFold(pt.State, operationSucceeded) -} - -func (pt pollingTrackerBase) latestResponse() *http.Response { - return pt.resp -} - -// error checking common to all trackers -func (pt pollingTrackerBase) baseCheckForErrors() error { - // for Azure-AsyncOperations the response body cannot be nil or empty - if pt.Pm == PollingAsyncOperation { - if pt.resp.Body == nil || pt.resp.ContentLength == 0 { - return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil") - } - if pt.rawBody["status"] == nil { - return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body") - } - } - return nil -} - -// default initialization of polling URL/method. each verb tracker will update this as required. -func (pt *pollingTrackerBase) initPollingMethod() error { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - return nil - } - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh != "" { - pt.URI = lh - pt.Pm = PollingLocation - return nil - } - // it's ok if we didn't find a polling header, this will be handled elsewhere - return nil -} - -// DELETE - -type pollingTrackerDelete struct { - pollingTrackerBase -} - -func (pt *pollingTrackerDelete) updatePollingMethod() error { - // for 201 the Location header is required - if pt.resp.StatusCode == http.StatusCreated { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response") - } else { - pt.URI = lh - } - pt.Pm = PollingLocation - pt.FinalGetURI = pt.URI - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - // when both headers are returned we use the value in the Location header for the final GET - pt.FinalGetURI = lh - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerDelete) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerDelete) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent -} - -// PATCH - -type pollingTrackerPatch struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPatch) updatePollingMethod() error { - // by default we can use the original URL for polling and final GET - if pt.URI == "" { - pt.URI = pt.resp.Request.URL.String() - } - if pt.FinalGetURI == "" { - pt.FinalGetURI = pt.resp.Request.URL.String() - } - if pt.Pm == PollingUnknown { - pt.Pm = PollingRequestURI - } - // for 201 it's permissible for no headers to be returned - if pt.resp.StatusCode == http.StatusCreated { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - // note the absence of the "final GET" mechanism for PATCH - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - if ao == "" { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } else { - pt.URI = lh - pt.Pm = PollingLocation - } - } - } - return nil -} - -func (pt pollingTrackerPatch) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerPatch) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated -} - -// POST - -type pollingTrackerPost struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPost) updatePollingMethod() error { - // 201 requires Location header - if pt.resp.StatusCode == http.StatusCreated { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response") - } else { - pt.URI = lh - pt.FinalGetURI = lh - pt.Pm = PollingLocation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - // when both headers are returned we use the value in the Location header for the final GET - pt.FinalGetURI = lh - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerPost) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerPost) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent -} - -// PUT - -type pollingTrackerPut struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPut) updatePollingMethod() error { - // by default we can use the original URL for polling and final GET - if pt.URI == "" { - pt.URI = pt.resp.Request.URL.String() - } - if pt.FinalGetURI == "" { - pt.FinalGetURI = pt.resp.Request.URL.String() - } - if pt.Pm == PollingUnknown { - pt.Pm = PollingRequestURI - } - // for 201 it's permissible for no headers to be returned - if pt.resp.StatusCode == http.StatusCreated { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerPut) checkForErrors() error { - err := pt.baseCheckForErrors() - if err != nil { - return err - } - // if there are no LRO headers then the body cannot be empty - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } - lh, err := getURLFromLocationHeader(pt.resp) - if err != nil { - return err - } - if ao == "" && lh == "" && len(pt.rawBody) == 0 { - return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body") - } - return nil -} - -func (pt pollingTrackerPut) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated -} - -// creates a polling tracker based on the verb of the original request -func createPollingTracker(resp *http.Response) (pollingTracker, error) { - var pt pollingTracker - switch strings.ToUpper(resp.Request.Method) { - case http.MethodDelete: - pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPatch: - pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPost: - pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPut: - pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}} - default: - return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method) - } - if err := pt.initializeState(); err != nil { - return pt, err - } - // this initializes the polling header values, we do this during creation in case the - // initial response send us invalid values; this way the API call will return a non-nil - // error (not doing this means the error shows up in Future.Done) - return pt, pt.updatePollingMethod() -} - -// gets the polling URL from the Azure-AsyncOperation header. -// ensures the URL is well-formed and absolute. -func getURLFromAsyncOpHeader(resp *http.Response) (string, error) { - s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) - if s == "" { - return "", nil - } - if !isValidURL(s) { - return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s) - } - return s, nil -} - -// gets the polling URL from the Location header. -// ensures the URL is well-formed and absolute. -func getURLFromLocationHeader(resp *http.Response) (string, error) { - s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation)) - if s == "" { - return "", nil - } - if !isValidURL(s) { - return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s) - } - return s, nil -} - -// verify that the URL is valid and absolute -func isValidURL(s string) bool { - u, err := url.Parse(s) - return err == nil && u.IsAbs() -} - -// PollingMethodType defines a type used for enumerating polling mechanisms. -type PollingMethodType string - -const ( - // PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header. - PollingAsyncOperation PollingMethodType = "AsyncOperation" - - // PollingLocation indicates the polling method uses the Location header. - PollingLocation PollingMethodType = "Location" - - // PollingRequestURI indicates the polling method uses the original request URI. - PollingRequestURI PollingMethodType = "RequestURI" - - // PollingUnknown indicates an unknown polling method and is the default value. - PollingUnknown PollingMethodType = "" -) - -// AsyncOpIncompleteError is the type that's returned from a future that has not completed. -type AsyncOpIncompleteError struct { - // FutureType is the name of the type composed of a azure.Future. - FutureType string -} - -// Error returns an error message including the originating type name of the error. -func (e AsyncOpIncompleteError) Error() string { - return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType) -} - -// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters. -func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError { - return AsyncOpIncompleteError{ - FutureType: futureType, - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go deleted file mode 100644 index 1328f1764c..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go +++ /dev/null @@ -1,388 +0,0 @@ -// Package azure provides Azure-specific implementations used with AutoRest. -// See the included examples for more detail. -package azure - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "regexp" - "strconv" - "strings" - - "github.com/Azure/go-autorest/autorest" -) - -const ( - // HeaderClientID is the Azure extension header to set a user-specified request ID. - HeaderClientID = "x-ms-client-request-id" - - // HeaderReturnClientID is the Azure extension header to set if the user-specified request ID - // should be included in the response. - HeaderReturnClientID = "x-ms-return-client-request-id" - - // HeaderContentType is the type of the content in the HTTP response. - HeaderContentType = "Content-Type" - - // HeaderRequestID is the Azure extension header of the service generated request ID returned - // in the response. - HeaderRequestID = "x-ms-request-id" -) - -// ServiceError encapsulates the error response from an Azure service. -// It adhears to the OData v4 specification for error responses. -type ServiceError struct { - Code string `json:"code"` - Message string `json:"message"` - Target *string `json:"target"` - Details []map[string]interface{} `json:"details"` - InnerError map[string]interface{} `json:"innererror"` - AdditionalInfo []map[string]interface{} `json:"additionalInfo"` -} - -func (se ServiceError) Error() string { - result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) - - if se.Target != nil { - result += fmt.Sprintf(" Target=%q", *se.Target) - } - - if se.Details != nil { - d, err := json.Marshal(se.Details) - if err != nil { - result += fmt.Sprintf(" Details=%v", se.Details) - } - result += fmt.Sprintf(" Details=%s", d) - } - - if se.InnerError != nil { - d, err := json.Marshal(se.InnerError) - if err != nil { - result += fmt.Sprintf(" InnerError=%v", se.InnerError) - } - result += fmt.Sprintf(" InnerError=%s", d) - } - - if se.AdditionalInfo != nil { - d, err := json.Marshal(se.AdditionalInfo) - if err != nil { - result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo) - } - result += fmt.Sprintf(" AdditionalInfo=%s", d) - } - - return result -} - -// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type. -func (se *ServiceError) UnmarshalJSON(b []byte) error { - // http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091 - - type serviceErrorInternal struct { - Code string `json:"code"` - Message string `json:"message"` - Target *string `json:"target,omitempty"` - AdditionalInfo []map[string]interface{} `json:"additionalInfo,omitempty"` - // not all services conform to the OData v4 spec. - // the following fields are where we've seen discrepancies - - // spec calls for []map[string]interface{} but have seen map[string]interface{} - Details interface{} `json:"details,omitempty"` - - // spec calls for map[string]interface{} but have seen []map[string]interface{} and string - InnerError interface{} `json:"innererror,omitempty"` - } - - sei := serviceErrorInternal{} - if err := json.Unmarshal(b, &sei); err != nil { - return err - } - - // copy the fields we know to be correct - se.AdditionalInfo = sei.AdditionalInfo - se.Code = sei.Code - se.Message = sei.Message - se.Target = sei.Target - - // converts an []interface{} to []map[string]interface{} - arrayOfObjs := func(v interface{}) ([]map[string]interface{}, bool) { - arrayOf, ok := v.([]interface{}) - if !ok { - return nil, false - } - final := []map[string]interface{}{} - for _, item := range arrayOf { - as, ok := item.(map[string]interface{}) - if !ok { - return nil, false - } - final = append(final, as) - } - return final, true - } - - // convert the remaining fields, falling back to raw JSON if necessary - - if c, ok := arrayOfObjs(sei.Details); ok { - se.Details = c - } else if c, ok := sei.Details.(map[string]interface{}); ok { - se.Details = []map[string]interface{}{c} - } else if sei.Details != nil { - // stuff into Details - se.Details = []map[string]interface{}{ - {"raw": sei.Details}, - } - } - - if c, ok := sei.InnerError.(map[string]interface{}); ok { - se.InnerError = c - } else if c, ok := arrayOfObjs(sei.InnerError); ok { - // if there's only one error extract it - if len(c) == 1 { - se.InnerError = c[0] - } else { - // multiple errors, stuff them into the value - se.InnerError = map[string]interface{}{ - "multi": c, - } - } - } else if c, ok := sei.InnerError.(string); ok { - se.InnerError = map[string]interface{}{"error": c} - } else if sei.InnerError != nil { - // stuff into InnerError - se.InnerError = map[string]interface{}{ - "raw": sei.InnerError, - } - } - return nil -} - -// RequestError describes an error response returned by Azure service. -type RequestError struct { - autorest.DetailedError - - // The error returned by the Azure service. - ServiceError *ServiceError `json:"error" xml:"Error"` - - // The request id (from the x-ms-request-id-header) of the request. - RequestID string -} - -// Error returns a human-friendly error message from service error. -func (e RequestError) Error() string { - return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v", - e.StatusCode, e.ServiceError) -} - -// IsAzureError returns true if the passed error is an Azure Service error; false otherwise. -func IsAzureError(e error) bool { - _, ok := e.(*RequestError) - return ok -} - -// Resource contains details about an Azure resource. -type Resource struct { - SubscriptionID string - ResourceGroup string - Provider string - ResourceType string - ResourceName string -} - -// String function returns a string in form of azureResourceID -func (r Resource) String() string { - return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s", r.SubscriptionID, r.ResourceGroup, r.Provider, r.ResourceType, r.ResourceName) -} - -// ParseResourceID parses a resource ID into a ResourceDetails struct. -// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource?tabs=json#resourceid. -func ParseResourceID(resourceID string) (Resource, error) { - - const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)` - resourceIDPattern := regexp.MustCompile(resourceIDPatternText) - match := resourceIDPattern.FindStringSubmatch(resourceID) - - if len(match) == 0 { - return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID) - } - - v := strings.Split(match[5], "/") - resourceName := v[len(v)-1] - - result := Resource{ - SubscriptionID: match[1], - ResourceGroup: match[2], - Provider: match[3], - ResourceType: match[4], - ResourceName: resourceName, - } - - return result, nil -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError { - if v, ok := original.(*RequestError); ok { - return *v - } - - statusCode := autorest.UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - return RequestError{ - DetailedError: autorest.DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - }, - } -} - -// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id -// header to true such that UUID accompanies the http.Response. -func WithReturningClientID(uuid string) autorest.PrepareDecorator { - preparer := autorest.CreatePreparer( - WithClientID(uuid), - WithReturnClientID(true)) - - return func(p autorest.Preparer) autorest.Preparer { - return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - return preparer.Prepare(r) - }) - } -} - -// WithClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). -func WithClientID(uuid string) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderClientID, uuid) -} - -// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-return-client-request-id whose boolean value indicates if the value of the -// x-ms-client-request-id header should be included in the http.Response. -func WithReturnClientID(b bool) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b)) -} - -// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the -// http.Request sent to the service (and returned in the http.Response) -func ExtractClientID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderClientID, resp) -} - -// ExtractRequestID extracts the Azure server generated request identifier from the -// x-ms-request-id header. -func ExtractRequestID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderRequestID, resp) -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an -// azure.RequestError by reading the response body unless the response HTTP status code -// is among the set passed. -// -// If there is a chance service may return responses other than the Azure error -// format and the response cannot be parsed into an error, a decoding error will -// be returned containing the response body. In any case, the Responder will -// return an error if the status code is not satisfied. -// -// If this Responder returns an error, the response body will be replaced with -// an in-memory reader, which needs no further closing. -func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { - return func(r autorest.Responder) autorest.Responder { - return autorest.ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) { - var e RequestError - defer resp.Body.Close() - - encodedAs := autorest.EncodedAsJSON - if strings.Contains(resp.Header.Get("Content-Type"), "xml") { - encodedAs = autorest.EncodedAsXML - } - - // Copy and replace the Body in case it does not contain an error object. - // This will leave the Body available to the caller. - b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e) - resp.Body = ioutil.NopCloser(&b) - if decodeErr != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, decodeErr) - } - if e.ServiceError == nil { - // Check if error is unwrapped ServiceError - decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) - if err := decoder.Decode(&e.ServiceError); err != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) - } - - // for example, should the API return the literal value `null` as the response - if e.ServiceError == nil { - e.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "Unknown service error", - Details: []map[string]interface{}{ - { - "HttpResponse.Body": b.String(), - }, - }, - } - } - } - - if e.ServiceError != nil && e.ServiceError.Message == "" { - // if we're here it means the returned error wasn't OData v4 compliant. - // try to unmarshal the body in hopes of getting something. - rawBody := map[string]interface{}{} - decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) - if err := decoder.Decode(&rawBody); err != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) - } - - e.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "Unknown service error", - } - if len(rawBody) > 0 { - e.ServiceError.Details = []map[string]interface{}{rawBody} - } - } - e.Response = resp - e.RequestID = ExtractRequestID(resp) - if e.StatusCode == nil { - e.StatusCode = resp.StatusCode - } - err = &e - } - return err - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go deleted file mode 100644 index b0a53769f2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ /dev/null @@ -1,331 +0,0 @@ -package azure - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "strings" -) - -const ( - // EnvironmentFilepathName captures the name of the environment variable containing the path to the file - // to be used while populating the Azure Environment. - EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH" - - // NotAvailable is used for endpoints and resource IDs that are not available for a given cloud. - NotAvailable = "N/A" -) - -var environments = map[string]Environment{ - "AZURECHINACLOUD": ChinaCloud, - "AZUREGERMANCLOUD": GermanCloud, - "AZURECLOUD": PublicCloud, - "AZUREPUBLICCLOUD": PublicCloud, - "AZUREUSGOVERNMENT": USGovernmentCloud, - "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, //TODO: deprecate -} - -// ResourceIdentifier contains a set of Azure resource IDs. -type ResourceIdentifier struct { - Graph string `json:"graph"` - KeyVault string `json:"keyVault"` - Datalake string `json:"datalake"` - Batch string `json:"batch"` - OperationalInsights string `json:"operationalInsights"` - OSSRDBMS string `json:"ossRDBMS"` - Storage string `json:"storage"` - Synapse string `json:"synapse"` - ServiceBus string `json:"serviceBus"` - SQLDatabase string `json:"sqlDatabase"` - CosmosDB string `json:"cosmosDB"` - ManagedHSM string `json:"managedHSM"` - MicrosoftGraph string `json:"microsoftGraph"` -} - -// Environment represents a set of endpoints for each of Azure's Clouds. -type Environment struct { - Name string `json:"name"` - ManagementPortalURL string `json:"managementPortalURL"` - PublishSettingsURL string `json:"publishSettingsURL"` - ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` - ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` - ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` - GalleryEndpoint string `json:"galleryEndpoint"` - KeyVaultEndpoint string `json:"keyVaultEndpoint"` - ManagedHSMEndpoint string `json:"managedHSMEndpoint"` - GraphEndpoint string `json:"graphEndpoint"` - ServiceBusEndpoint string `json:"serviceBusEndpoint"` - BatchManagementEndpoint string `json:"batchManagementEndpoint"` - MicrosoftGraphEndpoint string `json:"microsoftGraphEndpoint"` - StorageEndpointSuffix string `json:"storageEndpointSuffix"` - CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"` - MariaDBDNSSuffix string `json:"mariaDBDNSSuffix"` - MySQLDatabaseDNSSuffix string `json:"mySqlDatabaseDNSSuffix"` - PostgresqlDatabaseDNSSuffix string `json:"postgresqlDatabaseDNSSuffix"` - SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` - TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` - KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` - ManagedHSMDNSSuffix string `json:"managedHSMDNSSuffix"` - ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` - ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` - ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` - ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` - TokenAudience string `json:"tokenAudience"` - APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"` - SynapseEndpointSuffix string `json:"synapseEndpointSuffix"` - DatalakeSuffix string `json:"datalakeSuffix"` - ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"` -} - -var ( - // PublicCloud is the default public Azure cloud environment - PublicCloud = Environment{ - Name: "AzurePublicCloud", - ManagementPortalURL: "https://manage.windowsazure.com/", - PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.windows.net/", - ResourceManagerEndpoint: "https://management.azure.com/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", - GalleryEndpoint: "https://gallery.azure.com/", - KeyVaultEndpoint: "https://vault.azure.net/", - ManagedHSMEndpoint: "https://managedhsm.azure.net/", - GraphEndpoint: "https://graph.windows.net/", - ServiceBusEndpoint: "https://servicebus.windows.net/", - BatchManagementEndpoint: "https://batch.core.windows.net/", - MicrosoftGraphEndpoint: "https://graph.microsoft.com/", - StorageEndpointSuffix: "core.windows.net", - CosmosDBDNSSuffix: "documents.azure.com", - MariaDBDNSSuffix: "mariadb.database.azure.com", - MySQLDatabaseDNSSuffix: "mysql.database.azure.com", - PostgresqlDatabaseDNSSuffix: "postgres.database.azure.com", - SQLDatabaseDNSSuffix: "database.windows.net", - TrafficManagerDNSSuffix: "trafficmanager.net", - KeyVaultDNSSuffix: "vault.azure.net", - ManagedHSMDNSSuffix: "managedhsm.azure.net", - ServiceBusEndpointSuffix: "servicebus.windows.net", - ServiceManagementVMDNSSuffix: "cloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.azure.com", - ContainerRegistryDNSSuffix: "azurecr.io", - TokenAudience: "https://management.azure.com/", - APIManagementHostNameSuffix: "azure-api.net", - SynapseEndpointSuffix: "dev.azuresynapse.net", - DatalakeSuffix: "azuredatalakestore.net", - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.windows.net/", - KeyVault: "https://vault.azure.net", - Datalake: "https://datalake.azure.net/", - Batch: "https://batch.core.windows.net/", - OperationalInsights: "https://api.loganalytics.io", - OSSRDBMS: "https://ossrdbms-aad.database.windows.net", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.windows.net/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: "https://managedhsm.azure.net", - MicrosoftGraph: "https://graph.microsoft.com/", - }, - } - - // USGovernmentCloud is the cloud environment for the US Government - USGovernmentCloud = Environment{ - Name: "AzureUSGovernmentCloud", - ManagementPortalURL: "https://manage.windowsazure.us/", - PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", - ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.us/", - GalleryEndpoint: "https://gallery.usgovcloudapi.net/", - KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.windows.net/", - ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/", - BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/", - MicrosoftGraphEndpoint: "https://graph.microsoft.us/", - StorageEndpointSuffix: "core.usgovcloudapi.net", - CosmosDBDNSSuffix: "documents.azure.us", - MariaDBDNSSuffix: "mariadb.database.usgovcloudapi.net", - MySQLDatabaseDNSSuffix: "mysql.database.usgovcloudapi.net", - PostgresqlDatabaseDNSSuffix: "postgres.database.usgovcloudapi.net", - SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", - TrafficManagerDNSSuffix: "usgovtrafficmanager.net", - KeyVaultDNSSuffix: "vault.usgovcloudapi.net", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net", - ServiceManagementVMDNSSuffix: "usgovcloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.usgovcloudapi.net", - ContainerRegistryDNSSuffix: "azurecr.us", - TokenAudience: "https://management.usgovcloudapi.net/", - APIManagementHostNameSuffix: "azure-api.us", - SynapseEndpointSuffix: "dev.azuresynapse.usgovcloudapi.net", - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.windows.net/", - KeyVault: "https://vault.usgovcloudapi.net", - Datalake: NotAvailable, - Batch: "https://batch.core.usgovcloudapi.net/", - OperationalInsights: "https://api.loganalytics.us", - OSSRDBMS: "https://ossrdbms-aad.database.usgovcloudapi.net", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.usgovcloudapi.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.usgovcloudapi.net/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: "https://graph.microsoft.us/", - }, - } - - // ChinaCloud is the cloud environment operated in China - ChinaCloud = Environment{ - Name: "AzureChinaCloud", - ManagementPortalURL: "https://manage.chinacloudapi.com/", - PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/", - ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", - ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/", - GalleryEndpoint: "https://gallery.chinacloudapi.cn/", - KeyVaultEndpoint: "https://vault.azure.cn/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.chinacloudapi.cn/", - ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/", - BatchManagementEndpoint: "https://batch.chinacloudapi.cn/", - MicrosoftGraphEndpoint: "https://microsoftgraph.chinacloudapi.cn/", - StorageEndpointSuffix: "core.chinacloudapi.cn", - CosmosDBDNSSuffix: "documents.azure.cn", - MariaDBDNSSuffix: "mariadb.database.chinacloudapi.cn", - MySQLDatabaseDNSSuffix: "mysql.database.chinacloudapi.cn", - PostgresqlDatabaseDNSSuffix: "postgres.database.chinacloudapi.cn", - SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", - TrafficManagerDNSSuffix: "trafficmanager.cn", - KeyVaultDNSSuffix: "vault.azure.cn", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn", - ServiceManagementVMDNSSuffix: "chinacloudapp.cn", - ResourceManagerVMDNSSuffix: "cloudapp.chinacloudapi.cn", - ContainerRegistryDNSSuffix: "azurecr.cn", - TokenAudience: "https://management.chinacloudapi.cn/", - APIManagementHostNameSuffix: "azure-api.cn", - SynapseEndpointSuffix: "dev.azuresynapse.azure.cn", - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.chinacloudapi.cn/", - KeyVault: "https://vault.azure.cn", - Datalake: NotAvailable, - Batch: "https://batch.chinacloudapi.cn/", - OperationalInsights: NotAvailable, - OSSRDBMS: "https://ossrdbms-aad.database.chinacloudapi.cn", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.chinacloudapi.cn/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: "https://microsoftgraph.chinacloudapi.cn", - }, - } - - // GermanCloud is the cloud environment operated in Germany - GermanCloud = Environment{ - Name: "AzureGermanCloud", - ManagementPortalURL: "http://portal.microsoftazure.de/", - PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.cloudapi.de/", - ResourceManagerEndpoint: "https://management.microsoftazure.de/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", - GalleryEndpoint: "https://gallery.cloudapi.de/", - KeyVaultEndpoint: "https://vault.microsoftazure.de/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.cloudapi.de/", - ServiceBusEndpoint: "https://servicebus.cloudapi.de/", - BatchManagementEndpoint: "https://batch.cloudapi.de/", - MicrosoftGraphEndpoint: NotAvailable, - StorageEndpointSuffix: "core.cloudapi.de", - CosmosDBDNSSuffix: "documents.microsoftazure.de", - MariaDBDNSSuffix: "mariadb.database.cloudapi.de", - MySQLDatabaseDNSSuffix: "mysql.database.cloudapi.de", - PostgresqlDatabaseDNSSuffix: "postgres.database.cloudapi.de", - SQLDatabaseDNSSuffix: "database.cloudapi.de", - TrafficManagerDNSSuffix: "azuretrafficmanager.de", - KeyVaultDNSSuffix: "vault.microsoftazure.de", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.cloudapi.de", - ServiceManagementVMDNSSuffix: "azurecloudapp.de", - ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de", - ContainerRegistryDNSSuffix: NotAvailable, - TokenAudience: "https://management.microsoftazure.de/", - APIManagementHostNameSuffix: NotAvailable, - SynapseEndpointSuffix: NotAvailable, - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.cloudapi.de/", - KeyVault: "https://vault.microsoftazure.de", - Datalake: NotAvailable, - Batch: "https://batch.cloudapi.de/", - OperationalInsights: NotAvailable, - OSSRDBMS: "https://ossrdbms-aad.database.cloudapi.de", - Storage: "https://storage.azure.com/", - Synapse: NotAvailable, - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.cloudapi.de/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: NotAvailable, - }, - } -) - -// EnvironmentFromName returns an Environment based on the common name specified. -func EnvironmentFromName(name string) (Environment, error) { - // IMPORTANT - // As per @radhikagupta5: - // This is technical debt, fundamentally here because Kubernetes is not currently accepting - // contributions to the providers. Once that is an option, the provider should be updated to - // directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation - // from this method based on the name that is provided to us. - if strings.EqualFold(name, "AZURESTACKCLOUD") { - return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName)) - } - - name = strings.ToUpper(name) - env, ok := environments[name] - if !ok { - return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) - } - - return env, nil -} - -// EnvironmentFromFile loads an Environment from a configuration file available on disk. -// This function is particularly useful in the Hybrid Cloud model, where one must define their own -// endpoints. -func EnvironmentFromFile(location string) (unmarshaled Environment, err error) { - fileContents, err := ioutil.ReadFile(location) - if err != nil { - return - } - - err = json.Unmarshal(fileContents, &unmarshaled) - - return -} - -// SetEnvironment updates the environment map with the specified values. -func SetEnvironment(name string, env Environment) { - environments[strings.ToUpper(name)] = env -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go deleted file mode 100644 index 507f9e95cf..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go +++ /dev/null @@ -1,245 +0,0 @@ -package azure - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" - - "github.com/Azure/go-autorest/autorest" -) - -// Copyright 2017 Microsoft Corporation -// -// 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. - -type audience []string - -type authentication struct { - LoginEndpoint string `json:"loginEndpoint"` - Audiences audience `json:"audiences"` -} - -type environmentMetadataInfo struct { - GalleryEndpoint string `json:"galleryEndpoint"` - GraphEndpoint string `json:"graphEndpoint"` - PortalEndpoint string `json:"portalEndpoint"` - Authentication authentication `json:"authentication"` -} - -// EnvironmentProperty represent property names that clients can override -type EnvironmentProperty string - -const ( - // EnvironmentName ... - EnvironmentName EnvironmentProperty = "name" - // EnvironmentManagementPortalURL .. - EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL" - // EnvironmentPublishSettingsURL ... - EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL" - // EnvironmentServiceManagementEndpoint ... - EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint" - // EnvironmentResourceManagerEndpoint ... - EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint" - // EnvironmentActiveDirectoryEndpoint ... - EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint" - // EnvironmentGalleryEndpoint ... - EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint" - // EnvironmentKeyVaultEndpoint ... - EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint" - // EnvironmentGraphEndpoint ... - EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint" - // EnvironmentServiceBusEndpoint ... - EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint" - // EnvironmentBatchManagementEndpoint ... - EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint" - // EnvironmentStorageEndpointSuffix ... - EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix" - // EnvironmentSQLDatabaseDNSSuffix ... - EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix" - // EnvironmentTrafficManagerDNSSuffix ... - EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix" - // EnvironmentKeyVaultDNSSuffix ... - EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix" - // EnvironmentServiceBusEndpointSuffix ... - EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix" - // EnvironmentServiceManagementVMDNSSuffix ... - EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix" - // EnvironmentResourceManagerVMDNSSuffix ... - EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix" - // EnvironmentContainerRegistryDNSSuffix ... - EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix" - // EnvironmentTokenAudience ... - EnvironmentTokenAudience EnvironmentProperty = "tokenAudience" -) - -// OverrideProperty represents property name and value that clients can override -type OverrideProperty struct { - Key EnvironmentProperty - Value string -} - -// EnvironmentFromURL loads an Environment from a URL -// This function is particularly useful in the Hybrid Cloud model, where one may define their own -// endpoints. -func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) { - var metadataEnvProperties environmentMetadataInfo - - if resourceManagerEndpoint == "" { - return environment, fmt.Errorf("Metadata resource manager endpoint is empty") - } - - if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil { - return environment, err - } - - // Give priority to user's override values - overrideProperties(&environment, properties) - - if environment.Name == "" { - environment.Name = "HybridEnvironment" - } - stampDNSSuffix := environment.StorageEndpointSuffix - if stampDNSSuffix == "" { - stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/") - environment.StorageEndpointSuffix = stampDNSSuffix - } - if environment.KeyVaultDNSSuffix == "" { - environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix) - } - if environment.KeyVaultEndpoint == "" { - environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix) - } - if environment.TokenAudience == "" { - environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0] - } - if environment.ActiveDirectoryEndpoint == "" { - environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint - } - if environment.ResourceManagerEndpoint == "" { - environment.ResourceManagerEndpoint = resourceManagerEndpoint - } - if environment.GalleryEndpoint == "" { - environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint - } - if environment.GraphEndpoint == "" { - environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint - } - - return environment, nil -} - -func overrideProperties(environment *Environment, properties []OverrideProperty) { - for _, property := range properties { - switch property.Key { - case EnvironmentName: - { - environment.Name = property.Value - } - case EnvironmentManagementPortalURL: - { - environment.ManagementPortalURL = property.Value - } - case EnvironmentPublishSettingsURL: - { - environment.PublishSettingsURL = property.Value - } - case EnvironmentServiceManagementEndpoint: - { - environment.ServiceManagementEndpoint = property.Value - } - case EnvironmentResourceManagerEndpoint: - { - environment.ResourceManagerEndpoint = property.Value - } - case EnvironmentActiveDirectoryEndpoint: - { - environment.ActiveDirectoryEndpoint = property.Value - } - case EnvironmentGalleryEndpoint: - { - environment.GalleryEndpoint = property.Value - } - case EnvironmentKeyVaultEndpoint: - { - environment.KeyVaultEndpoint = property.Value - } - case EnvironmentGraphEndpoint: - { - environment.GraphEndpoint = property.Value - } - case EnvironmentServiceBusEndpoint: - { - environment.ServiceBusEndpoint = property.Value - } - case EnvironmentBatchManagementEndpoint: - { - environment.BatchManagementEndpoint = property.Value - } - case EnvironmentStorageEndpointSuffix: - { - environment.StorageEndpointSuffix = property.Value - } - case EnvironmentSQLDatabaseDNSSuffix: - { - environment.SQLDatabaseDNSSuffix = property.Value - } - case EnvironmentTrafficManagerDNSSuffix: - { - environment.TrafficManagerDNSSuffix = property.Value - } - case EnvironmentKeyVaultDNSSuffix: - { - environment.KeyVaultDNSSuffix = property.Value - } - case EnvironmentServiceBusEndpointSuffix: - { - environment.ServiceBusEndpointSuffix = property.Value - } - case EnvironmentServiceManagementVMDNSSuffix: - { - environment.ServiceManagementVMDNSSuffix = property.Value - } - case EnvironmentResourceManagerVMDNSSuffix: - { - environment.ResourceManagerVMDNSSuffix = property.Value - } - case EnvironmentContainerRegistryDNSSuffix: - { - environment.ContainerRegistryDNSSuffix = property.Value - } - case EnvironmentTokenAudience: - { - environment.TokenAudience = property.Value - } - } - } -} - -func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) { - client := autorest.NewClientWithUserAgent("") - managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0") - req, _ := http.NewRequest("GET", managementEndpoint, nil) - response, err := client.Do(req) - if err != nil { - return environment, err - } - defer response.Body.Close() - jsonResponse, err := ioutil.ReadAll(response.Body) - if err != nil { - return environment, err - } - err = json.Unmarshal(jsonResponse, &environment) - return environment, err -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go deleted file mode 100644 index 5b52357f95..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2017 Microsoft Corporation -// -// 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 azure - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/Azure/go-autorest/autorest" -) - -// DoRetryWithRegistration tries to register the resource provider in case it is unregistered. -// It also handles request retries -func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator { - return func(s autorest.Sender) autorest.Sender { - return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := autorest.NewRetriableRequest(r) - for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - - resp, err = autorest.SendWithSender(s, rr.Request(), - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return resp, err - } - - if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration { - return resp, err - } - - var re RequestError - if strings.Contains(r.Header.Get("Content-Type"), "xml") { - // XML errors (e.g. Storage Data Plane) only return the inner object - err = autorest.Respond(resp, autorest.ByUnmarshallingXML(&re.ServiceError)) - } else { - err = autorest.Respond(resp, autorest.ByUnmarshallingJSON(&re)) - } - - if err != nil { - return resp, err - } - err = re - - if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" { - regErr := register(client, r, re) - if regErr != nil { - return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %w", regErr, err) - } - } - } - return resp, err - }) - } -} - -func getProvider(re RequestError) (string, error) { - if re.ServiceError != nil && len(re.ServiceError.Details) > 0 { - return re.ServiceError.Details[0]["target"].(string), nil - } - return "", errors.New("provider was not found in the response") -} - -func register(client autorest.Client, originalReq *http.Request, re RequestError) error { - subID := getSubscription(originalReq.URL.Path) - if subID == "" { - return errors.New("missing parameter subscriptionID to register resource provider") - } - providerName, err := getProvider(re) - if err != nil { - return fmt.Errorf("missing parameter provider to register resource provider: %s", err) - } - newURL := url.URL{ - Scheme: originalReq.URL.Scheme, - Host: originalReq.URL.Host, - } - - // taken from the resources SDK - // with almost identical code, this sections are easier to mantain - // It is also not a good idea to import the SDK here - // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252 - pathParameters := map[string]interface{}{ - "resourceProviderNamespace": autorest.Encode("path", providerName), - "subscriptionId": autorest.Encode("path", subID), - } - - const APIVersion = "2016-09-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsPost(), - autorest.WithBaseURL(newURL.String()), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters), - autorest.WithQueryParameters(queryParameters), - ) - - req, err := preparer.Prepare(&http.Request{}) - if err != nil { - return err - } - req = req.WithContext(originalReq.Context()) - - resp, err := autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return err - } - - type Provider struct { - RegistrationState *string `json:"registrationState,omitempty"` - } - var provider Provider - - err = autorest.Respond( - resp, - WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&provider), - autorest.ByClosing(), - ) - if err != nil { - return err - } - - // poll for registered provisioning state - registrationStartTime := time.Now() - for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) { - // taken from the resources SDK - // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45 - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(newURL.String()), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters), - autorest.WithQueryParameters(queryParameters), - ) - req, err = preparer.Prepare(&http.Request{}) - if err != nil { - return err - } - req = req.WithContext(originalReq.Context()) - - resp, err := autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return err - } - - err = autorest.Respond( - resp, - WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&provider), - autorest.ByClosing(), - ) - if err != nil { - return err - } - - if provider.RegistrationState != nil && - *provider.RegistrationState == "Registered" { - break - } - - delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done()) - if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) { - return originalReq.Context().Err() - } - } - if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) { - return errors.New("polling for resource provider registration has exceeded the polling duration") - } - return err -} - -func getSubscription(path string) string { - parts := strings.Split(path, "/") - for i, v := range parts { - if v == "subscriptions" && (i+1) < len(parts) { - return parts[i+1] - } - } - return "" -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go deleted file mode 100644 index bb5f9396e9..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ /dev/null @@ -1,328 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "crypto/tls" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "strings" - "time" - - "github.com/Azure/go-autorest/logger" -) - -const ( - // DefaultPollingDelay is a reasonable delay between polling requests. - DefaultPollingDelay = 30 * time.Second - - // DefaultPollingDuration is a reasonable total polling duration. - DefaultPollingDuration = 15 * time.Minute - - // DefaultRetryAttempts is number of attempts for retry status codes (5xx). - DefaultRetryAttempts = 3 - - // DefaultRetryDuration is the duration to wait between retries. - DefaultRetryDuration = 30 * time.Second -) - -var ( - // StatusCodesForRetry are a defined group of status code for which the client will retry - StatusCodesForRetry = []int{ - http.StatusRequestTimeout, // 408 - http.StatusTooManyRequests, // 429 - http.StatusInternalServerError, // 500 - http.StatusBadGateway, // 502 - http.StatusServiceUnavailable, // 503 - http.StatusGatewayTimeout, // 504 - } -) - -const ( - requestFormat = `HTTP Request Begin =================================================== -%s -===================================================== HTTP Request End -` - responseFormat = `HTTP Response Begin =================================================== -%s -===================================================== HTTP Response End -` -) - -// Response serves as the base for all responses from generated clients. It provides access to the -// last http.Response. -type Response struct { - *http.Response `json:"-"` -} - -// IsHTTPStatus returns true if the returned HTTP status code matches the provided status code. -// If there was no response (i.e. the underlying http.Response is nil) the return value is false. -func (r Response) IsHTTPStatus(statusCode int) bool { - if r.Response == nil { - return false - } - return r.Response.StatusCode == statusCode -} - -// HasHTTPStatus returns true if the returned HTTP status code matches one of the provided status codes. -// If there was no response (i.e. the underlying http.Response is nil) or not status codes are provided -// the return value is false. -func (r Response) HasHTTPStatus(statusCodes ...int) bool { - return ResponseHasStatusCode(r.Response, statusCodes...) -} - -// LoggingInspector implements request and response inspectors that log the full request and -// response to a supplied log. -type LoggingInspector struct { - Logger *log.Logger -} - -// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) WithInspection() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - var body, b bytes.Buffer - - defer r.Body.Close() - - r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body)) - if err := r.Write(&b); err != nil { - return nil, fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(requestFormat, b.String()) - - r.Body = ioutil.NopCloser(&body) - return p.Prepare(r) - }) - } -} - -// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) ByInspecting() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - var body, b bytes.Buffer - defer resp.Body.Close() - resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body)) - if err := resp.Write(&b); err != nil { - return fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(responseFormat, b.String()) - - resp.Body = ioutil.NopCloser(&body) - return r.Respond(resp) - }) - } -} - -// Client is the base for autorest generated clients. It provides default, "do nothing" -// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the -// standard, undecorated http.Client as a default Sender. -// -// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and -// return responses that compose with Response. -// -// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom -// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit -// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence -// sending the request by providing a decorated Sender. -type Client struct { - Authorizer Authorizer - Sender Sender - RequestInspector PrepareDecorator - ResponseInspector RespondDecorator - - // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header - PollingDelay time.Duration - - // PollingDuration sets the maximum polling time after which an error is returned. - // Setting this to zero will use the provided context to control the duration. - PollingDuration time.Duration - - // RetryAttempts sets the total number of times the client will attempt to make an HTTP request. - // Set the value to 1 to disable retries. DO NOT set the value to less than 1. - RetryAttempts int - - // RetryDuration sets the delay duration for retries. - RetryDuration time.Duration - - // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent - // through the Do method. - UserAgent string - - Jar http.CookieJar - - // Set to true to skip attempted registration of resource providers (false by default). - SkipResourceProviderRegistration bool - - // SendDecorators can be used to override the default chain of SendDecorators. - // This can be used to specify things like a custom retry SendDecorator. - // Set this to an empty slice to use no SendDecorators. - SendDecorators []SendDecorator -} - -// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed -// string. -func NewClientWithUserAgent(ua string) Client { - return newClient(ua, tls.RenegotiateNever) -} - -// ClientOptions contains various Client configuration options. -type ClientOptions struct { - // UserAgent is an optional user-agent string to append to the default user agent. - UserAgent string - - // Renegotiation is an optional setting to control client-side TLS renegotiation. - Renegotiation tls.RenegotiationSupport -} - -// NewClientWithOptions returns an instance of a Client with the specified values. -func NewClientWithOptions(options ClientOptions) Client { - return newClient(options.UserAgent, options.Renegotiation) -} - -func newClient(ua string, renegotiation tls.RenegotiationSupport) Client { - c := Client{ - PollingDelay: DefaultPollingDelay, - PollingDuration: DefaultPollingDuration, - RetryAttempts: DefaultRetryAttempts, - RetryDuration: DefaultRetryDuration, - UserAgent: UserAgent(), - } - c.Sender = c.sender(renegotiation) - c.AddToUserAgent(ua) - return c -} - -// AddToUserAgent adds an extension to the current user agent -func (c *Client) AddToUserAgent(extension string) error { - if extension != "" { - c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent) -} - -// Do implements the Sender interface by invoking the active Sender after applying authorization. -// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent -// is set, apply set the User-Agent header. -func (c Client) Do(r *http.Request) (*http.Response, error) { - if r.UserAgent() == "" { - r, _ = Prepare(r, - WithUserAgent(c.UserAgent)) - } - // NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations - r, err := Prepare(r, - c.WithAuthorization(), - c.WithInspection()) - if err != nil { - var resp *http.Response - if detErr, ok := err.(DetailedError); ok { - // if the authorization failed (e.g. invalid credentials) there will - // be a response associated with the error, be sure to return it. - resp = detErr.Response - } - return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") - } - logger.Instance.WriteRequest(r, logger.Filter{ - Header: func(k string, v []string) (bool, []string) { - // remove the auth token from the log - if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") { - v = []string{"**REDACTED**"} - } - return true, v - }, - }) - resp, err := SendWithSender(c.sender(tls.RenegotiateNever), r) - if resp == nil && err == nil { - err = errors.New("autorest: received nil response and error") - } - logger.Instance.WriteResponse(resp, logger.Filter{}) - Respond(resp, c.ByInspecting()) - return resp, err -} - -// sender returns the Sender to which to send requests. -func (c Client) sender(renengotiation tls.RenegotiationSupport) Sender { - if c.Sender == nil { - return sender(renengotiation) - } - return c.Sender -} - -// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator -// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer. -func (c Client) WithAuthorization() PrepareDecorator { - return c.authorizer().WithAuthorization() -} - -// authorizer returns the Authorizer to use. -func (c Client) authorizer() Authorizer { - if c.Authorizer == nil { - return NullAuthorizer{} - } - return c.Authorizer -} - -// WithInspection is a convenience method that passes the request to the supplied RequestInspector, -// if present, or returns the WithNothing PrepareDecorator otherwise. -func (c Client) WithInspection() PrepareDecorator { - if c.RequestInspector == nil { - return WithNothing() - } - return c.RequestInspector -} - -// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, -// if present, or returns the ByIgnoring RespondDecorator otherwise. -func (c Client) ByInspecting() RespondDecorator { - if c.ResponseInspector == nil { - return ByIgnoring() - } - return c.ResponseInspector -} - -// Send sends the provided http.Request using the client's Sender or the default sender. -// It returns the http.Response and possible error. It also accepts a, possibly empty, -// default set of SendDecorators used when sending the request. -// SendDecorators have the following precedence: -// 1. In a request's context via WithSendDecorators() -// 2. Specified on the client in SendDecorators -// 3. The default values specified in this method -func (c Client) Send(req *http.Request, decorators ...SendDecorator) (*http.Response, error) { - if c.SendDecorators != nil { - decorators = c.SendDecorators - } - inCtx := req.Context().Value(ctxSendDecorators{}) - if sd, ok := inCtx.([]SendDecorator); ok { - decorators = sd - } - return SendWithSender(c, req, decorators...) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go deleted file mode 100644 index c457106568..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/date.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) -defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of -time.Time types. And both convert to time.Time through a ToTime method. -*/ -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "fmt" - "time" -) - -const ( - fullDate = "2006-01-02" - fullDateJSON = `"2006-01-02"` - dateFormat = "%04d-%02d-%02d" - jsonFormat = `"%04d-%02d-%02d"` -) - -// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e., -// 2006-01-02). -type Date struct { - time.Time -} - -// ParseDate create a new Date from the passed string. -func ParseDate(date string) (d Date, err error) { - return parseDate(date, fullDate) -} - -func parseDate(date string, format string) (Date, error) { - d, err := time.Parse(format, date) - return Date{Time: d}, err -} - -// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalBinary() ([]byte, error) { - return d.MarshalText() -} - -// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalBinary(data []byte) error { - return d.UnmarshalText(data) -} - -// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalJSON() (json []byte, err error) { - return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalJSON(data []byte) (err error) { - d.Time, err = time.Parse(fullDateJSON, string(data)) - return err -} - -// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalText() (text []byte, err error) { - return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalText(data []byte) (err error) { - d.Time, err = time.Parse(fullDate, string(data)) - return err -} - -// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02). -func (d Date) String() string { - return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day()) -} - -// ToTime returns a Date as a time.Time -func (d Date) ToTime() time.Time { - return d.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go deleted file mode 100644 index 4e05432071..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go deleted file mode 100644 index b453fad049..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/time.go +++ /dev/null @@ -1,103 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "regexp" - "time" -) - -// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. -const ( - azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"` - azureUtcFormat = "2006-01-02T15:04:05.999999999" - rfc3339JSON = `"` + time.RFC3339Nano + `"` - rfc3339 = time.RFC3339Nano - tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$` -) - -// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -type Time struct { - time.Time -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalBinary() ([]byte, error) { - return t.Time.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalJSON() (json []byte, err error) { - return t.Time.MarshalJSON() -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalJSON(data []byte) (err error) { - timeFormat := azureUtcFormatJSON - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339JSON - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalText() (text []byte, err error) { - return t.Time.MarshalText() -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalText(data []byte) (err error) { - timeFormat := azureUtcFormat - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339 - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// String returns the Time formatted as an RFC3339 date-time string (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) String() string { - // Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} - -// ToTime returns a Time as a time.Time -func (t Time) ToTime() time.Time { - return t.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go deleted file mode 100644 index 48fb39ba9b..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go +++ /dev/null @@ -1,100 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "errors" - "time" -) - -const ( - rfc1123JSON = `"` + time.RFC1123 + `"` - rfc1123 = time.RFC1123 -) - -// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -type TimeRFC1123 struct { - time.Time -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123JSON, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalJSON() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") - } - b := []byte(t.Format(rfc1123JSON)) - return b, nil -} - -// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalText() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") - } - - b := []byte(t.Format(rfc1123)) - return b, nil -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalBinary() ([]byte, error) { - return t.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// ToTime returns a Time as a time.Time -func (t TimeRFC1123) ToTime() time.Time { - return t.Time -} - -// String returns the Time formatted as an RFC1123 date-time string (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) String() string { - // Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go deleted file mode 100644 index 7073959b2a..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go +++ /dev/null @@ -1,123 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "time" -) - -// unixEpoch is the moment in time that should be treated as timestamp 0. -var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC) - -// UnixTime marshals and unmarshals a time that is represented as the number -// of seconds (ignoring skip-seconds) since the Unix Epoch. -type UnixTime time.Time - -// Duration returns the time as a Duration since the UnixEpoch. -func (t UnixTime) Duration() time.Duration { - return time.Time(t).Sub(unixEpoch) -} - -// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch. -func NewUnixTimeFromSeconds(seconds float64) UnixTime { - return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second))) -} - -// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch. -func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime { - return NewUnixTimeFromDuration(time.Duration(nanoseconds)) -} - -// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch. -func NewUnixTimeFromDuration(dur time.Duration) UnixTime { - return UnixTime(unixEpoch.Add(dur)) -} - -// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0' -func UnixEpoch() time.Time { - return unixEpoch -} - -// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements. -// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.) -func (t UnixTime) MarshalJSON() ([]byte, error) { - buffer := &bytes.Buffer{} - enc := json.NewEncoder(buffer) - err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9) - if err != nil { - return nil, err - } - return buffer.Bytes(), nil -} - -// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since -// midnight January 1st, 1970. -func (t *UnixTime) UnmarshalJSON(text []byte) error { - dec := json.NewDecoder(bytes.NewReader(text)) - - var secondsSinceEpoch float64 - if err := dec.Decode(&secondsSinceEpoch); err != nil { - return err - } - - *t = NewUnixTimeFromSeconds(secondsSinceEpoch) - - return nil -} - -// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number. -func (t UnixTime) MarshalText() ([]byte, error) { - cast := time.Time(t) - return cast.MarshalText() -} - -// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch. -func (t *UnixTime) UnmarshalText(raw []byte) error { - var unmarshaled time.Time - - if err := unmarshaled.UnmarshalText(raw); err != nil { - return err - } - - *t = UnixTime(unmarshaled) - return nil -} - -// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch. -func (t UnixTime) MarshalBinary() ([]byte, error) { - buf := &bytes.Buffer{} - - payload := int64(t.Duration()) - - if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime. -func (t *UnixTime) UnmarshalBinary(raw []byte) error { - var nanosecondsSinceEpoch int64 - - if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil { - return err - } - *t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch) - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go deleted file mode 100644 index 12addf0ebb..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go +++ /dev/null @@ -1,25 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "strings" - "time" -) - -// ParseTime to parse Time string to specified format. -func ParseTime(format string, t string) (d time.Time, err error) { - return time.Parse(format, strings.ToUpper(t)) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go deleted file mode 100644 index 35098eda8e..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/error.go +++ /dev/null @@ -1,103 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "fmt" - "net/http" -) - -const ( - // UndefinedStatusCode is used when HTTP status code is not available for an error. - UndefinedStatusCode = 0 -) - -// DetailedError encloses a error with details of the package, method, and associated HTTP -// status code (if any). -type DetailedError struct { - Original error - - // PackageType is the package type of the object emitting the error. For types, the value - // matches that produced the the '%T' format specifier of the fmt package. For other elements, - // such as functions, it is just the package name (e.g., "autorest"). - PackageType string - - // Method is the name of the method raising the error. - Method string - - // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. - StatusCode interface{} - - // Message is the error message. - Message string - - // Service Error is the response body of failed API in bytes - ServiceError []byte - - // Response is the response object that was returned during failure if applicable. - Response *http.Response -} - -// NewError creates a new Error conforming object from the passed packageType, method, and -// message. message is treated as a format string to which the optional args apply. -func NewError(packageType string, method string, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, nil, message, args...) -} - -// NewErrorWithResponse creates a new Error conforming object from the passed -// packageType, method, statusCode of the given resp (UndefinedStatusCode if -// resp is nil), and message. message is treated as a format string to which the -// optional args apply. -func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, resp, message, args...) -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - if v, ok := original.(DetailedError); ok { - return v - } - - statusCode := UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - - return DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - Response: resp, - } -} - -// Error returns a formatted containing all available details (i.e., PackageType, Method, -// StatusCode, Message, and original error (if any)). -func (e DetailedError) Error() string { - if e.Original == nil { - return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode) - } - return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original) -} - -// Unwrap returns the original error. -func (e DetailedError) Unwrap() error { - return e.Original -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go deleted file mode 100644 index 792f82d4b6..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go deleted file mode 100644 index 121a66fa88..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ /dev/null @@ -1,549 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "context" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "net/url" - "strings" -) - -const ( - mimeTypeJSON = "application/json" - mimeTypeOctetStream = "application/octet-stream" - mimeTypeFormPost = "application/x-www-form-urlencoded" - - headerAuthorization = "Authorization" - headerAuxAuthorization = "x-ms-authorization-auxiliary" - headerContentType = "Content-Type" - headerUserAgent = "User-Agent" -) - -// used as a key type in context.WithValue() -type ctxPrepareDecorators struct{} - -// WithPrepareDecorators adds the specified PrepareDecorators to the provided context. -// If no PrepareDecorators are provided the context is unchanged. -func WithPrepareDecorators(ctx context.Context, prepareDecorator []PrepareDecorator) context.Context { - if len(prepareDecorator) == 0 { - return ctx - } - return context.WithValue(ctx, ctxPrepareDecorators{}, prepareDecorator) -} - -// GetPrepareDecorators returns the PrepareDecorators in the provided context or the provided default PrepareDecorators. -func GetPrepareDecorators(ctx context.Context, defaultPrepareDecorators ...PrepareDecorator) []PrepareDecorator { - inCtx := ctx.Value(ctxPrepareDecorators{}) - if pd, ok := inCtx.([]PrepareDecorator); ok { - return pd - } - return defaultPrepareDecorators -} - -// Preparer is the interface that wraps the Prepare method. -// -// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations -// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used. -type Preparer interface { - Prepare(*http.Request) (*http.Request, error) -} - -// PreparerFunc is a method that implements the Preparer interface. -type PreparerFunc func(*http.Request) (*http.Request, error) - -// Prepare implements the Preparer interface on PreparerFunc. -func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) { - return pf(r) -} - -// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then affect the result. -type PrepareDecorator func(Preparer) Preparer - -// CreatePreparer creates, decorates, and returns a Preparer. -// Without decorators, the returned Preparer returns the passed http.Request unmodified. -// Preparers are safe to share and re-use. -func CreatePreparer(decorators ...PrepareDecorator) Preparer { - return DecoratePreparer( - Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })), - decorators...) -} - -// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it -// applies to the Preparer. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (change the http.Request and then pass it -// along) or a post-decorator (pass the http.Request along and alter it on return). -func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer { - for _, decorate := range decorators { - p = decorate(p) - } - return p -} - -// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. -// It creates a Preparer from the decorators which it then applies to the passed http.Request. -func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) { - if r == nil { - return nil, NewError("autorest", "Prepare", "Invoked without an http.Request") - } - return CreatePreparer(decorators...).Prepare(r) -} - -// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed -// http.Request. -func WithNothing() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - return p.Prepare(r) - }) - } -} - -// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to -// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before -// adding the header. -func WithHeader(header string, value string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - setHeader(r, http.CanonicalHeaderKey(header), value) - } - return r, err - }) - } -} - -// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to -// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before -// adding them. -func WithHeaders(headers map[string]interface{}) PrepareDecorator { - h := ensureValueStrings(headers) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.Header == nil { - r.Header = make(http.Header) - } - - for name, value := range h { - r.Header.Set(http.CanonicalHeaderKey(name), value) - } - } - return r, err - }) - } -} - -// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the supplied token. -func WithBearerAuthorization(token string) PrepareDecorator { - return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token)) -} - -// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value -// is the passed contentType. -func AsContentType(contentType string) PrepareDecorator { - return WithHeader(headerContentType, contentType) -} - -// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the -// passed string. -func WithUserAgent(ua string) PrepareDecorator { - return WithHeader(headerUserAgent, ua) -} - -// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/x-www-form-urlencoded". -func AsFormURLEncoded() PrepareDecorator { - return AsContentType(mimeTypeFormPost) -} - -// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/json". -func AsJSON() PrepareDecorator { - return AsContentType(mimeTypeJSON) -} - -// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header. -func AsOctetStream() PrepareDecorator { - return AsContentType(mimeTypeOctetStream) -} - -// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The -// decorator does not validate that the passed method string is a known HTTP method. -func WithMethod(method string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r.Method = method - return p.Prepare(r) - }) - } -} - -// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE. -func AsDelete() PrepareDecorator { return WithMethod("DELETE") } - -// AsGet returns a PrepareDecorator that sets the HTTP method to GET. -func AsGet() PrepareDecorator { return WithMethod("GET") } - -// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD. -func AsHead() PrepareDecorator { return WithMethod("HEAD") } - -// AsMerge returns a PrepareDecorator that sets the HTTP method to MERGE. -func AsMerge() PrepareDecorator { return WithMethod("MERGE") } - -// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS. -func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") } - -// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH. -func AsPatch() PrepareDecorator { return WithMethod("PATCH") } - -// AsPost returns a PrepareDecorator that sets the HTTP method to POST. -func AsPost() PrepareDecorator { return WithMethod("POST") } - -// AsPut returns a PrepareDecorator that sets the HTTP method to PUT. -func AsPut() PrepareDecorator { return WithMethod("PUT") } - -// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed -// from the supplied baseUrl. Query parameters will be encoded as required. -func WithBaseURL(baseURL string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var u *url.URL - if u, err = url.Parse(baseURL); err != nil { - return r, err - } - if u.Scheme == "" { - return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) - } - if u.RawQuery != "" { - // handle unencoded semicolons (ideally the server would send them already encoded) - u.RawQuery = strings.Replace(u.RawQuery, ";", "%3B", -1) - q, err := url.ParseQuery(u.RawQuery) - if err != nil { - return r, err - } - u.RawQuery = q.Encode() - } - r.URL = u - } - return r, err - }) - } -} - -// WithBytes returns a PrepareDecorator that takes a list of bytes -// which passes the bytes directly to the body -func WithBytes(input *[]byte) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if input == nil { - return r, fmt.Errorf("Input Bytes was nil") - } - - r.ContentLength = int64(len(*input)) - r.Body = ioutil.NopCloser(bytes.NewReader(*input)) - } - return r, err - }) - } -} - -// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the -// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map. -func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(urlParameters) - for key, value := range parameters { - baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1) - } - return WithBaseURL(baseURL) -} - -// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the -// http.Request body. -func WithFormData(v url.Values) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - s := v.Encode() - - setHeader(r, http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) - r.ContentLength = int64(len(s)) - r.Body = ioutil.NopCloser(strings.NewReader(s)) - } - return r, err - }) - } -} - -// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters -// into the http.Request body. -func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var body bytes.Buffer - writer := multipart.NewWriter(&body) - for key, value := range formDataParameters { - if rc, ok := value.(io.ReadCloser); ok { - var fd io.Writer - if fd, err = writer.CreateFormFile(key, key); err != nil { - return r, err - } - if _, err = io.Copy(fd, rc); err != nil { - return r, err - } - } else { - if err = writer.WriteField(key, ensureValueString(value)); err != nil { - return r, err - } - } - } - if err = writer.Close(); err != nil { - return r, err - } - setHeader(r, http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) - r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) - r.ContentLength = int64(body.Len()) - return r, err - } - return r, err - }) - } -} - -// WithFile returns a PrepareDecorator that sends file in request body. -func WithFile(f io.ReadCloser) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := ioutil.ReadAll(f) - if err != nil { - return r, err - } - r.Body = ioutil.NopCloser(bytes.NewReader(b)) - r.ContentLength = int64(len(b)) - } - return r, err - }) - } -} - -// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request -// and sets the Content-Length header. -func WithBool(v bool) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the -// request and sets the Content-Length header. -func WithFloat32(v float32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the -// request and sets the Content-Length header. -func WithFloat64(v float64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request -// and sets the Content-Length header. -func WithInt32(v int32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request -// and sets the Content-Length header. -func WithInt64(v int64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithString returns a PrepareDecorator that encodes the passed string into the body of the request -// and sets the Content-Length header. -func WithString(v string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - r.ContentLength = int64(len(v)) - r.Body = ioutil.NopCloser(strings.NewReader(v)) - } - return r, err - }) - } -} - -// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the -// request and sets the Content-Length header. -func WithJSON(v interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := json.Marshal(v) - if err == nil { - r.ContentLength = int64(len(b)) - r.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - } - return r, err - }) - } -} - -// WithXML returns a PrepareDecorator that encodes the data passed as XML into the body of the -// request and sets the Content-Length header. -func WithXML(v interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := xml.Marshal(v) - if err == nil { - // we have to tack on an XML header - withHeader := xml.Header + string(b) - bytesWithHeader := []byte(withHeader) - - r.ContentLength = int64(len(bytesWithHeader)) - setHeader(r, headerContentLength, fmt.Sprintf("%d", len(bytesWithHeader))) - r.Body = ioutil.NopCloser(bytes.NewReader(bytesWithHeader)) - } - } - return r, err - }) - } -} - -// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path -// is absolute (that is, it begins with a "/"), it replaces the existing path. -func WithPath(path string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPath", "Invoked with a nil URL") - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The -// values will be escaped (aka URL encoded) before insertion into the path. -func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := escapeValueStrings(ensureValueStrings(pathParameters)) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. -func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(pathParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -func parseURL(u *url.URL, path string) (*url.URL, error) { - p := strings.TrimRight(u.String(), "/") - if !strings.HasPrefix(path, "/") { - path = "/" + path - } - return url.Parse(p + path) -} - -// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters -// given in the supplied map (i.e., key=value). -func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator { - parameters := MapToValues(queryParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") - } - v := r.URL.Query() - for key, value := range parameters { - for i := range value { - d, err := url.QueryUnescape(value[i]) - if err != nil { - return r, err - } - value[i] = d - } - v[key] = value - } - r.URL.RawQuery = v.Encode() - } - return r, err - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go deleted file mode 100644 index 349e1963a2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/responder.go +++ /dev/null @@ -1,269 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "net/http" - "strings" -) - -// Responder is the interface that wraps the Respond method. -// -// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold -// state since Responders may be shared and re-used. -type Responder interface { - Respond(*http.Response) error -} - -// ResponderFunc is a method that implements the Responder interface. -type ResponderFunc func(*http.Response) error - -// Respond implements the Responder interface on ResponderFunc. -func (rf ResponderFunc) Respond(r *http.Response) error { - return rf(r) -} - -// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to -// the http.Response and pass it along or, first, pass the http.Response along then react. -type RespondDecorator func(Responder) Responder - -// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned -// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share -// and re-used: It depends on the applied decorators. For example, a standard decorator that closes -// the response body is fine to share whereas a decorator that reads the body into a passed struct -// is not. -// -// To prevent memory leaks, ensure that at least one Responder closes the response body. -func CreateResponder(decorators ...RespondDecorator) Responder { - return DecorateResponder( - Responder(ResponderFunc(func(r *http.Response) error { return nil })), - decorators...) -} - -// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it -// applies to the Responder. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (react to the http.Response and then pass it -// along) or a post-decorator (pass the http.Response along and then react). -func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder { - for _, decorate := range decorators { - r = decorate(r) - } - return r -} - -// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. -// It creates a Responder from the decorators it then applies to the passed http.Response. -func Respond(r *http.Response, decorators ...RespondDecorator) error { - if r == nil { - return nil - } - return CreateResponder(decorators...).Respond(r) -} - -// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined -// to the next RespondDecorator. -func ByIgnoring() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - return r.Respond(resp) - }) - } -} - -// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as -// the Body is read. -func ByCopying(b *bytes.Buffer) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - resp.Body = TeeReadCloser(resp.Body, b) - } - return err - }) - } -} - -// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which -// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed -// Responder is invoked prior to discarding the response body, the decorator may occur anywhere -// within the set. -func ByDiscardingBody() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil { - return fmt.Errorf("Error discarding the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it -// closes the response body. Since the passed Responder is invoked prior to closing the response -// body, the decorator may occur anywhere within the set. -func ByClosing() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which -// it closes the response if the passed Responder returns an error and the response body exists. -func ByClosingIfError() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err != nil && resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByUnmarshallingBytes returns a RespondDecorator that copies the Bytes returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingBytes(v *[]byte) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - bytes, errInner := ioutil.ReadAll(resp.Body) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else { - *v = bytes - } - } - return err - }) - } -} - -// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingJSON(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := ioutil.ReadAll(resp.Body) - // Some responses might include a BOM, remove for successful unmarshalling - b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else if len(strings.Trim(string(b), " ")) > 0 { - errInner = json.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingXML(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := ioutil.ReadAll(resp.Body) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else { - errInner = xml.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response -// StatusCode is among the set passed. On error, response body is fully read into a buffer and -// presented in the returned error, as well as in the response body. -func WithErrorUnlessStatusCode(codes ...int) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - if resp.Body != nil { - defer resp.Body.Close() - b, _ := ioutil.ReadAll(resp.Body) - derr.ServiceError = b - resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - err = derr - } - return err - }) - } -} - -// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is -// anything other than HTTP 200. -func WithErrorUnlessOK() RespondDecorator { - return WithErrorUnlessStatusCode(http.StatusOK) -} - -// ExtractHeader extracts all values of the specified header from the http.Response. It returns an -// empty string slice if the passed http.Response is nil or the header does not exist. -func ExtractHeader(header string, resp *http.Response) []string { - if resp != nil && resp.Header != nil { - return resp.Header[http.CanonicalHeaderKey(header)] - } - return nil -} - -// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It -// returns an empty string if the passed http.Response is nil or the header does not exist. -func ExtractHeaderValue(header string, resp *http.Response) string { - h := ExtractHeader(header, resp) - if len(h) > 0 { - return h[0] - } - return "" -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go deleted file mode 100644 index fa11dbed79..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go +++ /dev/null @@ -1,52 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "io" - "io/ioutil" - "net/http" -) - -// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic. -func NewRetriableRequest(req *http.Request) *RetriableRequest { - return &RetriableRequest{req: req} -} - -// Request returns the wrapped HTTP request. -func (rr *RetriableRequest) Request() *http.Request { - return rr.req -} - -func (rr *RetriableRequest) prepareFromByteReader() (err error) { - // fall back to making a copy (only do this once) - b := []byte{} - if rr.req.ContentLength > 0 { - b = make([]byte, rr.req.ContentLength) - _, err = io.ReadFull(rr.req.Body, b) - if err != nil { - return err - } - } else { - b, err = ioutil.ReadAll(rr.req.Body) - if err != nil { - return err - } - } - rr.br = bytes.NewReader(b) - rr.req.Body = ioutil.NopCloser(rr.br) - return err -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go deleted file mode 100644 index 4c87030e81..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build !go1.8 -// +build !go1.8 - -// Copyright 2017 Microsoft Corporation -// -// 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 autorest - -import ( - "bytes" - "io/ioutil" - "net/http" -) - -// RetriableRequest provides facilities for retrying an HTTP request. -type RetriableRequest struct { - req *http.Request - br *bytes.Reader -} - -// Prepare signals that the request is about to be sent. -func (rr *RetriableRequest) Prepare() (err error) { - // preserve the request body; this is to support retry logic as - // the underlying transport will always close the reqeust body - if rr.req.Body != nil { - if rr.br != nil { - _, err = rr.br.Seek(0, 0 /*io.SeekStart*/) - rr.req.Body = ioutil.NopCloser(rr.br) - } - if err != nil { - return err - } - if rr.br == nil { - // fall back to making a copy (only do this once) - err = rr.prepareFromByteReader() - } - } - return err -} - -func removeRequestBody(req *http.Request) { - req.Body = nil - req.ContentLength = 0 -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go deleted file mode 100644 index 05847c08ba..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go +++ /dev/null @@ -1,67 +0,0 @@ -//go:build go1.8 -// +build go1.8 - -// Copyright 2017 Microsoft Corporation -// -// 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 autorest - -import ( - "bytes" - "io" - "io/ioutil" - "net/http" -) - -// RetriableRequest provides facilities for retrying an HTTP request. -type RetriableRequest struct { - req *http.Request - rc io.ReadCloser - br *bytes.Reader -} - -// Prepare signals that the request is about to be sent. -func (rr *RetriableRequest) Prepare() (err error) { - // preserve the request body; this is to support retry logic as - // the underlying transport will always close the reqeust body - if rr.req.Body != nil { - if rr.rc != nil { - rr.req.Body = rr.rc - } else if rr.br != nil { - _, err = rr.br.Seek(0, io.SeekStart) - rr.req.Body = ioutil.NopCloser(rr.br) - } - if err != nil { - return err - } - if rr.req.GetBody != nil { - // this will allow us to preserve the body without having to - // make a copy. note we need to do this on each iteration - rr.rc, err = rr.req.GetBody() - if err != nil { - return err - } - } else if rr.br == nil { - // fall back to making a copy (only do this once) - err = rr.prepareFromByteReader() - } - } - return err -} - -func removeRequestBody(req *http.Request) { - req.Body = nil - req.GetBody = nil - req.ContentLength = 0 -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go deleted file mode 100644 index 118de81411..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ /dev/null @@ -1,458 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "context" - "crypto/tls" - "fmt" - "log" - "math" - "net" - "net/http" - "net/http/cookiejar" - "strconv" - "sync" - "time" - - "github.com/Azure/go-autorest/logger" - "github.com/Azure/go-autorest/tracing" -) - -// there is one sender per TLS renegotiation type, i.e. count of tls.RenegotiationSupport enums -const defaultSendersCount = 3 - -type defaultSender struct { - sender Sender - init *sync.Once -} - -// each type of sender will be created on demand in sender() -var defaultSenders [defaultSendersCount]defaultSender - -func init() { - for i := 0; i < defaultSendersCount; i++ { - defaultSenders[i].init = &sync.Once{} - } -} - -// used as a key type in context.WithValue() -type ctxSendDecorators struct{} - -// WithSendDecorators adds the specified SendDecorators to the provided context. -// If no SendDecorators are provided the context is unchanged. -func WithSendDecorators(ctx context.Context, sendDecorator []SendDecorator) context.Context { - if len(sendDecorator) == 0 { - return ctx - } - return context.WithValue(ctx, ctxSendDecorators{}, sendDecorator) -} - -// GetSendDecorators returns the SendDecorators in the provided context or the provided default SendDecorators. -func GetSendDecorators(ctx context.Context, defaultSendDecorators ...SendDecorator) []SendDecorator { - inCtx := ctx.Value(ctxSendDecorators{}) - if sd, ok := inCtx.([]SendDecorator); ok { - return sd - } - return defaultSendDecorators -} - -// Sender is the interface that wraps the Do method to send HTTP requests. -// -// The standard http.Client conforms to this interface. -type Sender interface { - Do(*http.Request) (*http.Response, error) -} - -// SenderFunc is a method that implements the Sender interface. -type SenderFunc func(*http.Request) (*http.Response, error) - -// Do implements the Sender interface on SenderFunc. -func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { - return sf(r) -} - -// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then react to the -// http.Response result. -type SendDecorator func(Sender) Sender - -// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. -func CreateSender(decorators ...SendDecorator) Sender { - return DecorateSender(sender(tls.RenegotiateNever), decorators...) -} - -// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to -// the Sender. Decorators are applied in the order received, but their affect upon the request -// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a -// post-decorator (pass the http.Request along and react to the results in http.Response). -func DecorateSender(s Sender, decorators ...SendDecorator) Sender { - for _, decorate := range decorators { - s = decorate(s) - } - return s -} - -// Send sends, by means of the default http.Client, the passed http.Request, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// Send is a convenience method and not recommended for production. Advanced users should use -// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client). -// -// Send will not poll or retry requests. -func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return SendWithSender(sender(tls.RenegotiateNever), r, decorators...) -} - -// SendWithSender sends the passed http.Request, through the provided Sender, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// SendWithSender will not poll or retry requests. -func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return DecorateSender(s, decorators...).Do(r) -} - -func sender(renengotiation tls.RenegotiationSupport) Sender { - // note that we can't init defaultSenders in init() since it will - // execute before calling code has had a chance to enable tracing - defaultSenders[renengotiation].init.Do(func() { - // copied from http.DefaultTransport with a TLS minimum version. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - Renegotiation: renengotiation, - }, - } - var roundTripper http.RoundTripper = transport - if tracing.IsEnabled() { - roundTripper = tracing.NewTransport(transport) - } - j, _ := cookiejar.New(nil) - defaultSenders[renengotiation].sender = &http.Client{Jar: j, Transport: roundTripper} - }) - return defaultSenders[renengotiation].sender -} - -// AfterDelay returns a SendDecorator that delays for the passed time.Duration before -// invoking the Sender. The delay may be terminated by closing the optional channel on the -// http.Request. If canceled, no further Senders are invoked. -func AfterDelay(d time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - if !DelayForBackoff(d, 0, r.Context().Done()) { - return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") - } - return s.Do(r) - }) - } -} - -// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request. -func AsIs() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return s.Do(r) - }) - } -} - -// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which -// it closes the response if the passed Sender returns an error and the response body exists. -func DoCloseIfError() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err != nil { - Respond(resp, ByDiscardingBody(), ByClosing()) - } - return resp, err - }) - } -} - -// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is -// among the set passed. Since these are artificial errors, the response body may still require -// closing. -func DoErrorIfStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response -// StatusCode is among the set passed. Since these are artificial errors, the response body -// may still require closing. -func DoErrorUnlessStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the -// passed status codes. It expects the http.Response to contain a Location header providing the -// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than -// the supplied duration. It will delay between requests for the duration specified in the -// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by -// closing the optional channel on the http.Request. -func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - resp, err = s.Do(r) - - if err == nil && ResponseHasStatusCode(resp, codes...) { - r, err = NewPollingRequestWithContext(r.Context(), resp) - - for err == nil && ResponseHasStatusCode(resp, codes...) { - Respond(resp, - ByDiscardingBody(), - ByClosing()) - resp, err = SendWithSender(s, r, - AfterDelay(GetRetryAfter(resp, delay))) - } - } - - return resp, err - }) - } -} - -// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on -// the http.Request. -func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - for attempt := 0; attempt < attempts; attempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - if err == nil { - return resp, err - } - logger.Instance.Writef(logger.LogError, "DoRetryForAttempts: received error for attempt %d: %v\n", attempt+1, err) - if !DelayForBackoff(backoff, attempt, r.Context().Done()) { - return nil, r.Context().Err() - } - } - return resp, err - }) - } -} - -// Count429AsRetry indicates that a 429 response should be included as a retry attempt. -var Count429AsRetry = true - -// Max429Delay is the maximum duration to wait between retries on a 429 if no Retry-After header was received. -var Max429Delay time.Duration - -// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by cancelling the context on the http.Request. -// NOTE: Code http.StatusTooManyRequests (429) will *not* be counted against the number of attempts. -func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, 0, codes...) - }) - } -} - -// DoRetryForStatusCodesWithCap returns a SendDecorator that retries for specified statusCodes for up to the -// specified number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). To cap the maximum possible delay between iterations specify a value greater -// than zero for cap. Retrying may be canceled by cancelling the context on the http.Request. -func DoRetryForStatusCodesWithCap(attempts int, backoff, cap time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, cap, codes...) - }) - } -} - -func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempts int, backoff, cap time.Duration, codes ...int) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - // Increment to add the first call (attempts denotes number of retries) - for attempt, delayCount := 0, 0; attempt < attempts+1; { - err = rr.Prepare() - if err != nil { - return - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - // we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication - // resp and err will both have a value, so in this case we don't want to retry as it will never succeed. - if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) { - return resp, err - } - if err != nil { - logger.Instance.Writef(logger.LogError, "DoRetryForStatusCodes: received error for attempt %d: %v\n", attempt+1, err) - } - delayed := DelayWithRetryAfter(resp, r.Context().Done()) - // if this was a 429 set the delay cap as specified. - // applicable only in the absence of a retry-after header. - if resp != nil && resp.StatusCode == http.StatusTooManyRequests { - cap = Max429Delay - } - if !delayed && !DelayForBackoffWithCap(backoff, cap, delayCount, r.Context().Done()) { - return resp, r.Context().Err() - } - // when count429 == false don't count a 429 against the number - // of attempts so that we continue to retry until it succeeds - if count429 || (resp == nil || resp.StatusCode != http.StatusTooManyRequests) { - attempt++ - } - // delay count is tracked separately from attempts to - // ensure that 429 participates in exponential back-off - delayCount++ - } - return resp, err -} - -// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header. -// The value of Retry-After can be either the number of seconds or a date in RFC1123 format. -// The function returns true after successfully waiting for the specified duration. If there is -// no Retry-After header or the wait is cancelled the return value is false. -func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool { - if resp == nil { - return false - } - var dur time.Duration - ra := resp.Header.Get("Retry-After") - if retryAfter, _ := strconv.Atoi(ra); retryAfter > 0 { - dur = time.Duration(retryAfter) * time.Second - } else if t, err := time.Parse(time.RFC1123, ra); err == nil { - dur = t.Sub(time.Now()) - } - if dur > 0 { - select { - case <-time.After(dur): - return true - case <-cancel: - return false - } - } - return false -} - -// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal -// to or greater than the specified duration, exponentially backing off between requests using the -// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the -// optional channel on the http.Request. -func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - end := time.Now().Add(d) - for attempt := 0; time.Now().Before(end); attempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - if err == nil { - return resp, err - } - logger.Instance.Writef(logger.LogError, "DoRetryForDuration: received error for attempt %d: %v\n", attempt+1, err) - if !DelayForBackoff(backoff, attempt, r.Context().Done()) { - return nil, r.Context().Err() - } - } - return resp, err - }) - } -} - -// WithLogging returns a SendDecorator that implements simple before and after logging of the -// request. -func WithLogging(logger *log.Logger) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - logger.Printf("Sending %s %s", r.Method, r.URL) - resp, err := s.Do(r) - if err != nil { - logger.Printf("%s %s received error '%v'", r.Method, r.URL, err) - } else { - logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status) - } - return resp, err - }) - } -} - -// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of -// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set -// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early, -// returns false. -// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt -// count. -func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool { - return DelayForBackoffWithCap(backoff, 0, attempt, cancel) -} - -// DelayForBackoffWithCap invokes time.After for the supplied backoff duration raised to the power of -// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set -// to zero for no delay. To cap the maximum possible delay specify a value greater than zero for cap. -// The delay may be canceled by closing the passed channel. If terminated early, returns false. -// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt -// count. -func DelayForBackoffWithCap(backoff, cap time.Duration, attempt int, cancel <-chan struct{}) bool { - d := time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second - if cap > 0 && d > cap { - d = cap - } - logger.Instance.Writef(logger.LogInfo, "DelayForBackoffWithCap: sleeping for %s\n", d) - select { - case <-time.After(d): - return true - case <-cancel: - return false - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go deleted file mode 100644 index 3467b8fa60..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ /dev/null @@ -1,232 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "reflect" - "strings" -) - -// EncodedAs is a series of constants specifying various data encodings -type EncodedAs string - -const ( - // EncodedAsJSON states that data is encoded as JSON - EncodedAsJSON EncodedAs = "JSON" - - // EncodedAsXML states that data is encoded as Xml - EncodedAsXML EncodedAs = "XML" -) - -// Decoder defines the decoding method json.Decoder and xml.Decoder share -type Decoder interface { - Decode(v interface{}) error -} - -// NewDecoder creates a new decoder appropriate to the passed encoding. -// encodedAs specifies the type of encoding and r supplies the io.Reader containing the -// encoded data. -func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder { - if encodedAs == EncodedAsJSON { - return json.NewDecoder(r) - } else if encodedAs == EncodedAsXML { - return xml.NewDecoder(r) - } - return nil -} - -// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy -// is especially useful if there is a chance the data will fail to decode. -// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v -// is the decoding destination. -func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) { - b := bytes.Buffer{} - return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v) -} - -// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. -// It utilizes io.TeeReader to copy the data read and has the same behavior when reading. -// Further, when it is closed, it ensures that rc is closed as well. -func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser { - return &teeReadCloser{rc, io.TeeReader(rc, w)} -} - -type teeReadCloser struct { - rc io.ReadCloser - r io.Reader -} - -func (t *teeReadCloser) Read(p []byte) (int, error) { - return t.r.Read(p) -} - -func (t *teeReadCloser) Close() error { - return t.rc.Close() -} - -func containsInt(ints []int, n int) bool { - for _, i := range ints { - if i == n { - return true - } - } - return false -} - -func escapeValueStrings(m map[string]string) map[string]string { - for key, value := range m { - m[key] = url.QueryEscape(value) - } - return m -} - -func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string { - mapOfStrings := make(map[string]string) - for key, value := range mapOfInterface { - mapOfStrings[key] = ensureValueString(value) - } - return mapOfStrings -} - -func ensureValueString(value interface{}) string { - if value == nil { - return "" - } - switch v := value.(type) { - case string: - return v - case []byte: - return string(v) - default: - return fmt.Sprintf("%v", v) - } -} - -// MapToValues method converts map[string]interface{} to url.Values. -func MapToValues(m map[string]interface{}) url.Values { - v := url.Values{} - for key, value := range m { - x := reflect.ValueOf(value) - if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { - for i := 0; i < x.Len(); i++ { - v.Add(key, ensureValueString(x.Index(i))) - } - } else { - v.Add(key, ensureValueString(value)) - } - } - return v -} - -// AsStringSlice method converts interface{} to []string. -// s must be of type slice or array or an error is returned. -// Each element of s will be converted to its string representation. -func AsStringSlice(s interface{}) ([]string, error) { - v := reflect.ValueOf(s) - if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { - return nil, NewError("autorest", "AsStringSlice", "the value's type is not a slice or array.") - } - stringSlice := make([]string, 0, v.Len()) - - for i := 0; i < v.Len(); i++ { - stringSlice = append(stringSlice, fmt.Sprintf("%v", v.Index(i))) - } - return stringSlice, nil -} - -// String method converts interface v to string. If interface is a list, it -// joins list elements using the separator. Note that only sep[0] will be used for -// joining if any separator is specified. -func String(v interface{}, sep ...string) string { - if len(sep) == 0 { - return ensureValueString(v) - } - stringSlice, ok := v.([]string) - if ok == false { - var err error - stringSlice, err = AsStringSlice(v) - if err != nil { - panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err)) - } - } - return ensureValueString(strings.Join(stringSlice, sep[0])) -} - -// Encode method encodes url path and query parameters. -func Encode(location string, v interface{}, sep ...string) string { - s := String(v, sep...) - switch strings.ToLower(location) { - case "path": - return pathEscape(s) - case "query": - return queryEscape(s) - default: - return s - } -} - -func pathEscape(s string) string { - return strings.Replace(url.QueryEscape(s), "+", "%20", -1) -} - -func queryEscape(s string) string { - return url.QueryEscape(s) -} - -// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't). -// This is mainly useful for long-running operations that use the Azure-AsyncOperation -// header, so we change the initial PUT into a GET to retrieve the final result. -func ChangeToGet(req *http.Request) *http.Request { - req.Method = "GET" - req.Body = nil - req.ContentLength = 0 - req.Header.Del("Content-Length") - return req -} - -// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false -// if it's not. If the error doesn't implement the net.Error interface the return value is true. -func IsTemporaryNetworkError(err error) bool { - if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { - return true - } - return false -} - -// DrainResponseBody reads the response body then closes it. -func DrainResponseBody(resp *http.Response) error { - if resp != nil && resp.Body != nil { - _, err := io.Copy(ioutil.Discard, resp.Body) - resp.Body.Close() - return err - } - return nil -} - -func setHeader(r *http.Request, key, value string) { - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(key, value) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go b/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go deleted file mode 100644 index 3133fcc08e..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build go1.13 -// +build go1.13 - -// Copyright 2017 Microsoft Corporation -// -// 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 autorest - -import ( - "errors" - - "github.com/Azure/go-autorest/autorest/adal" -) - -// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError interface. -func IsTokenRefreshError(err error) bool { - var tre adal.TokenRefreshError - return errors.As(err, &tre) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go b/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go deleted file mode 100644 index 851e152db4..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build !go1.13 -// +build !go1.13 - -// Copyright 2017 Microsoft Corporation -// -// 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 autorest - -import "github.com/Azure/go-autorest/autorest/adal" - -// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError -// interface. If err is a DetailedError it will walk the chain of Original errors. -func IsTokenRefreshError(err error) bool { - if _, ok := err.(adal.TokenRefreshError); ok { - return true - } - if de, ok := err.(DetailedError); ok { - return IsTokenRefreshError(de.Original) - } - return false -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go deleted file mode 100644 index 713e23581d..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/version.go +++ /dev/null @@ -1,41 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "fmt" - "runtime" -) - -const number = "v14.2.1" - -var ( - userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - number, - ) -) - -// UserAgent returns a string containing the Go version, system architecture and OS, and the go-autorest version. -func UserAgent() string { - return userAgent -} - -// Version returns the semantic version (see http://semver.org). -func Version() string { - return number -} diff --git a/vendor/github.com/Azure/go-autorest/azure-pipelines.yml b/vendor/github.com/Azure/go-autorest/azure-pipelines.yml deleted file mode 100644 index 6fb8404fd0..0000000000 --- a/vendor/github.com/Azure/go-autorest/azure-pipelines.yml +++ /dev/null @@ -1,105 +0,0 @@ -variables: - GOPATH: '$(system.defaultWorkingDirectory)/work' - sdkPath: '$(GOPATH)/src/github.com/$(build.repository.name)' - -jobs: - - job: 'goautorest' - displayName: 'Run go-autorest CI Checks' - - strategy: - matrix: - Linux_Go113: - vm.image: 'ubuntu-18.04' - go.version: '1.13' - Linux_Go114: - vm.image: 'ubuntu-18.04' - go.version: '1.14' - - pool: - vmImage: '$(vm.image)' - - steps: - - task: GoTool@0 - inputs: - version: '$(go.version)' - displayName: "Select Go Version" - - - script: | - set -e - mkdir -p '$(GOPATH)/bin' - mkdir -p '$(sdkPath)' - shopt -s extglob - mv !(work) '$(sdkPath)' - echo '##vso[task.prependpath]$(GOPATH)/bin' - displayName: 'Create Go Workspace' - - - script: | - set -e - curl -sSL https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure -v - go install ./vendor/golang.org/x/lint/golint - go get github.com/jstemmer/go-junit-report - go get github.com/axw/gocov/gocov - go get github.com/AlekSi/gocov-xml - go get -u github.com/matm/gocov-html - workingDirectory: '$(sdkPath)' - displayName: 'Install Dependencies' - - - script: | - go vet ./autorest/... - go vet ./logger/... - go vet ./tracing/... - workingDirectory: '$(sdkPath)' - displayName: 'Vet' - - - script: | - go build -v ./autorest/... - go build -v ./logger/... - go build -v ./tracing/... - workingDirectory: '$(sdkPath)' - displayName: 'Build' - - - script: | - set -e - go test -race -v -coverprofile=coverage.txt -covermode atomic ./autorest/... ./logger/... ./tracing/... 2>&1 | go-junit-report > report.xml - gocov convert coverage.txt > coverage.json - gocov-xml < coverage.json > coverage.xml - gocov-html < coverage.json > coverage.html - workingDirectory: '$(sdkPath)' - displayName: 'Run Tests' - - - script: grep -L -r --include *.go --exclude-dir vendor -P "Copyright (\d{4}|\(c\)) Microsoft" ./ | tee >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Copyright Header Check' - failOnStderr: true - condition: succeededOrFailed() - - - script: | - gofmt -s -l -w ./autorest/. >&2 - gofmt -s -l -w ./logger/. >&2 - gofmt -s -l -w ./tracing/. >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Format Check' - failOnStderr: true - condition: succeededOrFailed() - - - script: | - golint ./autorest/... >&2 - golint ./logger/... >&2 - golint ./tracing/... >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Linter Check' - failOnStderr: true - condition: succeededOrFailed() - - - task: PublishTestResults@2 - inputs: - testRunner: JUnit - testResultsFiles: $(sdkPath)/report.xml - failTaskOnFailedTests: true - - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: Cobertura - summaryFileLocation: $(sdkPath)/coverage.xml - additionalCodeCoverageFiles: $(sdkPath)/coverage.html diff --git a/vendor/github.com/Azure/go-autorest/doc.go b/vendor/github.com/Azure/go-autorest/doc.go deleted file mode 100644 index 99ae6ca988..0000000000 --- a/vendor/github.com/Azure/go-autorest/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Package go-autorest provides an HTTP request client for use with Autorest-generated API client packages. -*/ -package go_autorest - -// Copyright 2017 Microsoft Corporation -// -// 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/Azure/go-autorest/logger/LICENSE b/vendor/github.com/Azure/go-autorest/logger/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/logger/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/logger/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go deleted file mode 100644 index 0aa27680db..0000000000 --- a/vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package logger - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/logger/logger.go b/vendor/github.com/Azure/go-autorest/logger/logger.go deleted file mode 100644 index 2f5d8cc1a1..0000000000 --- a/vendor/github.com/Azure/go-autorest/logger/logger.go +++ /dev/null @@ -1,337 +0,0 @@ -package logger - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "strings" - "sync" - "time" -) - -// LevelType tells a logger the minimum level to log. When code reports a log entry, -// the LogLevel indicates the level of the log entry. The logger only records entries -// whose level is at least the level it was told to log. See the Log* constants. -// For example, if a logger is configured with LogError, then LogError, LogPanic, -// and LogFatal entries will be logged; lower level entries are ignored. -type LevelType uint32 - -const ( - // LogNone tells a logger not to log any entries passed to it. - LogNone LevelType = iota - - // LogFatal tells a logger to log all LogFatal entries passed to it. - LogFatal - - // LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it. - LogPanic - - // LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it. - LogError - - // LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogWarning - - // LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogInfo - - // LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogDebug - - // LogAuth is a special case of LogDebug, it tells a logger to also log the body of an authentication request and response. - // NOTE: this can disclose sensitive information, use with care. - LogAuth -) - -const ( - logNone = "NONE" - logFatal = "FATAL" - logPanic = "PANIC" - logError = "ERROR" - logWarning = "WARNING" - logInfo = "INFO" - logDebug = "DEBUG" - logAuth = "AUTH" - logUnknown = "UNKNOWN" -) - -// ParseLevel converts the specified string into the corresponding LevelType. -func ParseLevel(s string) (lt LevelType, err error) { - switch strings.ToUpper(s) { - case logFatal: - lt = LogFatal - case logPanic: - lt = LogPanic - case logError: - lt = LogError - case logWarning: - lt = LogWarning - case logInfo: - lt = LogInfo - case logDebug: - lt = LogDebug - case logAuth: - lt = LogAuth - default: - err = fmt.Errorf("bad log level '%s'", s) - } - return -} - -// String implements the stringer interface for LevelType. -func (lt LevelType) String() string { - switch lt { - case LogNone: - return logNone - case LogFatal: - return logFatal - case LogPanic: - return logPanic - case LogError: - return logError - case LogWarning: - return logWarning - case LogInfo: - return logInfo - case LogDebug: - return logDebug - case LogAuth: - return logAuth - default: - return logUnknown - } -} - -// Filter defines functions for filtering HTTP request/response content. -type Filter struct { - // URL returns a potentially modified string representation of a request URL. - URL func(u *url.URL) string - - // Header returns a potentially modified set of values for the specified key. - // To completely exclude the header key/values return false. - Header func(key string, val []string) (bool, []string) - - // Body returns a potentially modified request/response body. - Body func(b []byte) []byte -} - -func (f Filter) processURL(u *url.URL) string { - if f.URL == nil { - return u.String() - } - return f.URL(u) -} - -func (f Filter) processHeader(k string, val []string) (bool, []string) { - if f.Header == nil { - return true, val - } - return f.Header(k, val) -} - -func (f Filter) processBody(b []byte) []byte { - if f.Body == nil { - return b - } - return f.Body(b) -} - -// Writer defines methods for writing to a logging facility. -type Writer interface { - // Writeln writes the specified message with the standard log entry header and new-line character. - Writeln(level LevelType, message string) - - // Writef writes the specified format specifier with the standard log entry header and no new-line character. - Writef(level LevelType, format string, a ...interface{}) - - // WriteRequest writes the specified HTTP request to the logger if the log level is greater than - // or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher. - // Custom filters can be specified to exclude URL, header, and/or body content from the log. - // By default no request content is excluded. - WriteRequest(req *http.Request, filter Filter) - - // WriteResponse writes the specified HTTP response to the logger if the log level is greater than - // or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher. - // Custom filters can be specified to exclude URL, header, and/or body content from the log. - // By default no response content is excluded. - WriteResponse(resp *http.Response, filter Filter) -} - -// Instance is the default log writer initialized during package init. -// This can be replaced with a custom implementation as required. -var Instance Writer - -// default log level -var logLevel = LogNone - -// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL. -// If no value was specified the default value is LogNone. -// Custom loggers can call this to retrieve the configured log level. -func Level() LevelType { - return logLevel -} - -func init() { - // separated for testing purposes - initDefaultLogger() -} - -func initDefaultLogger() { - // init with nilLogger so callers don't have to do a nil check on Default - Instance = nilLogger{} - llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL")) - if llStr == "" { - return - } - var err error - logLevel, err = ParseLevel(llStr) - if err != nil { - fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error()) - return - } - if logLevel == LogNone { - return - } - // default to stderr - dest := os.Stderr - lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE") - if strings.EqualFold(lfStr, "stdout") { - dest = os.Stdout - } else if lfStr != "" { - lf, err := os.Create(lfStr) - if err == nil { - dest = lf - } else { - fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error()) - } - } - Instance = fileLogger{ - logLevel: logLevel, - mu: &sync.Mutex{}, - logFile: dest, - } -} - -// the nil logger does nothing -type nilLogger struct{} - -func (nilLogger) Writeln(LevelType, string) {} - -func (nilLogger) Writef(LevelType, string, ...interface{}) {} - -func (nilLogger) WriteRequest(*http.Request, Filter) {} - -func (nilLogger) WriteResponse(*http.Response, Filter) {} - -// A File is used instead of a Logger so the stream can be flushed after every write. -type fileLogger struct { - logLevel LevelType - mu *sync.Mutex // for synchronizing writes to logFile - logFile *os.File -} - -func (fl fileLogger) Writeln(level LevelType, message string) { - fl.Writef(level, "%s\n", message) -} - -func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) { - if fl.logLevel >= level { - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...)) - fl.logFile.Sync() - } -} - -func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) { - if req == nil || fl.logLevel < LogInfo { - return - } - b := &bytes.Buffer{} - fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL)) - // dump headers - for k, v := range req.Header { - if ok, mv := filter.processHeader(k, v); ok { - fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) - } - } - if fl.shouldLogBody(req.Header, req.Body) { - // dump body - body, err := ioutil.ReadAll(req.Body) - if err == nil { - fmt.Fprintln(b, string(filter.processBody(body))) - if nc, ok := req.Body.(io.Seeker); ok { - // rewind to the beginning - nc.Seek(0, io.SeekStart) - } else { - // recreate the body - req.Body = ioutil.NopCloser(bytes.NewReader(body)) - } - } else { - fmt.Fprintf(b, "failed to read body: %v\n", err) - } - } - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprint(fl.logFile, b.String()) - fl.logFile.Sync() -} - -func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) { - if resp == nil || fl.logLevel < LogInfo { - return - } - b := &bytes.Buffer{} - fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL)) - // dump headers - for k, v := range resp.Header { - if ok, mv := filter.processHeader(k, v); ok { - fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) - } - } - if fl.shouldLogBody(resp.Header, resp.Body) { - // dump body - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err == nil { - fmt.Fprintln(b, string(filter.processBody(body))) - resp.Body = ioutil.NopCloser(bytes.NewReader(body)) - } else { - fmt.Fprintf(b, "failed to read body: %v\n", err) - } - } - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprint(fl.logFile, b.String()) - fl.logFile.Sync() -} - -// returns true if the provided body should be included in the log -func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool { - ct := header.Get("Content-Type") - return fl.logLevel >= LogDebug && body != nil && !strings.Contains(ct, "application/octet-stream") -} - -// creates standard header for log entries, it contains a timestamp and the log level -func entryHeader(level LevelType) string { - // this format provides a fixed number of digits so the size of the timestamp is constant - return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String()) -} diff --git a/vendor/github.com/Azure/go-autorest/tracing/LICENSE b/vendor/github.com/Azure/go-autorest/tracing/LICENSE deleted file mode 100644 index b9d6a27ea9..0000000000 --- a/vendor/github.com/Azure/go-autorest/tracing/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - 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 - - Copyright 2015 Microsoft Corporation - - 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/Azure/go-autorest/tracing/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go deleted file mode 100644 index e163975cd4..0000000000 --- a/vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package tracing - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/tracing/tracing.go b/vendor/github.com/Azure/go-autorest/tracing/tracing.go deleted file mode 100644 index 0e7a6e9625..0000000000 --- a/vendor/github.com/Azure/go-autorest/tracing/tracing.go +++ /dev/null @@ -1,67 +0,0 @@ -package tracing - -// Copyright 2018 Microsoft Corporation -// -// 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. - -import ( - "context" - "net/http" -) - -// Tracer represents an HTTP tracing facility. -type Tracer interface { - NewTransport(base *http.Transport) http.RoundTripper - StartSpan(ctx context.Context, name string) context.Context - EndSpan(ctx context.Context, httpStatusCode int, err error) -} - -var ( - tracer Tracer -) - -// Register will register the provided Tracer. Pass nil to unregister a Tracer. -func Register(t Tracer) { - tracer = t -} - -// IsEnabled returns true if a Tracer has been registered. -func IsEnabled() bool { - return tracer != nil -} - -// NewTransport creates a new instrumenting http.RoundTripper for the -// registered Tracer. If no Tracer has been registered it returns nil. -func NewTransport(base *http.Transport) http.RoundTripper { - if tracer != nil { - return tracer.NewTransport(base) - } - return nil -} - -// StartSpan starts a trace span with the specified name, associating it with the -// provided context. Has no effect if a Tracer has not been registered. -func StartSpan(ctx context.Context, name string) context.Context { - if tracer != nil { - return tracer.StartSpan(ctx, name) - } - return ctx -} - -// EndSpan ends a previously started span stored in the context. -// Has no effect if a Tracer has not been registered. -func EndSpan(ctx context.Context, httpStatusCode int, err error) { - if tracer != nil { - tracer.EndSpan(ctx, httpStatusCode, err) - } -} diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore index cd11be9653..fe79e3adda 100644 --- a/vendor/github.com/BurntSushi/toml/.gitignore +++ b/vendor/github.com/BurntSushi/toml/.gitignore @@ -1,2 +1,2 @@ -toml.test +/toml.test /toml-test diff --git a/vendor/github.com/BurntSushi/toml/COMPATIBLE b/vendor/github.com/BurntSushi/toml/COMPATIBLE deleted file mode 100644 index f621b01196..0000000000 --- a/vendor/github.com/BurntSushi/toml/COMPATIBLE +++ /dev/null @@ -1 +0,0 @@ -Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0). diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md index cc13f8667f..3651cfa960 100644 --- a/vendor/github.com/BurntSushi/toml/README.md +++ b/vendor/github.com/BurntSushi/toml/README.md @@ -1,6 +1,5 @@ TOML stands for Tom's Obvious, Minimal Language. This Go package provides a -reflection interface similar to Go's standard library `json` and `xml` -packages. +reflection interface similar to Go's standard library `json` and `xml` packages. Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0). @@ -10,7 +9,7 @@ See the [releases page](https://github.com/BurntSushi/toml/releases) for a changelog; this information is also in the git tag annotations (e.g. `git show v0.4.0`). -This library requires Go 1.13 or newer; install it with: +This library requires Go 1.13 or newer; add it to your go.mod with: % go get github.com/BurntSushi/toml@latest @@ -19,16 +18,7 @@ It also comes with a TOML validator CLI tool: % go install github.com/BurntSushi/toml/cmd/tomlv@latest % tomlv some-toml-file.toml -### Testing -This package passes all tests in [toml-test] for both the decoder and the -encoder. - -[toml-test]: https://github.com/BurntSushi/toml-test - ### Examples -This package works similar to how the Go standard library handles XML and JSON. -Namely, data is loaded into Go values via reflection. - For the simplest example, consider some TOML file as just a list of keys and values: @@ -40,7 +30,7 @@ Perfection = [ 6, 28, 496, 8128 ] DOB = 1987-07-05T05:45:00Z ``` -Which could be defined in Go as: +Which can be decoded with: ```go type Config struct { @@ -48,20 +38,15 @@ type Config struct { Cats []string Pi float64 Perfection []int - DOB time.Time // requires `import time` + DOB time.Time } -``` - -And then decoded with: -```go var conf Config -err := toml.Decode(tomlData, &conf) -// handle error +_, err := toml.Decode(tomlData, &conf) ``` -You can also use struct tags if your struct field name doesn't map to a TOML -key value directly: +You can also use struct tags if your struct field name doesn't map to a TOML key +value directly: ```toml some_key_NAME = "wat" @@ -73,139 +58,63 @@ type TOML struct { } ``` -Beware that like other most other decoders **only exported fields** are -considered when encoding and decoding; private fields are silently ignored. +Beware that like other decoders **only exported fields** are considered when +encoding and decoding; private fields are silently ignored. ### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces -Here's an example that automatically parses duration strings into -`time.Duration` values: +Here's an example that automatically parses values in a `mail.Address`: ```toml -[[song]] -name = "Thunder Road" -duration = "4m49s" - -[[song]] -name = "Stairway to Heaven" -duration = "8m03s" -``` - -Which can be decoded with: - -```go -type song struct { - Name string - Duration duration -} -type songs struct { - Song []song -} -var favorites songs -if _, err := toml.Decode(blob, &favorites); err != nil { - log.Fatal(err) -} - -for _, s := range favorites.Song { - fmt.Printf("%s (%s)\n", s.Name, s.Duration) -} +contacts = [ + "Donald Duck ", + "Scrooge McDuck ", +] ``` -And you'll also need a `duration` type that satisfies the -`encoding.TextUnmarshaler` interface: +Can be decoded with: ```go -type duration struct { - time.Duration +// Create address type which satisfies the encoding.TextUnmarshaler interface. +type address struct { + *mail.Address } -func (d *duration) UnmarshalText(text []byte) error { +func (a *address) UnmarshalText(text []byte) error { var err error - d.Duration, err = time.ParseDuration(string(text)) + a.Address, err = mail.ParseAddress(string(text)) return err } + +// Decode it. +func decode() { + blob := ` + contacts = [ + "Donald Duck ", + "Scrooge McDuck ", + ] + ` + + var contacts struct { + Contacts []address + } + + _, err := toml.Decode(blob, &contacts) + if err != nil { + log.Fatal(err) + } + + for _, c := range contacts.Contacts { + fmt.Printf("%#v\n", c.Address) + } + + // Output: + // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"} + // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"} +} ``` To target TOML specifically you can implement `UnmarshalTOML` TOML interface in a similar way. ### More complex usage -Here's an example of how to load the example from the official spec page: - -```toml -# This is a TOML document. Boom. - -title = "TOML Example" - -[owner] -name = "Tom Preston-Werner" -organization = "GitHub" -bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." -dob = 1979-05-27T07:32:00Z # First class dates? Why not? - -[database] -server = "192.168.1.1" -ports = [ 8001, 8001, 8002 ] -connection_max = 5000 -enabled = true - -[servers] - - # You can indent as you please. Tabs or spaces. TOML don't care. - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -[clients] -data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] -``` - -And the corresponding Go types are: - -```go -type tomlConfig struct { - Title string - Owner ownerInfo - DB database `toml:"database"` - Servers map[string]server - Clients clients -} - -type ownerInfo struct { - Name string - Org string `toml:"organization"` - Bio string - DOB time.Time -} - -type database struct { - Server string - Ports []int - ConnMax int `toml:"connection_max"` - Enabled bool -} - -type server struct { - IP string - DC string -} - -type clients struct { - Data [][]interface{} - Hosts []string -} -``` - -Note that a case insensitive match will be tried if an exact match can't be -found. - -A working example of the above can be found in `_example/example.{go,toml}`. +See the [`_example/`](/_example) directory for a more complex example. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go index e24f0c5d5c..0ca1dc4fee 100644 --- a/vendor/github.com/BurntSushi/toml/decode.go +++ b/vendor/github.com/BurntSushi/toml/decode.go @@ -1,14 +1,18 @@ package toml import ( + "bytes" "encoding" + "encoding/json" "fmt" "io" "io/ioutil" "math" "os" "reflect" + "strconv" "strings" + "time" ) // Unmarshaler is the interface implemented by objects that can unmarshal a @@ -17,16 +21,35 @@ type Unmarshaler interface { UnmarshalTOML(interface{}) error } -// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`. -func Unmarshal(p []byte, v interface{}) error { - _, err := Decode(string(p), v) +// Unmarshal decodes the contents of data in TOML format into a pointer v. +// +// See [Decoder] for a description of the decoding process. +func Unmarshal(data []byte, v interface{}) error { + _, err := NewDecoder(bytes.NewReader(data)).Decode(v) return err } +// Decode the TOML data in to the pointer v. +// +// See [Decoder] for a description of the decoding process. +func Decode(data string, v interface{}) (MetaData, error) { + return NewDecoder(strings.NewReader(data)).Decode(v) +} + +// DecodeFile reads the contents of a file and decodes it with [Decode]. +func DecodeFile(path string, v interface{}) (MetaData, error) { + fp, err := os.Open(path) + if err != nil { + return MetaData{}, err + } + defer fp.Close() + return NewDecoder(fp).Decode(v) +} + // Primitive is a TOML value that hasn't been decoded into a Go value. // // This type can be used for any value, which will cause decoding to be delayed. -// You can use the PrimitiveDecode() function to "manually" decode these values. +// You can use [PrimitiveDecode] to "manually" decode these values. // // NOTE: The underlying representation of a `Primitive` value is subject to // change. Do not rely on it. @@ -42,36 +65,22 @@ type Primitive struct { // The significand precision for float32 and float64 is 24 and 53 bits; this is // the range a natural number can be stored in a float without loss of data. const ( - maxSafeFloat32Int = 16777215 // 2^24-1 - maxSafeFloat64Int = 9007199254740991 // 2^53-1 + maxSafeFloat32Int = 16777215 // 2^24-1 + maxSafeFloat64Int = int64(9007199254740991) // 2^53-1 ) -// PrimitiveDecode is just like the other `Decode*` functions, except it -// decodes a TOML value that has already been parsed. Valid primitive values -// can *only* be obtained from values filled by the decoder functions, -// including this method. (i.e., `v` may contain more `Primitive` -// values.) -// -// Meta data for primitive values is included in the meta data returned by -// the `Decode*` functions with one exception: keys returned by the Undecoded -// method will only reflect keys that were decoded. Namely, any keys hidden -// behind a Primitive will be considered undecoded. Executing this method will -// update the undecoded keys in the meta data. (See the example.) -func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { - md.context = primValue.context - defer func() { md.context = nil }() - return md.unify(primValue.undecoded, rvalue(v)) -} - // Decoder decodes TOML data. // -// TOML tables correspond to Go structs or maps (dealer's choice – they can be -// used interchangeably). +// TOML tables correspond to Go structs or maps; they can be used +// interchangeably, but structs offer better type safety. // // TOML table arrays correspond to either a slice of structs or a slice of maps. // -// TOML datetimes correspond to Go time.Time values. Local datetimes are parsed -// in the local timezone. +// TOML datetimes correspond to [time.Time]. Local datetimes are parsed in the +// local timezone. +// +// [time.Duration] types are treated as nanoseconds if the TOML value is an +// integer, or they're parsed with time.ParseDuration() if they're strings. // // All other TOML types (float, string, int, bool and array) correspond to the // obvious Go types. @@ -80,9 +89,9 @@ func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { // interface, in which case any primitive TOML value (floats, strings, integers, // booleans, datetimes) will be converted to a []byte and given to the value's // UnmarshalText method. See the Unmarshaler example for a demonstration with -// time duration strings. +// email addresses. // -// Key mapping +// ### Key mapping // // TOML keys can map to either keys in a Go map or field names in a Go struct. // The special `toml` struct tag can be used to map TOML keys to struct fields @@ -109,6 +118,7 @@ func NewDecoder(r io.Reader) *Decoder { var ( unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem() unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem() ) // Decode TOML data in to the pointer `v`. @@ -120,10 +130,10 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) { s = "%v" } - return MetaData{}, e("cannot decode to non-pointer "+s, reflect.TypeOf(v)) + return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v)) } if rv.IsNil() { - return MetaData{}, e("cannot decode to nil value of %q", reflect.TypeOf(v)) + return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v)) } // Check if this is a supported type: struct, map, interface{}, or something @@ -133,7 +143,7 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) { if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map && !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) && !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) { - return MetaData{}, e("cannot decode to type %s", rt) + return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt) } // TODO: parser should read from io.Reader? Or at the very least, make it @@ -150,30 +160,29 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) { md := MetaData{ mapping: p.mapping, - types: p.types, + keyInfo: p.keyInfo, keys: p.ordered, decoded: make(map[string]struct{}, len(p.ordered)), context: nil, + data: data, } return md, md.unify(p.mapping, rv) } -// Decode the TOML data in to the pointer v. +// PrimitiveDecode is just like the other Decode* functions, except it decodes a +// TOML value that has already been parsed. Valid primitive values can *only* be +// obtained from values filled by the decoder functions, including this method. +// (i.e., v may contain more [Primitive] values.) // -// See the documentation on Decoder for a description of the decoding process. -func Decode(data string, v interface{}) (MetaData, error) { - return NewDecoder(strings.NewReader(data)).Decode(v) -} - -// DecodeFile is just like Decode, except it will automatically read the -// contents of the file at path and decode it for you. -func DecodeFile(path string, v interface{}) (MetaData, error) { - fp, err := os.Open(path) - if err != nil { - return MetaData{}, err - } - defer fp.Close() - return NewDecoder(fp).Decode(v) +// Meta data for primitive values is included in the meta data returned by the +// Decode* functions with one exception: keys returned by the Undecoded method +// will only reflect keys that were decoded. Namely, any keys hidden behind a +// Primitive will be considered undecoded. Executing this method will update the +// undecoded keys in the meta data. (See the example.) +func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { + md.context = primValue.context + defer func() { md.context = nil }() + return md.unify(primValue.undecoded, rvalue(v)) } // unify performs a sort of type unification based on the structure of `rv`, @@ -184,7 +193,7 @@ func DecodeFile(path string, v interface{}) (MetaData, error) { func (md *MetaData) unify(data interface{}, rv reflect.Value) error { // Special case. Look for a `Primitive` value. // TODO: #76 would make this superfluous after implemented. - if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() { + if rv.Type() == primitiveType { // Save the undecoded data and the key context into the primitive // value. context := make(Key, len(md.context)) @@ -196,17 +205,14 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error { return nil } - // Special case. Unmarshaler Interface support. - if rv.CanAddr() { - if v, ok := rv.Addr().Interface().(Unmarshaler); ok { - return v.UnmarshalTOML(data) - } + rvi := rv.Interface() + if v, ok := rvi.(Unmarshaler); ok { + return v.UnmarshalTOML(data) } - - // Special case. Look for a value satisfying the TextUnmarshaler interface. - if v, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + if v, ok := rvi.(encoding.TextUnmarshaler); ok { return md.unifyText(data, v) } + // TODO: // The behavior here is incorrect whenever a Go type satisfies the // encoding.TextUnmarshaler interface but also corresponds to a TOML hash or @@ -217,7 +223,6 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error { k := rv.Kind() - // laziness if k >= reflect.Int && k <= reflect.Uint64 { return md.unifyInt(data, rv) } @@ -243,15 +248,14 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error { case reflect.Bool: return md.unifyBool(data, rv) case reflect.Interface: - // we only support empty interfaces. - if rv.NumMethod() > 0 { - return e("unsupported type %s", rv.Type()) + if rv.NumMethod() > 0 { // Only support empty interfaces are supported. + return md.e("unsupported type %s", rv.Type()) } return md.unifyAnything(data, rv) case reflect.Float32, reflect.Float64: return md.unifyFloat64(data, rv) } - return e("unsupported type %s", rv.Kind()) + return md.e("unsupported type %s", rv.Kind()) } func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { @@ -260,7 +264,7 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { if mapping == nil { return nil } - return e("type mismatch for %s: expected table but found %T", + return md.e("type mismatch for %s: expected table but found %T", rv.Type().String(), mapping) } @@ -286,13 +290,14 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { if isUnifiable(subv) { md.decoded[md.context.add(key).String()] = struct{}{} md.context = append(md.context, key) + err := md.unify(datum, subv) if err != nil { return err } md.context = md.context[0 : len(md.context)-1] } else if f.name != "" { - return e("cannot write unexported field %s.%s", rv.Type().String(), f.name) + return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name) } } } @@ -300,10 +305,10 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { } func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { - if k := rv.Type().Key().Kind(); k != reflect.String { - return fmt.Errorf( - "toml: cannot decode to a map with non-string key type (%s in %q)", - k, rv.Type()) + keyType := rv.Type().Key().Kind() + if keyType != reflect.String && keyType != reflect.Interface { + return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)", + keyType, rv.Type()) } tmap, ok := mapping.(map[string]interface{}) @@ -321,13 +326,22 @@ func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { md.context = append(md.context, k) rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) - if err := md.unify(v, rvval); err != nil { + + err := md.unify(v, indirect(rvval)) + if err != nil { return err } md.context = md.context[0 : len(md.context)-1] rvkey := indirect(reflect.New(rv.Type().Key())) - rvkey.SetString(k) + + switch keyType { + case reflect.Interface: + rvkey.Set(reflect.ValueOf(k)) + case reflect.String: + rvkey.SetString(k) + } + rv.SetMapIndex(rvkey, rvval) } return nil @@ -342,7 +356,7 @@ func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error { return md.badtype("slice", data) } if l := datav.Len(); l != rv.Len() { - return e("expected array length %d; got TOML array of length %d", rv.Len(), l) + return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l) } return md.unifySliceArray(datav, rv) } @@ -375,6 +389,18 @@ func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { } func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error { + _, ok := rv.Interface().(json.Number) + if ok { + if i, ok := data.(int64); ok { + rv.SetString(strconv.FormatInt(i, 10)) + } else if f, ok := data.(float64); ok { + rv.SetString(strconv.FormatFloat(f, 'f', -1, 64)) + } else { + return md.badtype("string", data) + } + return nil + } + if s, ok := data.(string); ok { rv.SetString(s) return nil @@ -383,11 +409,13 @@ func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error { } func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { + rvk := rv.Kind() + if num, ok := data.(float64); ok { - switch rv.Kind() { + switch rvk { case reflect.Float32: if num < -math.MaxFloat32 || num > math.MaxFloat32 { - return e("value %f is out of range for float32", num) + return md.parseErr(errParseRange{i: num, size: rvk.String()}) } fallthrough case reflect.Float64: @@ -399,20 +427,11 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { } if num, ok := data.(int64); ok { - switch rv.Kind() { - case reflect.Float32: - if num < -maxSafeFloat32Int || num > maxSafeFloat32Int { - return e("value %d is out of range for float32", num) - } - fallthrough - case reflect.Float64: - if num < -maxSafeFloat64Int || num > maxSafeFloat64Int { - return e("value %d is out of range for float64", num) - } - rv.SetFloat(float64(num)) - default: - panic("bug") + if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) || + (rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) } + rv.SetFloat(float64(num)) return nil } @@ -420,50 +439,46 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { } func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error { - if num, ok := data.(int64); ok { - if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 { - switch rv.Kind() { - case reflect.Int, reflect.Int64: - // No bounds checking necessary. - case reflect.Int8: - if num < math.MinInt8 || num > math.MaxInt8 { - return e("value %d is out of range for int8", num) - } - case reflect.Int16: - if num < math.MinInt16 || num > math.MaxInt16 { - return e("value %d is out of range for int16", num) - } - case reflect.Int32: - if num < math.MinInt32 || num > math.MaxInt32 { - return e("value %d is out of range for int32", num) - } + _, ok := rv.Interface().(time.Duration) + if ok { + // Parse as string duration, and fall back to regular integer parsing + // (as nanosecond) if this is not a string. + if s, ok := data.(string); ok { + dur, err := time.ParseDuration(s) + if err != nil { + return md.parseErr(errParseDuration{s}) } - rv.SetInt(num) - } else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 { - unum := uint64(num) - switch rv.Kind() { - case reflect.Uint, reflect.Uint64: - // No bounds checking necessary. - case reflect.Uint8: - if num < 0 || unum > math.MaxUint8 { - return e("value %d is out of range for uint8", num) - } - case reflect.Uint16: - if num < 0 || unum > math.MaxUint16 { - return e("value %d is out of range for uint16", num) - } - case reflect.Uint32: - if num < 0 || unum > math.MaxUint32 { - return e("value %d is out of range for uint32", num) - } - } - rv.SetUint(unum) - } else { - panic("unreachable") + rv.SetInt(int64(dur)) + return nil } - return nil } - return md.badtype("integer", data) + + num, ok := data.(int64) + if !ok { + return md.badtype("integer", data) + } + + rvk := rv.Kind() + switch { + case rvk >= reflect.Int && rvk <= reflect.Int64: + if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) || + (rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) || + (rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetInt(num) + case rvk >= reflect.Uint && rvk <= reflect.Uint64: + unum := uint64(num) + if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) || + rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) || + rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetUint(unum) + default: + panic("unreachable") + } + return nil } func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error { @@ -488,7 +503,7 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro return err } s = string(text) - case TextMarshaler: + case encoding.TextMarshaler: text, err := sdata.MarshalText() if err != nil { return err @@ -514,7 +529,30 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro } func (md *MetaData) badtype(dst string, data interface{}) error { - return e("incompatible types: TOML key %q has type %T; destination has type %s", md.context, data, dst) + return md.e("incompatible types: TOML value has type %T; destination has type %s", data, dst) +} + +func (md *MetaData) parseErr(err error) error { + k := md.context.String() + return ParseError{ + LastKey: k, + Position: md.keyInfo[k].pos, + Line: md.keyInfo[k].pos.Line, + err: err, + input: string(md.data), + } +} + +func (md *MetaData) e(format string, args ...interface{}) error { + f := "toml: " + if len(md.context) > 0 { + f = fmt.Sprintf("toml: (last key %q): ", md.context) + p := md.keyInfo[md.context.String()].pos + if p.Line > 0 { + f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context) + } + } + return fmt.Errorf(f+format, args...) } // rvalue returns a reflect.Value of `v`. All pointers are resolved. @@ -533,7 +571,11 @@ func indirect(v reflect.Value) reflect.Value { if v.Kind() != reflect.Ptr { if v.CanSet() { pv := v.Addr() - if _, ok := pv.Interface().(encoding.TextUnmarshaler); ok { + pvi := pv.Interface() + if _, ok := pvi.(encoding.TextUnmarshaler); ok { + return pv + } + if _, ok := pvi.(Unmarshaler); ok { return pv } } @@ -549,12 +591,12 @@ func isUnifiable(rv reflect.Value) bool { if rv.CanSet() { return true } - if _, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + rvi := rv.Interface() + if _, ok := rvi.(encoding.TextUnmarshaler); ok { + return true + } + if _, ok := rvi.(Unmarshaler); ok { return true } return false } - -func e(format string, args ...interface{}) error { - return fmt.Errorf("toml: "+format, args...) -} diff --git a/vendor/github.com/BurntSushi/toml/decode_go116.go b/vendor/github.com/BurntSushi/toml/decode_go116.go index eddfb641b8..086d0b6866 100644 --- a/vendor/github.com/BurntSushi/toml/decode_go116.go +++ b/vendor/github.com/BurntSushi/toml/decode_go116.go @@ -7,8 +7,8 @@ import ( "io/fs" ) -// DecodeFS is just like Decode, except it will automatically read the contents -// of the file at `path` from a fs.FS instance. +// DecodeFS reads the contents of a file from [fs.FS] and decodes it with +// [Decode]. func DecodeFS(fsys fs.FS, path string, v interface{}) (MetaData, error) { fp, err := fsys.Open(path) if err != nil { diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go index 099c4a77d2..81a7c0fe9f 100644 --- a/vendor/github.com/BurntSushi/toml/doc.go +++ b/vendor/github.com/BurntSushi/toml/doc.go @@ -1,13 +1,11 @@ -/* -Package toml implements decoding and encoding of TOML files. - -This package supports TOML v1.0.0, as listed on https://toml.io - -There is also support for delaying decoding with the Primitive type, and -querying the set of keys in a TOML document with the MetaData type. - -The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator, -and can be used to verify if TOML document is valid. It can also be used to -print the type of each key. -*/ +// Package toml implements decoding and encoding of TOML files. +// +// This package supports TOML v1.0.0, as specified at https://toml.io +// +// There is also support for delaying decoding with the Primitive type, and +// querying the set of keys in a TOML document with the MetaData type. +// +// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator, +// and can be used to verify if TOML document is valid. It can also be used to +// print the type of each key. package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go index dee4e6d319..930e1d521a 100644 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ b/vendor/github.com/BurntSushi/toml/encode.go @@ -3,6 +3,7 @@ package toml import ( "bufio" "encoding" + "encoding/json" "errors" "fmt" "io" @@ -63,6 +64,12 @@ var dblQuotedReplacer = strings.NewReplacer( "\x7f", `\u007f`, ) +var ( + marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + timeType = reflect.TypeOf((*time.Time)(nil)).Elem() +) + // Marshaler is the interface implemented by types that can marshal themselves // into valid TOML. type Marshaler interface { @@ -72,9 +79,12 @@ type Marshaler interface { // Encoder encodes a Go to a TOML document. // // The mapping between Go values and TOML values should be precisely the same as -// for the Decode* functions. +// for [Decode]. // -// The toml.Marshaler and encoder.TextMarshaler interfaces are supported to +// time.Time is encoded as a RFC 3339 string, and time.Duration as its string +// representation. +// +// The [Marshaler] and [encoding.TextMarshaler] interfaces are supported to // encoding the value as custom TOML. // // If you want to write arbitrary binary data then you will need to use @@ -85,6 +95,17 @@ type Marshaler interface { // // Go maps will be sorted alphabetically by key for deterministic output. // +// The toml struct tag can be used to provide the key name; if omitted the +// struct field name will be used. If the "omitempty" option is present the +// following value will be skipped: +// +// - arrays, slices, maps, and string with len of 0 +// - struct with all zero values +// - bool false +// +// If omitzero is given all int and float types with a value of 0 will be +// skipped. +// // Encoding Go values without a corresponding TOML representation will return an // error. Examples of this includes maps with non-string keys, slices with nil // elements, embedded non-struct types, and nested slices containing maps or @@ -109,7 +130,7 @@ func NewEncoder(w io.Writer) *Encoder { } } -// Encode writes a TOML representation of the Go value to the Encoder's writer. +// Encode writes a TOML representation of the Go value to the [Encoder]'s writer. // // An error is returned if the value given cannot be encoded to a valid TOML // document. @@ -136,18 +157,15 @@ func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { } func (enc *Encoder) encode(key Key, rv reflect.Value) { - // Special case: time needs to be in ISO8601 format. - // - // Special case: if we can marshal the type to text, then we used that. This - // prevents the encoder for handling these types as generic structs (or - // whatever the underlying type of a TextMarshaler is). - switch t := rv.Interface().(type) { - case time.Time, encoding.TextMarshaler, Marshaler: + // If we can marshal the type to text, then we use that. This prevents the + // encoder for handling these types as generic structs (or whatever the + // underlying type of a TextMarshaler is). + switch { + case isMarshaler(rv): enc.writeKeyValue(key, rv, false) return - // TODO: #76 would make this superfluous after implemented. - case Primitive: - enc.encode(key, reflect.ValueOf(t.undecoded)) + case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented. + enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded)) return } @@ -212,18 +230,44 @@ func (enc *Encoder) eElement(rv reflect.Value) { if err != nil { encPanic(err) } - enc.writeQuoted(string(s)) + if s == nil { + encPanic(errors.New("MarshalTOML returned nil and no error")) + } + enc.w.Write(s) return case encoding.TextMarshaler: s, err := v.MarshalText() if err != nil { encPanic(err) } + if s == nil { + encPanic(errors.New("MarshalText returned nil and no error")) + } enc.writeQuoted(string(s)) return + case time.Duration: + enc.writeQuoted(v.String()) + return + case json.Number: + n, _ := rv.Interface().(json.Number) + + if n == "" { /// Useful zero value. + enc.w.WriteByte('0') + return + } else if v, err := n.Int64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } else if v, err := n.Float64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } + encPanic(fmt.Errorf("unable to convert %q to int64 or float64", n)) } switch rv.Kind() { + case reflect.Ptr: + enc.eElement(rv.Elem()) + return case reflect.String: enc.writeQuoted(rv.String()) case reflect.Bool: @@ -259,7 +303,7 @@ func (enc *Encoder) eElement(rv reflect.Value) { case reflect.Interface: enc.eElement(rv.Elem()) default: - encPanic(fmt.Errorf("unexpected primitive type: %T", rv.Interface())) + encPanic(fmt.Errorf("unexpected type: %T", rv.Interface())) } } @@ -280,7 +324,7 @@ func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { length := rv.Len() enc.wf("[") for i := 0; i < length; i++ { - elem := rv.Index(i) + elem := eindirect(rv.Index(i)) enc.eElement(elem) if i != length-1 { enc.wf(", ") @@ -294,7 +338,7 @@ func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { encPanic(errNoKey) } for i := 0; i < rv.Len(); i++ { - trv := rv.Index(i) + trv := eindirect(rv.Index(i)) if isNil(trv) { continue } @@ -319,7 +363,7 @@ func (enc *Encoder) eTable(key Key, rv reflect.Value) { } func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) { - switch rv := eindirect(rv); rv.Kind() { + switch rv.Kind() { case reflect.Map: enc.eMap(key, rv, inline) case reflect.Struct: @@ -341,7 +385,7 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { var mapKeysDirect, mapKeysSub []string for _, mapKey := range rv.MapKeys() { k := mapKey.String() - if typeIsTable(tomlTypeOfGo(rv.MapIndex(mapKey))) { + if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) { mapKeysSub = append(mapKeysSub, k) } else { mapKeysDirect = append(mapKeysDirect, k) @@ -351,7 +395,7 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { var writeMapKeys = func(mapKeys []string, trailC bool) { sort.Strings(mapKeys) for i, mapKey := range mapKeys { - val := rv.MapIndex(reflect.ValueOf(mapKey)) + val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey))) if isNil(val) { continue } @@ -379,6 +423,13 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { const is32Bit = (32 << (^uint(0) >> 63)) == 32 +func pointerTo(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + return pointerTo(t.Elem()) + } + return t +} + func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { // Write keys for fields directly under this key first, because if we write // a field that creates a new table then all keys under it will be in that @@ -395,31 +446,25 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { addFields = func(rt reflect.Type, rv reflect.Value, start []int) { for i := 0; i < rt.NumField(); i++ { f := rt.Field(i) - if f.PkgPath != "" && !f.Anonymous { /// Skip unexported fields. + isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct + if f.PkgPath != "" && !isEmbed { /// Skip unexported fields. + continue + } + opts := getOptions(f.Tag) + if opts.skip { continue } - frv := rv.Field(i) + frv := eindirect(rv.Field(i)) // Treat anonymous struct fields with tag names as though they are // not anonymous, like encoding/json does. // // Non-struct anonymous fields use the normal encoding logic. - if f.Anonymous { - t := f.Type - switch t.Kind() { - case reflect.Struct: - if getOptions(f.Tag).name == "" { - addFields(t, frv, append(start, f.Index...)) - continue - } - case reflect.Ptr: - if t.Elem().Kind() == reflect.Struct && getOptions(f.Tag).name == "" { - if !frv.IsNil() { - addFields(t.Elem(), frv.Elem(), append(start, f.Index...)) - } - continue - } + if isEmbed { + if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct { + addFields(frv.Type(), frv, append(start, f.Index...)) + continue } } @@ -445,7 +490,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { writeFields := func(fields [][]int) { for _, fieldIndex := range fields { fieldType := rt.FieldByIndex(fieldIndex) - fieldVal := rv.FieldByIndex(fieldIndex) + fieldVal := eindirect(rv.FieldByIndex(fieldIndex)) if isNil(fieldVal) { /// Don't write anything for nil fields. continue @@ -459,7 +504,8 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { if opts.name != "" { keyName = opts.name } - if opts.omitempty && isEmpty(fieldVal) { + + if opts.omitempty && enc.isEmpty(fieldVal) { continue } if opts.omitzero && isZero(fieldVal) { @@ -498,6 +544,21 @@ func tomlTypeOfGo(rv reflect.Value) tomlType { if isNil(rv) || !rv.IsValid() { return nil } + + if rv.Kind() == reflect.Struct { + if rv.Type() == timeType { + return tomlDatetime + } + if isMarshaler(rv) { + return tomlString + } + return tomlHash + } + + if isMarshaler(rv) { + return tomlString + } + switch rv.Kind() { case reflect.Bool: return tomlBool @@ -509,7 +570,7 @@ func tomlTypeOfGo(rv reflect.Value) tomlType { case reflect.Float32, reflect.Float64: return tomlFloat case reflect.Array, reflect.Slice: - if typeEqual(tomlHash, tomlArrayType(rv)) { + if isTableArray(rv) { return tomlArrayHash } return tomlArray @@ -519,67 +580,35 @@ func tomlTypeOfGo(rv reflect.Value) tomlType { return tomlString case reflect.Map: return tomlHash - case reflect.Struct: - if _, ok := rv.Interface().(time.Time); ok { - return tomlDatetime - } - if isMarshaler(rv) { - return tomlString - } - return tomlHash default: - if isMarshaler(rv) { - return tomlString - } - encPanic(errors.New("unsupported type: " + rv.Kind().String())) panic("unreachable") } } func isMarshaler(rv reflect.Value) bool { - switch rv.Interface().(type) { - case encoding.TextMarshaler: - return true - case Marshaler: - return true - } - - // Someone used a pointer receiver: we can make it work for pointer values. - if rv.CanAddr() { - if _, ok := rv.Addr().Interface().(encoding.TextMarshaler); ok { - return true - } - if _, ok := rv.Addr().Interface().(Marshaler); ok { - return true - } - } - return false + return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml) } -// tomlArrayType returns the element type of a TOML array. The type returned -// may be nil if it cannot be determined (e.g., a nil slice or a zero length -// slize). This function may also panic if it finds a type that cannot be -// expressed in TOML (such as nil elements, heterogeneous arrays or directly -// nested arrays of tables). -func tomlArrayType(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() || rv.Len() == 0 { - return nil +// isTableArray reports if all entries in the array or slice are a table. +func isTableArray(arr reflect.Value) bool { + if isNil(arr) || !arr.IsValid() || arr.Len() == 0 { + return false } - /// Don't allow nil. - rvlen := rv.Len() - for i := 1; i < rvlen; i++ { - if tomlTypeOfGo(rv.Index(i)) == nil { + ret := true + for i := 0; i < arr.Len(); i++ { + tt := tomlTypeOfGo(eindirect(arr.Index(i))) + // Don't allow nil. + if tt == nil { encPanic(errArrayNilElement) } - } - firstType := tomlTypeOfGo(rv.Index(0)) - if firstType == nil { - encPanic(errArrayNilElement) + if ret && !typeEqual(tomlHash, tt) { + ret = false + } } - return firstType + return ret } type tagOptions struct { @@ -620,10 +649,26 @@ func isZero(rv reflect.Value) bool { return false } -func isEmpty(rv reflect.Value) bool { +func (enc *Encoder) isEmpty(rv reflect.Value) bool { switch rv.Kind() { case reflect.Array, reflect.Slice, reflect.Map, reflect.String: return rv.Len() == 0 + case reflect.Struct: + if rv.Type().Comparable() { + return reflect.Zero(rv.Type()).Interface() == rv.Interface() + } + // Need to also check if all the fields are empty, otherwise something + // like this with uncomparable types will always return true: + // + // type a struct{ field b } + // type b struct{ s []string } + // s := a{field: b{s: []string{"AAA"}}} + for i := 0; i < rv.NumField(); i++ { + if !enc.isEmpty(rv.Field(i)) { + return false + } + } + return true case reflect.Bool: return !rv.Bool() } @@ -638,16 +683,15 @@ func (enc *Encoder) newline() { // Write a key/value pair: // -// key = +// key = // // This is also used for "k = v" in inline tables; so something like this will // be written in three calls: // -// ┌────────────────────┐ -// │ ┌───┐ ┌─────┐│ -// v v v v vv -// key = {k = v, k2 = v2} -// +// ┌───────────────────┐ +// │ ┌───┐ ┌────┐│ +// v v v v vv +// key = {k = 1, k2 = 2} func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) { if len(key) == 0 { encPanic(errNoKey) @@ -675,13 +719,25 @@ func encPanic(err error) { panic(tomlEncodeError{err}) } +// Resolve any level of pointers to the actual value (e.g. **string → string). func eindirect(v reflect.Value) reflect.Value { - switch v.Kind() { - case reflect.Ptr, reflect.Interface: - return eindirect(v.Elem()) - default: + if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface { + if isMarshaler(v) { + return v + } + if v.CanAddr() { /// Special case for marshalers; see #358. + if pv := v.Addr(); isMarshaler(pv) { + return pv + } + } return v } + + if v.IsNil() { + return v + } + + return eindirect(v.Elem()) } func isNil(rv reflect.Value) bool { diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go index 36edc46554..f4f390e647 100644 --- a/vendor/github.com/BurntSushi/toml/error.go +++ b/vendor/github.com/BurntSushi/toml/error.go @@ -5,57 +5,60 @@ import ( "strings" ) -// ParseError is returned when there is an error parsing the TOML syntax. -// -// For example invalid syntax, duplicate keys, etc. +// ParseError is returned when there is an error parsing the TOML syntax such as +// invalid syntax, duplicate keys, etc. // // In addition to the error message itself, you can also print detailed location -// information with context by using ErrorWithLocation(): +// information with context by using [ErrorWithPosition]: // -// toml: error: Key 'fruit' was already created and cannot be used as an array. +// toml: error: Key 'fruit' was already created and cannot be used as an array. // -// At line 4, column 2-7: +// At line 4, column 2-7: // -// 2 | fruit = [] -// 3 | -// 4 | [[fruit]] # Not allowed -// ^^^^^ +// 2 | fruit = [] +// 3 | +// 4 | [[fruit]] # Not allowed +// ^^^^^ // -// Furthermore, the ErrorWithUsage() can be used to print the above with some -// more detailed usage guidance: +// [ErrorWithUsage] can be used to print the above with some more detailed usage +// guidance: // -// toml: error: newlines not allowed within inline tables +// toml: error: newlines not allowed within inline tables // -// At line 1, column 18: +// At line 1, column 18: // -// 1 | x = [{ key = 42 # -// ^ +// 1 | x = [{ key = 42 # +// ^ // -// Error help: +// Error help: // -// Inline tables must always be on a single line: +// Inline tables must always be on a single line: // -// table = {key = 42, second = 43} +// table = {key = 42, second = 43} // -// It is invalid to split them over multiple lines like so: +// It is invalid to split them over multiple lines like so: // -// # INVALID -// table = { -// key = 42, -// second = 43 -// } +// # INVALID +// table = { +// key = 42, +// second = 43 +// } // -// Use regular for this: +// Use regular for this: // -// [table] -// key = 42 -// second = 43 +// [table] +// key = 42 +// second = 43 type ParseError struct { Message string // Short technical message. Usage string // Longer message with usage guidance; may be blank. Position Position // Position of the error LastKey string // Last parsed key, may be blank. - Line int // Line the error occurred. Deprecated: use Position. + + // Line the error occurred. + // + // Deprecated: use [Position]. + Line int err error input string @@ -83,7 +86,7 @@ func (pe ParseError) Error() string { // ErrorWithUsage() returns the error with detailed location context. // -// See the documentation on ParseError. +// See the documentation on [ParseError]. func (pe ParseError) ErrorWithPosition() string { if pe.input == "" { // Should never happen, but just in case. return pe.Error() @@ -124,13 +127,17 @@ func (pe ParseError) ErrorWithPosition() string { // ErrorWithUsage() returns the error with detailed location context and usage // guidance. // -// See the documentation on ParseError. +// See the documentation on [ParseError]. func (pe ParseError) ErrorWithUsage() string { m := pe.ErrorWithPosition() if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" { - return m + "Error help:\n\n " + - strings.ReplaceAll(strings.TrimSpace(u.Usage()), "\n", "\n ") + - "\n" + lines := strings.Split(strings.TrimSpace(u.Usage()), "\n") + for i := range lines { + if lines[i] != "" { + lines[i] = " " + lines[i] + } + } + return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n" } return m } @@ -160,6 +167,11 @@ type ( errLexInvalidDate struct{ v string } errLexInlineTableNL struct{} errLexStringNL struct{} + errParseRange struct { + i interface{} // int or float + size string // "int64", "uint16", etc. + } + errParseDuration struct{ d string } ) func (e errLexControl) Error() string { @@ -179,6 +191,10 @@ func (e errLexInlineTableNL) Error() string { return "newlines not allowed withi func (e errLexInlineTableNL) Usage() string { return usageInlineNewline } func (e errLexStringNL) Error() string { return "strings cannot contain newlines" } func (e errLexStringNL) Usage() string { return usageStringNewline } +func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) } +func (e errParseRange) Usage() string { return usageIntOverflow } +func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) } +func (e errParseDuration) Usage() string { return usageDuration } const usageEscape = ` A '\' inside a "-delimited string is interpreted as an escape character. @@ -227,3 +243,37 @@ Instead use """ or ''' to split strings over multiple lines: string = """Hello, world!""" ` + +const usageIntOverflow = ` +This number is too large; this may be an error in the TOML, but it can also be a +bug in the program that uses too small of an integer. + +The maximum and minimum values are: + + size │ lowest │ highest + ───────┼────────────────┼────────── + int8 │ -128 │ 127 + int16 │ -32,768 │ 32,767 + int32 │ -2,147,483,648 │ 2,147,483,647 + int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷ + uint8 │ 0 │ 255 + uint16 │ 0 │ 65535 + uint32 │ 0 │ 4294967295 + uint64 │ 0 │ 1.8 × 10¹⁸ + +int refers to int32 on 32-bit systems and int64 on 64-bit systems. +` + +const usageDuration = ` +A duration must be as "number", without any spaces. Valid units are: + + ns nanoseconds (billionth of a second) + us, µs microseconds (millionth of a second) + ms milliseconds (thousands of a second) + s seconds + m minutes + h hours + +You can combine multiple units; for example "5m10s" for 5 minutes and 10 +seconds. +` diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go index 63ef20f474..d4d70871d8 100644 --- a/vendor/github.com/BurntSushi/toml/lex.go +++ b/vendor/github.com/BurntSushi/toml/lex.go @@ -82,7 +82,7 @@ func (lx *lexer) nextItem() item { return item default: lx.state = lx.state(lx) - //fmt.Printf(" STATE %-24s current: %-10q stack: %s\n", lx.state, lx.current(), lx.stack) + //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack) } } } @@ -128,6 +128,11 @@ func (lx lexer) getPos() Position { } func (lx *lexer) emit(typ itemType) { + // Needed for multiline strings ending with an incomplete UTF-8 sequence. + if lx.start > lx.pos { + lx.error(errLexUTF8{lx.input[lx.pos]}) + return + } lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()} lx.start = lx.pos } @@ -711,7 +716,17 @@ func lexMultilineString(lx *lexer) stateFn { if lx.peek() == '"' { /// Check if we already lexed 5 's; if so we have 6 now, and /// that's just too many man! - if strings.HasSuffix(lx.current(), `"""""`) { + /// + /// Second check is for the edge case: + /// + /// two quotes allowed. + /// vv + /// """lol \"""""" + /// ^^ ^^^---- closing three + /// escaped + /// + /// But ugly, but it works + if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) { return lx.errorf(`unexpected '""""""'`) } lx.backup() @@ -756,7 +771,7 @@ func lexRawString(lx *lexer) stateFn { } // lexMultilineRawString consumes a raw string. Nothing can be escaped in such -// a string. It assumes that the beginning "'''" has already been consumed and +// a string. It assumes that the beginning ''' has already been consumed and // ignored. func lexMultilineRawString(lx *lexer) stateFn { r := lx.next() @@ -802,8 +817,7 @@ func lexMultilineRawString(lx *lexer) stateFn { // lexMultilineStringEscape consumes an escaped character. It assumes that the // preceding '\\' has already been consumed. func lexMultilineStringEscape(lx *lexer) stateFn { - // Handle the special case first: - if isNL(lx.next()) { + if isNL(lx.next()) { /// \ escaping newline. return lexMultilineString } lx.backup() diff --git a/vendor/github.com/BurntSushi/toml/meta.go b/vendor/github.com/BurntSushi/toml/meta.go index 868619fb97..71847a0415 100644 --- a/vendor/github.com/BurntSushi/toml/meta.go +++ b/vendor/github.com/BurntSushi/toml/meta.go @@ -12,10 +12,11 @@ import ( type MetaData struct { context Key // Used only during decoding. + keyInfo map[string]keyInfo mapping map[string]interface{} - types map[string]tomlType keys []Key decoded map[string]struct{} + data []byte // Input file; for errors. } // IsDefined reports if the key exists in the TOML data. @@ -50,8 +51,8 @@ func (md *MetaData) IsDefined(key ...string) bool { // Type will return the empty string if given an empty key or a key that does // not exist. Keys are case sensitive. func (md *MetaData) Type(key ...string) string { - if typ, ok := md.types[Key(key).String()]; ok { - return typ.typeString() + if ki, ok := md.keyInfo[Key(key).String()]; ok { + return ki.tomlType.typeString() } return "" } @@ -70,7 +71,7 @@ func (md *MetaData) Keys() []Key { // Undecoded returns all keys that have not been decoded in the order in which // they appear in the original TOML document. // -// This includes keys that haven't been decoded because of a Primitive value. +// This includes keys that haven't been decoded because of a [Primitive] value. // Once the Primitive value is decoded, the keys will be considered decoded. // // Also note that decoding into an empty interface will result in no decoding, @@ -88,7 +89,7 @@ func (md *MetaData) Undecoded() []Key { return undecoded } -// Key represents any TOML key, including key groups. Use (MetaData).Keys to get +// Key represents any TOML key, including key groups. Use [MetaData.Keys] to get // values of this type. type Key []string diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go index 8269cca170..d2542d6f92 100644 --- a/vendor/github.com/BurntSushi/toml/parse.go +++ b/vendor/github.com/BurntSushi/toml/parse.go @@ -16,12 +16,18 @@ type parser struct { currentKey string // Base key name for everything except hashes. pos Position // Current position in the TOML file. - ordered []Key // List of keys in the order that they appear in the TOML data. + ordered []Key // List of keys in the order that they appear in the TOML data. + + keyInfo map[string]keyInfo // Map keyname → info about the TOML key. mapping map[string]interface{} // Map keyname → key value. - types map[string]tomlType // Map keyname → TOML type. implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names"). } +type keyInfo struct { + pos Position + tomlType tomlType +} + func parse(data string) (p *parser, err error) { defer func() { if r := recover(); r != nil { @@ -57,8 +63,8 @@ func parse(data string) (p *parser, err error) { } p = &parser{ + keyInfo: make(map[string]keyInfo), mapping: make(map[string]interface{}), - types: make(map[string]tomlType), lx: lex(data), ordered: make([]Key, 0), implicits: make(map[string]struct{}), @@ -74,6 +80,15 @@ func parse(data string) (p *parser, err error) { return p, nil } +func (p *parser) panicErr(it item, err error) { + panic(ParseError{ + err: err, + Position: it.pos, + Line: it.pos.Len, + LastKey: p.current(), + }) +} + func (p *parser) panicItemf(it item, format string, v ...interface{}) { panic(ParseError{ Message: fmt.Sprintf(format, v...), @@ -94,7 +109,7 @@ func (p *parser) panicf(format string, v ...interface{}) { func (p *parser) next() item { it := p.lx.nextItem() - //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.line, it.val) + //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val) if it.typ == itemError { if it.err != nil { panic(ParseError{ @@ -146,7 +161,7 @@ func (p *parser) topLevel(item item) { p.assertEqual(itemTableEnd, name.typ) p.addContext(key, false) - p.setType("", tomlHash) + p.setType("", tomlHash, item.pos) p.ordered = append(p.ordered, key) case itemArrayTableStart: // [[ .. ]] name := p.nextPos() @@ -158,7 +173,7 @@ func (p *parser) topLevel(item item) { p.assertEqual(itemArrayTableEnd, name.typ) p.addContext(key, true) - p.setType("", tomlArrayHash) + p.setType("", tomlArrayHash, item.pos) p.ordered = append(p.ordered, key) case itemKeyStart: // key = .. outerContext := p.context @@ -181,8 +196,9 @@ func (p *parser) topLevel(item item) { } /// Set value. - val, typ := p.value(p.next(), false) - p.set(p.currentKey, val, typ) + vItem := p.next() + val, typ := p.value(vItem, false) + p.set(p.currentKey, val, typ, vItem.pos) p.ordered = append(p.ordered, p.context.add(p.currentKey)) /// Remove the context we added (preserving any context from [tbl] lines). @@ -220,7 +236,7 @@ func (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) { case itemString: return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it) case itemMultilineString: - return p.replaceEscapes(it, stripFirstNewline(stripEscapedNewlines(it.val))), p.typeOfPrimitive(it) + return p.replaceEscapes(it, stripFirstNewline(p.stripEscapedNewlines(it.val))), p.typeOfPrimitive(it) case itemRawString: return it.val, p.typeOfPrimitive(it) case itemRawMultilineString: @@ -266,7 +282,7 @@ func (p *parser) valueInteger(it item) (interface{}, tomlType) { // So mark the former as a bug but the latter as a legitimate user // error. if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { - p.panicItemf(it, "Integer '%s' is out of the range of 64-bit signed integers.", it.val) + p.panicErr(it, errParseRange{i: it.val, size: "int64"}) } else { p.bug("Expected integer value, but got '%s'.", it.val) } @@ -304,7 +320,7 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) { num, err := strconv.ParseFloat(val, 64) if err != nil { if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { - p.panicItemf(it, "Float '%s' is out of the range of 64-bit IEEE-754 floating-point numbers.", it.val) + p.panicErr(it, errParseRange{i: it.val, size: "float64"}) } else { p.panicItemf(it, "Invalid float value: %q", it.val) } @@ -343,9 +359,8 @@ func (p *parser) valueDatetime(it item) (interface{}, tomlType) { } func (p *parser) valueArray(it item) (interface{}, tomlType) { - p.setType(p.currentKey, tomlArray) + p.setType(p.currentKey, tomlArray, it.pos) - // p.setType(p.currentKey, typ) var ( types []tomlType @@ -414,7 +429,7 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom /// Set the value. val, typ := p.value(p.next(), false) - p.set(p.currentKey, val, typ) + p.set(p.currentKey, val, typ, it.pos) p.ordered = append(p.ordered, p.context.add(p.currentKey)) hash[p.currentKey] = val @@ -533,9 +548,10 @@ func (p *parser) addContext(key Key, array bool) { } // set calls setValue and setType. -func (p *parser) set(key string, val interface{}, typ tomlType) { +func (p *parser) set(key string, val interface{}, typ tomlType, pos Position) { p.setValue(key, val) - p.setType(key, typ) + p.setType(key, typ, pos) + } // setValue sets the given key to the given value in the current context. @@ -599,7 +615,7 @@ func (p *parser) setValue(key string, value interface{}) { // // Note that if `key` is empty, then the type given will be applied to the // current context (which is either a table or an array of tables). -func (p *parser) setType(key string, typ tomlType) { +func (p *parser) setType(key string, typ tomlType, pos Position) { keyContext := make(Key, 0, len(p.context)+1) keyContext = append(keyContext, p.context...) if len(key) > 0 { // allow type setting for hashes @@ -611,7 +627,7 @@ func (p *parser) setType(key string, typ tomlType) { if len(keyContext) == 0 { keyContext = Key{""} } - p.types[keyContext.String()] = typ + p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos} } // Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and @@ -619,7 +635,7 @@ func (p *parser) setType(key string, typ tomlType) { func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} } func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) } func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok } -func (p *parser) isArray(key Key) bool { return p.types[key.String()] == tomlArray } +func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray } func (p *parser) addImplicitContext(key Key) { p.addImplicit(key) p.addContext(key, false) @@ -647,7 +663,7 @@ func stripFirstNewline(s string) string { } // Remove newlines inside triple-quoted strings if a line ends with "\". -func stripEscapedNewlines(s string) string { +func (p *parser) stripEscapedNewlines(s string) string { split := strings.Split(s, "\n") if len(split) < 1 { return s @@ -679,6 +695,10 @@ func stripEscapedNewlines(s string) string { continue } + if i == len(split)-1 { + p.panicf("invalid escape: '\\ '") + } + split[i] = line[:len(line)-1] // Remove \ if len(split)-1 > i { split[i+1] = strings.TrimLeft(split[i+1], " \t\r") @@ -706,10 +726,8 @@ func (p *parser) replaceEscapes(it item, str string) string { switch s[r] { default: p.bug("Expected valid escape code after \\, but got %q.", s[r]) - return "" case ' ', '\t': p.panicItemf(it, "invalid escape: '\\%c'", s[r]) - return "" case 'b': replaced = append(replaced, rune(0x0008)) r += 1 diff --git a/vendor/github.com/MakeNowJust/heredoc/LICENSE b/vendor/github.com/MakeNowJust/heredoc/LICENSE index 8a58c22208..6d0eb9d5d6 100644 --- a/vendor/github.com/MakeNowJust/heredoc/LICENSE +++ b/vendor/github.com/MakeNowJust/heredoc/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2017 TSUYUSATO Kitsune +Copyright (c) 2014-2019 TSUYUSATO Kitsune Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/MakeNowJust/heredoc/README.md b/vendor/github.com/MakeNowJust/heredoc/README.md index a3a65faba1..e9924d2974 100644 --- a/vendor/github.com/MakeNowJust/heredoc/README.md +++ b/vendor/github.com/MakeNowJust/heredoc/README.md @@ -1,4 +1,6 @@ -# heredoc [![CircleCI](https://circleci.com/gh/MakeNowJust/heredoc.svg?style=svg)](https://circleci.com/gh/MakeNowJust/heredoc) [![Go Walker](http://gowalker.org/api/v1/badge)](https://gowalker.org/github.com/MakeNowJust/heredoc) +# heredoc + +[![Build Status](https://circleci.com/gh/MakeNowJust/heredoc.svg?style=svg)](https://circleci.com/gh/MakeNowJust/heredoc) [![GoDoc](https://godoc.org/github.com/MakeNowJusti/heredoc?status.svg)](https://godoc.org/github.com/MakeNowJust/heredoc) ## About @@ -15,8 +17,6 @@ $ go get github.com/MakeNowJust/heredoc ```go // usual import "github.com/MakeNowJust/heredoc" -// shortcuts -import . "github.com/MakeNowJust/heredoc/dot" ``` ## Example @@ -26,11 +26,11 @@ package main import ( "fmt" - . "github.com/MakeNowJust/heredoc/dot" + "github.com/MakeNowJust/heredoc" ) func main() { - fmt.Println(D(` + fmt.Println(heredoc.Doc(` Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, ... @@ -45,8 +45,7 @@ func main() { ## API Document - - [Go Walker - github.com/MakeNowJust/heredoc](https://gowalker.org/github.com/MakeNowJust/heredoc) - - [Go Walker - github.com/MakeNowJust/heredoc/dot](https://gowalker.org/github.com/MakeNowJust/heredoc/dot) + - [heredoc - GoDoc](https://godoc.org/github.com/MakeNowJust/heredoc) ## License diff --git a/vendor/github.com/MakeNowJust/heredoc/heredoc.go b/vendor/github.com/MakeNowJust/heredoc/heredoc.go index fea12e622f..1fc0469555 100644 --- a/vendor/github.com/MakeNowJust/heredoc/heredoc.go +++ b/vendor/github.com/MakeNowJust/heredoc/heredoc.go @@ -1,24 +1,31 @@ -// Copyright (c) 2014-2017 TSUYUSATO Kitsune +// Copyright (c) 2014-2019 TSUYUSATO Kitsune // This software is released under the MIT License. // http://opensource.org/licenses/mit-license.php // Package heredoc provides creation of here-documents from raw strings. // // Golang supports raw-string syntax. +// // doc := ` // Foo // Bar // ` +// // But raw-string cannot recognize indentation. Thus such content is an indented string, equivalent to +// // "\n\tFoo\n\tBar\n" +// // I dont't want this! // // However this problem is solved by package heredoc. +// // doc := heredoc.Doc(` // Foo // Bar // `) +// // Is equivalent to +// // "Foo\nBar\n" package heredoc @@ -33,7 +40,7 @@ const maxInt = int(^uint(0) >> 1) // Doc returns un-indented string as here-document. func Doc(raw string) string { skipFirstLine := false - if raw[0] == '\n' { + if len(raw) > 0 && raw[0] == '\n' { raw = raw[1:] } else { skipFirstLine = true diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml index fdbdf1448c..c87d1c4b90 100644 --- a/vendor/github.com/Masterminds/semver/v3/.golangci.yml +++ b/vendor/github.com/Masterminds/semver/v3/.golangci.yml @@ -4,23 +4,27 @@ run: linters: disable-all: true enable: + - misspell + - structcheck + - govet + - staticcheck - deadcode - - dupl - errcheck - - gofmt - - goimports - - golint - - gosimple - - govet + - varcheck + - unparam - ineffassign - - misspell - nakedret - - structcheck + - gocyclo + - dupl + - goimports + - revive + - gosec + - gosimple + - typecheck - unused - - varcheck linters-settings: gofmt: simplify: true dupl: - threshold: 400 + threshold: 600 diff --git a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md index 1f90c38d26..f12626423a 100644 --- a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 3.2.0 (2022-11-28) + +### Added + +- #190: Added text marshaling and unmarshaling +- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) +- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) +- #179: Added New() version constructor (thanks @kazhuravlev) + +### Changed + +- #182/#183: Updated CI testing setup + +### Fixed + +- #186: Fixing issue where validation of constraint section gave false positives +- #176: Fix constraints check with *-0 (thanks @mtt0) +- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) +- #161: Fixed godoc (thanks @afirth) + ## 3.1.1 (2020-11-23) ### Fixed diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go index 547613f044..203072e464 100644 --- a/vendor/github.com/Masterminds/semver/v3/constraints.go +++ b/vendor/github.com/Masterminds/semver/v3/constraints.go @@ -134,6 +134,23 @@ func (cs Constraints) String() string { return strings.Join(buf, " || ") } +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (cs *Constraints) UnmarshalText(text []byte) error { + temp, err := NewConstraint(string(text)) + if err != nil { + return err + } + + *cs = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (cs Constraints) MarshalText() ([]byte, error) { + return []byte(cs.String()), nil +} + var constraintOps map[string]cfunc var constraintRegex *regexp.Regexp var constraintRangeRegex *regexp.Regexp @@ -180,8 +197,13 @@ func init() { ops, cvRegex)) + // The first time a constraint shows up will look slightly different from + // future times it shows up due to a leading space or comma in a given + // string. validConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `^(\s*(%s)\s*(%s)\s*\,?)+$`, + `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, + ops, + cvRegex, ops, cvRegex)) } @@ -233,7 +255,7 @@ func parseConstraint(c string) (*constraint, error) { patchDirty := false dirty := false if isX(m[3]) || m[3] == "" { - ver = "0.0.0" + ver = fmt.Sprintf("0.0.0%s", m[6]) dirty = true } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { minorDirty = true @@ -534,6 +556,10 @@ func constraintCaret(v *Version, c *constraint) (bool, error) { } return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) } + // ^ when the minor is 0 and minor > 0 is =0.0.z + if c.con.Minor() == 0 && v.Minor() > 0 { + return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) + } // At this point the major is 0 and the minor is 0 and not dirty. The patch // is not dirty so we need to check if they are equal. If they are not equal diff --git a/vendor/github.com/Masterminds/semver/v3/doc.go b/vendor/github.com/Masterminds/semver/v3/doc.go index 391aa46b76..74f97caa57 100644 --- a/vendor/github.com/Masterminds/semver/v3/doc.go +++ b/vendor/github.com/Masterminds/semver/v3/doc.go @@ -3,12 +3,12 @@ Package semver provides the ability to work with Semantic Versions (http://semve Specifically it provides the ability to: - * Parse semantic versions - * Sort semantic versions - * Check if a semantic version fits within a set of constraints - * Optionally work with a `v` prefix + - Parse semantic versions + - Sort semantic versions + - Check if a semantic version fits within a set of constraints + - Optionally work with a `v` prefix -Parsing Semantic Versions +# Parsing Semantic Versions There are two functions that can parse semantic versions. The `StrictNewVersion` function only parses valid version 2 semantic versions as outlined in the @@ -21,48 +21,48 @@ that can be sorted, compared, and used in constraints. When parsing a version an optional error can be returned if there is an issue parsing the version. For example, - v, err := semver.NewVersion("1.2.3-beta.1+b345") + v, err := semver.NewVersion("1.2.3-beta.1+b345") The version object has methods to get the parts of the version, compare it to other versions, convert the version back into a string, and get the original string. For more details please see the documentation at https://godoc.org/github.com/Masterminds/semver. -Sorting Semantic Versions +# Sorting Semantic Versions A set of versions can be sorted using the `sort` package from the standard library. For example, - raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} - vs := make([]*semver.Version, len(raw)) - for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } - vs[i] = v - } + vs[i] = v + } - sort.Sort(semver.Collection(vs)) + sort.Sort(semver.Collection(vs)) -Checking Version Constraints and Comparing Versions +# Checking Version Constraints and Comparing Versions There are two methods for comparing versions. One uses comparison methods on `Version` instances and the other is using Constraints. There are some important differences to notes between these two methods of comparison. -1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include prereleases - within the comparison. It will provide an answer valid with the comparison - spec section at https://semver.org/#spec-item-11 -2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering prereleases to be invalid if the - ranges does not include on. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. -3. Constraint ranges can have some complex rules including the shorthard use of - ~ and ^. For more details on those see the options below. + 1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer valid with the comparison + spec section at https://semver.org/#spec-item-11 + 2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include on. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. + 3. Constraint ranges can have some complex rules including the shorthard use of + ~ and ^. For more details on those see the options below. There are differences between the two methods or checking versions because the comparison methods on `Version` follow the specification while comparison ranges @@ -76,19 +76,19 @@ patters with their versions. Checking a version against version constraints is one of the most featureful parts of the package. - c, err := semver.NewConstraint(">= 1.2.3") - if err != nil { - // Handle constraint not being parsable. - } + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parsable. + } - v, err := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parsable. - } - // Check if the version meets the constraints. The a variable will be true. - a := c.Check(v) + v, err := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parsable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) -Basic Comparisons +# Basic Comparisons There are two elements to the comparisons. First, a comparison string is a list of comma or space separated AND comparisons. These are then separated by || (OR) @@ -99,31 +99,31 @@ greater than or equal to 4.2.3. This can also be written as The basic comparisons are: - * `=`: equal (aliased to no operator) - * `!=`: not equal - * `>`: greater than - * `<`: less than - * `>=`: greater than or equal to - * `<=`: less than or equal to + - `=`: equal (aliased to no operator) + - `!=`: not equal + - `>`: greater than + - `<`: less than + - `>=`: greater than or equal to + - `<=`: less than or equal to -Hyphen Range Comparisons +# Hyphen Range Comparisons There are multiple methods to handle ranges and the first is hyphens ranges. These look like: - * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` - * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` + - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` -Wildcards In Comparisons +# Wildcards In Comparisons The `x`, `X`, and `*` characters can be used as a wildcard character. This works for all comparison operators. When used on the `=` operator it falls back to the tilde operation. For example, - * `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - * `>= 1.2.x` is equivalent to `>= 1.2.0` - * `<= 2.x` is equivalent to `<= 3` - * `*` is equivalent to `>= 0.0.0` + - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `>= 1.2.x` is equivalent to `>= 1.2.0` + - `<= 2.x` is equivalent to `<= 3` + - `*` is equivalent to `>= 0.0.0` Tilde Range Comparisons (Patch) @@ -131,11 +131,11 @@ The tilde (`~`) comparison operator is for patch level ranges when a minor version is specified and major level changes when the minor number is missing. For example, - * `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` - * `~1` is equivalent to `>= 1, < 2` - * `~2.3` is equivalent to `>= 2.3 < 2.4` - * `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - * `~1.x` is equivalent to `>= 1 < 2` + - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` + - `~1` is equivalent to `>= 1, < 2` + - `~2.3` is equivalent to `>= 2.3 < 2.4` + - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `~1.x` is equivalent to `>= 1 < 2` Caret Range Comparisons (Major) @@ -144,41 +144,41 @@ The caret (`^`) comparison operator is for major level changes once a stable as the API stability level. This is useful when comparisons of API versions as a major change is API breaking. For example, - * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` - * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` - * `^2.3` is equivalent to `>= 2.3, < 3` - * `^2.x` is equivalent to `>= 2.0.0, < 3` - * `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` - * `^0.2` is equivalent to `>=0.2.0 <0.3.0` - * `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` - * `^0.0` is equivalent to `>=0.0.0 <0.1.0` - * `^0` is equivalent to `>=0.0.0 <1.0.0` + - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` + - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` + - `^2.3` is equivalent to `>= 2.3, < 3` + - `^2.x` is equivalent to `>= 2.0.0, < 3` + - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` + - `^0.2` is equivalent to `>=0.2.0 <0.3.0` + - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` + - `^0.0` is equivalent to `>=0.0.0 <0.1.0` + - `^0` is equivalent to `>=0.0.0 <1.0.0` -Validation +# Validation In addition to testing a version against a constraint, a version can be validated against a constraint. When validation fails a slice of errors containing why a version didn't meet the constraint is returned. For example, - c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") - if err != nil { - // Handle constraint not being parseable. - } - - v, _ := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parseable. - } - - // Validate a version against a constraint. - a, msgs := c.Validate(v) - // a is false - for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" - } + c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + + // Validate a version against a constraint. + a, msgs := c.Validate(v) + // a is false + for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" + } */ package semver diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go index d6b9cda3ee..7c4bed3347 100644 --- a/vendor/github.com/Masterminds/semver/v3/version.go +++ b/vendor/github.com/Masterminds/semver/v3/version.go @@ -55,14 +55,16 @@ func init() { versionRegex = regexp.MustCompile("^" + semVerRegex + "$") } -const num string = "0123456789" -const allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +const ( + num string = "0123456789" + allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +) // StrictNewVersion parses a given version and returns an instance of Version or // an error if unable to parse the version. Only parses valid semantic versions. // Performs checking that can find errors within the version. -// If you want to coerce a version, such as 1 or 1.2, and perse that as the 1.x -// releases of semver provided use the NewSemver() function. +// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x +// releases of semver did, use the NewVersion() function. func StrictNewVersion(v string) (*Version, error) { // Parsing here does not use RegEx in order to increase performance and reduce // allocations. @@ -207,6 +209,23 @@ func NewVersion(v string) (*Version, error) { return sv, nil } +// New creates a new instance of Version with each of the parts passed in as +// arguments instead of parsing a version string. +func New(major, minor, patch uint64, pre, metadata string) *Version { + v := Version{ + major: major, + minor: minor, + patch: patch, + pre: pre, + metadata: metadata, + original: "", + } + + v.original = v.String() + + return &v +} + // MustParse parses a given version and panics on error. func MustParse(v string) *Version { sv, err := NewVersion(v) @@ -267,7 +286,6 @@ func (v Version) Metadata() string { // originalVPrefix returns the original 'v' prefix if any. func (v Version) originalVPrefix() string { - // Note, only lowercase v is supported as a prefix by the parser. if v.original != "" && v.original[:1] == "v" { return v.original[:1] @@ -436,6 +454,23 @@ func (v Version) MarshalJSON() ([]byte, error) { return json.Marshal(v.String()) } +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(text []byte) error { + temp, err := NewVersion(string(text)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (v Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} + // Scan implements the SQL.Scanner interface. func (v *Version) Scan(value interface{}) error { var s string @@ -470,7 +505,6 @@ func compareSegment(v, o uint64) int { } func comparePrerelease(v, o string) int { - // split the prelease versions by their part. The separator, per the spec, // is a . sparts := strings.Split(v, ".") @@ -562,7 +596,6 @@ func comparePrePart(s, o string) int { return 1 } return -1 - } // Like strings.ContainsAny but does an only instead of any. diff --git a/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md index fcdd4e88ae..2ce45dd4ec 100644 --- a/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md +++ b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md @@ -1,8 +1,21 @@ # Changelog +## Release 3.2.3 (2022-11-29) + +### Changed + +- Updated docs (thanks @book987 @aJetHorn @neelayu @pellizzetti @apricote @SaigyoujiYuyuko233 @AlekSi) +- #348: Updated huandu/xstrings which fixed a snake case bug (thanks @yxxhero) +- #353: Updated masterminds/semver which included bug fixes +- #354: Updated golang.org/x/crypto which included bug fixes + +## Release 3.2.2 (2021-02-04) + +This is a re-release of 3.2.1 to satisfy something with the Go module system. + ## Release 3.2.1 (2021-02-04) -### Changed +### Changed - Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr) diff --git a/vendor/github.com/Masterminds/sprig/v3/README.md b/vendor/github.com/Masterminds/sprig/v3/README.md index c37ba01c21..3e22c60e1a 100644 --- a/vendor/github.com/Masterminds/sprig/v3/README.md +++ b/vendor/github.com/Masterminds/sprig/v3/README.md @@ -17,10 +17,9 @@ JavaScript libraries, such as [underscore.js](http://underscorejs.org/). ## IMPORTANT NOTES Sprig leverages [mergo](https://github.com/imdario/mergo) to handle merges. In -its v0.3.9 release there was a behavior change that impacts merging template -functions in sprig. It is currently recommended to use v0.3.8 of that package. -Using v0.3.9 will cause sprig tests to fail. The issue in mergo is tracked at -https://github.com/imdario/mergo/issues/139. +its v0.3.9 release, there was a behavior change that impacts merging template +functions in sprig. It is currently recommended to use v0.3.10 or later of that package. +Using v0.3.9 will cause sprig tests to fail. ## Package Versions @@ -51,7 +50,7 @@ To load the Sprig `FuncMap`: ```go import ( - "github.com/Masterminds/sprig" + "github.com/Masterminds/sprig/v3" "html/template" ) diff --git a/vendor/github.com/Masterminds/squirrel/part.go b/vendor/github.com/Masterminds/squirrel/part.go index f3a7b1545a..c58f68f1a4 100644 --- a/vendor/github.com/Masterminds/squirrel/part.go +++ b/vendor/github.com/Masterminds/squirrel/part.go @@ -19,7 +19,7 @@ func (p part) ToSql() (sql string, args []interface{}, err error) { case nil: // no-op case Sqlizer: - sql, args, err = pred.ToSql() + sql, args, err = nestedToSql(pred) case string: sql = pred args = p.args diff --git a/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go b/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go index 504e763d2e..c20148ad33 100644 --- a/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go +++ b/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go @@ -32,7 +32,7 @@ type QueryRowerContext interface { QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner } -// RunnerContext groups the Runner interface, along with the Contect versions of each of +// RunnerContext groups the Runner interface, along with the Context versions of each of // its methods type RunnerContext interface { Runner diff --git a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go index 689e4da6bd..2342a7fcd6 100644 --- a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go +++ b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go @@ -113,6 +113,69 @@ func BasicInfoHeader(name string, size int64, fileInfo *winio.FileBasicInfo) *ta return hdr } +// SecurityDescriptorFromTarHeader reads the SDDL associated with the header of the current file +// from the tar header and returns the security descriptor into a byte slice. +func SecurityDescriptorFromTarHeader(hdr *tar.Header) ([]byte, error) { + // Maintaining old SDDL-based behavior for backward + // compatibility. All new tar headers written by this library + // will have raw binary for the security descriptor. + var sd []byte + var err error + if sddl, ok := hdr.PAXRecords[hdrSecurityDescriptor]; ok { + sd, err = winio.SddlToSecurityDescriptor(sddl) + if err != nil { + return nil, err + } + } + if sdraw, ok := hdr.PAXRecords[hdrRawSecurityDescriptor]; ok { + sd, err = base64.StdEncoding.DecodeString(sdraw) + if err != nil { + return nil, err + } + } + return sd, nil +} + +// ExtendedAttributesFromTarHeader reads the EAs associated with the header of the +// current file from the tar header and returns it as a byte slice. +func ExtendedAttributesFromTarHeader(hdr *tar.Header) ([]byte, error) { + var eas []winio.ExtendedAttribute + var eadata []byte + var err error + for k, v := range hdr.PAXRecords { + if !strings.HasPrefix(k, hdrEaPrefix) { + continue + } + data, err := base64.StdEncoding.DecodeString(v) + if err != nil { + return nil, err + } + eas = append(eas, winio.ExtendedAttribute{ + Name: k[len(hdrEaPrefix):], + Value: data, + }) + } + if len(eas) != 0 { + eadata, err = winio.EncodeExtendedAttributes(eas) + if err != nil { + return nil, err + } + } + return eadata, nil +} + +// EncodeReparsePointFromTarHeader reads the ReparsePoint structure from the tar header +// and encodes it into a byte slice. The file for which this function is called must be a +// symlink. +func EncodeReparsePointFromTarHeader(hdr *tar.Header) []byte { + _, isMountPoint := hdr.PAXRecords[hdrMountPoint] + rp := winio.ReparsePoint{ + Target: filepath.FromSlash(hdr.Linkname), + IsMountPoint: isMountPoint, + } + return winio.EncodeReparsePoint(&rp) +} + // WriteTarFileFromBackupStream writes a file to a tar writer using data from a Win32 backup stream. // // This encodes Win32 metadata as tar pax vendor extensions starting with MSWINDOWS. @@ -358,21 +421,10 @@ func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *win // tar file that was not processed, or io.EOF is there are no more. func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) (*tar.Header, error) { bw := winio.NewBackupStreamWriter(w) - var sd []byte - var err error - // Maintaining old SDDL-based behavior for backward compatibility. All new tar headers written - // by this library will have raw binary for the security descriptor. - if sddl, ok := hdr.PAXRecords[hdrSecurityDescriptor]; ok { - sd, err = winio.SddlToSecurityDescriptor(sddl) - if err != nil { - return nil, err - } - } - if sdraw, ok := hdr.PAXRecords[hdrRawSecurityDescriptor]; ok { - sd, err = base64.StdEncoding.DecodeString(sdraw) - if err != nil { - return nil, err - } + + sd, err := SecurityDescriptorFromTarHeader(hdr) + if err != nil { + return nil, err } if len(sd) != 0 { bhdr := winio.BackupHeader{ @@ -388,25 +440,12 @@ func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) ( return nil, err } } - var eas []winio.ExtendedAttribute - for k, v := range hdr.PAXRecords { - if !strings.HasPrefix(k, hdrEaPrefix) { - continue - } - data, err := base64.StdEncoding.DecodeString(v) - if err != nil { - return nil, err - } - eas = append(eas, winio.ExtendedAttribute{ - Name: k[len(hdrEaPrefix):], - Value: data, - }) + + eadata, err := ExtendedAttributesFromTarHeader(hdr) + if err != nil { + return nil, err } - if len(eas) != 0 { - eadata, err := winio.EncodeExtendedAttributes(eas) - if err != nil { - return nil, err - } + if len(eadata) != 0 { bhdr := winio.BackupHeader{ Id: winio.BackupEaData, Size: int64(len(eadata)), @@ -420,13 +459,9 @@ func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) ( return nil, err } } + if hdr.Typeflag == tar.TypeSymlink { - _, isMountPoint := hdr.PAXRecords[hdrMountPoint] - rp := winio.ReparsePoint{ - Target: filepath.FromSlash(hdr.Linkname), - IsMountPoint: isMountPoint, - } - reparse := winio.EncodeReparsePoint(&rp) + reparse := EncodeReparsePointFromTarHeader(hdr) bhdr := winio.BackupHeader{ Id: winio.BackupReparseData, Size: int64(len(reparse)), @@ -439,7 +474,9 @@ func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) ( if err != nil { return nil, err } + } + if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA { bhdr := winio.BackupHeader{ Id: winio.BackupData, diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go index 0385e41081..293ab54c80 100644 --- a/vendor/github.com/Microsoft/go-winio/file.go +++ b/vendor/github.com/Microsoft/go-winio/file.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package winio @@ -143,6 +144,11 @@ func (f *win32File) Close() error { return nil } +// IsClosed checks if the file has been closed +func (f *win32File) IsClosed() bool { + return f.closing.isSet() +} + // prepareIo prepares for a new IO operation. // The caller must call f.wg.Done() when the IO is finished, prior to Close() returning. func (f *win32File) prepareIo() (*ioOperation, error) { diff --git a/vendor/github.com/Microsoft/go-winio/hvsock.go b/vendor/github.com/Microsoft/go-winio/hvsock.go index b632f8f8bb..b2b644d002 100644 --- a/vendor/github.com/Microsoft/go-winio/hvsock.go +++ b/vendor/github.com/Microsoft/go-winio/hvsock.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package winio @@ -252,15 +253,23 @@ func (conn *HvsockConn) Close() error { return conn.sock.Close() } +func (conn *HvsockConn) IsClosed() bool { + return conn.sock.IsClosed() +} + func (conn *HvsockConn) shutdown(how int) error { - err := syscall.Shutdown(conn.sock.handle, syscall.SHUT_RD) + if conn.IsClosed() { + return ErrFileClosed + } + + err := syscall.Shutdown(conn.sock.handle, how) if err != nil { return os.NewSyscallError("shutdown", err) } return nil } -// CloseRead shuts down the read end of the socket. +// CloseRead shuts down the read end of the socket, preventing future read operations. func (conn *HvsockConn) CloseRead() error { err := conn.shutdown(syscall.SHUT_RD) if err != nil { @@ -269,8 +278,8 @@ func (conn *HvsockConn) CloseRead() error { return nil } -// CloseWrite shuts down the write end of the socket, notifying the other endpoint that -// no more data will be written. +// CloseWrite shuts down the write end of the socket, preventing future write operations and +// notifying the other endpoint that no more data will be written. func (conn *HvsockConn) CloseWrite() error { err := conn.shutdown(syscall.SHUT_WR) if err != nil { diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go index f497c0e391..2d9161e2de 100644 --- a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go @@ -14,8 +14,6 @@ import ( "encoding/binary" "fmt" "strconv" - - "golang.org/x/sys/windows" ) // Variant specifies which GUID variant (or "type") of the GUID. It determines @@ -41,13 +39,6 @@ type Version uint8 var _ = (encoding.TextMarshaler)(GUID{}) var _ = (encoding.TextUnmarshaler)(&GUID{}) -// GUID represents a GUID/UUID. It has the same structure as -// golang.org/x/sys/windows.GUID so that it can be used with functions expecting -// that type. It is defined as its own type so that stringification and -// marshaling can be supported. The representation matches that used by native -// Windows code. -type GUID windows.GUID - // NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122. func NewV4() (GUID, error) { var b [16]byte diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go new file mode 100644 index 0000000000..f64d828c0b --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go @@ -0,0 +1,15 @@ +// +build !windows + +package guid + +// GUID represents a GUID/UUID. It has the same structure as +// golang.org/x/sys/windows.GUID so that it can be used with functions expecting +// that type. It is defined as its own type as that is only available to builds +// targeted at `windows`. The representation matches that used by native Windows +// code. +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go new file mode 100644 index 0000000000..83617f4eee --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go @@ -0,0 +1,10 @@ +package guid + +import "golang.org/x/sys/windows" + +// GUID represents a GUID/UUID. It has the same structure as +// golang.org/x/sys/windows.GUID so that it can be used with functions expecting +// that type. It is defined as its own type so that stringification and +// marshaling can be supported. The representation matches that used by native +// Windows code. +type GUID windows.GUID diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go b/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go index fca241590c..602920786c 100644 --- a/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go @@ -3,11 +3,10 @@ package security import ( + "fmt" "os" "syscall" "unsafe" - - "github.com/pkg/errors" ) type ( @@ -72,7 +71,7 @@ func GrantVmGroupAccess(name string) error { // Stat (to determine if `name` is a directory). s, err := os.Stat(name) if err != nil { - return errors.Wrapf(err, "%s os.Stat %s", gvmga, name) + return fmt.Errorf("%s os.Stat %s: %w", gvmga, name, err) } // Get a handle to the file/directory. Must defer Close on success. @@ -88,7 +87,7 @@ func GrantVmGroupAccess(name string) error { sd := uintptr(0) origDACL := uintptr(0) if err := getSecurityInfo(fd, uint32(ot), uint32(si), nil, nil, &origDACL, nil, &sd); err != nil { - return errors.Wrapf(err, "%s GetSecurityInfo %s", gvmga, name) + return fmt.Errorf("%s GetSecurityInfo %s: %w", gvmga, name, err) } defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(sd))) @@ -102,7 +101,7 @@ func GrantVmGroupAccess(name string) error { // And finally use SetSecurityInfo to apply the updated DACL. if err := setSecurityInfo(fd, uint32(ot), uint32(si), uintptr(0), uintptr(0), newDACL, uintptr(0)); err != nil { - return errors.Wrapf(err, "%s SetSecurityInfo %s", gvmga, name) + return fmt.Errorf("%s SetSecurityInfo %s: %w", gvmga, name, err) } return nil @@ -120,7 +119,7 @@ func createFile(name string, isDir bool) (syscall.Handle, error) { } fd, err := syscall.CreateFile(&namep[0], da, sm, nil, syscall.OPEN_EXISTING, fa, 0) if err != nil { - return 0, errors.Wrapf(err, "%s syscall.CreateFile %s", gvmga, name) + return 0, fmt.Errorf("%s syscall.CreateFile %s: %w", gvmga, name, err) } return fd, nil } @@ -131,7 +130,7 @@ func generateDACLWithAcesAdded(name string, isDir bool, origDACL uintptr) (uintp // Generate pointers to the SIDs based on the string SIDs sid, err := syscall.StringToSid(sidVmGroup) if err != nil { - return 0, errors.Wrapf(err, "%s syscall.StringToSid %s %s", gvmga, name, sidVmGroup) + return 0, fmt.Errorf("%s syscall.StringToSid %s %s: %w", gvmga, name, sidVmGroup, err) } inheritance := inheritModeNoInheritance @@ -154,7 +153,7 @@ func generateDACLWithAcesAdded(name string, isDir bool, origDACL uintptr) (uintp modifiedDACL := uintptr(0) if err := setEntriesInAcl(uintptr(uint32(1)), uintptr(unsafe.Pointer(&eaArray[0])), origDACL, &modifiedDACL); err != nil { - return 0, errors.Wrapf(err, "%s SetEntriesInAcl %s", gvmga, name) + return 0, fmt.Errorf("%s SetEntriesInAcl %s: %w", gvmga, name, err) } return modifiedDACL, nil diff --git a/vendor/github.com/Microsoft/go-winio/vhd/vhd.go b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go index a33a36c0ff..f7f78fc230 100644 --- a/vendor/github.com/Microsoft/go-winio/vhd/vhd.go +++ b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package vhd @@ -7,14 +8,13 @@ import ( "syscall" "github.com/Microsoft/go-winio/pkg/guid" - "github.com/pkg/errors" "golang.org/x/sys/windows" ) //go:generate go run mksyscall_windows.go -output zvhd_windows.go vhd.go //sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) = virtdisk.CreateVirtualDisk -//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) = virtdisk.OpenVirtualDisk +//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (win32err error) = virtdisk.OpenVirtualDisk //sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) = virtdisk.AttachVirtualDisk //sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) = virtdisk.DetachVirtualDisk //sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) = virtdisk.GetVirtualDiskPhysicalPath @@ -62,13 +62,27 @@ type OpenVirtualDiskParameters struct { Version2 OpenVersion2 } +// The higher level `OpenVersion2` struct uses bools to refer to `GetInfoOnly` and `ReadOnly` for ease of use. However, +// the internal windows structure uses `BOOLS` aka int32s for these types. `openVersion2` is used for translating +// `OpenVersion2` fields to the correct windows internal field types on the `Open____` methods. +type openVersion2 struct { + getInfoOnly int32 + readOnly int32 + resiliencyGUID guid.GUID +} + +type openVirtualDiskParameters struct { + version uint32 + version2 openVersion2 +} + type AttachVersion2 struct { RestrictedOffset uint64 RestrictedLength uint64 } type AttachVirtualDiskParameters struct { - Version uint32 // Must always be set to 2 + Version uint32 Version2 AttachVersion2 } @@ -146,16 +160,13 @@ func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error { return err } - if err := syscall.CloseHandle(handle); err != nil { - return err - } - return nil + return syscall.CloseHandle(handle) } // DetachVirtualDisk detaches a virtual hard disk by handle. func DetachVirtualDisk(handle syscall.Handle) (err error) { if err := detachVirtualDisk(handle, 0, 0); err != nil { - return errors.Wrap(err, "failed to detach virtual disk") + return fmt.Errorf("failed to detach virtual disk: %w", err) } return nil } @@ -185,7 +196,7 @@ func AttachVirtualDisk(handle syscall.Handle, attachVirtualDiskFlag AttachVirtua parameters, nil, ); err != nil { - return errors.Wrap(err, "failed to attach virtual disk") + return fmt.Errorf("failed to attach virtual disk: %w", err) } return nil } @@ -209,7 +220,7 @@ func AttachVhd(path string) (err error) { AttachVirtualDiskFlagNone, ¶ms, ); err != nil { - return errors.Wrap(err, "failed to attach virtual disk") + return fmt.Errorf("failed to attach virtual disk: %w", err) } return nil } @@ -234,19 +245,35 @@ func OpenVirtualDiskWithParameters(vhdPath string, virtualDiskAccessMask Virtual var ( handle syscall.Handle defaultType VirtualStorageType + getInfoOnly int32 + readOnly int32 ) if parameters.Version != 2 { return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version) } + if parameters.Version2.GetInfoOnly { + getInfoOnly = 1 + } + if parameters.Version2.ReadOnly { + readOnly = 1 + } + params := &openVirtualDiskParameters{ + version: parameters.Version, + version2: openVersion2{ + getInfoOnly, + readOnly, + parameters.Version2.ResiliencyGUID, + }, + } if err := openVirtualDisk( &defaultType, vhdPath, uint32(virtualDiskAccessMask), uint32(openVirtualDiskFlags), - parameters, + params, &handle, ); err != nil { - return 0, errors.Wrap(err, "failed to open virtual disk") + return 0, fmt.Errorf("failed to open virtual disk: %w", err) } return handle, nil } @@ -272,7 +299,7 @@ func CreateVirtualDisk(path string, virtualDiskAccessMask VirtualDiskAccessMask, nil, &handle, ); err != nil { - return handle, errors.Wrap(err, "failed to create virtual disk") + return handle, fmt.Errorf("failed to create virtual disk: %w", err) } return handle, nil } @@ -290,7 +317,7 @@ func GetVirtualDiskPhysicalPath(handle syscall.Handle) (_ string, err error) { &diskPathSizeInBytes, &diskPhysicalPathBuf[0], ); err != nil { - return "", errors.Wrap(err, "failed to get disk physical path") + return "", fmt.Errorf("failed to get disk physical path: %w", err) } return windows.UTF16ToString(diskPhysicalPathBuf[:]), nil } @@ -314,10 +341,10 @@ func CreateDiffVhd(diffVhdPath, baseVhdPath string, blockSizeInMB uint32) error createParams, ) if err != nil { - return fmt.Errorf("failed to create differencing vhd: %s", err) + return fmt.Errorf("failed to create differencing vhd: %w", err) } if err := syscall.CloseHandle(vhdHandle); err != nil { - return fmt.Errorf("failed to close differencing vhd handle: %s", err) + return fmt.Errorf("failed to close differencing vhd handle: %w", err) } return nil } diff --git a/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go b/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go index 7fb5f3651b..1d7498db3b 100644 --- a/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go +++ b/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go @@ -88,7 +88,7 @@ func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint return } -func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) { +func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (win32err error) { var _p0 *uint16 _p0, win32err = syscall.UTF16PtrFromString(path) if win32err != nil { @@ -97,7 +97,7 @@ func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtua return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, openVirtualDiskFlags, parameters, handle) } -func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) { +func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (win32err error) { r0, _, _ := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) if r0 != 0 { win32err = syscall.Errno(r0) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go b/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go index 27a62a7238..f46af33bb6 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go @@ -86,6 +86,12 @@ type Container interface { // container to be terminated by some error condition (including calling // Close). Wait() error + // WaitChannel returns the wait channel of the container + WaitChannel() <-chan struct{} + // WaitError returns the container termination error. + // This function should only be called after the channel in WaitChannel() + // is closed. Otherwise it is not thread safe. + WaitError() error // Modify sends a request to modify container resources Modify(ctx context.Context, config interface{}) error } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go index e21354ffd6..295d4b849c 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go @@ -154,7 +154,7 @@ func (e *HcsError) Error() string { func (e *HcsError) Temporary() bool { err, ok := e.Err.(net.Error) - return ok && err.Temporary() + return ok && err.Temporary() //nolint:staticcheck } func (e *HcsError) Timeout() bool { @@ -193,7 +193,7 @@ func (e *SystemError) Error() string { func (e *SystemError) Temporary() bool { err, ok := e.Err.(net.Error) - return ok && err.Temporary() + return ok && err.Temporary() //nolint:staticcheck } func (e *SystemError) Timeout() bool { @@ -224,7 +224,7 @@ func (e *ProcessError) Error() string { func (e *ProcessError) Temporary() bool { err, ok := e.Err.(net.Error) - return ok && err.Temporary() + return ok && err.Temporary() //nolint:staticcheck } func (e *ProcessError) Timeout() bool { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go index 75499c967f..a76f6b253e 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go @@ -4,17 +4,22 @@ import ( "context" "encoding/json" "errors" + "fmt" "strings" "sync" "syscall" + "time" "github.com/Microsoft/hcsshim/internal/cow" "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/jobobject" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/vmcompute" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -28,7 +33,8 @@ type System struct { waitBlock chan struct{} waitError error exitError error - os, typ string + os, typ, owner string + startTime time.Time } func newSystem(id string) *System { @@ -38,6 +44,11 @@ func newSystem(id string) *System { } } +// Implementation detail for silo naming, this should NOT be relied upon very heavily. +func siloNameFmt(containerID string) string { + return fmt.Sprintf(`\Container_%s`, containerID) +} + // CreateComputeSystem creates a new compute system with the given configuration but does not start it. func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface interface{}) (_ *System, err error) { operation := "hcs::CreateComputeSystem" @@ -127,6 +138,7 @@ func (computeSystem *System) getCachedProperties(ctx context.Context) error { } computeSystem.typ = strings.ToLower(props.SystemType) computeSystem.os = strings.ToLower(props.RuntimeOSType) + computeSystem.owner = strings.ToLower(props.Owner) if computeSystem.os == "" && computeSystem.typ == "container" { // Pre-RS5 HCS did not return the OS, but it only supported containers // that ran Windows. @@ -195,7 +207,7 @@ func (computeSystem *System) Start(ctx context.Context) (err error) { if err != nil { return makeSystemError(computeSystem, operation, err, events) } - + computeSystem.startTime = time.Now() return nil } @@ -275,11 +287,19 @@ func (computeSystem *System) waitBackground() { oc.SetSpanStatus(span, err) } +func (computeSystem *System) WaitChannel() <-chan struct{} { + return computeSystem.waitBlock +} + +func (computeSystem *System) WaitError() error { + return computeSystem.waitError +} + // Wait synchronously waits for the compute system to shutdown or terminate. If // the compute system has already exited returns the previous error (if any). func (computeSystem *System) Wait() error { - <-computeSystem.waitBlock - return computeSystem.waitError + <-computeSystem.WaitChannel() + return computeSystem.WaitError() } // ExitError returns an error describing the reason the compute system terminated. @@ -324,11 +344,115 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr return properties, nil } -// PropertiesV2 returns the requested container properties targeting a V2 schema container. -func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) { - computeSystem.handleLock.RLock() - defer computeSystem.handleLock.RUnlock() +// queryInProc handles querying for container properties without reaching out to HCS. `props` +// will be updated to contain any data returned from the queries present in `types`. If any properties +// failed to be queried they will be tallied up and returned in as the first return value. Failures on +// query are NOT considered errors; the only failure case for this method is if the containers job object +// cannot be opened. +func (computeSystem *System) queryInProc(ctx context.Context, props *hcsschema.Properties, types []hcsschema.PropertyType) ([]hcsschema.PropertyType, error) { + // In the future we can make use of some new functionality in the HCS that allows you + // to pass a job object for HCS to use for the container. Currently, the only way we'll + // be able to open the job/silo is if we're running as SYSTEM. + jobOptions := &jobobject.Options{ + UseNTVariant: true, + Name: siloNameFmt(computeSystem.id), + } + job, err := jobobject.Open(ctx, jobOptions) + if err != nil { + return nil, err + } + defer job.Close() + + var fallbackQueryTypes []hcsschema.PropertyType + for _, propType := range types { + switch propType { + case hcsschema.PTStatistics: + // Handle a bad caller asking for the same type twice. No use in re-querying if this is + // filled in already. + if props.Statistics == nil { + props.Statistics, err = computeSystem.statisticsInProc(job) + if err != nil { + log.G(ctx).WithError(err).Warn("failed to get statistics in-proc") + + fallbackQueryTypes = append(fallbackQueryTypes, propType) + } + } + default: + fallbackQueryTypes = append(fallbackQueryTypes, propType) + } + } + + return fallbackQueryTypes, nil +} + +// statisticsInProc emulates what HCS does to grab statistics for a given container with a small +// change to make grabbing the private working set total much more efficient. +func (computeSystem *System) statisticsInProc(job *jobobject.JobObject) (*hcsschema.Statistics, error) { + // Start timestamp for these stats before we grab them to match HCS + timestamp := time.Now() + + memInfo, err := job.QueryMemoryStats() + if err != nil { + return nil, err + } + + processorInfo, err := job.QueryProcessorStats() + if err != nil { + return nil, err + } + + storageInfo, err := job.QueryStorageStats() + if err != nil { + return nil, err + } + + // This calculates the private working set more efficiently than HCS does. HCS calls NtQuerySystemInformation + // with the class SystemProcessInformation which returns an array containing system information for *every* + // process running on the machine. They then grab the pids that are running in the container and filter down + // the entries in the array to only what's running in that silo and start tallying up the total. This doesn't + // work well as performance should get worse if more processess are running on the machine in general and not + // just in the container. All of the additional information besides the WorkingSetPrivateSize field is ignored + // as well which isn't great and is wasted work to fetch. + // + // HCS only let's you grab statistics in an all or nothing fashion, so we can't just grab the private + // working set ourselves and ask for everything else seperately. The optimization we can make here is + // to open the silo ourselves and do the same queries for the rest of the info, as well as calculating + // the private working set in a more efficient manner by: + // + // 1. Find the pids running in the silo + // 2. Get a process handle for every process (only need PROCESS_QUERY_LIMITED_INFORMATION access) + // 3. Call NtQueryInformationProcess on each process with the class ProcessVmCounters + // 4. Tally up the total using the field PrivateWorkingSetSize in VM_COUNTERS_EX2. + privateWorkingSet, err := job.QueryPrivateWorkingSet() + if err != nil { + return nil, err + } + + return &hcsschema.Statistics{ + Timestamp: timestamp, + ContainerStartTime: computeSystem.startTime, + Uptime100ns: uint64(time.Since(computeSystem.startTime).Nanoseconds()) / 100, + Memory: &hcsschema.MemoryStats{ + MemoryUsageCommitBytes: memInfo.JobMemory, + MemoryUsageCommitPeakBytes: memInfo.PeakJobMemoryUsed, + MemoryUsagePrivateWorkingSetBytes: privateWorkingSet, + }, + Processor: &hcsschema.ProcessorStats{ + RuntimeKernel100ns: uint64(processorInfo.TotalKernelTime), + RuntimeUser100ns: uint64(processorInfo.TotalUserTime), + TotalRuntime100ns: uint64(processorInfo.TotalKernelTime + processorInfo.TotalUserTime), + }, + Storage: &hcsschema.StorageStats{ + ReadCountNormalized: uint64(storageInfo.ReadStats.IoCount), + ReadSizeBytes: storageInfo.ReadStats.TotalSize, + WriteCountNormalized: uint64(storageInfo.WriteStats.IoCount), + WriteSizeBytes: storageInfo.WriteStats.TotalSize, + }, + }, nil +} +// hcsPropertiesV2Query is a helper to make a HcsGetComputeSystemProperties call using the V2 schema property types. +func (computeSystem *System) hcsPropertiesV2Query(ctx context.Context, types []hcsschema.PropertyType) (*hcsschema.Properties, error) { operation := "hcs::System::PropertiesV2" queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types}) @@ -345,12 +469,66 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem if propertiesJSON == "" { return nil, ErrUnexpectedValue } - properties := &hcsschema.Properties{} - if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil { + props := &hcsschema.Properties{} + if err := json.Unmarshal([]byte(propertiesJSON), props); err != nil { return nil, makeSystemError(computeSystem, operation, err, nil) } - return properties, nil + return props, nil +} + +// PropertiesV2 returns the requested compute systems properties targeting a V2 schema compute system. +func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (_ *hcsschema.Properties, err error) { + computeSystem.handleLock.RLock() + defer computeSystem.handleLock.RUnlock() + + // Let HCS tally up the total for VM based queries instead of querying ourselves. + if computeSystem.typ != "container" { + return computeSystem.hcsPropertiesV2Query(ctx, types) + } + + // Define a starter Properties struct with the default fields returned from every + // query. Owner is only returned from Statistics but it's harmless to include. + properties := &hcsschema.Properties{ + Id: computeSystem.id, + SystemType: computeSystem.typ, + RuntimeOsType: computeSystem.os, + Owner: computeSystem.owner, + } + + logEntry := log.G(ctx) + // First lets try and query ourselves without reaching to HCS. If any of the queries fail + // we'll take note and fallback to querying HCS for any of the failed types. + fallbackTypes, err := computeSystem.queryInProc(ctx, properties, types) + if err == nil && len(fallbackTypes) == 0 { + return properties, nil + } else if err != nil { + logEntry.WithError(fmt.Errorf("failed to query compute system properties in-proc: %w", err)) + fallbackTypes = types + } + + logEntry.WithFields(logrus.Fields{ + logfields.ContainerID: computeSystem.id, + "propertyTypes": fallbackTypes, + }).Info("falling back to HCS for property type queries") + + hcsProperties, err := computeSystem.hcsPropertiesV2Query(ctx, fallbackTypes) + if err != nil { + return nil, err + } + + // Now add in anything that we might have successfully queried in process. + if properties.Statistics != nil { + hcsProperties.Statistics = properties.Statistics + hcsProperties.Owner = properties.Owner + } + + // For future support for querying processlist in-proc as well. + if properties.ProcessList != nil { + hcsProperties.ProcessList = properties.ProcessList + } + + return hcsProperties, nil } // Pause pauses the execution of the computeSystem. This feature is not enabled in TP5. diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go b/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go index 591a2631e4..84b3682184 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go @@ -21,10 +21,11 @@ const ( ) type NatPolicy struct { - Type PolicyType `json:"Type"` - Protocol string `json:",omitempty"` - InternalPort uint16 `json:",omitempty"` - ExternalPort uint16 `json:",omitempty"` + Type PolicyType `json:"Type"` + Protocol string `json:",omitempty"` + InternalPort uint16 `json:",omitempty"` + ExternalPort uint16 `json:",omitempty"` + ExternalPortReserved bool `json:",omitempty"` } type QosPolicy struct { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go new file mode 100644 index 0000000000..5d6acd69e6 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go @@ -0,0 +1,111 @@ +package jobobject + +import ( + "context" + "fmt" + "sync" + "unsafe" + + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/queue" + "github.com/Microsoft/hcsshim/internal/winapi" + "github.com/sirupsen/logrus" + "golang.org/x/sys/windows" +) + +var ( + ioInitOnce sync.Once + initIOErr error + // Global iocp handle that will be re-used for every job object + ioCompletionPort windows.Handle + // Mapping of job handle to queue to place notifications in. + jobMap sync.Map +) + +// MsgAllProcessesExited is a type representing a message that every process in a job has exited. +type MsgAllProcessesExited struct{} + +// MsgUnimplemented represents a message that we are aware of, but that isn't implemented currently. +// This should not be treated as an error. +type MsgUnimplemented struct{} + +// pollIOCP polls the io completion port forever. +func pollIOCP(ctx context.Context, iocpHandle windows.Handle) { + var ( + overlapped uintptr + code uint32 + key uintptr + ) + + for { + err := windows.GetQueuedCompletionStatus(iocpHandle, &code, &key, (**windows.Overlapped)(unsafe.Pointer(&overlapped)), windows.INFINITE) + if err != nil { + log.G(ctx).WithError(err).Error("failed to poll for job object message") + continue + } + if val, ok := jobMap.Load(key); ok { + msq, ok := val.(*queue.MessageQueue) + if !ok { + log.G(ctx).WithField("value", msq).Warn("encountered non queue type in job map") + continue + } + notification, err := parseMessage(code, overlapped) + if err != nil { + log.G(ctx).WithFields(logrus.Fields{ + "code": code, + "overlapped": overlapped, + }).Warn("failed to parse job object message") + continue + } + if err := msq.Enqueue(notification); err == queue.ErrQueueClosed { + // Write will only return an error when the queue is closed. + // The only time a queue would ever be closed is when we call `Close` on + // the job it belongs to which also removes it from the jobMap, so something + // went wrong here. We can't return as this is reading messages for all jobs + // so just log it and move on. + log.G(ctx).WithFields(logrus.Fields{ + "code": code, + "overlapped": overlapped, + }).Warn("tried to write to a closed queue") + continue + } + } else { + log.G(ctx).Warn("received a message for a job not present in the mapping") + } + } +} + +func parseMessage(code uint32, overlapped uintptr) (interface{}, error) { + // Check code and parse out relevant information related to that notification + // that we care about. For now all we handle is the message that all processes + // in the job have exited. + switch code { + case winapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: + return MsgAllProcessesExited{}, nil + // Other messages for completeness and a check to make sure that if we fall + // into the default case that this is a code we don't know how to handle. + case winapi.JOB_OBJECT_MSG_END_OF_JOB_TIME: + case winapi.JOB_OBJECT_MSG_END_OF_PROCESS_TIME: + case winapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: + case winapi.JOB_OBJECT_MSG_NEW_PROCESS: + case winapi.JOB_OBJECT_MSG_EXIT_PROCESS: + case winapi.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: + case winapi.JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: + case winapi.JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: + case winapi.JOB_OBJECT_MSG_NOTIFICATION_LIMIT: + default: + return nil, fmt.Errorf("unknown job notification type: %d", code) + } + return MsgUnimplemented{}, nil +} + +// Assigns an IO completion port to get notified of events for the registered job +// object. +func attachIOCP(job windows.Handle, iocp windows.Handle) error { + info := winapi.JOBOBJECT_ASSOCIATE_COMPLETION_PORT{ + CompletionKey: job, + CompletionPort: iocp, + } + _, err := windows.SetInformationJobObject(job, windows.JobObjectAssociateCompletionPortInformation, uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))) + return err +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go new file mode 100644 index 0000000000..c9fdd921a7 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go @@ -0,0 +1,538 @@ +package jobobject + +import ( + "context" + "errors" + "fmt" + "sync" + "unsafe" + + "github.com/Microsoft/hcsshim/internal/queue" + "github.com/Microsoft/hcsshim/internal/winapi" + "golang.org/x/sys/windows" +) + +// This file provides higher level constructs for the win32 job object API. +// Most of the core creation and management functions are already present in "golang.org/x/sys/windows" +// (CreateJobObject, AssignProcessToJobObject, etc.) as well as most of the limit information +// structs and associated limit flags. Whatever is not present from the job object API +// in golang.org/x/sys/windows is located in /internal/winapi. +// +// https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects + +// JobObject is a high level wrapper around a Windows job object. Holds a handle to +// the job, a queue to receive iocp notifications about the lifecycle +// of the job and a mutex for synchronized handle access. +type JobObject struct { + handle windows.Handle + mq *queue.MessageQueue + handleLock sync.RWMutex +} + +// JobLimits represents the resource constraints that can be applied to a job object. +type JobLimits struct { + CPULimit uint32 + CPUWeight uint32 + MemoryLimitInBytes uint64 + MaxIOPS int64 + MaxBandwidth int64 +} + +type CPURateControlType uint32 + +const ( + WeightBased CPURateControlType = iota + RateBased +) + +// Processor resource controls +const ( + cpuLimitMin = 1 + cpuLimitMax = 10000 + cpuWeightMin = 1 + cpuWeightMax = 9 +) + +var ( + ErrAlreadyClosed = errors.New("the handle has already been closed") + ErrNotRegistered = errors.New("job is not registered to receive notifications") +) + +// Options represents the set of configurable options when making or opening a job object. +type Options struct { + // `Name` specifies the name of the job object if a named job object is desired. + Name string + // `Notifications` specifies if the job will be registered to receive notifications. + // Defaults to false. + Notifications bool + // `UseNTVariant` specifies if we should use the `Nt` variant of Open/CreateJobObject. + // Defaults to false. + UseNTVariant bool + // `IOTracking` enables tracking I/O statistics on the job object. More specifically this + // calls SetInformationJobObject with the JobObjectIoAttribution class. + EnableIOTracking bool +} + +// Create creates a job object. +// +// If options.Name is an empty string, the job will not be assigned a name. +// +// If options.Notifications are not enabled `PollNotifications` will return immediately with error `errNotRegistered`. +// +// If `options` is nil, use default option values. +// +// Returns a JobObject structure and an error if there is one. +func Create(ctx context.Context, options *Options) (_ *JobObject, err error) { + if options == nil { + options = &Options{} + } + + var jobName *winapi.UnicodeString + if options.Name != "" { + jobName, err = winapi.NewUnicodeString(options.Name) + if err != nil { + return nil, err + } + } + + var jobHandle windows.Handle + if options.UseNTVariant { + oa := winapi.ObjectAttributes{ + Length: unsafe.Sizeof(winapi.ObjectAttributes{}), + ObjectName: jobName, + Attributes: 0, + } + status := winapi.NtCreateJobObject(&jobHandle, winapi.JOB_OBJECT_ALL_ACCESS, &oa) + if status != 0 { + return nil, winapi.RtlNtStatusToDosError(status) + } + } else { + var jobNameBuf *uint16 + if jobName != nil && jobName.Buffer != nil { + jobNameBuf = jobName.Buffer + } + jobHandle, err = windows.CreateJobObject(nil, jobNameBuf) + if err != nil { + return nil, err + } + } + + defer func() { + if err != nil { + windows.Close(jobHandle) + } + }() + + job := &JobObject{ + handle: jobHandle, + } + + // If the IOCP we'll be using to receive messages for all jobs hasn't been + // created, create it and start polling. + if options.Notifications { + mq, err := setupNotifications(ctx, job) + if err != nil { + return nil, err + } + job.mq = mq + } + + if options.EnableIOTracking { + if err := enableIOTracking(jobHandle); err != nil { + return nil, err + } + } + + return job, nil +} + +// Open opens an existing job object with name provided in `options`. If no name is provided +// return an error since we need to know what job object to open. +// +// If options.Notifications is false `PollNotifications` will return immediately with error `errNotRegistered`. +// +// Returns a JobObject structure and an error if there is one. +func Open(ctx context.Context, options *Options) (_ *JobObject, err error) { + if options == nil || (options != nil && options.Name == "") { + return nil, errors.New("no job object name specified to open") + } + + unicodeJobName, err := winapi.NewUnicodeString(options.Name) + if err != nil { + return nil, err + } + + var jobHandle windows.Handle + if options != nil && options.UseNTVariant { + oa := winapi.ObjectAttributes{ + Length: unsafe.Sizeof(winapi.ObjectAttributes{}), + ObjectName: unicodeJobName, + Attributes: 0, + } + status := winapi.NtOpenJobObject(&jobHandle, winapi.JOB_OBJECT_ALL_ACCESS, &oa) + if status != 0 { + return nil, winapi.RtlNtStatusToDosError(status) + } + } else { + jobHandle, err = winapi.OpenJobObject(winapi.JOB_OBJECT_ALL_ACCESS, false, unicodeJobName.Buffer) + if err != nil { + return nil, err + } + } + + defer func() { + if err != nil { + windows.Close(jobHandle) + } + }() + + job := &JobObject{ + handle: jobHandle, + } + + // If the IOCP we'll be using to receive messages for all jobs hasn't been + // created, create it and start polling. + if options != nil && options.Notifications { + mq, err := setupNotifications(ctx, job) + if err != nil { + return nil, err + } + job.mq = mq + } + + return job, nil +} + +// helper function to setup notifications for creating/opening a job object +func setupNotifications(ctx context.Context, job *JobObject) (*queue.MessageQueue, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + ioInitOnce.Do(func() { + h, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff) + if err != nil { + initIOErr = err + return + } + ioCompletionPort = h + go pollIOCP(ctx, h) + }) + + if initIOErr != nil { + return nil, initIOErr + } + + mq := queue.NewMessageQueue() + jobMap.Store(uintptr(job.handle), mq) + if err := attachIOCP(job.handle, ioCompletionPort); err != nil { + jobMap.Delete(uintptr(job.handle)) + return nil, fmt.Errorf("failed to attach job to IO completion port: %w", err) + } + return mq, nil +} + +// PollNotification will poll for a job object notification. This call should only be called once +// per job (ideally in a goroutine loop) and will block if there is not a notification ready. +// This call will return immediately with error `ErrNotRegistered` if the job was not registered +// to receive notifications during `Create`. Internally, messages will be queued and there +// is no worry of messages being dropped. +func (job *JobObject) PollNotification() (interface{}, error) { + if job.mq == nil { + return nil, ErrNotRegistered + } + return job.mq.Dequeue() +} + +// UpdateProcThreadAttribute updates the passed in ProcThreadAttributeList to contain what is necessary to +// launch a process in a job at creation time. This can be used to avoid having to call Assign() after a process +// has already started running. +func (job *JobObject) UpdateProcThreadAttribute(attrList *windows.ProcThreadAttributeListContainer) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if err := attrList.Update( + winapi.PROC_THREAD_ATTRIBUTE_JOB_LIST, + unsafe.Pointer(&job.handle), + unsafe.Sizeof(job.handle), + ); err != nil { + return fmt.Errorf("failed to update proc thread attributes for job object: %w", err) + } + + return nil +} + +// Close closes the job object handle. +func (job *JobObject) Close() error { + job.handleLock.Lock() + defer job.handleLock.Unlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if err := windows.Close(job.handle); err != nil { + return err + } + + if job.mq != nil { + job.mq.Close() + } + // Handles now invalid so if the map entry to receive notifications for this job still + // exists remove it so we can stop receiving notifications. + if _, ok := jobMap.Load(uintptr(job.handle)); ok { + jobMap.Delete(uintptr(job.handle)) + } + + job.handle = 0 + return nil +} + +// Assign assigns a process to the job object. +func (job *JobObject) Assign(pid uint32) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if pid == 0 { + return errors.New("invalid pid: 0") + } + hProc, err := windows.OpenProcess(winapi.PROCESS_ALL_ACCESS, true, pid) + if err != nil { + return err + } + defer windows.Close(hProc) + return windows.AssignProcessToJobObject(job.handle, hProc) +} + +// Terminate terminates the job, essentially calls TerminateProcess on every process in the +// job. +func (job *JobObject) Terminate(exitCode uint32) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + if job.handle == 0 { + return ErrAlreadyClosed + } + return windows.TerminateJobObject(job.handle, exitCode) +} + +// Pids returns all of the process IDs in the job object. +func (job *JobObject) Pids() ([]uint32, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := winapi.JOBOBJECT_BASIC_PROCESS_ID_LIST{} + err := winapi.QueryInformationJobObject( + job.handle, + winapi.JobObjectBasicProcessIdList, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ) + + // This is either the case where there is only one process or no processes in + // the job. Any other case will result in ERROR_MORE_DATA. Check if info.NumberOfProcessIdsInList + // is 1 and just return this, otherwise return an empty slice. + if err == nil { + if info.NumberOfProcessIdsInList == 1 { + return []uint32{uint32(info.ProcessIdList[0])}, nil + } + // Return empty slice instead of nil to play well with the caller of this. + // Do not return an error if no processes are running inside the job + return []uint32{}, nil + } + + if err != winapi.ERROR_MORE_DATA { + return nil, fmt.Errorf("failed initial query for PIDs in job object: %w", err) + } + + jobBasicProcessIDListSize := unsafe.Sizeof(info) + (unsafe.Sizeof(info.ProcessIdList[0]) * uintptr(info.NumberOfAssignedProcesses-1)) + buf := make([]byte, jobBasicProcessIDListSize) + if err = winapi.QueryInformationJobObject( + job.handle, + winapi.JobObjectBasicProcessIdList, + unsafe.Pointer(&buf[0]), + uint32(len(buf)), + nil, + ); err != nil { + return nil, fmt.Errorf("failed to query for PIDs in job object: %w", err) + } + + bufInfo := (*winapi.JOBOBJECT_BASIC_PROCESS_ID_LIST)(unsafe.Pointer(&buf[0])) + pids := make([]uint32, bufInfo.NumberOfProcessIdsInList) + for i, bufPid := range bufInfo.AllPids() { + pids[i] = uint32(bufPid) + } + return pids, nil +} + +// QueryMemoryStats gets the memory stats for the job object. +func (job *JobObject) QueryMemoryStats() (*winapi.JOBOBJECT_MEMORY_USAGE_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := winapi.JOBOBJECT_MEMORY_USAGE_INFORMATION{} + if err := winapi.QueryInformationJobObject( + job.handle, + winapi.JobObjectMemoryUsageInformation, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ); err != nil { + return nil, fmt.Errorf("failed to query for job object memory stats: %w", err) + } + return &info, nil +} + +// QueryProcessorStats gets the processor stats for the job object. +func (job *JobObject) QueryProcessorStats() (*winapi.JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := winapi.JOBOBJECT_BASIC_ACCOUNTING_INFORMATION{} + if err := winapi.QueryInformationJobObject( + job.handle, + winapi.JobObjectBasicAccountingInformation, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ); err != nil { + return nil, fmt.Errorf("failed to query for job object process stats: %w", err) + } + return &info, nil +} + +// QueryStorageStats gets the storage (I/O) stats for the job object. This call will error +// if either `EnableIOTracking` wasn't set to true on creation of the job, or SetIOTracking() +// hasn't been called since creation of the job. +func (job *JobObject) QueryStorageStats() (*winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION{ + ControlFlags: winapi.JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE, + } + if err := winapi.QueryInformationJobObject( + job.handle, + winapi.JobObjectIoAttribution, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ); err != nil { + return nil, fmt.Errorf("failed to query for job object storage stats: %w", err) + } + return &info, nil +} + +// QueryPrivateWorkingSet returns the private working set size for the job. This is calculated by adding up the +// private working set for every process running in the job. +func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) { + pids, err := job.Pids() + if err != nil { + return 0, err + } + + openAndQueryWorkingSet := func(pid uint32) (uint64, error) { + h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid) + if err != nil { + // Continue to the next if OpenProcess doesn't return a valid handle (fails). Handles a + // case where one of the pids in the job exited before we open. + return 0, nil + } + defer func() { + _ = windows.Close(h) + }() + // Check if the process is actually running in the job still. There's a small chance + // that the process could have exited and had its pid re-used between grabbing the pids + // in the job and opening the handle to it above. + var inJob int32 + if err := winapi.IsProcessInJob(h, job.handle, &inJob); err != nil { + // This shouldn't fail unless we have incorrect access rights which we control + // here so probably best to error out if this failed. + return 0, err + } + // Don't report stats for this process as it's not running in the job. This shouldn't be + // an error condition though. + if inJob == 0 { + return 0, nil + } + + var vmCounters winapi.VM_COUNTERS_EX2 + status := winapi.NtQueryInformationProcess( + h, + winapi.ProcessVmCounters, + unsafe.Pointer(&vmCounters), + uint32(unsafe.Sizeof(vmCounters)), + nil, + ) + if !winapi.NTSuccess(status) { + return 0, fmt.Errorf("failed to query information for process: %w", winapi.RtlNtStatusToDosError(status)) + } + return uint64(vmCounters.PrivateWorkingSetSize), nil + } + + var jobWorkingSetSize uint64 + for _, pid := range pids { + workingSet, err := openAndQueryWorkingSet(pid) + if err != nil { + return 0, err + } + jobWorkingSetSize += workingSet + } + + return jobWorkingSetSize, nil +} + +// SetIOTracking enables IO tracking for processes in the job object. +// This enables use of the QueryStorageStats method. +func (job *JobObject) SetIOTracking() error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + return enableIOTracking(job.handle) +} + +func enableIOTracking(job windows.Handle) error { + info := winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION{ + ControlFlags: winapi.JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE, + } + if _, err := windows.SetInformationJobObject( + job, + winapi.JobObjectIoAttribution, + uintptr(unsafe.Pointer(&info)), + uint32(unsafe.Sizeof(info)), + ); err != nil { + return fmt.Errorf("failed to enable IO tracking on job object: %w", err) + } + return nil +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go new file mode 100644 index 0000000000..4efde292c4 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go @@ -0,0 +1,315 @@ +package jobobject + +import ( + "errors" + "fmt" + "unsafe" + + "github.com/Microsoft/hcsshim/internal/winapi" + "golang.org/x/sys/windows" +) + +const ( + memoryLimitMax uint64 = 0xffffffffffffffff +) + +func isFlagSet(flag, controlFlags uint32) bool { + return (flag & controlFlags) == flag +} + +// SetResourceLimits sets resource limits on the job object (cpu, memory, storage). +func (job *JobObject) SetResourceLimits(limits *JobLimits) error { + // Go through and check what limits were specified and apply them to the job. + if limits.MemoryLimitInBytes != 0 { + if err := job.SetMemoryLimit(limits.MemoryLimitInBytes); err != nil { + return fmt.Errorf("failed to set job object memory limit: %w", err) + } + } + + if limits.CPULimit != 0 { + if err := job.SetCPULimit(RateBased, limits.CPULimit); err != nil { + return fmt.Errorf("failed to set job object cpu limit: %w", err) + } + } else if limits.CPUWeight != 0 { + if err := job.SetCPULimit(WeightBased, limits.CPUWeight); err != nil { + return fmt.Errorf("failed to set job object cpu limit: %w", err) + } + } + + if limits.MaxBandwidth != 0 || limits.MaxIOPS != 0 { + if err := job.SetIOLimit(limits.MaxBandwidth, limits.MaxIOPS); err != nil { + return fmt.Errorf("failed to set io limit on job object: %w", err) + } + } + return nil +} + +// SetTerminateOnLastHandleClose sets the job object flag that specifies that the job should terminate +// all processes in the job on the last open handle being closed. +func (job *JobObject) SetTerminateOnLastHandleClose() error { + info, err := job.getExtendedInformation() + if err != nil { + return err + } + info.BasicLimitInformation.LimitFlags |= windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE + return job.setExtendedInformation(info) +} + +// SetMemoryLimit sets the memory limit of the job object based on the given `memoryLimitInBytes`. +func (job *JobObject) SetMemoryLimit(memoryLimitInBytes uint64) error { + if memoryLimitInBytes >= memoryLimitMax { + return errors.New("memory limit specified exceeds the max size") + } + + info, err := job.getExtendedInformation() + if err != nil { + return err + } + + info.JobMemoryLimit = uintptr(memoryLimitInBytes) + info.BasicLimitInformation.LimitFlags |= windows.JOB_OBJECT_LIMIT_JOB_MEMORY + return job.setExtendedInformation(info) +} + +// GetMemoryLimit gets the memory limit in bytes of the job object. +func (job *JobObject) GetMemoryLimit() (uint64, error) { + info, err := job.getExtendedInformation() + if err != nil { + return 0, err + } + return uint64(info.JobMemoryLimit), nil +} + +// SetCPULimit sets the CPU limit depending on the specified `CPURateControlType` to +// `rateControlValue` for the job object. +func (job *JobObject) SetCPULimit(rateControlType CPURateControlType, rateControlValue uint32) error { + cpuInfo, err := job.getCPURateControlInformation() + if err != nil { + return err + } + switch rateControlType { + case WeightBased: + if rateControlValue < cpuWeightMin || rateControlValue > cpuWeightMax { + return fmt.Errorf("processor weight value of `%d` is invalid", rateControlValue) + } + cpuInfo.ControlFlags |= winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | winapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED + cpuInfo.Value = rateControlValue + case RateBased: + if rateControlValue < cpuLimitMin || rateControlValue > cpuLimitMax { + return fmt.Errorf("processor rate of `%d` is invalid", rateControlValue) + } + cpuInfo.ControlFlags |= winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | winapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP + cpuInfo.Value = rateControlValue + default: + return errors.New("invalid job object cpu rate control type") + } + return job.setCPURateControlInfo(cpuInfo) +} + +// GetCPULimit gets the cpu limits for the job object. +// `rateControlType` is used to indicate what type of cpu limit to query for. +func (job *JobObject) GetCPULimit(rateControlType CPURateControlType) (uint32, error) { + info, err := job.getCPURateControlInformation() + if err != nil { + return 0, err + } + + if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE, info.ControlFlags) { + return 0, errors.New("the job does not have cpu rate control enabled") + } + + switch rateControlType { + case WeightBased: + if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED, info.ControlFlags) { + return 0, errors.New("cannot get cpu weight for job object without cpu weight option set") + } + case RateBased: + if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP, info.ControlFlags) { + return 0, errors.New("cannot get cpu rate hard cap for job object without cpu rate hard cap option set") + } + default: + return 0, errors.New("invalid job object cpu rate control type") + } + return info.Value, nil +} + +// SetCPUAffinity sets the processor affinity for the job object. +// The affinity is passed in as a bitmask. +func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error { + info, err := job.getExtendedInformation() + if err != nil { + return err + } + info.BasicLimitInformation.LimitFlags |= uint32(windows.JOB_OBJECT_LIMIT_AFFINITY) + info.BasicLimitInformation.Affinity = uintptr(affinityBitMask) + return job.setExtendedInformation(info) +} + +// GetCPUAffinity gets the processor affinity for the job object. +// The returned affinity is a bitmask. +func (job *JobObject) GetCPUAffinity() (uint64, error) { + info, err := job.getExtendedInformation() + if err != nil { + return 0, err + } + return uint64(info.BasicLimitInformation.Affinity), nil +} + +// SetIOLimit sets the IO limits specified on the job object. +func (job *JobObject) SetIOLimit(maxBandwidth, maxIOPS int64) error { + ioInfo, err := job.getIOLimit() + if err != nil { + return err + } + ioInfo.ControlFlags |= winapi.JOB_OBJECT_IO_RATE_CONTROL_ENABLE + if maxBandwidth != 0 { + ioInfo.MaxBandwidth = maxBandwidth + } + if maxIOPS != 0 { + ioInfo.MaxIops = maxIOPS + } + return job.setIORateControlInfo(ioInfo) +} + +// GetIOMaxBandwidthLimit gets the max bandwidth for the job object. +func (job *JobObject) GetIOMaxBandwidthLimit() (int64, error) { + info, err := job.getIOLimit() + if err != nil { + return 0, err + } + return info.MaxBandwidth, nil +} + +// GetIOMaxIopsLimit gets the max iops for the job object. +func (job *JobObject) GetIOMaxIopsLimit() (int64, error) { + info, err := job.getIOLimit() + if err != nil { + return 0, err + } + return info.MaxIops, nil +} + +// Helper function for getting a job object's extended information. +func (job *JobObject) getExtendedInformation() (*windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{} + if err := winapi.QueryInformationJobObject( + job.handle, + windows.JobObjectExtendedLimitInformation, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ); err != nil { + return nil, fmt.Errorf("query %v returned error: %w", info, err) + } + return &info, nil +} + +// Helper function for getting a job object's CPU rate control information. +func (job *JobObject) getCPURateControlInformation() (*winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + info := winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION{} + if err := winapi.QueryInformationJobObject( + job.handle, + windows.JobObjectCpuRateControlInformation, + unsafe.Pointer(&info), + uint32(unsafe.Sizeof(info)), + nil, + ); err != nil { + return nil, fmt.Errorf("query %v returned error: %w", info, err) + } + return &info, nil +} + +// Helper function for setting a job object's extended information. +func (job *JobObject) setExtendedInformation(info *windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if _, err := windows.SetInformationJobObject( + job.handle, + windows.JobObjectExtendedLimitInformation, + uintptr(unsafe.Pointer(info)), + uint32(unsafe.Sizeof(*info)), + ); err != nil { + return fmt.Errorf("failed to set Extended info %v on job object: %w", info, err) + } + return nil +} + +// Helper function for querying job handle for IO limit information. +func (job *JobObject) getIOLimit() (*winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + ioInfo := &winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION{} + var blockCount uint32 = 1 + + if _, err := winapi.QueryIoRateControlInformationJobObject( + job.handle, + nil, + &ioInfo, + &blockCount, + ); err != nil { + return nil, fmt.Errorf("query %v returned error: %w", ioInfo, err) + } + + if !isFlagSet(winapi.JOB_OBJECT_IO_RATE_CONTROL_ENABLE, ioInfo.ControlFlags) { + return nil, fmt.Errorf("query %v cannot get IO limits for job object without IO rate control option set", ioInfo) + } + return ioInfo, nil +} + +// Helper function for setting a job object's IO rate control information. +func (job *JobObject) setIORateControlInfo(ioInfo *winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if _, err := winapi.SetIoRateControlInformationJobObject(job.handle, ioInfo); err != nil { + return fmt.Errorf("failed to set IO limit info %v on job object: %w", ioInfo, err) + } + return nil +} + +// Helper function for setting a job object's CPU rate control information. +func (job *JobObject) setCPURateControlInfo(cpuInfo *winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION) error { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + if _, err := windows.SetInformationJobObject( + job.handle, + windows.JobObjectCpuRateControlInformation, + uintptr(unsafe.Pointer(cpuInfo)), + uint32(unsafe.Sizeof(cpuInfo)), + ); err != nil { + return fmt.Errorf("failed to set cpu limit info %v on job object: %w", cpuInfo, err) + } + return nil +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/queue/mq.go b/vendor/github.com/Microsoft/hcsshim/internal/queue/mq.go new file mode 100644 index 0000000000..4eb9bb9f1f --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/queue/mq.go @@ -0,0 +1,92 @@ +package queue + +import ( + "errors" + "sync" +) + +var ErrQueueClosed = errors.New("the queue is closed for reading and writing") + +// MessageQueue represents a threadsafe message queue to be used to retrieve or +// write messages to. +type MessageQueue struct { + m *sync.RWMutex + c *sync.Cond + messages []interface{} + closed bool +} + +// NewMessageQueue returns a new MessageQueue. +func NewMessageQueue() *MessageQueue { + m := &sync.RWMutex{} + return &MessageQueue{ + m: m, + c: sync.NewCond(m), + messages: []interface{}{}, + } +} + +// Enqueue writes `msg` to the queue. +func (mq *MessageQueue) Enqueue(msg interface{}) error { + mq.m.Lock() + defer mq.m.Unlock() + + if mq.closed { + return ErrQueueClosed + } + mq.messages = append(mq.messages, msg) + // Signal a waiter that there is now a value available in the queue. + mq.c.Signal() + return nil +} + +// Dequeue will read a value from the queue and remove it. If the queue +// is empty, this will block until the queue is closed or a value gets enqueued. +func (mq *MessageQueue) Dequeue() (interface{}, error) { + mq.m.Lock() + defer mq.m.Unlock() + + for !mq.closed && mq.size() == 0 { + mq.c.Wait() + } + + // We got woken up, check if it's because the queue got closed. + if mq.closed { + return nil, ErrQueueClosed + } + + val := mq.messages[0] + mq.messages[0] = nil + mq.messages = mq.messages[1:] + return val, nil +} + +// Size returns the size of the queue. +func (mq *MessageQueue) Size() int { + mq.m.RLock() + defer mq.m.RUnlock() + return mq.size() +} + +// Nonexported size check to check if the queue is empty inside already locked functions. +func (mq *MessageQueue) size() int { + return len(mq.messages) +} + +// Close closes the queue for future writes or reads. Any attempts to read or write from the +// queue after close will return ErrQueueClosed. This is safe to call multiple times. +func (mq *MessageQueue) Close() { + mq.m.Lock() + defer mq.m.Unlock() + + // Already closed, noop + if mq.closed { + return + } + + mq.messages = nil + mq.closed = true + // If there's anybody currently waiting on a value from Dequeue, we need to + // broadcast so the read(s) can return ErrQueueClosed. + mq.c.Broadcast() +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/iocp.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/iocp.go deleted file mode 100644 index 4e609cbf1c..0000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/iocp.go +++ /dev/null @@ -1,3 +0,0 @@ -package winapi - -//sys GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go index ba12b1ad92..7eb13f8f0a 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go @@ -24,7 +24,10 @@ const ( // Access rights for creating or opening job objects. // // https://docs.microsoft.com/en-us/windows/win32/procthread/job-object-security-and-access-rights -const JOB_OBJECT_ALL_ACCESS = 0x1F001F +const ( + JOB_OBJECT_QUERY = 0x0004 + JOB_OBJECT_ALL_ACCESS = 0x1F001F +) // IO limit flags // @@ -93,7 +96,7 @@ type JOBOBJECT_BASIC_PROCESS_ID_LIST struct { // AllPids returns all the process Ids in the job object. func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr { - return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList] + return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList:p.NumberOfProcessIdsInList] } // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_accounting_information @@ -162,7 +165,7 @@ type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct { // PBOOL Result // ); // -//sys IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) = kernel32.IsProcessInJob +//sys IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) = kernel32.IsProcessInJob // BOOL QueryInformationJobObject( // HANDLE hJob, @@ -172,7 +175,7 @@ type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct { // LPDWORD lpReturnLength // ); // -//sys QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) = kernel32.QueryInformationJobObject +//sys QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo unsafe.Pointer, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) = kernel32.QueryInformationJobObject // HANDLE OpenJobObjectW( // DWORD dwDesiredAccess, diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go index 37839435b9..222529f433 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go @@ -6,3 +6,60 @@ const ( PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x20016 PROC_THREAD_ATTRIBUTE_JOB_LIST = 0x2000D ) + +// ProcessVmCounters corresponds to the _VM_COUNTERS_EX and _VM_COUNTERS_EX2 structures. +const ProcessVmCounters = 3 + +// __kernel_entry NTSTATUS NtQueryInformationProcess( +// [in] HANDLE ProcessHandle, +// [in] PROCESSINFOCLASS ProcessInformationClass, +// [out] PVOID ProcessInformation, +// [in] ULONG ProcessInformationLength, +// [out, optional] PULONG ReturnLength +// ); +// +//sys NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo unsafe.Pointer, processInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQueryInformationProcess + +// typedef struct _VM_COUNTERS_EX +// { +// SIZE_T PeakVirtualSize; +// SIZE_T VirtualSize; +// ULONG PageFaultCount; +// SIZE_T PeakWorkingSetSize; +// SIZE_T WorkingSetSize; +// SIZE_T QuotaPeakPagedPoolUsage; +// SIZE_T QuotaPagedPoolUsage; +// SIZE_T QuotaPeakNonPagedPoolUsage; +// SIZE_T QuotaNonPagedPoolUsage; +// SIZE_T PagefileUsage; +// SIZE_T PeakPagefileUsage; +// SIZE_T PrivateUsage; +// } VM_COUNTERS_EX, *PVM_COUNTERS_EX; +// +type VM_COUNTERS_EX struct { + PeakVirtualSize uintptr + VirtualSize uintptr + PageFaultCount uint32 + PeakWorkingSetSize uintptr + WorkingSetSize uintptr + QuotaPeakPagedPoolUsage uintptr + QuotaPagedPoolUsage uintptr + QuotaPeakNonPagedPoolUsage uintptr + QuotaNonPagedPoolUsage uintptr + PagefileUsage uintptr + PeakPagefileUsage uintptr + PrivateUsage uintptr +} + +// typedef struct _VM_COUNTERS_EX2 +// { +// VM_COUNTERS_EX CountersEx; +// SIZE_T PrivateWorkingSetSize; +// SIZE_T SharedCommitUsage; +// } VM_COUNTERS_EX2, *PVM_COUNTERS_EX2; +// +type VM_COUNTERS_EX2 struct { + CountersEx VM_COUNTERS_EX + PrivateWorkingSetSize uintptr + SharedCommitUsage uintptr +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/system.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/system.go index 327f57d7c2..78fe01a4b4 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/system.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/system.go @@ -12,7 +12,8 @@ const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 // ULONG SystemInformationLength, // PULONG ReturnLength // ); -//sys NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQuerySystemInformation +// +//sys NtQuerySystemInformation(systemInfoClass int, systemInformation unsafe.Pointer, systemInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQuerySystemInformation type SYSTEM_PROCESS_INFORMATION struct { NextEntryOffset uint32 // ULONG diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go index 1d4ba3c4f8..d2cc9d9fba 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go @@ -2,4 +2,4 @@ // be thought of as an extension to golang.org/x/sys/windows. package winapi -//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go console.go system.go net.go path.go thread.go iocp.go jobobject.go logon.go memory.go process.go processor.go devices.go filesystem.go errors.go +//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go user.go console.go system.go net.go path.go thread.go jobobject.go logon.go memory.go process.go processor.go devices.go filesystem.go errors.go diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go index 4eb64b4c0c..1f16cf0b8e 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go @@ -50,7 +50,6 @@ var ( procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId") procSearchPathW = modkernel32.NewProc("SearchPathW") procCreateRemoteThread = modkernel32.NewProc("CreateRemoteThread") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") procIsProcessInJob = modkernel32.NewProc("IsProcessInJob") procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject") procOpenJobObjectW = modkernel32.NewProc("OpenJobObjectW") @@ -61,6 +60,7 @@ var ( procLogonUserW = modadvapi32.NewProc("LogonUserW") procLocalAlloc = modkernel32.NewProc("LocalAlloc") procLocalFree = modkernel32.NewProc("LocalFree") + procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA") procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA") @@ -100,7 +100,7 @@ func resizePseudoConsole(hPc windows.Handle, size uint32) (hr error) { return } -func NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) { +func NtQuerySystemInformation(systemInfoClass int, systemInformation unsafe.Pointer, systemInfoLength uint32, returnLength *uint32) (status uint32) { r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInfoClass), uintptr(systemInformation), uintptr(systemInfoLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) status = uint32(r0) return @@ -140,19 +140,7 @@ func CreateRemoteThread(process windows.Handle, sa *windows.SecurityAttributes, return } -func GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) { +func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) { r1, _, e1 := syscall.Syscall(procIsProcessInJob.Addr(), 3, uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result))) if r1 == 0 { if e1 != 0 { @@ -164,7 +152,7 @@ func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result return } -func QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) { +func QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo unsafe.Pointer, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) { r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(jobHandle), uintptr(infoClass), uintptr(jobObjectInfo), uintptr(jobObjectInformationLength), uintptr(unsafe.Pointer(lpReturnLength)), 0) if r1 == 0 { if e1 != 0 { @@ -256,6 +244,12 @@ func LocalFree(ptr uintptr) { return } +func NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo unsafe.Pointer, processInfoLength uint32, returnLength *uint32) (status uint32) { + r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInfoClass), uintptr(processInfo), uintptr(processInfoLength), uintptr(unsafe.Pointer(returnLength)), 0) + status = uint32(r0) + return +} + func GetActiveProcessorCount(groupNumber uint16) (amount uint32) { r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) amount = uint32(r0) diff --git a/vendor/github.com/PuerkitoBio/purell/.gitignore b/vendor/github.com/PuerkitoBio/purell/.gitignore deleted file mode 100644 index 748e4c8073..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.sublime-* -.DS_Store -*.swp -*.swo -tags diff --git a/vendor/github.com/PuerkitoBio/purell/.travis.yml b/vendor/github.com/PuerkitoBio/purell/.travis.yml deleted file mode 100644 index cf31e6af6d..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go - -go: - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - "1.10.x" - - "1.11.x" - - tip diff --git a/vendor/github.com/PuerkitoBio/purell/LICENSE b/vendor/github.com/PuerkitoBio/purell/LICENSE deleted file mode 100644 index 4b9986dea7..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012, Martin Angers -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 the author 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/PuerkitoBio/purell/README.md b/vendor/github.com/PuerkitoBio/purell/README.md deleted file mode 100644 index 07de0c4986..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/README.md +++ /dev/null @@ -1,188 +0,0 @@ -# Purell - -Purell is a tiny Go library to normalize URLs. It returns a pure URL. Pure-ell. Sanitizer and all. Yeah, I know... - -Based on the [wikipedia paper][wiki] and the [RFC 3986 document][rfc]. - -[![build status](https://travis-ci.org/PuerkitoBio/purell.svg?branch=master)](http://travis-ci.org/PuerkitoBio/purell) - -## Install - -`go get github.com/PuerkitoBio/purell` - -## Changelog - -* **v1.1.1** : Fix failing test due to Go1.12 changes (thanks to @ianlancetaylor). -* **2016-11-14 (v1.1.0)** : IDN: Conform to RFC 5895: Fold character width (thanks to @beeker1121). -* **2016-07-27 (v1.0.0)** : Normalize IDN to ASCII (thanks to @zenovich). -* **2015-02-08** : Add fix for relative paths issue ([PR #5][pr5]) and add fix for unnecessary encoding of reserved characters ([see issue #7][iss7]). -* **v0.2.0** : Add benchmarks, Attempt IDN support. -* **v0.1.0** : Initial release. - -## Examples - -From `example_test.go` (note that in your code, you would import "github.com/PuerkitoBio/purell", and would prefix references to its methods and constants with "purell."): - -```go -package purell - -import ( - "fmt" - "net/url" -) - -func ExampleNormalizeURLString() { - if normalized, err := NormalizeURLString("hTTp://someWEBsite.com:80/Amazing%3f/url/", - FlagLowercaseScheme|FlagLowercaseHost|FlagUppercaseEscapes); err != nil { - panic(err) - } else { - fmt.Print(normalized) - } - // Output: http://somewebsite.com:80/Amazing%3F/url/ -} - -func ExampleMustNormalizeURLString() { - normalized := MustNormalizeURLString("hTTpS://someWEBsite.com:443/Amazing%fa/url/", - FlagsUnsafeGreedy) - fmt.Print(normalized) - - // Output: http://somewebsite.com/Amazing%FA/url -} - -func ExampleNormalizeURL() { - if u, err := url.Parse("Http://SomeUrl.com:8080/a/b/.././c///g?c=3&a=1&b=9&c=0#target"); err != nil { - panic(err) - } else { - normalized := NormalizeURL(u, FlagsUsuallySafeGreedy|FlagRemoveDuplicateSlashes|FlagRemoveFragment) - fmt.Print(normalized) - } - - // Output: http://someurl.com:8080/a/c/g?c=3&a=1&b=9&c=0 -} -``` - -## API - -As seen in the examples above, purell offers three methods, `NormalizeURLString(string, NormalizationFlags) (string, error)`, `MustNormalizeURLString(string, NormalizationFlags) (string)` and `NormalizeURL(*url.URL, NormalizationFlags) (string)`. They all normalize the provided URL based on the specified flags. Here are the available flags: - -```go -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) -``` - -For convenience, the set of flags `FlagsSafe`, `FlagsUsuallySafe[Greedy|NonGreedy]`, `FlagsUnsafe[Greedy|NonGreedy]` and `FlagsAll[Greedy|NonGreedy]` are provided for the similarly grouped normalizations on [wikipedia's URL normalization page][wiki]. You can add (using the bitwise OR `|` operator) or remove (using the bitwise AND NOT `&^` operator) individual flags from the sets if required, to build your own custom set. - -The [full godoc reference is available on gopkgdoc][godoc]. - -Some things to note: - -* `FlagDecodeUnnecessaryEscapes`, `FlagEncodeNecessaryEscapes`, `FlagUppercaseEscapes` and `FlagRemoveEmptyQuerySeparator` are always implicitly set, because internally, the URL string is parsed as an URL object, which automatically decodes unnecessary escapes, uppercases and encodes necessary ones, and removes empty query separators (an unnecessary `?` at the end of the url). So this operation cannot **not** be done. For this reason, `FlagRemoveEmptyQuerySeparator` (as well as the other three) has been included in the `FlagsSafe` convenience set, instead of `FlagsUnsafe`, where Wikipedia puts it. - -* The `FlagDecodeUnnecessaryEscapes` decodes the following escapes (*from -> to*): - - %24 -> $ - - %26 -> & - - %2B-%3B -> +,-./0123456789:; - - %3D -> = - - %40-%5A -> @ABCDEFGHIJKLMNOPQRSTUVWXYZ - - %5F -> _ - - %61-%7A -> abcdefghijklmnopqrstuvwxyz - - %7E -> ~ - - -* When the `NormalizeURL` function is used (passing an URL object), this source URL object is modified (that is, after the call, the URL object will be modified to reflect the normalization). - -* The *replace IP with domain name* normalization (`http://208.77.188.166/ → http://www.example.com/`) is obviously not possible for a library without making some network requests. This is not implemented in purell. - -* The *remove unused query string parameters* and *remove default query parameters* are also not implemented, since this is a very case-specific normalization, and it is quite trivial to do with an URL object. - -### Safe vs Usually Safe vs Unsafe - -Purell allows you to control the level of risk you take while normalizing an URL. You can aggressively normalize, play it totally safe, or anything in between. - -Consider the following URL: - -`HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -Normalizing with the `FlagsSafe` gives: - -`https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -With the `FlagsUsuallySafeGreedy`: - -`https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid` - -And with `FlagsUnsafeGreedy`: - -`http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3` - -## TODOs - -* Add a class/default instance to allow specifying custom directory index names? At the moment, removing directory index removes `(^|/)((?:default|index)\.\w{1,4})$`. - -## Thanks / Contributions - -@rogpeppe -@jehiah -@opennota -@pchristopher1275 -@zenovich -@beeker1121 - -## License - -The [BSD 3-Clause license][bsd]. - -[bsd]: http://opensource.org/licenses/BSD-3-Clause -[wiki]: http://en.wikipedia.org/wiki/URL_normalization -[rfc]: http://tools.ietf.org/html/rfc3986#section-6 -[godoc]: http://go.pkgdoc.org/github.com/PuerkitoBio/purell -[pr5]: https://github.com/PuerkitoBio/purell/pull/5 -[iss7]: https://github.com/PuerkitoBio/purell/issues/7 diff --git a/vendor/github.com/PuerkitoBio/purell/purell.go b/vendor/github.com/PuerkitoBio/purell/purell.go deleted file mode 100644 index 6d0fc190a1..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/purell.go +++ /dev/null @@ -1,379 +0,0 @@ -/* -Package purell offers URL normalization as described on the wikipedia page: -http://en.wikipedia.org/wiki/URL_normalization -*/ -package purell - -import ( - "bytes" - "fmt" - "net/url" - "regexp" - "sort" - "strconv" - "strings" - - "github.com/PuerkitoBio/urlesc" - "golang.org/x/net/idna" - "golang.org/x/text/unicode/norm" - "golang.org/x/text/width" -) - -// A set of normalization flags determines how a URL will -// be normalized. -type NormalizationFlags uint - -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) - -const ( - defaultHttpPort = ":80" - defaultHttpsPort = ":443" -) - -// Regular expressions used by the normalizations -var rxPort = regexp.MustCompile(`(:\d+)/?$`) -var rxDirIndex = regexp.MustCompile(`(^|/)((?:default|index)\.\w{1,4})$`) -var rxDupSlashes = regexp.MustCompile(`/{2,}`) -var rxDWORDHost = regexp.MustCompile(`^(\d+)((?:\.+)?(?:\:\d*)?)$`) -var rxOctalHost = regexp.MustCompile(`^(0\d*)\.(0\d*)\.(0\d*)\.(0\d*)((?:\.+)?(?:\:\d*)?)$`) -var rxHexHost = regexp.MustCompile(`^0x([0-9A-Fa-f]+)((?:\.+)?(?:\:\d*)?)$`) -var rxHostDots = regexp.MustCompile(`^(.+?)(:\d+)?$`) -var rxEmptyPort = regexp.MustCompile(`:+$`) - -// Map of flags to implementation function. -// FlagDecodeUnnecessaryEscapes has no action, since it is done automatically -// by parsing the string as an URL. Same for FlagUppercaseEscapes and FlagRemoveEmptyQuerySeparator. - -// Since maps have undefined traversing order, make a slice of ordered keys -var flagsOrder = []NormalizationFlags{ - FlagLowercaseScheme, - FlagLowercaseHost, - FlagRemoveDefaultPort, - FlagRemoveDirectoryIndex, - FlagRemoveDotSegments, - FlagRemoveFragment, - FlagForceHTTP, // Must be after remove default port (because https=443/http=80) - FlagRemoveDuplicateSlashes, - FlagRemoveWWW, - FlagAddWWW, - FlagSortQuery, - FlagDecodeDWORDHost, - FlagDecodeOctalHost, - FlagDecodeHexHost, - FlagRemoveUnnecessaryHostDots, - FlagRemoveEmptyPortSeparator, - FlagRemoveTrailingSlash, // These two (add/remove trailing slash) must be last - FlagAddTrailingSlash, -} - -// ... and then the map, where order is unimportant -var flags = map[NormalizationFlags]func(*url.URL){ - FlagLowercaseScheme: lowercaseScheme, - FlagLowercaseHost: lowercaseHost, - FlagRemoveDefaultPort: removeDefaultPort, - FlagRemoveDirectoryIndex: removeDirectoryIndex, - FlagRemoveDotSegments: removeDotSegments, - FlagRemoveFragment: removeFragment, - FlagForceHTTP: forceHTTP, - FlagRemoveDuplicateSlashes: removeDuplicateSlashes, - FlagRemoveWWW: removeWWW, - FlagAddWWW: addWWW, - FlagSortQuery: sortQuery, - FlagDecodeDWORDHost: decodeDWORDHost, - FlagDecodeOctalHost: decodeOctalHost, - FlagDecodeHexHost: decodeHexHost, - FlagRemoveUnnecessaryHostDots: removeUnncessaryHostDots, - FlagRemoveEmptyPortSeparator: removeEmptyPortSeparator, - FlagRemoveTrailingSlash: removeTrailingSlash, - FlagAddTrailingSlash: addTrailingSlash, -} - -// MustNormalizeURLString returns the normalized string, and panics if an error occurs. -// It takes an URL string as input, as well as the normalization flags. -func MustNormalizeURLString(u string, f NormalizationFlags) string { - result, e := NormalizeURLString(u, f) - if e != nil { - panic(e) - } - return result -} - -// NormalizeURLString returns the normalized string, or an error if it can't be parsed into an URL object. -// It takes an URL string as input, as well as the normalization flags. -func NormalizeURLString(u string, f NormalizationFlags) (string, error) { - parsed, err := url.Parse(u) - if err != nil { - return "", err - } - - if f&FlagLowercaseHost == FlagLowercaseHost { - parsed.Host = strings.ToLower(parsed.Host) - } - - // The idna package doesn't fully conform to RFC 5895 - // (https://tools.ietf.org/html/rfc5895), so we do it here. - // Taken from Go 1.8 cycle source, courtesy of bradfitz. - // TODO: Remove when (if?) idna package conforms to RFC 5895. - parsed.Host = width.Fold.String(parsed.Host) - parsed.Host = norm.NFC.String(parsed.Host) - if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil { - return "", err - } - - return NormalizeURL(parsed, f), nil -} - -// NormalizeURL returns the normalized string. -// It takes a parsed URL object as input, as well as the normalization flags. -func NormalizeURL(u *url.URL, f NormalizationFlags) string { - for _, k := range flagsOrder { - if f&k == k { - flags[k](u) - } - } - return urlesc.Escape(u) -} - -func lowercaseScheme(u *url.URL) { - if len(u.Scheme) > 0 { - u.Scheme = strings.ToLower(u.Scheme) - } -} - -func lowercaseHost(u *url.URL) { - if len(u.Host) > 0 { - u.Host = strings.ToLower(u.Host) - } -} - -func removeDefaultPort(u *url.URL) { - if len(u.Host) > 0 { - scheme := strings.ToLower(u.Scheme) - u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { - if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) { - return "" - } - return val - }) - } -} - -func removeTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if strings.HasSuffix(u.Path, "/") { - u.Path = u.Path[:l-1] - } - } else if l = len(u.Host); l > 0 { - if strings.HasSuffix(u.Host, "/") { - u.Host = u.Host[:l-1] - } - } -} - -func addTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } else if l = len(u.Host); l > 0 { - if !strings.HasSuffix(u.Host, "/") { - u.Host += "/" - } - } -} - -func removeDotSegments(u *url.URL) { - if len(u.Path) > 0 { - var dotFree []string - var lastIsDot bool - - sections := strings.Split(u.Path, "/") - for _, s := range sections { - if s == ".." { - if len(dotFree) > 0 { - dotFree = dotFree[:len(dotFree)-1] - } - } else if s != "." { - dotFree = append(dotFree, s) - } - lastIsDot = (s == "." || s == "..") - } - // Special case if host does not end with / and new path does not begin with / - u.Path = strings.Join(dotFree, "/") - if u.Host != "" && !strings.HasSuffix(u.Host, "/") && !strings.HasPrefix(u.Path, "/") { - u.Path = "/" + u.Path - } - // Special case if the last segment was a dot, make sure the path ends with a slash - if lastIsDot && !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } -} - -func removeDirectoryIndex(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDirIndex.ReplaceAllString(u.Path, "$1") - } -} - -func removeFragment(u *url.URL) { - u.Fragment = "" -} - -func forceHTTP(u *url.URL) { - if strings.ToLower(u.Scheme) == "https" { - u.Scheme = "http" - } -} - -func removeDuplicateSlashes(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") - } -} - -func removeWWW(u *url.URL) { - if len(u.Host) > 0 && strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = u.Host[4:] - } -} - -func addWWW(u *url.URL) { - if len(u.Host) > 0 && !strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = "www." + u.Host - } -} - -func sortQuery(u *url.URL) { - q := u.Query() - - if len(q) > 0 { - arKeys := make([]string, len(q)) - i := 0 - for k := range q { - arKeys[i] = k - i++ - } - sort.Strings(arKeys) - buf := new(bytes.Buffer) - for _, k := range arKeys { - sort.Strings(q[k]) - for _, v := range q[k] { - if buf.Len() > 0 { - buf.WriteRune('&') - } - buf.WriteString(fmt.Sprintf("%s=%s", k, urlesc.QueryEscape(v))) - } - } - - // Rebuild the raw query string - u.RawQuery = buf.String() - } -} - -func decodeDWORDHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxDWORDHost.FindStringSubmatch(u.Host); len(matches) > 2 { - var parts [4]int64 - - dword, _ := strconv.ParseInt(matches[1], 10, 0) - for i, shift := range []uint{24, 16, 8, 0} { - parts[i] = dword >> shift & 0xFF - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[2]) - } - } -} - -func decodeOctalHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxOctalHost.FindStringSubmatch(u.Host); len(matches) > 5 { - var parts [4]int64 - - for i := 1; i <= 4; i++ { - parts[i-1], _ = strconv.ParseInt(matches[i], 8, 0) - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[5]) - } - } -} - -func decodeHexHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHexHost.FindStringSubmatch(u.Host); len(matches) > 2 { - // Conversion is safe because of regex validation - parsed, _ := strconv.ParseInt(matches[1], 16, 0) - // Set host as DWORD (base 10) encoded host - u.Host = fmt.Sprintf("%d%s", parsed, matches[2]) - // The rest is the same as decoding a DWORD host - decodeDWORDHost(u) - } - } -} - -func removeUnncessaryHostDots(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHostDots.FindStringSubmatch(u.Host); len(matches) > 1 { - // Trim the leading and trailing dots - u.Host = strings.Trim(matches[1], ".") - if len(matches) > 2 { - u.Host += matches[2] - } - } - } -} - -func removeEmptyPortSeparator(u *url.URL) { - if len(u.Host) > 0 { - u.Host = rxEmptyPort.ReplaceAllString(u.Host, "") - } -} diff --git a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml b/vendor/github.com/PuerkitoBio/urlesc/.travis.yml deleted file mode 100644 index ba6b225f91..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -go: - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - tip - -install: - - go build . - -script: - - go test -v diff --git a/vendor/github.com/PuerkitoBio/urlesc/LICENSE b/vendor/github.com/PuerkitoBio/urlesc/LICENSE deleted file mode 100644 index 7448756763..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -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/PuerkitoBio/urlesc/README.md b/vendor/github.com/PuerkitoBio/urlesc/README.md deleted file mode 100644 index 57aff0a539..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/README.md +++ /dev/null @@ -1,16 +0,0 @@ -urlesc [![Build Status](https://travis-ci.org/PuerkitoBio/urlesc.svg?branch=master)](https://travis-ci.org/PuerkitoBio/urlesc) [![GoDoc](http://godoc.org/github.com/PuerkitoBio/urlesc?status.svg)](http://godoc.org/github.com/PuerkitoBio/urlesc) -====== - -Package urlesc implements query escaping as per RFC 3986. - -It contains some parts of the net/url package, modified so as to allow -some reserved characters incorrectly escaped by net/url (see [issue 5684](https://github.com/golang/go/issues/5684)). - -## Install - - go get github.com/PuerkitoBio/urlesc - -## License - -Go license (BSD-3-Clause) - diff --git a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go b/vendor/github.com/PuerkitoBio/urlesc/urlesc.go deleted file mode 100644 index 1b84624594..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go +++ /dev/null @@ -1,180 +0,0 @@ -// 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 urlesc implements query escaping as per RFC 3986. -// It contains some parts of the net/url package, modified so as to allow -// some reserved characters incorrectly escaped by net/url. -// See https://github.com/golang/go/issues/5684 -package urlesc - -import ( - "bytes" - "net/url" - "strings" -) - -type encoding int - -const ( - encodePath encoding = 1 + iota - encodeUserPassword - encodeQueryComponent - encodeFragment -) - -// Return true if the specified character should be escaped when -// appearing in a URL string, according to RFC 3986. -func shouldEscape(c byte, mode encoding) bool { - // §2.3 Unreserved characters (alphanum) - if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' { - return false - } - - switch c { - case '-', '.', '_', '~': // §2.3 Unreserved characters (mark) - return false - - // §2.2 Reserved characters (reserved) - case ':', '/', '?', '#', '[', ']', '@', // gen-delims - '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // sub-delims - // Different sections of the URL allow a few of - // the reserved characters to appear unescaped. - switch mode { - case encodePath: // §3.3 - // The RFC allows sub-delims and : @. - // '/', '[' and ']' can be used to assign meaning to individual path - // segments. This package only manipulates the path as a whole, - // so we allow those as well. That leaves only ? and # to escape. - return c == '?' || c == '#' - - case encodeUserPassword: // §3.2.1 - // The RFC allows : and sub-delims in - // userinfo. The parsing of userinfo treats ':' as special so we must escape - // all the gen-delims. - return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@' - - case encodeQueryComponent: // §3.4 - // The RFC allows / and ?. - return c != '/' && c != '?' - - case encodeFragment: // §4.1 - // The RFC text is silent but the grammar allows - // everything, so escape nothing but # - return c == '#' - } - } - - // Everything else must be escaped. - return true -} - -// QueryEscape escapes the string so it can be safely placed -// inside a URL query. -func QueryEscape(s string) string { - return escape(s, encodeQueryComponent) -} - -func escape(s string, mode encoding) string { - spaceCount, hexCount := 0, 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c, mode) { - if c == ' ' && mode == encodeQueryComponent { - spaceCount++ - } else { - hexCount++ - } - } - } - - if spaceCount == 0 && hexCount == 0 { - return s - } - - t := make([]byte, len(s)+2*hexCount) - j := 0 - for i := 0; i < len(s); i++ { - switch c := s[i]; { - case c == ' ' && mode == encodeQueryComponent: - t[j] = '+' - j++ - case shouldEscape(c, mode): - t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] - j += 3 - default: - t[j] = s[i] - j++ - } - } - return string(t) -} - -var uiReplacer = strings.NewReplacer( - "%21", "!", - "%27", "'", - "%28", "(", - "%29", ")", - "%2A", "*", -) - -// unescapeUserinfo unescapes some characters that need not to be escaped as per RFC3986. -func unescapeUserinfo(s string) string { - return uiReplacer.Replace(s) -} - -// Escape reassembles the URL into a valid URL string. -// The general form of the result is one of: -// -// scheme:opaque -// scheme://userinfo@host/path?query#fragment -// -// If u.Opaque is non-empty, String uses the first form; -// otherwise it uses the second form. -// -// In the second form, the following rules apply: -// - if u.Scheme is empty, scheme: is omitted. -// - if u.User is nil, userinfo@ is omitted. -// - if u.Host is empty, host/ is omitted. -// - if u.Scheme and u.Host are empty and u.User is nil, -// the entire scheme://userinfo@host/ is omitted. -// - if u.Host is non-empty and u.Path begins with a /, -// the form host/path does not add its own /. -// - if u.RawQuery is empty, ?query is omitted. -// - if u.Fragment is empty, #fragment is omitted. -func Escape(u *url.URL) string { - var buf bytes.Buffer - if u.Scheme != "" { - buf.WriteString(u.Scheme) - buf.WriteByte(':') - } - if u.Opaque != "" { - buf.WriteString(u.Opaque) - } else { - if u.Scheme != "" || u.Host != "" || u.User != nil { - buf.WriteString("//") - if ui := u.User; ui != nil { - buf.WriteString(unescapeUserinfo(ui.String())) - buf.WriteByte('@') - } - if h := u.Host; h != "" { - buf.WriteString(h) - } - } - if u.Path != "" && u.Path[0] != '/' && u.Host != "" { - buf.WriteByte('/') - } - buf.WriteString(escape(u.Path, encodePath)) - } - if u.RawQuery != "" { - buf.WriteByte('?') - buf.WriteString(u.RawQuery) - } - if u.Fragment != "" { - buf.WriteByte('#') - buf.WriteString(escape(u.Fragment, encodeFragment)) - } - return buf.String() -} diff --git a/vendor/github.com/blang/semver/.travis.yml b/vendor/github.com/blang/semver/.travis.yml deleted file mode 100644 index 102fb9a691..0000000000 --- a/vendor/github.com/blang/semver/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: go -matrix: - include: - - go: 1.4.3 - - go: 1.5.4 - - go: 1.6.3 - - go: 1.7 - - go: tip - allow_failures: - - go: tip -install: -- go get golang.org/x/tools/cmd/cover -- go get github.com/mattn/goveralls -script: -- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci - -repotoken $COVERALLS_TOKEN -- echo "Build examples" ; cd examples && go build -- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .) -env: - global: - secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw= diff --git a/vendor/github.com/blang/semver/LICENSE b/vendor/github.com/blang/semver/LICENSE deleted file mode 100644 index 5ba5c86fcb..0000000000 --- a/vendor/github.com/blang/semver/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2014 Benedikt Lang - -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/blang/semver/README.md b/vendor/github.com/blang/semver/README.md deleted file mode 100644 index 08b2e4a3d7..0000000000 --- a/vendor/github.com/blang/semver/README.md +++ /dev/null @@ -1,194 +0,0 @@ -semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master) -====== - -semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`. - -Usage ------ -```bash -$ go get github.com/blang/semver -``` -Note: Always vendor your dependencies or fix on a specific version tag. - -```go -import github.com/blang/semver -v1, err := semver.Make("1.0.0-beta") -v2, err := semver.Make("2.0.0-beta") -v1.Compare(v2) -``` - -Also check the [GoDocs](http://godoc.org/github.com/blang/semver). - -Why should I use this lib? ------ - -- Fully spec compatible -- No reflection -- No regex -- Fully tested (Coverage >99%) -- Readable parsing/validation errors -- Fast (See [Benchmarks](#benchmarks)) -- Only Stdlib -- Uses values instead of pointers -- Many features, see below - - -Features ------ - -- Parsing and validation at all levels -- Comparator-like comparisons -- Compare Helper Methods -- InPlace manipulation -- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1` -- Wildcards `>=1.x`, `<=2.5.x` -- Sortable (implements sort.Interface) -- database/sql compatible (sql.Scanner/Valuer) -- encoding/json compatible (json.Marshaler/Unmarshaler) - -Ranges ------- - -A `Range` is a set of conditions which specify which versions satisfy the range. - -A condition is composed of an operator and a version. The supported operators are: - -- `<1.0.0` Less than `1.0.0` -- `<=1.0.0` Less than or equal to `1.0.0` -- `>1.0.0` Greater than `1.0.0` -- `>=1.0.0` Greater than or equal to `1.0.0` -- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0` -- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`. - -Note that spaces between the operator and the version will be gracefully tolerated. - -A `Range` can link multiple `Ranges` separated by space: - -Ranges can be linked by logical AND: - - - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0` - - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2` - -Ranges can also be linked by logical OR: - - - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x` - -AND has a higher precedence than OR. It's not possible to use brackets. - -Ranges can be combined by both AND and OR - - - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` - -Range usage: - -``` -v, err := semver.Parse("1.2.3") -range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0") -if range(v) { - //valid -} - -``` - -Example ------ - -Have a look at full examples in [examples/main.go](examples/main.go) - -```go -import github.com/blang/semver - -v, err := semver.Make("0.0.1-alpha.preview+123.github") -fmt.Printf("Major: %d\n", v.Major) -fmt.Printf("Minor: %d\n", v.Minor) -fmt.Printf("Patch: %d\n", v.Patch) -fmt.Printf("Pre: %s\n", v.Pre) -fmt.Printf("Build: %s\n", v.Build) - -// Prerelease versions array -if len(v.Pre) > 0 { - fmt.Println("Prerelease versions:") - for i, pre := range v.Pre { - fmt.Printf("%d: %q\n", i, pre) - } -} - -// Build meta data array -if len(v.Build) > 0 { - fmt.Println("Build meta data:") - for i, build := range v.Build { - fmt.Printf("%d: %q\n", i, build) - } -} - -v001, err := semver.Make("0.0.1") -// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE -v001.GT(v) == true -v.LT(v001) == true -v.GTE(v) == true -v.LTE(v) == true - -// Or use v.Compare(v2) for comparisons (-1, 0, 1): -v001.Compare(v) == 1 -v.Compare(v001) == -1 -v.Compare(v) == 0 - -// Manipulate Version in place: -v.Pre[0], err = semver.NewPRVersion("beta") -if err != nil { - fmt.Printf("Error parsing pre release version: %q", err) -} - -fmt.Println("\nValidate versions:") -v.Build[0] = "?" - -err = v.Validate() -if err != nil { - fmt.Printf("Validation failed: %s\n", err) -} -``` - - -Benchmarks ------ - - BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op - BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op - BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op - BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op - BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op - BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op - BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op - BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op - BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op - BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op - BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op - BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op - BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op - BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op - BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op - BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op - -See benchmark cases at [semver_test.go](semver_test.go) - - -Motivation ------ - -I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like. - - -Contribution ------ - -Feel free to make a pull request. For bigger changes create a issue first to discuss about it. - - -License ------ - -See [LICENSE](LICENSE) file. diff --git a/vendor/github.com/blang/semver/json.go b/vendor/github.com/blang/semver/json.go deleted file mode 100644 index a74bf7c449..0000000000 --- a/vendor/github.com/blang/semver/json.go +++ /dev/null @@ -1,23 +0,0 @@ -package semver - -import ( - "encoding/json" -) - -// MarshalJSON implements the encoding/json.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalJSON implements the encoding/json.Unmarshaler interface. -func (v *Version) UnmarshalJSON(data []byte) (err error) { - var versionString string - - if err = json.Unmarshal(data, &versionString); err != nil { - return - } - - *v, err = Parse(versionString) - - return -} diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json deleted file mode 100644 index 1cf8ebdd9c..0000000000 --- a/vendor/github.com/blang/semver/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "author": "blang", - "bugs": { - "URL": "https://github.com/blang/semver/issues", - "url": "https://github.com/blang/semver/issues" - }, - "gx": { - "dvcsimport": "github.com/blang/semver" - }, - "gxVersion": "0.10.0", - "language": "go", - "license": "MIT", - "name": "semver", - "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "3.5.1" -} - diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go deleted file mode 100644 index fca406d479..0000000000 --- a/vendor/github.com/blang/semver/range.go +++ /dev/null @@ -1,416 +0,0 @@ -package semver - -import ( - "fmt" - "strconv" - "strings" - "unicode" -) - -type wildcardType int - -const ( - noneWildcard wildcardType = iota - majorWildcard wildcardType = 1 - minorWildcard wildcardType = 2 - patchWildcard wildcardType = 3 -) - -func wildcardTypefromInt(i int) wildcardType { - switch i { - case 1: - return majorWildcard - case 2: - return minorWildcard - case 3: - return patchWildcard - default: - return noneWildcard - } -} - -type comparator func(Version, Version) bool - -var ( - compEQ comparator = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 0 - } - compNE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) != 0 - } - compGT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 1 - } - compGE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) >= 0 - } - compLT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == -1 - } - compLE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) <= 0 - } -) - -type versionRange struct { - v Version - c comparator -} - -// rangeFunc creates a Range from the given versionRange. -func (vr *versionRange) rangeFunc() Range { - return Range(func(v Version) bool { - return vr.c(v, vr.v) - }) -} - -// Range represents a range of versions. -// A Range can be used to check if a Version satisfies it: -// -// range, err := semver.ParseRange(">1.0.0 <2.0.0") -// range(semver.MustParse("1.1.1") // returns true -type Range func(Version) bool - -// OR combines the existing Range with another Range using logical OR. -func (rf Range) OR(f Range) Range { - return Range(func(v Version) bool { - return rf(v) || f(v) - }) -} - -// AND combines the existing Range with another Range using logical AND. -func (rf Range) AND(f Range) Range { - return Range(func(v Version) bool { - return rf(v) && f(v) - }) -} - -// ParseRange parses a range and returns a Range. -// If the range could not be parsed an error is returned. -// -// Valid ranges are: -// - "<1.0.0" -// - "<=1.0.0" -// - ">1.0.0" -// - ">=1.0.0" -// - "1.0.0", "=1.0.0", "==1.0.0" -// - "!1.0.0", "!=1.0.0" -// -// A Range can consist of multiple ranges separated by space: -// Ranges can be linked by logical AND: -// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0" -// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2 -// -// Ranges can also be linked by logical OR: -// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x" -// -// AND has a higher precedence than OR. It's not possible to use brackets. -// -// Ranges can be combined by both AND and OR -// -// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` -func ParseRange(s string) (Range, error) { - parts := splitAndTrim(s) - orParts, err := splitORParts(parts) - if err != nil { - return nil, err - } - expandedParts, err := expandWildcardVersion(orParts) - if err != nil { - return nil, err - } - var orFn Range - for _, p := range expandedParts { - var andFn Range - for _, ap := range p { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - vr, err := buildVersionRange(opStr, vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err) - } - rf := vr.rangeFunc() - - // Set function - if andFn == nil { - andFn = rf - } else { // Combine with existing function - andFn = andFn.AND(rf) - } - } - if orFn == nil { - orFn = andFn - } else { - orFn = orFn.OR(andFn) - } - - } - return orFn, nil -} - -// splitORParts splits the already cleaned parts by '||'. -// Checks for invalid positions of the operator and returns an -// error if found. -func splitORParts(parts []string) ([][]string, error) { - var ORparts [][]string - last := 0 - for i, p := range parts { - if p == "||" { - if i == 0 { - return nil, fmt.Errorf("First element in range is '||'") - } - ORparts = append(ORparts, parts[last:i]) - last = i + 1 - } - } - if last == len(parts) { - return nil, fmt.Errorf("Last element in range is '||'") - } - ORparts = append(ORparts, parts[last:]) - return ORparts, nil -} - -// buildVersionRange takes a slice of 2: operator and version -// and builds a versionRange, otherwise an error. -func buildVersionRange(opStr, vStr string) (*versionRange, error) { - c := parseComparator(opStr) - if c == nil { - return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, "")) - } - v, err := Parse(vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err) - } - - return &versionRange{ - v: v, - c: c, - }, nil - -} - -// inArray checks if a byte is contained in an array of bytes -func inArray(s byte, list []byte) bool { - for _, el := range list { - if el == s { - return true - } - } - return false -} - -// splitAndTrim splits a range string by spaces and cleans whitespaces -func splitAndTrim(s string) (result []string) { - last := 0 - var lastChar byte - excludeFromSplit := []byte{'>', '<', '='} - for i := 0; i < len(s); i++ { - if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) { - if last < i-1 { - result = append(result, s[last:i]) - } - last = i + 1 - } else if s[i] != ' ' { - lastChar = s[i] - } - } - if last < len(s)-1 { - result = append(result, s[last:]) - } - - for i, v := range result { - result[i] = strings.Replace(v, " ", "", -1) - } - - // parts := strings.Split(s, " ") - // for _, x := range parts { - // if s := strings.TrimSpace(x); len(s) != 0 { - // result = append(result, s) - // } - // } - return -} - -// splitComparatorVersion splits the comparator from the version. -// Input must be free of leading or trailing spaces. -func splitComparatorVersion(s string) (string, string, error) { - i := strings.IndexFunc(s, unicode.IsDigit) - if i == -1 { - return "", "", fmt.Errorf("Could not get version from string: %q", s) - } - return strings.TrimSpace(s[0:i]), s[i:], nil -} - -// getWildcardType will return the type of wildcard that the -// passed version contains -func getWildcardType(vStr string) wildcardType { - parts := strings.Split(vStr, ".") - nparts := len(parts) - wildcard := parts[nparts-1] - - possibleWildcardType := wildcardTypefromInt(nparts) - if wildcard == "x" { - return possibleWildcardType - } - - return noneWildcard -} - -// createVersionFromWildcard will convert a wildcard version -// into a regular version, replacing 'x's with '0's, handling -// special cases like '1.x.x' and '1.x' -func createVersionFromWildcard(vStr string) string { - // handle 1.x.x - vStr2 := strings.Replace(vStr, ".x.x", ".x", 1) - vStr2 = strings.Replace(vStr2, ".x", ".0", 1) - parts := strings.Split(vStr2, ".") - - // handle 1.x - if len(parts) == 2 { - return vStr2 + ".0" - } - - return vStr2 -} - -// incrementMajorVersion will increment the major version -// of the passed version -func incrementMajorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[0]) - if err != nil { - return "", err - } - parts[0] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// incrementMajorVersion will increment the minor version -// of the passed version -func incrementMinorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[1]) - if err != nil { - return "", err - } - parts[1] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// expandWildcardVersion will expand wildcards inside versions -// following these rules: -// -// * when dealing with patch wildcards: -// >= 1.2.x will become >= 1.2.0 -// <= 1.2.x will become < 1.3.0 -// > 1.2.x will become >= 1.3.0 -// < 1.2.x will become < 1.2.0 -// != 1.2.x will become < 1.2.0 >= 1.3.0 -// -// * when dealing with minor wildcards: -// >= 1.x will become >= 1.0.0 -// <= 1.x will become < 2.0.0 -// > 1.x will become >= 2.0.0 -// < 1.0 will become < 1.0.0 -// != 1.x will become < 1.0.0 >= 2.0.0 -// -// * when dealing with wildcards without -// version operator: -// 1.2.x will become >= 1.2.0 < 1.3.0 -// 1.x will become >= 1.0.0 < 2.0.0 -func expandWildcardVersion(parts [][]string) ([][]string, error) { - var expandedParts [][]string - for _, p := range parts { - var newParts []string - for _, ap := range p { - if strings.Index(ap, "x") != -1 { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - - versionWildcardType := getWildcardType(vStr) - flatVersion := createVersionFromWildcard(vStr) - - var resultOperator string - var shouldIncrementVersion bool - switch opStr { - case ">": - resultOperator = ">=" - shouldIncrementVersion = true - case ">=": - resultOperator = ">=" - case "<": - resultOperator = "<" - case "<=": - resultOperator = "<" - shouldIncrementVersion = true - case "", "=", "==": - newParts = append(newParts, ">="+flatVersion) - resultOperator = "<" - shouldIncrementVersion = true - case "!=", "!": - newParts = append(newParts, "<"+flatVersion) - resultOperator = ">=" - shouldIncrementVersion = true - } - - var resultVersion string - if shouldIncrementVersion { - switch versionWildcardType { - case patchWildcard: - resultVersion, _ = incrementMinorVersion(flatVersion) - case minorWildcard: - resultVersion, _ = incrementMajorVersion(flatVersion) - } - } else { - resultVersion = flatVersion - } - - ap = resultOperator + resultVersion - } - newParts = append(newParts, ap) - } - expandedParts = append(expandedParts, newParts) - } - - return expandedParts, nil -} - -func parseComparator(s string) comparator { - switch s { - case "==": - fallthrough - case "": - fallthrough - case "=": - return compEQ - case ">": - return compGT - case ">=": - return compGE - case "<": - return compLT - case "<=": - return compLE - case "!": - fallthrough - case "!=": - return compNE - } - - return nil -} - -// MustParseRange is like ParseRange but panics if the range cannot be parsed. -func MustParseRange(s string) Range { - r, err := ParseRange(s) - if err != nil { - panic(`semver: ParseRange(` + s + `): ` + err.Error()) - } - return r -} diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go deleted file mode 100644 index 8ee0842e6a..0000000000 --- a/vendor/github.com/blang/semver/semver.go +++ /dev/null @@ -1,418 +0,0 @@ -package semver - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -const ( - numbers string = "0123456789" - alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" - alphanum = alphas + numbers -) - -// SpecVersion is the latest fully supported spec version of semver -var SpecVersion = Version{ - Major: 2, - Minor: 0, - Patch: 0, -} - -// Version represents a semver compatible version -type Version struct { - Major uint64 - Minor uint64 - Patch uint64 - Pre []PRVersion - Build []string //No Precendence -} - -// Version to string -func (v Version) String() string { - b := make([]byte, 0, 5) - b = strconv.AppendUint(b, v.Major, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Minor, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Patch, 10) - - if len(v.Pre) > 0 { - b = append(b, '-') - b = append(b, v.Pre[0].String()...) - - for _, pre := range v.Pre[1:] { - b = append(b, '.') - b = append(b, pre.String()...) - } - } - - if len(v.Build) > 0 { - b = append(b, '+') - b = append(b, v.Build[0]...) - - for _, build := range v.Build[1:] { - b = append(b, '.') - b = append(b, build...) - } - } - - return string(b) -} - -// Equals checks if v is equal to o. -func (v Version) Equals(o Version) bool { - return (v.Compare(o) == 0) -} - -// EQ checks if v is equal to o. -func (v Version) EQ(o Version) bool { - return (v.Compare(o) == 0) -} - -// NE checks if v is not equal to o. -func (v Version) NE(o Version) bool { - return (v.Compare(o) != 0) -} - -// GT checks if v is greater than o. -func (v Version) GT(o Version) bool { - return (v.Compare(o) == 1) -} - -// GTE checks if v is greater than or equal to o. -func (v Version) GTE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// GE checks if v is greater than or equal to o. -func (v Version) GE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// LT checks if v is less than o. -func (v Version) LT(o Version) bool { - return (v.Compare(o) == -1) -} - -// LTE checks if v is less than or equal to o. -func (v Version) LTE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// LE checks if v is less than or equal to o. -func (v Version) LE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// Compare compares Versions v to o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v Version) Compare(o Version) int { - if v.Major != o.Major { - if v.Major > o.Major { - return 1 - } - return -1 - } - if v.Minor != o.Minor { - if v.Minor > o.Minor { - return 1 - } - return -1 - } - if v.Patch != o.Patch { - if v.Patch > o.Patch { - return 1 - } - return -1 - } - - // Quick comparison if a version has no prerelease versions - if len(v.Pre) == 0 && len(o.Pre) == 0 { - return 0 - } else if len(v.Pre) == 0 && len(o.Pre) > 0 { - return 1 - } else if len(v.Pre) > 0 && len(o.Pre) == 0 { - return -1 - } - - i := 0 - for ; i < len(v.Pre) && i < len(o.Pre); i++ { - if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 { - continue - } else if comp == 1 { - return 1 - } else { - return -1 - } - } - - // If all pr versions are the equal but one has further prversion, this one greater - if i == len(v.Pre) && i == len(o.Pre) { - return 0 - } else if i == len(v.Pre) && i < len(o.Pre) { - return -1 - } else { - return 1 - } - -} - -// Validate validates v and returns error in case -func (v Version) Validate() error { - // Major, Minor, Patch already validated using uint64 - - for _, pre := range v.Pre { - if !pre.IsNum { //Numeric prerelease versions already uint64 - if len(pre.VersionStr) == 0 { - return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr) - } - if !containsOnly(pre.VersionStr, alphanum) { - return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr) - } - } - } - - for _, build := range v.Build { - if len(build) == 0 { - return fmt.Errorf("Build meta data can not be empty %q", build) - } - if !containsOnly(build, alphanum) { - return fmt.Errorf("Invalid character(s) found in build meta data %q", build) - } - } - - return nil -} - -// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error -func New(s string) (vp *Version, err error) { - v, err := Parse(s) - vp = &v - return -} - -// Make is an alias for Parse, parses version string and returns a validated Version or error -func Make(s string) (Version, error) { - return Parse(s) -} - -// ParseTolerant allows for certain version specifications that do not strictly adhere to semver -// specs to be parsed by this library. It does so by normalizing versions before passing them to -// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions -// with only major and minor components specified -func ParseTolerant(s string) (Version, error) { - s = strings.TrimSpace(s) - s = strings.TrimPrefix(s, "v") - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) < 3 { - if strings.ContainsAny(parts[len(parts)-1], "+-") { - return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data") - } - for len(parts) < 3 { - parts = append(parts, "0") - } - s = strings.Join(parts, ".") - } - - return Parse(s) -} - -// Parse parses version string and returns a validated Version or error -func Parse(s string) (Version, error) { - if len(s) == 0 { - return Version{}, errors.New("Version string empty") - } - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) != 3 { - return Version{}, errors.New("No Major.Minor.Patch elements found") - } - - // Major - if !containsOnly(parts[0], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0]) - } - if hasLeadingZeroes(parts[0]) { - return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0]) - } - major, err := strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return Version{}, err - } - - // Minor - if !containsOnly(parts[1], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1]) - } - if hasLeadingZeroes(parts[1]) { - return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1]) - } - minor, err := strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return Version{}, err - } - - v := Version{} - v.Major = major - v.Minor = minor - - var build, prerelease []string - patchStr := parts[2] - - if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 { - build = strings.Split(patchStr[buildIndex+1:], ".") - patchStr = patchStr[:buildIndex] - } - - if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 { - prerelease = strings.Split(patchStr[preIndex+1:], ".") - patchStr = patchStr[:preIndex] - } - - if !containsOnly(patchStr, numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr) - } - if hasLeadingZeroes(patchStr) { - return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr) - } - patch, err := strconv.ParseUint(patchStr, 10, 64) - if err != nil { - return Version{}, err - } - - v.Patch = patch - - // Prerelease - for _, prstr := range prerelease { - parsedPR, err := NewPRVersion(prstr) - if err != nil { - return Version{}, err - } - v.Pre = append(v.Pre, parsedPR) - } - - // Build meta data - for _, str := range build { - if len(str) == 0 { - return Version{}, errors.New("Build meta data is empty") - } - if !containsOnly(str, alphanum) { - return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str) - } - v.Build = append(v.Build, str) - } - - return v, nil -} - -// MustParse is like Parse but panics if the version cannot be parsed. -func MustParse(s string) Version { - v, err := Parse(s) - if err != nil { - panic(`semver: Parse(` + s + `): ` + err.Error()) - } - return v -} - -// PRVersion represents a PreRelease Version -type PRVersion struct { - VersionStr string - VersionNum uint64 - IsNum bool -} - -// NewPRVersion creates a new valid prerelease version -func NewPRVersion(s string) (PRVersion, error) { - if len(s) == 0 { - return PRVersion{}, errors.New("Prerelease is empty") - } - v := PRVersion{} - if containsOnly(s, numbers) { - if hasLeadingZeroes(s) { - return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s) - } - num, err := strconv.ParseUint(s, 10, 64) - - // Might never be hit, but just in case - if err != nil { - return PRVersion{}, err - } - v.VersionNum = num - v.IsNum = true - } else if containsOnly(s, alphanum) { - v.VersionStr = s - v.IsNum = false - } else { - return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s) - } - return v, nil -} - -// IsNumeric checks if prerelease-version is numeric -func (v PRVersion) IsNumeric() bool { - return v.IsNum -} - -// Compare compares two PreRelease Versions v and o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v PRVersion) Compare(o PRVersion) int { - if v.IsNum && !o.IsNum { - return -1 - } else if !v.IsNum && o.IsNum { - return 1 - } else if v.IsNum && o.IsNum { - if v.VersionNum == o.VersionNum { - return 0 - } else if v.VersionNum > o.VersionNum { - return 1 - } else { - return -1 - } - } else { // both are Alphas - if v.VersionStr == o.VersionStr { - return 0 - } else if v.VersionStr > o.VersionStr { - return 1 - } else { - return -1 - } - } -} - -// PreRelease version to string -func (v PRVersion) String() string { - if v.IsNum { - return strconv.FormatUint(v.VersionNum, 10) - } - return v.VersionStr -} - -func containsOnly(s string, set string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(set, r) - }) == -1 -} - -func hasLeadingZeroes(s string) bool { - return len(s) > 1 && s[0] == '0' -} - -// NewBuildVersion creates a new valid build version -func NewBuildVersion(s string) (string, error) { - if len(s) == 0 { - return "", errors.New("Buildversion is empty") - } - if !containsOnly(s, alphanum) { - return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s) - } - return s, nil -} diff --git a/vendor/github.com/blang/semver/sort.go b/vendor/github.com/blang/semver/sort.go deleted file mode 100644 index e18f880826..0000000000 --- a/vendor/github.com/blang/semver/sort.go +++ /dev/null @@ -1,28 +0,0 @@ -package semver - -import ( - "sort" -) - -// Versions represents multiple versions. -type Versions []Version - -// Len returns length of version collection -func (s Versions) Len() int { - return len(s) -} - -// Swap swaps two versions inside the collection by its indices -func (s Versions) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Less checks if version at index i is less than version at index j -func (s Versions) Less(i, j int) bool { - return s[i].LT(s[j]) -} - -// Sort sorts a slice of versions -func Sort(versions []Version) { - sort.Sort(Versions(versions)) -} diff --git a/vendor/github.com/blang/semver/sql.go b/vendor/github.com/blang/semver/sql.go deleted file mode 100644 index eb4d802666..0000000000 --- a/vendor/github.com/blang/semver/sql.go +++ /dev/null @@ -1,30 +0,0 @@ -package semver - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements the database/sql.Scanner interface. -func (v *Version) Scan(src interface{}) (err error) { - var str string - switch src := src.(type) { - case string: - str = src - case []byte: - str = string(src) - default: - return fmt.Errorf("Version.Scan: cannot convert %T to string.", src) - } - - if t, err := Parse(str); err == nil { - *v = t - } - - return -} - -// Value implements the database/sql/driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} diff --git a/vendor/github.com/cenkalti/backoff/v4/.gitignore b/vendor/github.com/cenkalti/backoff/v4/.gitignore new file mode 100644 index 0000000000..50d95c548b --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/.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 + +# IDEs +.idea/ diff --git a/vendor/github.com/cenkalti/backoff/v4/.travis.yml b/vendor/github.com/cenkalti/backoff/v4/.travis.yml new file mode 100644 index 0000000000..c79105c2fb --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.13 + - 1.x + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/cenkalti/backoff/v4/LICENSE b/vendor/github.com/cenkalti/backoff/v4/LICENSE new file mode 100644 index 0000000000..89b8179965 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +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/cenkalti/backoff/v4/README.md b/vendor/github.com/cenkalti/backoff/v4/README.md new file mode 100644 index 0000000000..16abdfc084 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/README.md @@ -0,0 +1,32 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +Import path is `github.com/cenkalti/backoff/v4`. Please note the version part at the end. + +Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation. + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4 +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png +[travis]: https://travis-ci.org/cenkalti/backoff +[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master +[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master +[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master + +[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[advanced example]: https://pkg.go.dev/github.com/cenkalti/backoff/v4?tab=doc#pkg-examples diff --git a/vendor/github.com/cenkalti/backoff/v4/backoff.go b/vendor/github.com/cenkalti/backoff/v4/backoff.go new file mode 100644 index 0000000000..3676ee405d --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // or backoff. Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/v4/context.go b/vendor/github.com/cenkalti/backoff/v4/context.go new file mode 100644 index 0000000000..48482330eb --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/context.go @@ -0,0 +1,62 @@ +package backoff + +import ( + "context" + "time" +) + +// BackOffContext is a backoff policy that stops retrying after the context +// is canceled. +type BackOffContext interface { // nolint: golint + BackOff + Context() context.Context +} + +type backOffContext struct { + BackOff + ctx context.Context +} + +// WithContext returns a BackOffContext with context ctx +// +// ctx must not be nil +func WithContext(b BackOff, ctx context.Context) BackOffContext { // nolint: golint + if ctx == nil { + panic("nil context") + } + + if b, ok := b.(*backOffContext); ok { + return &backOffContext{ + BackOff: b.BackOff, + ctx: ctx, + } + } + + return &backOffContext{ + BackOff: b, + ctx: ctx, + } +} + +func getContext(b BackOff) context.Context { + if cb, ok := b.(BackOffContext); ok { + return cb.Context() + } + if tb, ok := b.(*backOffTries); ok { + return getContext(tb.delegate) + } + return context.Background() +} + +func (b *backOffContext) Context() context.Context { + return b.ctx +} + +func (b *backOffContext) NextBackOff() time.Duration { + select { + case <-b.ctx.Done(): + return Stop + default: + return b.BackOff.NextBackOff() + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/exponential.go b/vendor/github.com/cenkalti/backoff/v4/exponential.go new file mode 100644 index 0000000000..2c56c1e718 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/exponential.go @@ -0,0 +1,161 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. + +The elapsed time can be reset by calling Reset(). + +Example: Given the following default arguments, for 10 tries the sequence will be, +and assuming we go over the MaxElapsedTime on the 10th try: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff returns Stop. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Stop time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + b := &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Stop: Stop, + Clock: SystemClock, + } + b.Reset() + return b +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +// Reset must be called before using b. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next backoff interval using the formula: +// Randomized interval = RetryInterval * (1 ± RandomizationFactor) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + elapsed := b.GetElapsedTime() + next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) + b.incrementCurrentInterval() + if b.MaxElapsedTime != 0 && elapsed+next > b.MaxElapsedTime { + return b.Stop + } + return next +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). It is +// safe to call even while the backoff policy is used by a running +// ticker. +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + if randomizationFactor == 0 { + return currentInterval // make sure no randomness is used when randomizationFactor is 0. + } + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/v4/retry.go b/vendor/github.com/cenkalti/backoff/v4/retry.go new file mode 100644 index 0000000000..1ce2507ebc --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/retry.go @@ -0,0 +1,112 @@ +package backoff + +import ( + "errors" + "time" +) + +// An Operation is executing by Retry() or RetryNotify(). +// The operation will be retried using a backoff policy if it returns an error. +type Operation func() error + +// Notify is a notify-on-error function. It receives an operation error and +// backoff delay if the operation failed (with an error). +// +// NOTE that if the backoff policy stated to stop retrying, +// the notify function isn't called. +type Notify func(error, time.Duration) + +// Retry the operation o until it does not return error or BackOff stops. +// o is guaranteed to be run at least once. +// +// If o returns a *PermanentError, the operation is not retried, and the +// wrapped error is returned. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +func Retry(o Operation, b BackOff) error { + return RetryNotify(o, b, nil) +} + +// RetryNotify calls notify function with the error and wait duration +// for each failed attempt before sleep. +func RetryNotify(operation Operation, b BackOff, notify Notify) error { + return RetryNotifyWithTimer(operation, b, notify, nil) +} + +// RetryNotifyWithTimer calls notify function with the error and wait duration using the given Timer +// for each failed attempt before sleep. +// A default timer that uses system timer is used when nil is passed. +func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error { + var err error + var next time.Duration + if t == nil { + t = &defaultTimer{} + } + + defer func() { + t.Stop() + }() + + ctx := getContext(b) + + b.Reset() + for { + if err = operation(); err == nil { + return nil + } + + var permanent *PermanentError + if errors.As(err, &permanent) { + return permanent.Err + } + + if next = b.NextBackOff(); next == Stop { + if cerr := ctx.Err(); cerr != nil { + return cerr + } + + return err + } + + if notify != nil { + notify(err, next) + } + + t.Start(next) + + select { + case <-ctx.Done(): + return ctx.Err() + case <-t.C(): + } + } +} + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +func (e *PermanentError) Unwrap() error { + return e.Err +} + +func (e *PermanentError) Is(target error) bool { + _, ok := target.(*PermanentError) + return ok +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) error { + if err == nil { + return nil + } + return &PermanentError{ + Err: err, + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/ticker.go b/vendor/github.com/cenkalti/backoff/v4/ticker.go new file mode 100644 index 0000000000..df9d68bce5 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/ticker.go @@ -0,0 +1,97 @@ +package backoff + +import ( + "context" + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOff + ctx context.Context + timer Timer + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + return NewTickerWithTimer(b, &defaultTimer{}) +} + +// NewTickerWithTimer returns a new Ticker with a custom timer. +// A default timer that uses system timer is used when nil is passed. +func NewTickerWithTimer(b BackOff, timer Timer) *Ticker { + if timer == nil { + timer = &defaultTimer{} + } + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: b, + ctx: getContext(b), + timer: timer, + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + case <-t.ctx.Done(): + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + t.timer.Start(next) + return t.timer.C() +} diff --git a/vendor/github.com/cenkalti/backoff/v4/timer.go b/vendor/github.com/cenkalti/backoff/v4/timer.go new file mode 100644 index 0000000000..8120d0213c --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/timer.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +type Timer interface { + Start(duration time.Duration) + Stop() + C() <-chan time.Time +} + +// defaultTimer implements Timer interface using time.Timer +type defaultTimer struct { + timer *time.Timer +} + +// C returns the timers channel which receives the current time when the timer fires. +func (t *defaultTimer) C() <-chan time.Time { + return t.timer.C +} + +// Start starts the timer to fire after the given duration +func (t *defaultTimer) Start(duration time.Duration) { + if t.timer == nil { + t.timer = time.NewTimer(duration) + } else { + t.timer.Reset(duration) + } +} + +// Stop is called when the timer is not used anymore and resources may be freed. +func (t *defaultTimer) Stop() { + if t.timer != nil { + t.timer.Stop() + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/tries.go b/vendor/github.com/cenkalti/backoff/v4/tries.go new file mode 100644 index 0000000000..28d58ca37c --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/tries.go @@ -0,0 +1,38 @@ +package backoff + +import "time" + +/* +WithMaxRetries creates a wrapper around another BackOff, which will +return Stop if NextBackOff() has been called too many times since +the last time Reset() was called + +Note: Implementation is not thread-safe. +*/ +func WithMaxRetries(b BackOff, max uint64) BackOff { + return &backOffTries{delegate: b, maxTries: max} +} + +type backOffTries struct { + delegate BackOff + maxTries uint64 + numTries uint64 +} + +func (b *backOffTries) NextBackOff() time.Duration { + if b.maxTries == 0 { + return Stop + } + if b.maxTries > 0 { + if b.maxTries <= b.numTries { + return Stop + } + b.numTries++ + } + return b.delegate.NextBackOff() +} + +func (b *backOffTries) Reset() { + b.numTries = 0 + b.delegate.Reset() +} diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md index 792b4a60b3..8bf0e5b781 100644 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ b/vendor/github.com/cespare/xxhash/v2/README.md @@ -3,8 +3,7 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2) [![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml) -xxhash is a Go implementation of the 64-bit -[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a +xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a high-quality hashing algorithm that is much faster than anything in the Go standard library. @@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error) func (*Digest) Sum64() uint64 ``` -This implementation provides a fast pure-Go implementation and an even faster -assembly implementation for amd64. +The package is written with optimized pure Go and also contains even faster +assembly implementations for amd64 and arm64. If desired, the `purego` build tag +opts into using the Go code even on those architectures. + +[xxHash]: http://cyan4973.github.io/xxHash/ ## Compatibility @@ -45,19 +47,20 @@ I recommend using the latest release of Go. Here are some quick benchmarks comparing the pure-Go and assembly implementations of Sum64. -| input size | purego | asm | -| --- | --- | --- | -| 5 B | 979.66 MB/s | 1291.17 MB/s | -| 100 B | 7475.26 MB/s | 7973.40 MB/s | -| 4 KB | 17573.46 MB/s | 17602.65 MB/s | -| 10 MB | 17131.46 MB/s | 17142.16 MB/s | +| input size | purego | asm | +| ---------- | --------- | --------- | +| 4 B | 1.3 GB/s | 1.2 GB/s | +| 16 B | 2.9 GB/s | 3.5 GB/s | +| 100 B | 6.9 GB/s | 8.1 GB/s | +| 4 KB | 11.7 GB/s | 16.7 GB/s | +| 10 MB | 12.0 GB/s | 17.3 GB/s | -These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using -the following commands under Go 1.11.2: +These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C +CPU using the following commands under Go 1.19.2: ``` -$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes' -$ go test -benchtime 10s -bench '/xxhash,direct,bytes' +benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$') +benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') ``` ## Projects using this package diff --git a/vendor/github.com/cespare/xxhash/v2/testall.sh b/vendor/github.com/cespare/xxhash/v2/testall.sh new file mode 100644 index 0000000000..94b9c44398 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/testall.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -eu -o pipefail + +# Small convenience script for running the tests with various combinations of +# arch/tags. This assumes we're running on amd64 and have qemu available. + +go test ./... +go test -tags purego ./... +GOARCH=arm64 go test +GOARCH=arm64 go test -tags purego diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go index 15c835d541..a9e0d45c9d 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go @@ -16,19 +16,11 @@ const ( prime5 uint64 = 2870177450012600261 ) -// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where -// possible in the Go code is worth a small (but measurable) performance boost -// by avoiding some MOVQs. Vars are needed for the asm and also are useful for -// convenience in the Go code in a few places where we need to intentionally -// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the -// result overflows a uint64). -var ( - prime1v = prime1 - prime2v = prime2 - prime3v = prime3 - prime4v = prime4 - prime5v = prime5 -) +// Store the primes in an array as well. +// +// The consts are used when possible in Go code to avoid MOVs but we need a +// contiguous array of the assembly code. +var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} // Digest implements hash.Hash64. type Digest struct { @@ -50,10 +42,10 @@ func New() *Digest { // Reset clears the Digest's state so that it can be reused. func (d *Digest) Reset() { - d.v1 = prime1v + prime2 + d.v1 = primes[0] + prime2 d.v2 = prime2 d.v3 = 0 - d.v4 = -prime1v + d.v4 = -primes[0] d.total = 0 d.n = 0 } @@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) { n = len(b) d.total += uint64(n) + memleft := d.mem[d.n&(len(d.mem)-1):] + if d.n+n < 32 { // This new data doesn't even fill the current block. - copy(d.mem[d.n:], b) + copy(memleft, b) d.n += n return } if d.n > 0 { // Finish off the partial block. - copy(d.mem[d.n:], b) + c := copy(memleft, b) d.v1 = round(d.v1, u64(d.mem[0:8])) d.v2 = round(d.v2, u64(d.mem[8:16])) d.v3 = round(d.v3, u64(d.mem[16:24])) d.v4 = round(d.v4, u64(d.mem[24:32])) - b = b[32-d.n:] + b = b[c:] d.n = 0 } @@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 { h += d.total - i, end := 0, d.n - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(d.mem[i:i+8])) + b := d.mem[:d.n&(len(d.mem)-1)] + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(d.mem[i:i+4])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for i < end { - h ^= uint64(d.mem[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 - i++ } h ^= h >> 33 diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go deleted file mode 100644 index ad14b807f4..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !appengine -// +build gc -// +build !purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b. -// -//go:noescape -func Sum64(b []byte) uint64 - -//go:noescape -func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s index be8db5bf79..3e8b132579 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s @@ -1,215 +1,209 @@ +//go:build !appengine && gc && !purego // +build !appengine // +build gc // +build !purego #include "textflag.h" -// Register allocation: -// AX h -// SI pointer to advance through b -// DX n -// BX loop end -// R8 v1, k1 -// R9 v2 -// R10 v3 -// R11 v4 -// R12 tmp -// R13 prime1v -// R14 prime2v -// DI prime4v - -// round reads from and advances the buffer pointer in SI. -// It assumes that R13 has prime1v and R14 has prime2v. -#define round(r) \ - 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 DI has prime4v. -#define mergeRound(acc, val) \ - IMULQ R14, val \ - ROLQ $31, val \ - IMULQ R13, val \ - XORQ val, acc \ - IMULQ R13, acc \ - ADDQ DI, acc +// Registers: +#define h AX +#define d AX +#define p SI // pointer to advance through b +#define n DX +#define end BX // loop end +#define v1 R8 +#define v2 R9 +#define v3 R10 +#define v4 R11 +#define x R12 +#define prime1 R13 +#define prime2 R14 +#define prime4 DI + +#define round(acc, x) \ + IMULQ prime2, x \ + ADDQ x, acc \ + ROLQ $31, acc \ + IMULQ prime1, acc + +// round0 performs the operation x = round(0, x). +#define round0(x) \ + IMULQ prime2, x \ + ROLQ $31, x \ + IMULQ prime1, x + +// mergeRound applies a merge round on the two registers acc and x. +// It assumes that prime1, prime2, and prime4 have been loaded. +#define mergeRound(acc, x) \ + round0(x) \ + XORQ x, acc \ + IMULQ prime1, acc \ + ADDQ prime4, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that there is at least one block +// to process. +#define blockLoop() \ +loop: \ + MOVQ +0(p), x \ + round(v1, x) \ + MOVQ +8(p), x \ + round(v2, x) \ + MOVQ +16(p), x \ + round(v3, x) \ + MOVQ +24(p), x \ + round(v4, x) \ + ADDQ $32, p \ + CMPQ p, end \ + JLE loop // func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT, $0-32 +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 // Load fixed primes. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 - MOVQ ·prime4v(SB), DI + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 + MOVQ ·primes+24(SB), prime4 // Load slice. - MOVQ b_base+0(FP), SI - MOVQ b_len+8(FP), DX - LEAQ (SI)(DX*1), BX + MOVQ b_base+0(FP), p + MOVQ b_len+8(FP), n + LEAQ (p)(n*1), end // The first loop limit will be len(b)-32. - SUBQ $32, BX + SUBQ $32, end // Check whether we have at least one block. - CMPQ DX, $32 + CMPQ n, $32 JLT noBlocks // Set up initial state (v1, v2, v3, v4). - MOVQ R13, R8 - ADDQ R14, R8 - MOVQ R14, R9 - XORQ R10, R10 - XORQ R11, R11 - SUBQ R13, R11 - - // Loop until SI > BX. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop - - MOVQ R8, AX - ROLQ $1, AX - MOVQ R9, R12 - ROLQ $7, R12 - ADDQ R12, AX - MOVQ R10, R12 - ROLQ $12, R12 - ADDQ R12, AX - MOVQ R11, R12 - ROLQ $18, R12 - ADDQ R12, AX - - mergeRound(AX, R8) - mergeRound(AX, R9) - mergeRound(AX, R10) - mergeRound(AX, R11) + MOVQ prime1, v1 + ADDQ prime2, v1 + MOVQ prime2, v2 + XORQ v3, v3 + XORQ v4, v4 + SUBQ prime1, v4 + + blockLoop() + + MOVQ v1, h + ROLQ $1, h + MOVQ v2, x + ROLQ $7, x + ADDQ x, h + MOVQ v3, x + ROLQ $12, x + ADDQ x, h + MOVQ v4, x + ROLQ $18, x + ADDQ x, h + + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) JMP afterBlocks noBlocks: - MOVQ ·prime5v(SB), AX + MOVQ ·primes+32(SB), h afterBlocks: - ADDQ DX, AX - - // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8. - ADDQ $24, BX - - CMPQ SI, BX - JG fourByte - -wordLoop: - // Calculate k1. - MOVQ (SI), R8 - ADDQ $8, SI - IMULQ R14, R8 - ROLQ $31, R8 - IMULQ R13, R8 - - XORQ R8, AX - ROLQ $27, AX - IMULQ R13, AX - ADDQ DI, AX - - CMPQ SI, BX - JLE wordLoop - -fourByte: - ADDQ $4, BX - CMPQ SI, BX - JG singles - - MOVL (SI), R8 - ADDQ $4, SI - IMULQ R13, R8 - XORQ R8, AX - - ROLQ $23, AX - IMULQ R14, AX - ADDQ ·prime3v(SB), AX - -singles: - ADDQ $4, BX - CMPQ SI, BX + ADDQ n, h + + ADDQ $24, end + CMPQ p, end + JG try4 + +loop8: + MOVQ (p), x + ADDQ $8, p + round0(x) + XORQ x, h + ROLQ $27, h + IMULQ prime1, h + ADDQ prime4, h + + CMPQ p, end + JLE loop8 + +try4: + ADDQ $4, end + CMPQ p, end + JG try1 + + MOVL (p), x + ADDQ $4, p + IMULQ prime1, x + XORQ x, h + + ROLQ $23, h + IMULQ prime2, h + ADDQ ·primes+16(SB), h + +try1: + ADDQ $4, end + CMPQ p, end JGE finalize -singlesLoop: - MOVBQZX (SI), R12 - ADDQ $1, SI - IMULQ ·prime5v(SB), R12 - XORQ R12, AX +loop1: + MOVBQZX (p), x + ADDQ $1, p + IMULQ ·primes+32(SB), x + XORQ x, h + ROLQ $11, h + IMULQ prime1, h - ROLQ $11, AX - IMULQ R13, AX - - CMPQ SI, BX - JL singlesLoop + CMPQ p, end + JL loop1 finalize: - MOVQ AX, R12 - SHRQ $33, R12 - XORQ R12, AX - IMULQ R14, AX - MOVQ AX, R12 - SHRQ $29, R12 - XORQ R12, AX - IMULQ ·prime3v(SB), AX - MOVQ AX, R12 - SHRQ $32, R12 - XORQ R12, AX - - MOVQ AX, ret+24(FP) + MOVQ h, x + SHRQ $33, x + XORQ x, h + IMULQ prime2, h + MOVQ h, x + SHRQ $29, x + XORQ x, h + IMULQ ·primes+16(SB), h + MOVQ h, x + SHRQ $32, x + XORQ x, h + + MOVQ h, ret+24(FP) RET -// writeBlocks uses the same registers as above except that it uses AX to store -// the d pointer. - // func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT, $0-40 +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 // Load fixed primes needed for round. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 // Load slice. - MOVQ b_base+8(FP), SI - MOVQ b_len+16(FP), DX - LEAQ (SI)(DX*1), BX - SUBQ $32, BX + MOVQ b_base+8(FP), p + MOVQ b_len+16(FP), n + LEAQ (p)(n*1), end + SUBQ $32, end // Load vN from d. - MOVQ d+0(FP), AX - MOVQ 0(AX), R8 // v1 - MOVQ 8(AX), R9 // v2 - MOVQ 16(AX), R10 // v3 - MOVQ 24(AX), R11 // v4 + MOVQ s+0(FP), d + MOVQ 0(d), v1 + MOVQ 8(d), v2 + MOVQ 16(d), v3 + MOVQ 24(d), v4 // We don't need to check the loop condition here; this function is // always called with at least one block of data to process. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop + blockLoop() // Copy vN back to d. - MOVQ R8, 0(AX) - MOVQ R9, 8(AX) - MOVQ R10, 16(AX) - MOVQ R11, 24(AX) - - // The number of bytes written is SI minus the old base pointer. - SUBQ b_base+8(FP), SI - MOVQ SI, ret+32(FP) + MOVQ v1, 0(d) + MOVQ v2, 8(d) + MOVQ v3, 16(d) + MOVQ v4, 24(d) + + // The number of bytes written is p minus the old base pointer. + SUBQ b_base+8(FP), p + MOVQ p, ret+32(FP) RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s new file mode 100644 index 0000000000..7e3145a221 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s @@ -0,0 +1,183 @@ +//go:build !appengine && gc && !purego +// +build !appengine +// +build gc +// +build !purego + +#include "textflag.h" + +// Registers: +#define digest R1 +#define h R2 // return value +#define p R3 // input pointer +#define n R4 // input length +#define nblocks R5 // n / 32 +#define prime1 R7 +#define prime2 R8 +#define prime3 R9 +#define prime4 R10 +#define prime5 R11 +#define v1 R12 +#define v2 R13 +#define v3 R14 +#define v4 R15 +#define x1 R20 +#define x2 R21 +#define x3 R22 +#define x4 R23 + +#define round(acc, x) \ + MADD prime2, acc, x, acc \ + ROR $64-31, acc \ + MUL prime1, acc + +// round0 performs the operation x = round(0, x). +#define round0(x) \ + MUL prime2, x \ + ROR $64-31, x \ + MUL prime1, x + +#define mergeRound(acc, x) \ + round0(x) \ + EOR x, acc \ + MADD acc, prime4, prime1, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that n >= 32. +#define blockLoop() \ + LSR $5, n, nblocks \ + PCALIGN $16 \ + loop: \ + LDP.P 16(p), (x1, x2) \ + LDP.P 16(p), (x3, x4) \ + round(v1, x1) \ + round(v2, x2) \ + round(v3, x3) \ + round(v4, x4) \ + SUB $1, nblocks \ + CBNZ nblocks, loop + +// func Sum64(b []byte) uint64 +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 + LDP b_base+0(FP), (p, n) + + LDP ·primes+0(SB), (prime1, prime2) + LDP ·primes+16(SB), (prime3, prime4) + MOVD ·primes+32(SB), prime5 + + CMP $32, n + CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 } + BLT afterLoop + + ADD prime1, prime2, v1 + MOVD prime2, v2 + MOVD $0, v3 + NEG prime1, v4 + + blockLoop() + + ROR $64-1, v1, x1 + ROR $64-7, v2, x2 + ADD x1, x2 + ROR $64-12, v3, x3 + ROR $64-18, v4, x4 + ADD x3, x4 + ADD x2, x4, h + + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) + +afterLoop: + ADD n, h + + TBZ $4, n, try8 + LDP.P 16(p), (x1, x2) + + round0(x1) + + // NOTE: here and below, sequencing the EOR after the ROR (using a + // rotated register) is worth a small but measurable speedup for small + // inputs. + ROR $64-27, h + EOR x1 @> 64-27, h, h + MADD h, prime4, prime1, h + + round0(x2) + ROR $64-27, h + EOR x2 @> 64-27, h, h + MADD h, prime4, prime1, h + +try8: + TBZ $3, n, try4 + MOVD.P 8(p), x1 + + round0(x1) + ROR $64-27, h + EOR x1 @> 64-27, h, h + MADD h, prime4, prime1, h + +try4: + TBZ $2, n, try2 + MOVWU.P 4(p), x2 + + MUL prime1, x2 + ROR $64-23, h + EOR x2 @> 64-23, h, h + MADD h, prime3, prime2, h + +try2: + TBZ $1, n, try1 + MOVHU.P 2(p), x3 + AND $255, x3, x1 + LSR $8, x3, x2 + + MUL prime5, x1 + ROR $64-11, h + EOR x1 @> 64-11, h, h + MUL prime1, h + + MUL prime5, x2 + ROR $64-11, h + EOR x2 @> 64-11, h, h + MUL prime1, h + +try1: + TBZ $0, n, finalize + MOVBU (p), x4 + + MUL prime5, x4 + ROR $64-11, h + EOR x4 @> 64-11, h, h + MUL prime1, h + +finalize: + EOR h >> 33, h + MUL prime2, h + EOR h >> 29, h + MUL prime3, h + EOR h >> 32, h + + MOVD h, ret+24(FP) + RET + +// func writeBlocks(d *Digest, b []byte) int +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 + LDP ·primes+0(SB), (prime1, prime2) + + // Load state. Assume v[1-4] are stored contiguously. + MOVD d+0(FP), digest + LDP 0(digest), (v1, v2) + LDP 16(digest), (v3, v4) + + LDP b_base+8(FP), (p, n) + + blockLoop() + + // Store updated state. + STP (v1, v2), 0(digest) + STP (v3, v4), 16(digest) + + BIC $31, n + MOVD n, ret+32(FP) + RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go new file mode 100644 index 0000000000..9216e0a40c --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go @@ -0,0 +1,15 @@ +//go:build (amd64 || arm64) && !appengine && gc && !purego +// +build amd64 arm64 +// +build !appengine +// +build gc +// +build !purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +// +//go:noescape +func Sum64(b []byte) uint64 + +//go:noescape +func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go index 4a5a821603..26df13bba4 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go @@ -1,4 +1,5 @@ -// +build !amd64 appengine !gc purego +//go:build (!amd64 && !arm64) || appengine || !gc || purego +// +build !amd64,!arm64 appengine !gc purego package xxhash @@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 { var h uint64 if n >= 32 { - v1 := prime1v + prime2 + v1 := primes[0] + prime2 v2 := prime2 v3 := uint64(0) - v4 := -prime1v + v4 := -primes[0] for len(b) >= 32 { v1 = round(v1, u64(b[0:8:len(b)])) v2 = round(v2, u64(b[8:16:len(b)])) @@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 { h += uint64(n) - i, end := 0, len(b) - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(b[i:i+8:len(b)])) + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(b[i:i+4:len(b)])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for ; i < end; i++ { - h ^= uint64(b[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go index fc9bea7a31..e86f1b5fd8 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine // This file contains the safe implementations of otherwise unsafe-using code. diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go index 376e0ca2e4..1c1638fd88 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go @@ -1,3 +1,4 @@ +//go:build !appengine // +build !appengine // This file encapsulates usage of unsafe. @@ -11,7 +12,7 @@ import ( // In the future it's possible that compiler optimizations will make these // XxxString functions unnecessary by realizing that calls such as -// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205. +// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205. // If that happens, even if we keep these functions they can be replaced with // the trivial safe code. diff --git a/vendor/github.com/chai2010/gettext-go/.travis.yml b/vendor/github.com/chai2010/gettext-go/.travis.yml new file mode 100644 index 0000000000..4eac3982bc --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/.travis.yml @@ -0,0 +1,5 @@ +language: go + +go: + - "1.14" + - tip diff --git a/vendor/github.com/chai2010/gettext-go/README.md b/vendor/github.com/chai2010/gettext-go/README.md new file mode 100644 index 0000000000..9381bd1522 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/README.md @@ -0,0 +1,191 @@ +- *赞助 BTC: 1Cbd6oGAUUyBi7X7MaR4np4nTmQZXVgkCW* +- *赞助 ETH: 0x623A3C3a72186A6336C79b18Ac1eD36e1c71A8a6* +- *Go语言付费QQ群: 1055927514* + +---- + +# gettext-go: GNU gettext for Go ([Imported By Kubernetes](https://pkg.go.dev/github.com/chai2010/gettext-go@v0.1.0/gettext?tab=importedby)) + +- PkgDoc: [http://godoc.org/github.com/chai2010/gettext-go](http://godoc.org/github.com/chai2010/gettext-go) +- PkgDoc: [http://pkg.go.dev/github.com/chai2010/gettext-go](http://pkg.go.dev/github.com/chai2010/gettext-go) + +## Install + +1. `go get github.com/chai2010/gettext-go` +2. `go run hello.go` + +The godoc.org or go.dev has more information. + +## Examples + +```Go +package main + +import ( + "fmt" + + "github.com/chai2010/gettext-go" +) + +func main() { + gettext := gettext.New("hello", "./examples/locale").SetLanguage("zh_CN") + fmt.Println(gettext.Gettext("Hello, world!")) + + // Output: 你好, 世界! +} +``` + +```Go +package main + +import ( + "fmt" + + "github.com/chai2010/gettext-go" +) + +func main() { + gettext.SetLanguage("zh_CN") + gettext.BindLocale(gettext.New("hello", "locale")) + + // gettext.BindLocale("hello", "locale") // from locale dir + // gettext.BindLocale("hello", "locale.zip") // from locale zip file + // gettext.BindLocale("hello", "locale.zip", zipData) // from embedded zip data + + // translate source text + fmt.Println(gettext.Gettext("Hello, world!")) + // Output: 你好, 世界! + + // if no msgctxt in PO file (only msgid and msgstr), + // specify context as "" by + fmt.Println(gettext.PGettext("", "Hello, world!")) + // Output: 你好, 世界! + + // translate resource + fmt.Println(string(gettext.Getdata("poems.txt")))) + // Output: ... +} +``` + +Go file: [hello.go](https://github.com/chai2010/gettext-go/blob/master/examples/hello.go); PO file: [hello.po](https://github.com/chai2010/gettext-go/blob/master/examples/locale/default/LC_MESSAGES/hello.po); + +---- + +## API Changes (v0.1.0 vs v1.0.0) + +### Renamed package path + +| v0.1.0 (old) | v1.0.0 (new) | +| ----------------------------------------------- | --------------------------------------- | +| `github.com/chai2010/gettext-go/gettext` | `github.com/chai2010/gettext-go` | +| `github.com/chai2010/gettext-go/gettext/po` | `github.com/chai2010/gettext-go/po` | +| `github.com/chai2010/gettext-go/gettext/mo` | `github.com/chai2010/gettext-go/mo` | +| `github.com/chai2010/gettext-go/gettext/plural` | `github.com/chai2010/gettext-go/plural` | + +### Renamed functions + +| v0.1.0 (old) | v1.0.0 (new) | +| ---------------------------------- | --------------------------- | +| `gettext-go/gettext.*` | `gettext-go.*` | +| `gettext-go/gettext.DefaultLocal` | `gettext-go.DefaultLanguage`| +| `gettext-go/gettext.BindTextdomain`| `gettext-go.BindLocale` | +| `gettext-go/gettext.Textdomain` | `gettext-go.SetDomain` | +| `gettext-go/gettext.SetLocale` | `gettext-go.SetLanguage` | +| `gettext-go/gettext/po.Load` | `gettext-go/po.LoadFile` | +| `gettext-go/gettext/po.LoadData` | `gettext-go/po.Load` | +| `gettext-go/gettext/mo.Load` | `gettext-go/mo.LoadFile` | +| `gettext-go/gettext/mo.LoadData` | `gettext-go/mo.Load` | + +### Use empty string as the default context for `gettext.Gettext` + +```go +package main + +// v0.1.0 +// if the **context** missing, use `callerName(2)` as the context: + +// v1.0.0 +// if the **context** missing, use empty string as the context: + +func main() { + gettext.Gettext("hello") + // v0.1.0 => gettext.PGettext("main.main", "hello") + // v1.0.0 => gettext.PGettext("", "hello") + + gettext.DGettext("domain", "hello") + // v0.1.0 => gettext.DPGettext("domain", "main.main", "hello") + // v1.0.0 => gettext.DPGettext("domain", "", "hello") + + gettext.NGettext("domain", "hello", "hello2", n) + // v0.1.0 => gettext.PNGettext("domain", "main.main", "hello", "hello2", n) + // v1.0.0 => gettext.PNGettext("domain", "", "hello", "hello2", n) + + gettext.DNGettext("domain", "hello", "hello2", n) + // v0.1.0 => gettext.DPNGettext("domain", "main.main", "hello", "hello2", n) + // v1.0.0 => gettext.DPNGettext("domain", "", "hello", "hello2", n) +} +``` + +### `BindLocale` support `FileSystem` interface + +```go +// Use FileSystem: +// BindLocale(New("poedit", "name", OS("path/to/dir"))) // bind "poedit" domain +// BindLocale(New("poedit", "name", OS("path/to.zip"))) // bind "poedit" domain +``` + +## New API in v1.0.0 + +`Gettexter` interface: + +```go +type Gettexter interface { + FileSystem() FileSystem + + GetDomain() string + SetDomain(domain string) Gettexter + + GetLanguage() string + SetLanguage(lang string) Gettexter + + Gettext(msgid string) string + PGettext(msgctxt, msgid string) string + + NGettext(msgid, msgidPlural string, n int) string + PNGettext(msgctxt, msgid, msgidPlural string, n int) string + + DGettext(domain, msgid string) string + DPGettext(domain, msgctxt, msgid string) string + DNGettext(domain, msgid, msgidPlural string, n int) string + DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string + + Getdata(name string) []byte + DGetdata(domain, name string) []byte +} + +func New(domain, path string, data ...interface{}) Gettexter +``` + +`FileSystem` interface: + +```go +type FileSystem interface { + LocaleList() []string + LoadMessagesFile(domain, lang, ext string) ([]byte, error) + LoadResourceFile(domain, lang, name string) ([]byte, error) + String() string +} + +func NewFS(name string, x interface{}) FileSystem +func OS(root string) FileSystem +func ZipFS(r *zip.Reader, name string) FileSystem +func NilFS(name string) FileSystem +``` + +---- + +## BUGS + +Please report bugs to . + +Thanks! diff --git a/vendor/github.com/chai2010/gettext-go/doc.go b/vendor/github.com/chai2010/gettext-go/doc.go new file mode 100644 index 0000000000..50dfea3305 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/doc.go @@ -0,0 +1,67 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package gettext implements a basic GNU's gettext library. + +Example: + import ( + "github.com/chai2010/gettext-go" + ) + + func main() { + gettext.SetLanguage("zh_CN") + + // gettext.BindLocale(gettext.New("hello", "locale")) // from locale dir + // gettext.BindLocale(gettext.New("hello", "locale.zip")) // from locale zip file + // gettext.BindLocale(gettext.New("hello", "locale.zip", zipData)) // from embedded zip data + + gettext.BindLocale(gettext.New("hello", "locale")) + + // translate source text + fmt.Println(gettext.Gettext("Hello, world!")) + // Output: 你好, 世界! + + // translate resource + fmt.Println(string(gettext.Getdata("poems.txt"))) + // Output: ... + } + +Translate directory struct("./examples/locale.zip"): + + Root: "path" or "file.zip/zipBaseName" + +-default # locale: $(LC_MESSAGES) or $(LANG) or "default" + | +-LC_MESSAGES # just for `gettext.Gettext` + | | +-hello.mo # $(Root)/$(lang)/LC_MESSAGES/$(domain).mo + | | +-hello.po # $(Root)/$(lang)/LC_MESSAGES/$(domain).po + | | \-hello.json # $(Root)/$(lang)/LC_MESSAGES/$(domain).json + | | + | \-LC_RESOURCE # just for `gettext.Getdata` + | +-hello # domain map a dir in resource translate + | +-favicon.ico # $(Root)/$(lang)/LC_RESOURCE/$(domain)/$(filename) + | \-poems.txt + | + \-zh_CN # simple chinese translate + +-LC_MESSAGES + | +-hello.po # try "$(domain).po" first + | +-hello.mo # try "$(domain).mo" second + | \-hello.json # try "$(domain).json" third + | + \-LC_RESOURCE + +-hello + +-favicon.ico # $(lang)/$(domain)/favicon.ico + \-poems.txt # $(lang)/$(domain)/poems.txt + +See: + http://en.wikipedia.org/wiki/Gettext + http://www.gnu.org/software/gettext/manual/html_node + http://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html + http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html + http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html + http://www.poedit.net/ + +Please report bugs to . +Thanks! +*/ +package gettext diff --git a/vendor/github.com/chai2010/gettext-go/fs.go b/vendor/github.com/chai2010/gettext-go/fs.go new file mode 100644 index 0000000000..4e66fae7c6 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/fs.go @@ -0,0 +1,84 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "archive/zip" + "bytes" + "fmt" +) + +type FileSystem interface { + LocaleList() []string + LoadMessagesFile(domain, lang, ext string) ([]byte, error) + LoadResourceFile(domain, lang, name string) ([]byte, error) + String() string +} + +func NewFS(name string, x interface{}) FileSystem { + if x == nil { + if name != "" { + return OS(name) + } + return NilFS(name) + } + + switch x := x.(type) { + case []byte: + if len(x) == 0 { + return OS(name) + } + if r, err := zip.NewReader(bytes.NewReader(x), int64(len(x))); err == nil { + return ZipFS(r, name) + } + if fs, err := newJson(x, name); err == nil { + return fs + } + case string: + if len(x) == 0 { + return OS(name) + } + if r, err := zip.NewReader(bytes.NewReader([]byte(x)), int64(len(x))); err == nil { + return ZipFS(r, name) + } + if fs, err := newJson([]byte(x), name); err == nil { + return fs + } + case FileSystem: + return x + } + + return NilFS(name) +} + +func OS(root string) FileSystem { + return newOsFS(root) +} + +func ZipFS(r *zip.Reader, name string) FileSystem { + return newZipFS(r, name) +} + +func NilFS(name string) FileSystem { + return &nilFS{name} +} + +type nilFS struct { + name string +} + +func (p *nilFS) LocaleList() []string { + return nil +} + +func (p *nilFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { + return nil, fmt.Errorf("not found") +} +func (p *nilFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { + return nil, fmt.Errorf("not found") +} +func (p *nilFS) String() string { + return "gettext.nilfs(" + p.name + ")" +} diff --git a/vendor/github.com/chai2010/gettext-go/fs_json.go b/vendor/github.com/chai2010/gettext-go/fs_json.go new file mode 100644 index 0000000000..c7138c9954 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/fs_json.go @@ -0,0 +1,66 @@ +// Copyright 2020 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "encoding/json" + "fmt" + "sort" +) + +type jsonFS struct { + name string + x map[string]struct { + LC_MESSAGES map[string][]struct { + MsgContext string `json:"msgctxt"` // msgctxt context + MsgId string `json:"msgid"` // msgid untranslated-string + MsgIdPlural string `json:"msgid_plural"` // msgid_plural untranslated-string-plural + MsgStr []string `json:"msgstr"` // msgstr translated-string + } + LC_RESOURCE map[string]map[string]string + } +} + +func isJsonData() bool { + return false +} + +func newJson(jsonData []byte, name string) (*jsonFS, error) { + p := &jsonFS{name: name} + if err := json.Unmarshal(jsonData, &p.x); err != nil { + return nil, err + } + + return p, nil +} + +func (p *jsonFS) LocaleList() []string { + var ss []string + for lang := range p.x { + ss = append(ss, lang) + } + sort.Strings(ss) + return ss +} + +func (p *jsonFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { + if v, ok := p.x[lang]; ok { + if v, ok := v.LC_MESSAGES[domain+ext]; ok { + return json.Marshal(v) + } + } + return nil, fmt.Errorf("not found") +} +func (p *jsonFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { + if v, ok := p.x[lang]; ok { + if v, ok := v.LC_RESOURCE[domain]; ok { + return []byte(v[name]), nil + } + } + return nil, fmt.Errorf("not found") +} +func (p *jsonFS) String() string { + return "gettext.nilfs(" + p.name + ")" +} diff --git a/vendor/github.com/chai2010/gettext-go/fs_os.go b/vendor/github.com/chai2010/gettext-go/fs_os.go new file mode 100644 index 0000000000..80d4f51bac --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/fs_os.go @@ -0,0 +1,91 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "archive/zip" + "bytes" + "fmt" + "io/ioutil" + "os" + "sort" + "strings" +) + +type osFS struct { + root string +} + +func newOsFS(root string) FileSystem { + // locale zip file + if fi, err := os.Stat(root); err == nil && !fi.IsDir() { + if strings.HasSuffix(strings.ToLower(root), ".zip") { + if x, err := ioutil.ReadFile(root); err == nil { + if r, err := zip.NewReader(bytes.NewReader(x), int64(len(x))); err == nil { + return ZipFS(r, root) + } + } + } + if strings.HasSuffix(strings.ToLower(root), ".json") { + if x, err := ioutil.ReadFile(root); err == nil { + if fs, err := newJson(x, root); err == nil { + return fs + } + } + } + } + + // locale dir + return &osFS{root: root} +} + +func (p *osFS) LocaleList() []string { + list, err := ioutil.ReadDir(p.root) + if err != nil { + return nil + } + ssMap := make(map[string]bool) + for _, dir := range list { + if dir.IsDir() { + ssMap[dir.Name()] = true + } + } + var locales = make([]string, 0, len(ssMap)) + for s := range ssMap { + locales = append(locales, s) + } + sort.Strings(locales) + return locales +} + +func (p *osFS) LoadMessagesFile(domain, locale, ext string) ([]byte, error) { + trName := p.makeMessagesFileName(domain, locale, ext) + rcData, err := ioutil.ReadFile(trName) + if err != nil { + return nil, err + } + return rcData, nil +} + +func (p *osFS) LoadResourceFile(domain, locale, name string) ([]byte, error) { + rcName := p.makeResourceFileName(domain, locale, name) + rcData, err := ioutil.ReadFile(rcName) + if err != nil { + return nil, err + } + return rcData, nil +} + +func (p *osFS) String() string { + return "gettext.localfs(" + p.root + ")" +} + +func (p *osFS) makeMessagesFileName(domain, lang, ext string) string { + return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.root, lang, domain, ext) +} + +func (p *osFS) makeResourceFileName(domain, lang, name string) string { + return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.root, lang, domain, name) +} diff --git a/vendor/github.com/chai2010/gettext-go/fs_zip.go b/vendor/github.com/chai2010/gettext-go/fs_zip.go new file mode 100644 index 0000000000..61eb8359da --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/fs_zip.go @@ -0,0 +1,142 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "archive/zip" + "fmt" + "io/ioutil" + "sort" + "strings" +) + +type zipFS struct { + root string + name string + r *zip.Reader +} + +func newZipFS(r *zip.Reader, name string) *zipFS { + fs := &zipFS{r: r, name: name} + fs.root = fs.zipRoot() + return fs +} + +func (p *zipFS) zipName() string { + name := p.name + if x := strings.LastIndexAny(name, `\/`); x != -1 { + name = name[x+1:] + } + name = strings.TrimSuffix(name, ".zip") + return name +} + +func (p *zipFS) zipRoot() string { + var somepath string + for _, f := range p.r.File { + if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { + somepath = f.Name + } + if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { + somepath = f.Name + } + } + if somepath == "" { + return p.zipName() + } + + ss := strings.Split(somepath, "/") + for i, s := range ss { + // $(root)/$(lang)/LC_MESSAGES + // $(root)/$(lang)/LC_RESOURCE + if (s == "LC_MESSAGES" || s == "LC_RESOURCE") && i >= 2 { + return strings.Join(ss[:i-1], "/") + } + } + + return p.zipName() +} + +func (p *zipFS) LocaleList() []string { + var locals []string + for s := range p.lsZip(p.r) { + locals = append(locals, s) + } + sort.Strings(locals) + return locals +} + +func (p *zipFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { + trName := p.makeMessagesFileName(domain, lang, ext) + for _, f := range p.r.File { + if f.Name != trName { + continue + } + rc, err := f.Open() + if err != nil { + return nil, err + } + rcData, err := ioutil.ReadAll(rc) + rc.Close() + return rcData, err + } + return nil, fmt.Errorf("not found") +} + +func (p *zipFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { + rcName := p.makeResourceFileName(domain, lang, name) + for _, f := range p.r.File { + if f.Name != rcName { + continue + } + rc, err := f.Open() + if err != nil { + return nil, err + } + rcData, err := ioutil.ReadAll(rc) + rc.Close() + return rcData, err + } + return nil, fmt.Errorf("not found") +} + +func (p *zipFS) String() string { + return "gettext.zipfs(" + p.name + ")" +} + +func (p *zipFS) makeMessagesFileName(domain, lang, ext string) string { + return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.root, lang, domain, ext) +} + +func (p *zipFS) makeResourceFileName(domain, lang, name string) string { + return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.root, lang, domain, name) +} + +func (p *zipFS) lsZip(r *zip.Reader) map[string]bool { + ssMap := make(map[string]bool) + for _, f := range r.File { + if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { + s := strings.TrimRight(f.Name[:x], `\/`) + if x = strings.LastIndexAny(s, `\/`); x != -1 { + s = s[x+1:] + } + if s != "" { + ssMap[s] = true + } + continue + } + if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { + s := strings.TrimRight(f.Name[:x], `\/`) + if x = strings.LastIndexAny(s, `\/`); x != -1 { + s = s[x+1:] + } + if s != "" { + ssMap[s] = true + } + continue + } + } + return ssMap +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext.go b/vendor/github.com/chai2010/gettext-go/gettext.go new file mode 100644 index 0000000000..7747188ab4 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/gettext.go @@ -0,0 +1,219 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +var ( + DefaultLanguage string = getDefaultLanguage() // use $(LC_MESSAGES) or $(LANG) or "default" +) + +type Gettexter interface { + FileSystem() FileSystem + + GetDomain() string + SetDomain(domain string) Gettexter + + GetLanguage() string + SetLanguage(lang string) Gettexter + + Gettext(msgid string) string + PGettext(msgctxt, msgid string) string + + NGettext(msgid, msgidPlural string, n int) string + PNGettext(msgctxt, msgid, msgidPlural string, n int) string + + DGettext(domain, msgid string) string + DPGettext(domain, msgctxt, msgid string) string + DNGettext(domain, msgid, msgidPlural string, n int) string + DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string + + Getdata(name string) []byte + DGetdata(domain, name string) []byte +} + +// New create Interface use default language. +func New(domain, path string, data ...interface{}) Gettexter { + return newLocale(domain, path, data...) +} + +var defaultGettexter struct { + lang string + domain string + Gettexter +} + +func init() { + defaultGettexter.lang = getDefaultLanguage() + defaultGettexter.domain = "default" + defaultGettexter.Gettexter = newLocale("", "") +} + +// BindLocale sets and queries program's domains. +// +// Examples: +// BindLocale(New("poedit", "locale")) // bind "poedit" domain +// +// Use zip file: +// BindLocale(New("poedit", "locale.zip")) // bind "poedit" domain +// BindLocale(New("poedit", "locale.zip", zipData)) // bind "poedit" domain +// +// Use FileSystem: +// BindLocale(New("poedit", "name", OS("path/to/dir"))) // bind "poedit" domain +// BindLocale(New("poedit", "name", OS("path/to.zip"))) // bind "poedit" domain +// +func BindLocale(g Gettexter) { + if g != nil { + defaultGettexter.Gettexter = g + defaultGettexter.SetLanguage(defaultGettexter.lang) + } else { + defaultGettexter.Gettexter = newLocale("", "") + defaultGettexter.SetLanguage(defaultGettexter.lang) + } +} + +// SetLanguage sets and queries the program's current lang. +// +// If the lang is not empty string, set the new locale. +// +// If the lang is empty string, don't change anything. +// +// Returns is the current locale. +// +// Examples: +// SetLanguage("") // get locale: return DefaultLocale +// SetLanguage("zh_CN") // set locale: return zh_CN +// SetLanguage("") // get locale: return zh_CN +func SetLanguage(lang string) string { + defaultGettexter.SetLanguage(lang) + return defaultGettexter.GetLanguage() +} + +// SetDomain sets and retrieves the current message domain. +// +// If the domain is not empty string, set the new domains. +// +// If the domain is empty string, don't change anything. +// +// Returns is the all used domains. +// +// Examples: +// SetDomain("poedit") // set domain: poedit +// SetDomain("") // get domain: return poedit +func SetDomain(domain string) string { + defaultGettexter.SetDomain(domain) + return defaultGettexter.GetDomain() +} + +// Gettext attempt to translate a text string into the user's native language, +// by looking up the translation in a message catalog. +// +// It use the caller's function name as the msgctxt. +// +// Examples: +// func Foo() { +// msg := gettext.Gettext("Hello") // msgctxt is "" +// } +func Gettext(msgid string) string { + return defaultGettexter.Gettext(msgid) +} + +// Getdata attempt to translate a resource file into the user's native language, +// by looking up the translation in a message catalog. +// +// Examples: +// func Foo() { +// Textdomain("hello") +// BindLocale("hello", "locale.zip", nilOrZipData) +// poems := gettext.Getdata("poems.txt") +// } +func Getdata(name string) []byte { + return defaultGettexter.Getdata(name) +} + +// NGettext attempt to translate a text string into the user's native language, +// by looking up the appropriate plural form of the translation in a message +// catalog. +// +// It use the caller's function name as the msgctxt. +// +// Examples: +// func Foo() { +// msg := gettext.NGettext("%d people", "%d peoples", 2) +// } +func NGettext(msgid, msgidPlural string, n int) string { + return defaultGettexter.NGettext(msgid, msgidPlural, n) +} + +// PGettext attempt to translate a text string into the user's native language, +// by looking up the translation in a message catalog. +// +// Examples: +// func Foo() { +// msg := gettext.PGettext("gettext-go.example", "Hello") // msgctxt is "gettext-go.example" +// } +func PGettext(msgctxt, msgid string) string { + return defaultGettexter.PGettext(msgctxt, msgid) +} + +// PNGettext attempt to translate a text string into the user's native language, +// by looking up the appropriate plural form of the translation in a message +// catalog. +// +// Examples: +// func Foo() { +// msg := gettext.PNGettext("gettext-go.example", "%d people", "%d peoples", 2) +// } +func PNGettext(msgctxt, msgid, msgidPlural string, n int) string { + return defaultGettexter.PNGettext(msgctxt, msgid, msgidPlural, n) +} + +// DGettext like Gettext(), but looking up the message in the specified domain. +// +// Examples: +// func Foo() { +// msg := gettext.DGettext("poedit", "Hello") +// } +func DGettext(domain, msgid string) string { + return defaultGettexter.DGettext(domain, msgid) +} + +// DNGettext like NGettext(), but looking up the message in the specified domain. +// +// Examples: +// func Foo() { +// msg := gettext.PNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) +// } +func DNGettext(domain, msgid, msgidPlural string, n int) string { + return defaultGettexter.DNGettext(domain, msgid, msgidPlural, n) +} + +// DPGettext like PGettext(), but looking up the message in the specified domain. +// +// Examples: +// func Foo() { +// msg := gettext.DPGettext("poedit", "gettext-go.example", "Hello") +// } +func DPGettext(domain, msgctxt, msgid string) string { + return defaultGettexter.DPGettext(domain, msgctxt, msgid) +} + +// DPNGettext like PNGettext(), but looking up the message in the specified domain. +// +// Examples: +// func Foo() { +// msg := gettext.DPNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) +// } +func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { + return defaultGettexter.DPNGettext(domain, msgctxt, msgid, msgidPlural, n) +} + +// DGetdata like Getdata(), but looking up the resource in the specified domain. +// +// Examples: +// func Foo() { +// msg := gettext.DGetdata("hello", "poems.txt") +// } +func DGetdata(domain, name string) []byte { + return defaultGettexter.DGetdata(domain, name) +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/caller.go b/vendor/github.com/chai2010/gettext-go/gettext/caller.go deleted file mode 100644 index e24aab3756..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/caller.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "regexp" - "runtime" -) - -var ( - reInit = regexp.MustCompile(`init·\d+$`) // main.init·1 - reClosure = regexp.MustCompile(`func·\d+$`) // main.func·001 -) - -// caller types: -// runtime.goexit -// runtime.main -// main.init -// main.main -// main.init·1 -> main.init -// main.func·001 -> main.func -// code.google.com/p/gettext-go/gettext.TestCallerName -// ... -func callerName(skip int) string { - pc, _, _, ok := runtime.Caller(skip) - if !ok { - return "" - } - name := runtime.FuncForPC(pc).Name() - if reInit.MatchString(name) { - return reInit.ReplaceAllString(name, "init") - } - if reClosure.MatchString(name) { - return reClosure.ReplaceAllString(name, "func") - } - return name -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/doc.go b/vendor/github.com/chai2010/gettext-go/gettext/doc.go deleted file mode 100644 index 422bf2c6d7..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2013 . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package gettext implements a basic GNU's gettext library. - -Example: - import ( - "github.com/chai2010/gettext-go/gettext" - ) - - func main() { - gettext.SetLocale("zh_CN") - gettext.Textdomain("hello") - - // gettext.BindTextdomain("hello", "local", nil) // from local dir - // gettext.BindTextdomain("hello", "local.zip", nil) // from local zip file - // gettext.BindTextdomain("hello", "local.zip", zipData) // from embedded zip data - - gettext.BindTextdomain("hello", "local", nil) - - // translate source text - fmt.Println(gettext.Gettext("Hello, world!")) - // Output: 你好, 世界! - - // translate resource - fmt.Println(string(gettext.Getdata("poems.txt"))) - // Output: ... - } - -Translate directory struct("../examples/local.zip"): - - Root: "path" or "file.zip/zipBaseName" - +-default # local: $(LC_MESSAGES) or $(LANG) or "default" - | +-LC_MESSAGES # just for `gettext.Gettext` - | | +-hello.mo # $(Root)/$(local)/LC_MESSAGES/$(domain).mo - | | \-hello.po # $(Root)/$(local)/LC_MESSAGES/$(domain).mo - | | - | \-LC_RESOURCE # just for `gettext.Getdata` - | +-hello # domain map a dir in resource translate - | +-favicon.ico # $(Root)/$(local)/LC_RESOURCE/$(domain)/$(filename) - | \-poems.txt - | - \-zh_CN # simple chinese translate - +-LC_MESSAGES - | +-hello.mo # try "$(domain).mo" first - | \-hello.po # try "$(domain).po" second - | - \-LC_RESOURCE - +-hello - +-favicon.ico # try "$(local)/$(domain)/file" first - \-poems.txt # try "default/$(domain)/file" second - -See: - http://en.wikipedia.org/wiki/Gettext - http://www.gnu.org/software/gettext/manual/html_node - http://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html - http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html - http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html - http://www.poedit.net/ - -Please report bugs to . -Thanks! -*/ -package gettext diff --git a/vendor/github.com/chai2010/gettext-go/gettext/domain.go b/vendor/github.com/chai2010/gettext-go/gettext/domain.go deleted file mode 100644 index f860b27b6b..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/domain.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "sync" -) - -type domainManager struct { - mutex sync.Mutex - locale string - domain string - domainMap map[string]*fileSystem - trTextMap map[string]*translator -} - -func newDomainManager() *domainManager { - return &domainManager{ - locale: DefaultLocale, - domainMap: make(map[string]*fileSystem), - trTextMap: make(map[string]*translator), - } -} - -func (p *domainManager) makeTrMapKey(domain, locale string) string { - return domain + "_$$$_" + locale -} - -func (p *domainManager) Bind(domain, path string, data []byte) (domains, paths []string) { - p.mutex.Lock() - defer p.mutex.Unlock() - - switch { - case domain != "" && path != "": // bind new domain - p.bindDomainTranslators(domain, path, data) - case domain != "" && path == "": // delete domain - p.deleteDomain(domain) - } - - // return all bind domain - for k, fs := range p.domainMap { - domains = append(domains, k) - paths = append(paths, fs.FsName) - } - return -} - -func (p *domainManager) SetLocale(locale string) string { - p.mutex.Lock() - defer p.mutex.Unlock() - if locale != "" { - p.locale = locale - } - return p.locale -} - -func (p *domainManager) SetDomain(domain string) string { - p.mutex.Lock() - defer p.mutex.Unlock() - if domain != "" { - p.domain = domain - } - return p.domain -} - -func (p *domainManager) Getdata(name string) []byte { - return p.getdata(p.domain, name) -} - -func (p *domainManager) DGetdata(domain, name string) []byte { - return p.getdata(domain, name) -} - -func (p *domainManager) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { - p.mutex.Lock() - defer p.mutex.Unlock() - return p.gettext(p.domain, msgctxt, msgid, msgidPlural, n) -} - -func (p *domainManager) DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { - p.mutex.Lock() - defer p.mutex.Unlock() - return p.gettext(domain, msgctxt, msgid, msgidPlural, n) -} - -func (p *domainManager) gettext(domain, msgctxt, msgid, msgidPlural string, n int) string { - if p.locale == "" || p.domain == "" { - return msgid - } - if _, ok := p.domainMap[domain]; !ok { - return msgid - } - if f, ok := p.trTextMap[p.makeTrMapKey(domain, p.locale)]; ok { - return f.PNGettext(msgctxt, msgid, msgidPlural, n) - } - return msgid -} - -func (p *domainManager) getdata(domain, name string) []byte { - if p.locale == "" || p.domain == "" { - return nil - } - if _, ok := p.domainMap[domain]; !ok { - return nil - } - if fs, ok := p.domainMap[domain]; ok { - if data, err := fs.LoadResourceFile(domain, p.locale, name); err == nil { - return data - } - if p.locale != "default" { - if data, err := fs.LoadResourceFile(domain, "default", name); err == nil { - return data - } - } - } - return nil -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/domain_helper.go b/vendor/github.com/chai2010/gettext-go/gettext/domain_helper.go deleted file mode 100644 index 8dce58e655..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/domain_helper.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "fmt" - "strings" -) - -func (p *domainManager) bindDomainTranslators(domain, path string, data []byte) { - if _, ok := p.domainMap[domain]; ok { - p.deleteDomain(domain) // delete old domain - } - fs := newFileSystem(path, data) - for locale, _ := range fs.LocaleMap { - trMapKey := p.makeTrMapKey(domain, locale) - if data, err := fs.LoadMessagesFile(domain, locale, ".mo"); err == nil { - p.trTextMap[trMapKey], _ = newMoTranslator( - fmt.Sprintf("%s_%s.mo", domain, locale), - data, - ) - continue - } - if data, err := fs.LoadMessagesFile(domain, locale, ".po"); err == nil { - p.trTextMap[trMapKey], _ = newPoTranslator( - fmt.Sprintf("%s_%s.po", domain, locale), - data, - ) - continue - } - p.trTextMap[p.makeTrMapKey(domain, locale)] = nilTranslator - } - p.domainMap[domain] = fs -} - -func (p *domainManager) deleteDomain(domain string) { - if _, ok := p.domainMap[domain]; !ok { - return - } - // delete all mo files - trMapKeyPrefix := p.makeTrMapKey(domain, "") - for k, _ := range p.trTextMap { - if strings.HasPrefix(k, trMapKeyPrefix) { - delete(p.trTextMap, k) - } - } - delete(p.domainMap, domain) -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/fs.go b/vendor/github.com/chai2010/gettext-go/gettext/fs.go deleted file mode 100644 index 1c2e23c1d0..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/fs.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "archive/zip" - "bytes" - "fmt" - "io/ioutil" - "log" - "os" - "strings" -) - -type fileSystem struct { - FsName string - FsRoot string - FsZipData []byte - LocaleMap map[string]bool -} - -func newFileSystem(path string, data []byte) *fileSystem { - fs := &fileSystem{ - FsName: path, - FsZipData: data, - } - if err := fs.init(); err != nil { - log.Printf("gettext-go: invalid domain, err = %v", err) - } - return fs -} - -func (p *fileSystem) init() error { - zipName := func(name string) string { - if x := strings.LastIndexAny(name, `\/`); x != -1 { - name = name[x+1:] - } - name = strings.TrimSuffix(name, ".zip") - return name - } - - // zip data - if len(p.FsZipData) != 0 { - p.FsRoot = zipName(p.FsName) - p.LocaleMap = p.lsZip(p.FsZipData) - return nil - } - - // local dir or zip file - fi, err := os.Stat(p.FsName) - if err != nil { - return err - } - - // local dir - if fi.IsDir() { - p.FsRoot = p.FsName - p.LocaleMap = p.lsDir(p.FsName) - return nil - } - - // local zip file - p.FsZipData, err = ioutil.ReadFile(p.FsName) - if err != nil { - return err - } - p.FsRoot = zipName(p.FsName) - p.LocaleMap = p.lsZip(p.FsZipData) - return nil -} - -func (p *fileSystem) LoadMessagesFile(domain, local, ext string) ([]byte, error) { - if len(p.FsZipData) == 0 { - trName := p.makeMessagesFileName(domain, local, ext) - rcData, err := ioutil.ReadFile(trName) - if err != nil { - return nil, err - } - return rcData, nil - } else { - r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData))) - if err != nil { - return nil, err - } - - trName := p.makeMessagesFileName(domain, local, ext) - for _, f := range r.File { - if f.Name != trName { - continue - } - rc, err := f.Open() - if err != nil { - return nil, err - } - rcData, err := ioutil.ReadAll(rc) - rc.Close() - return rcData, err - } - return nil, fmt.Errorf("not found") - } -} - -func (p *fileSystem) LoadResourceFile(domain, local, name string) ([]byte, error) { - if len(p.FsZipData) == 0 { - rcName := p.makeResourceFileName(domain, local, name) - rcData, err := ioutil.ReadFile(rcName) - if err != nil { - return nil, err - } - return rcData, nil - } else { - r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData))) - if err != nil { - return nil, err - } - - rcName := p.makeResourceFileName(domain, local, name) - for _, f := range r.File { - if f.Name != rcName { - continue - } - rc, err := f.Open() - if err != nil { - return nil, err - } - rcData, err := ioutil.ReadAll(rc) - rc.Close() - return rcData, err - } - return nil, fmt.Errorf("not found") - } -} - -func (p *fileSystem) makeMessagesFileName(domain, local, ext string) string { - return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.FsRoot, local, domain, ext) -} - -func (p *fileSystem) makeResourceFileName(domain, local, name string) string { - return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.FsRoot, local, domain, name) -} - -func (p *fileSystem) lsZip(data []byte) map[string]bool { - r, err := zip.NewReader(bytes.NewReader(data), int64(len(data))) - if err != nil { - return nil - } - ssMap := make(map[string]bool) - for _, f := range r.File { - if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { - s := strings.TrimRight(f.Name[:x], `\/`) - if x = strings.LastIndexAny(s, `\/`); x != -1 { - s = s[x+1:] - } - if s != "" { - ssMap[s] = true - } - continue - } - if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { - s := strings.TrimRight(f.Name[:x], `\/`) - if x = strings.LastIndexAny(s, `\/`); x != -1 { - s = s[x+1:] - } - if s != "" { - ssMap[s] = true - } - continue - } - } - return ssMap -} - -func (p *fileSystem) lsDir(path string) map[string]bool { - list, err := ioutil.ReadDir(path) - if err != nil { - return nil - } - ssMap := make(map[string]bool) - for _, dir := range list { - if dir.IsDir() { - ssMap[dir.Name()] = true - } - } - return ssMap -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/gettext.go b/vendor/github.com/chai2010/gettext-go/gettext/gettext.go deleted file mode 100644 index ca14065b22..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/gettext.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -var ( - defaultManager = newDomainManager() -) - -var ( - DefaultLocale = getDefaultLocale() // use $(LC_MESSAGES) or $(LANG) or "default" -) - -// SetLocale sets and queries the program's current locale. -// -// If the locale is not empty string, set the new local. -// -// If the locale is empty string, don't change anything. -// -// Returns is the current locale. -// -// Examples: -// SetLocale("") // get locale: return DefaultLocale -// SetLocale("zh_CN") // set locale: return zh_CN -// SetLocale("") // get locale: return zh_CN -func SetLocale(locale string) string { - return defaultManager.SetLocale(locale) -} - -// BindTextdomain sets and queries program's domains. -// -// If the domain and path are all not empty string, bind the new domain. -// If the domain already exists, return error. -// -// If the domain is not empty string, but the path is the empty string, -// delete the domain. -// If the domain don't exists, return error. -// -// If the domain and the path are all empty string, don't change anything. -// -// Returns is the all bind domains. -// -// Examples: -// BindTextdomain("poedit", "local", nil) // bind "poedit" domain -// BindTextdomain("", "", nil) // return all domains -// BindTextdomain("poedit", "", nil) // delete "poedit" domain -// BindTextdomain("", "", nil) // return all domains -// -// Use zip file: -// BindTextdomain("poedit", "local.zip", nil) // bind "poedit" domain -// BindTextdomain("poedit", "local.zip", zipData) // bind "poedit" domain -// -func BindTextdomain(domain, path string, zipData []byte) (domains, paths []string) { - return defaultManager.Bind(domain, path, zipData) -} - -// Textdomain sets and retrieves the current message domain. -// -// If the domain is not empty string, set the new domains. -// -// If the domain is empty string, don't change anything. -// -// Returns is the all used domains. -// -// Examples: -// Textdomain("poedit") // set domain: poedit -// Textdomain("") // get domain: return poedit -func Textdomain(domain string) string { - return defaultManager.SetDomain(domain) -} - -// Gettext attempt to translate a text string into the user's native language, -// by looking up the translation in a message catalog. -// -// It use the caller's function name as the msgctxt. -// -// Examples: -// func Foo() { -// msg := gettext.Gettext("Hello") // msgctxt is "some/package/name.Foo" -// } -func Gettext(msgid string) string { - return PGettext(callerName(2), msgid) -} - -// Getdata attempt to translate a resource file into the user's native language, -// by looking up the translation in a message catalog. -// -// Examples: -// func Foo() { -// Textdomain("hello") -// BindTextdomain("hello", "local.zip", nilOrZipData) -// poems := gettext.Getdata("poems.txt") -// } -func Getdata(name string) []byte { - return defaultManager.Getdata(name) -} - -// NGettext attempt to translate a text string into the user's native language, -// by looking up the appropriate plural form of the translation in a message -// catalog. -// -// It use the caller's function name as the msgctxt. -// -// Examples: -// func Foo() { -// msg := gettext.NGettext("%d people", "%d peoples", 2) -// } -func NGettext(msgid, msgidPlural string, n int) string { - return PNGettext(callerName(2), msgid, msgidPlural, n) -} - -// PGettext attempt to translate a text string into the user's native language, -// by looking up the translation in a message catalog. -// -// Examples: -// func Foo() { -// msg := gettext.PGettext("gettext-go.example", "Hello") // msgctxt is "gettext-go.example" -// } -func PGettext(msgctxt, msgid string) string { - return PNGettext(msgctxt, msgid, "", 0) -} - -// PNGettext attempt to translate a text string into the user's native language, -// by looking up the appropriate plural form of the translation in a message -// catalog. -// -// Examples: -// func Foo() { -// msg := gettext.PNGettext("gettext-go.example", "%d people", "%d peoples", 2) -// } -func PNGettext(msgctxt, msgid, msgidPlural string, n int) string { - return defaultManager.PNGettext(msgctxt, msgid, msgidPlural, n) -} - -// DGettext like Gettext(), but looking up the message in the specified domain. -// -// Examples: -// func Foo() { -// msg := gettext.DGettext("poedit", "Hello") -// } -func DGettext(domain, msgid string) string { - return DPGettext(domain, callerName(2), msgid) -} - -// DNGettext like NGettext(), but looking up the message in the specified domain. -// -// Examples: -// func Foo() { -// msg := gettext.PNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) -// } -func DNGettext(domain, msgid, msgidPlural string, n int) string { - return DPNGettext(domain, callerName(2), msgid, msgidPlural, n) -} - -// DPGettext like PGettext(), but looking up the message in the specified domain. -// -// Examples: -// func Foo() { -// msg := gettext.DPGettext("poedit", "gettext-go.example", "Hello") -// } -func DPGettext(domain, msgctxt, msgid string) string { - return DPNGettext(domain, msgctxt, msgid, "", 0) -} - -// DPNGettext like PNGettext(), but looking up the message in the specified domain. -// -// Examples: -// func Foo() { -// msg := gettext.DPNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) -// } -func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { - return defaultManager.DPNGettext(domain, msgctxt, msgid, msgidPlural, n) -} - -// DGetdata like Getdata(), but looking up the resource in the specified domain. -// -// Examples: -// func Foo() { -// msg := gettext.DGetdata("hello", "poems.txt") -// } -func DGetdata(domain, name string) []byte { - return defaultManager.DGetdata(domain, name) -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/local.go b/vendor/github.com/chai2010/gettext-go/gettext/local.go deleted file mode 100644 index 179a392fe2..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/local.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "os" - "strings" -) - -func getDefaultLocale() string { - if v := os.Getenv("LC_MESSAGES"); v != "" { - return simplifiedLocale(v) - } - if v := os.Getenv("LANG"); v != "" { - return simplifiedLocale(v) - } - return "default" -} - -func simplifiedLocale(lang string) string { - // en_US/en_US.UTF-8/zh_CN/zh_TW/el_GR@euro/... - if idx := strings.Index(lang, ":"); idx != -1 { - lang = lang[:idx] - } - if idx := strings.Index(lang, "@"); idx != -1 { - lang = lang[:idx] - } - if idx := strings.Index(lang, "."); idx != -1 { - lang = lang[:idx] - } - return strings.TrimSpace(lang) -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/doc.go b/vendor/github.com/chai2010/gettext-go/gettext/mo/doc.go deleted file mode 100644 index 9677680631..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/mo/doc.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package mo provides support for reading and writing GNU MO file. - -Examples: - import ( - "github.com/chai2010/gettext-go/gettext/mo" - ) - - func main() { - moFile, err := mo.Load("test.mo") - if err != nil { - log.Fatal(err) - } - fmt.Printf("%v", moFile) - } - -GNU MO file struct: - - byte - +------------------------------------------+ - 0 | magic number = 0x950412de | - | | - 4 | file format revision = 0 | - | | - 8 | number of strings | == N - | | - 12 | offset of table with original strings | == O - | | - 16 | offset of table with translation strings | == T - | | - 20 | size of hashing table | == S - | | - 24 | offset of hashing table | == H - | | - . . - . (possibly more entries later) . - . . - | | - O | length & offset 0th string ----------------. - O + 8 | length & offset 1st string ------------------. - ... ... | | - O + ((N-1)*8)| length & offset (N-1)th string | | | - | | | | - T | length & offset 0th translation ---------------. - T + 8 | length & offset 1st translation -----------------. - ... ... | | | | - T + ((N-1)*8)| length & offset (N-1)th translation | | | | | - | | | | | | - H | start hash table | | | | | - ... ... | | | | - H + S * 4 | end hash table | | | | | - | | | | | | - | NUL terminated 0th string <----------------' | | | - | | | | | - | NUL terminated 1st string <------------------' | | - | | | | - ... ... | | - | | | | - | NUL terminated 0th translation <---------------' | - | | | - | NUL terminated 1st translation <-----------------' - | | - ... ... - | | - +------------------------------------------+ - -The GNU MO file specification is at -http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html. -*/ -package mo diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/encoder.go b/vendor/github.com/chai2010/gettext-go/gettext/mo/encoder.go deleted file mode 100644 index 9b1c240b4f..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/mo/encoder.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mo - -import ( - "bytes" - "encoding/binary" - "sort" - "strings" -) - -type moHeader struct { - MagicNumber uint32 - MajorVersion uint16 - MinorVersion uint16 - MsgIdCount uint32 - MsgIdOffset uint32 - MsgStrOffset uint32 - HashSize uint32 - HashOffset uint32 -} - -type moStrPos struct { - Size uint32 // must keep fields order - Addr uint32 -} - -func encodeFile(f *File) []byte { - hdr := &moHeader{ - MagicNumber: MoMagicLittleEndian, - } - data := encodeData(hdr, f) - data = append(encodeHeader(hdr), data...) - return data -} - -// encode data and init moHeader -func encodeData(hdr *moHeader, f *File) []byte { - msgList := []Message{f.MimeHeader.toMessage()} - for _, v := range f.Messages { - if len(v.MsgId) == 0 { - continue - } - if len(v.MsgStr) == 0 && len(v.MsgStrPlural) == 0 { - continue - } - msgList = append(msgList, v) - } - sort.Sort(byMessages(msgList)) - - var buf bytes.Buffer - var msgIdPosList = make([]moStrPos, len(msgList)) - var msgStrPosList = make([]moStrPos, len(msgList)) - for i, v := range msgList { - // write msgid - msgId := encodeMsgId(v) - msgIdPosList[i].Addr = uint32(buf.Len() + MoHeaderSize) - msgIdPosList[i].Size = uint32(len(msgId)) - buf.WriteString(msgId) - // write msgstr - msgStr := encodeMsgStr(v) - msgStrPosList[i].Addr = uint32(buf.Len() + MoHeaderSize) - msgStrPosList[i].Size = uint32(len(msgStr)) - buf.WriteString(msgStr) - } - - hdr.MsgIdOffset = uint32(buf.Len() + MoHeaderSize) - binary.Write(&buf, binary.LittleEndian, msgIdPosList) - hdr.MsgStrOffset = uint32(buf.Len() + MoHeaderSize) - binary.Write(&buf, binary.LittleEndian, msgStrPosList) - - hdr.MsgIdCount = uint32(len(msgList)) - return buf.Bytes() -} - -// must called after encodeData -func encodeHeader(hdr *moHeader) []byte { - var buf bytes.Buffer - binary.Write(&buf, binary.LittleEndian, hdr) - return buf.Bytes() -} - -func encodeMsgId(v Message) string { - if v.MsgContext != "" && v.MsgIdPlural != "" { - return v.MsgContext + EotSeparator + v.MsgId + NulSeparator + v.MsgIdPlural - } - if v.MsgContext != "" && v.MsgIdPlural == "" { - return v.MsgContext + EotSeparator + v.MsgId - } - if v.MsgContext == "" && v.MsgIdPlural != "" { - return v.MsgId + NulSeparator + v.MsgIdPlural - } - return v.MsgId -} - -func encodeMsgStr(v Message) string { - if v.MsgIdPlural != "" { - return strings.Join(v.MsgStrPlural, NulSeparator) - } - return v.MsgStr -} - -type byMessages []Message - -func (d byMessages) Len() int { - return len(d) -} -func (d byMessages) Less(i, j int) bool { - if a, b := d[i].MsgContext, d[j].MsgContext; a != b { - return a < b - } - if a, b := d[i].MsgId, d[j].MsgId; a != b { - return a < b - } - if a, b := d[i].MsgIdPlural, d[j].MsgIdPlural; a != b { - return a < b - } - return false -} -func (d byMessages) Swap(i, j int) { - d[i], d[j] = d[j], d[i] -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/file.go b/vendor/github.com/chai2010/gettext-go/gettext/mo/file.go deleted file mode 100644 index b49a77b42a..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/mo/file.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mo - -import ( - "bytes" - "encoding/binary" - "fmt" - "io/ioutil" - "strings" -) - -const ( - MoHeaderSize = 28 - MoMagicLittleEndian = 0x950412de - MoMagicBigEndian = 0xde120495 - - EotSeparator = "\x04" // msgctxt and msgid separator - NulSeparator = "\x00" // msgid and msgstr separator -) - -// File represents an MO File. -// -// See http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html -type File struct { - MagicNumber uint32 - MajorVersion uint16 - MinorVersion uint16 - MsgIdCount uint32 - MsgIdOffset uint32 - MsgStrOffset uint32 - HashSize uint32 - HashOffset uint32 - MimeHeader Header - Messages []Message -} - -// Load loads a named mo file. -func Load(name string) (*File, error) { - data, err := ioutil.ReadFile(name) - if err != nil { - return nil, err - } - return LoadData(data) -} - -// LoadData loads mo file format data. -func LoadData(data []byte) (*File, error) { - r := bytes.NewReader(data) - - var magicNumber uint32 - if err := binary.Read(r, binary.LittleEndian, &magicNumber); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - var bo binary.ByteOrder - switch magicNumber { - case MoMagicLittleEndian: - bo = binary.LittleEndian - case MoMagicBigEndian: - bo = binary.BigEndian - default: - return nil, fmt.Errorf("gettext: %v", "invalid magic number") - } - - var header struct { - MajorVersion uint16 - MinorVersion uint16 - MsgIdCount uint32 - MsgIdOffset uint32 - MsgStrOffset uint32 - HashSize uint32 - HashOffset uint32 - } - if err := binary.Read(r, bo, &header); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - if v := header.MajorVersion; v != 0 && v != 1 { - return nil, fmt.Errorf("gettext: %v", "invalid version number") - } - if v := header.MinorVersion; v != 0 && v != 1 { - return nil, fmt.Errorf("gettext: %v", "invalid version number") - } - - msgIdStart := make([]uint32, header.MsgIdCount) - msgIdLen := make([]uint32, header.MsgIdCount) - if _, err := r.Seek(int64(header.MsgIdOffset), 0); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - for i := 0; i < int(header.MsgIdCount); i++ { - if err := binary.Read(r, bo, &msgIdLen[i]); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - if err := binary.Read(r, bo, &msgIdStart[i]); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - } - - msgStrStart := make([]int32, header.MsgIdCount) - msgStrLen := make([]int32, header.MsgIdCount) - if _, err := r.Seek(int64(header.MsgStrOffset), 0); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - for i := 0; i < int(header.MsgIdCount); i++ { - if err := binary.Read(r, bo, &msgStrLen[i]); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - if err := binary.Read(r, bo, &msgStrStart[i]); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - } - - file := &File{ - MagicNumber: magicNumber, - MajorVersion: header.MajorVersion, - MinorVersion: header.MinorVersion, - MsgIdCount: header.MsgIdCount, - MsgIdOffset: header.MsgIdOffset, - MsgStrOffset: header.MsgStrOffset, - HashSize: header.HashSize, - HashOffset: header.HashOffset, - } - for i := 0; i < int(header.MsgIdCount); i++ { - if _, err := r.Seek(int64(msgIdStart[i]), 0); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - msgIdData := make([]byte, msgIdLen[i]) - if _, err := r.Read(msgIdData); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - - if _, err := r.Seek(int64(msgStrStart[i]), 0); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - msgStrData := make([]byte, msgStrLen[i]) - if _, err := r.Read(msgStrData); err != nil { - return nil, fmt.Errorf("gettext: %v", err) - } - - if len(msgIdData) == 0 { - var msg = Message{ - MsgId: string(msgIdData), - MsgStr: string(msgStrData), - } - file.MimeHeader.fromMessage(&msg) - } else { - var msg = Message{ - MsgId: string(msgIdData), - MsgStr: string(msgStrData), - } - // Is this a context message? - if idx := strings.Index(msg.MsgId, EotSeparator); idx != -1 { - msg.MsgContext, msg.MsgId = msg.MsgId[:idx], msg.MsgId[idx+1:] - } - // Is this a plural message? - if idx := strings.Index(msg.MsgId, NulSeparator); idx != -1 { - msg.MsgId, msg.MsgIdPlural = msg.MsgId[:idx], msg.MsgId[idx+1:] - msg.MsgStrPlural = strings.Split(msg.MsgStr, NulSeparator) - msg.MsgStr = "" - } - file.Messages = append(file.Messages, msg) - } - } - - return file, nil -} - -// Save saves a mo file. -func (f *File) Save(name string) error { - return ioutil.WriteFile(name, f.Data(), 0666) -} - -// Save returns a mo file format data. -func (f *File) Data() []byte { - return encodeFile(f) -} - -// String returns the po format file string. -func (f *File) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "# version: %d.%d\n", f.MajorVersion, f.MinorVersion) - fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) - fmt.Fprintf(&buf, "\n") - - for k, v := range f.Messages { - fmt.Fprintf(&buf, `msgid "%v"`+"\n", k) - fmt.Fprintf(&buf, `msgstr "%s"`+"\n", v.MsgStr) - fmt.Fprintf(&buf, "\n") - } - - return buf.String() -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/message.go b/vendor/github.com/chai2010/gettext-go/gettext/mo/message.go deleted file mode 100644 index 91ad79bece..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/mo/message.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mo - -import ( - "bytes" - "fmt" -) - -// A MO file is made up of many entries, -// each entry holding the relation between an original untranslated string -// and its corresponding translation. -// -// See http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html -type Message struct { - MsgContext string // msgctxt context - MsgId string // msgid untranslated-string - MsgIdPlural string // msgid_plural untranslated-string-plural - MsgStr string // msgstr translated-string - MsgStrPlural []string // msgstr[0] translated-string-case-0 -} - -// String returns the po format entry string. -func (p Message) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) - if p.MsgIdPlural != "" { - fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) - } - if p.MsgStr != "" { - fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) - } - for i := 0; i < len(p.MsgStrPlural); i++ { - fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) - } - return buf.String() -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/plural/doc.go b/vendor/github.com/chai2010/gettext-go/gettext/plural/doc.go deleted file mode 100644 index 5641e2c3e7..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/plural/doc.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package plural provides standard plural formulas. - -Examples: - import ( - "code.google.com/p/gettext-go/gettext/plural" - ) - - func main() { - enFormula := plural.Formula("en_US") - xxFormula := plural.Formula("zh_CN") - - fmt.Printf("%s: %d\n", "en", enFormula(0)) - fmt.Printf("%s: %d\n", "en", enFormula(1)) - fmt.Printf("%s: %d\n", "en", enFormula(2)) - fmt.Printf("%s: %d\n", "??", xxFormula(0)) - fmt.Printf("%s: %d\n", "??", xxFormula(1)) - fmt.Printf("%s: %d\n", "??", xxFormula(2)) - fmt.Printf("%s: %d\n", "??", xxFormula(9)) - // Output: - // en: 0 - // en: 0 - // en: 1 - // ??: 0 - // ??: 0 - // ??: 1 - // ??: 8 - } - -See http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html -*/ -package plural diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/doc.go b/vendor/github.com/chai2010/gettext-go/gettext/po/doc.go deleted file mode 100644 index 12bac8f2a2..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/po/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package po provides support for reading and writing GNU PO file. - -Examples: - import ( - "github.com/chai2010/gettext-go/gettext/po" - ) - - func main() { - poFile, err := po.Load("test.po") - if err != nil { - log.Fatal(err) - } - fmt.Printf("%v", poFile) - } - -The GNU PO file specification is at -http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html. -*/ -package po diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/file.go b/vendor/github.com/chai2010/gettext-go/gettext/po/file.go deleted file mode 100644 index a9b7abf949..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/po/file.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package po - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "sort" -) - -// File represents an PO File. -// -// See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html -type File struct { - MimeHeader Header - Messages []Message -} - -// Load loads a named po file. -func Load(name string) (*File, error) { - data, err := ioutil.ReadFile(name) - if err != nil { - return nil, err - } - return LoadData(data) -} - -// LoadData loads po file format data. -func LoadData(data []byte) (*File, error) { - r := newLineReader(string(data)) - var file File - for { - var msg Message - if err := msg.readPoEntry(r); err != nil { - if err == io.EOF { - return &file, nil - } - return nil, err - } - if msg.MsgId == "" { - file.MimeHeader.parseHeader(&msg) - continue - } - file.Messages = append(file.Messages, msg) - } -} - -// Save saves a po file. -func (f *File) Save(name string) error { - return ioutil.WriteFile(name, []byte(f.String()), 0666) -} - -// Save returns a po file format data. -func (f *File) Data() []byte { - // sort the massge as ReferenceFile/ReferenceLine field - var messages []Message - messages = append(messages, f.Messages...) - sort.Sort(byMessages(messages)) - - var buf bytes.Buffer - fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) - for i := 0; i < len(messages); i++ { - fmt.Fprintf(&buf, "%s\n", messages[i].String()) - } - return buf.Bytes() -} - -// String returns the po format file string. -func (f *File) String() string { - return string(f.Data()) -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/message.go b/vendor/github.com/chai2010/gettext-go/gettext/po/message.go deleted file mode 100644 index a2cf2512c7..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/po/message.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package po - -import ( - "bytes" - "fmt" - "io" - "strconv" - "strings" -) - -// A PO file is made up of many entries, -// each entry holding the relation between an original untranslated string -// and its corresponding translation. -// -// See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html -type Message struct { - Comment // Coments - MsgContext string // msgctxt context - MsgId string // msgid untranslated-string - MsgIdPlural string // msgid_plural untranslated-string-plural - MsgStr string // msgstr translated-string - MsgStrPlural []string // msgstr[0] translated-string-case-0 -} - -type byMessages []Message - -func (d byMessages) Len() int { - return len(d) -} -func (d byMessages) Less(i, j int) bool { - if d[i].Comment.less(&d[j].Comment) { - return true - } - if a, b := d[i].MsgContext, d[j].MsgContext; a != b { - return a < b - } - if a, b := d[i].MsgId, d[j].MsgId; a != b { - return a < b - } - if a, b := d[i].MsgIdPlural, d[j].MsgIdPlural; a != b { - return a < b - } - return false -} -func (d byMessages) Swap(i, j int) { - d[i], d[j] = d[j], d[i] -} - -func (p *Message) readPoEntry(r *lineReader) (err error) { - *p = Message{} - if err = r.skipBlankLine(); err != nil { - return - } - defer func(oldPos int) { - newPos := r.currentPos() - if newPos != oldPos && err == io.EOF { - err = nil - } - }(r.currentPos()) - - if err = p.Comment.readPoComment(r); err != nil { - return - } - for { - var s string - if s, _, err = r.currentLine(); err != nil { - return - } - - if p.isInvalidLine(s) { - err = fmt.Errorf("gettext: line %d, %v", r.currentPos(), "invalid line") - return - } - if reComment.MatchString(s) || reBlankLine.MatchString(s) { - return - } - - if err = p.readMsgContext(r); err != nil { - return - } - if err = p.readMsgId(r); err != nil { - return - } - if err = p.readMsgIdPlural(r); err != nil { - return - } - if err = p.readMsgStrOrPlural(r); err != nil { - return - } - } -} - -func (p *Message) readMsgContext(r *lineReader) (err error) { - var s string - if s, _, err = r.currentLine(); err != nil { - return - } - if !reMsgContext.MatchString(s) { - return - } - p.MsgContext, err = p.readString(r) - return -} - -func (p *Message) readMsgId(r *lineReader) (err error) { - var s string - if s, _, err = r.currentLine(); err != nil { - return - } - if !reMsgId.MatchString(s) { - return - } - p.MsgId, err = p.readString(r) - return -} - -func (p *Message) readMsgIdPlural(r *lineReader) (err error) { - var s string - if s, _, err = r.currentLine(); err != nil { - return - } - if !reMsgIdPlural.MatchString(s) { - return - } - p.MsgIdPlural, err = p.readString(r) - return nil -} - -func (p *Message) readMsgStrOrPlural(r *lineReader) (err error) { - var s string - if s, _, err = r.currentLine(); err != nil { - return - } - if !reMsgStr.MatchString(s) && !reMsgStrPlural.MatchString(s) { - return - } - if reMsgStrPlural.MatchString(s) { - left, right := strings.Index(s, `[`), strings.LastIndex(s, `]`) - idx, _ := strconv.Atoi(s[left+1 : right]) - s, err = p.readString(r) - if n := len(p.MsgStrPlural); (idx + 1) > n { - p.MsgStrPlural = append(p.MsgStrPlural, make([]string, (idx+1)-n)...) - } - p.MsgStrPlural[idx] = s - } else { - p.MsgStr, err = p.readString(r) - } - return nil -} - -func (p *Message) readString(r *lineReader) (msg string, err error) { - var s string - if s, _, err = r.readLine(); err != nil { - return - } - msg += decodePoString(s) - for { - if s, _, err = r.readLine(); err != nil { - return - } - if !reStringLine.MatchString(s) { - r.unreadLine() - break - } - msg += decodePoString(s) - } - return -} - -// String returns the po format entry string. -func (p Message) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "%s", p.Comment.String()) - fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) - if p.MsgIdPlural != "" { - fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) - } - if p.MsgStr != "" { - fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) - } - for i := 0; i < len(p.MsgStrPlural); i++ { - fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) - } - return buf.String() -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/util.go b/vendor/github.com/chai2010/gettext-go/gettext/po/util.go deleted file mode 100644 index 52544832cf..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/po/util.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package po - -import ( - "bytes" - "strings" -) - -func decodePoString(text string) string { - lines := strings.Split(text, "\n") - for i := 0; i < len(lines); i++ { - left := strings.Index(lines[i], `"`) - right := strings.LastIndex(lines[i], `"`) - if left < 0 || right < 0 || left == right { - lines[i] = "" - continue - } - line := lines[i][left+1 : right] - data := make([]byte, 0, len(line)) - for i := 0; i < len(line); i++ { - if line[i] != '\\' { - data = append(data, line[i]) - continue - } - if i+1 >= len(line) { - break - } - switch line[i+1] { - case 'n': // \\n -> \n - data = append(data, '\n') - i++ - case 't': // \\t -> \n - data = append(data, '\t') - i++ - case '\\': // \\\ -> ? - data = append(data, '\\') - i++ - } - } - lines[i] = string(data) - } - return strings.Join(lines, "") -} - -func encodePoString(text string) string { - var buf bytes.Buffer - lines := strings.Split(text, "\n") - for i := 0; i < len(lines); i++ { - if lines[i] == "" { - if i != len(lines)-1 { - buf.WriteString(`"\n"` + "\n") - } - continue - } - buf.WriteRune('"') - for _, r := range lines[i] { - switch r { - case '\\': - buf.WriteString(`\\`) - case '"': - buf.WriteString(`\"`) - case '\n': - buf.WriteString(`\n`) - case '\t': - buf.WriteString(`\t`) - default: - buf.WriteRune(r) - } - } - buf.WriteString(`\n"` + "\n") - } - return buf.String() -} - -func encodeCommentPoString(text string) string { - var buf bytes.Buffer - lines := strings.Split(text, "\n") - if len(lines) > 1 { - buf.WriteString(`""` + "\n") - } - for i := 0; i < len(lines); i++ { - if len(lines) > 0 { - buf.WriteString("#| ") - } - buf.WriteRune('"') - for _, r := range lines[i] { - switch r { - case '\\': - buf.WriteString(`\\`) - case '"': - buf.WriteString(`\"`) - case '\n': - buf.WriteString(`\n`) - case '\t': - buf.WriteString(`\t`) - default: - buf.WriteRune(r) - } - } - if i < len(lines)-1 { - buf.WriteString(`\n"` + "\n") - } else { - buf.WriteString(`"`) - } - } - return buf.String() -} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/tr.go b/vendor/github.com/chai2010/gettext-go/gettext/tr.go deleted file mode 100644 index fedfbc301d..0000000000 --- a/vendor/github.com/chai2010/gettext-go/gettext/tr.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2013 ChaiShushan . All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gettext - -import ( - "github.com/chai2010/gettext-go/gettext/mo" - "github.com/chai2010/gettext-go/gettext/plural" - "github.com/chai2010/gettext-go/gettext/po" -) - -var nilTranslator = &translator{ - MessageMap: make(map[string]mo.Message), - PluralFormula: plural.Formula("??"), -} - -type translator struct { - MessageMap map[string]mo.Message - PluralFormula func(n int) int -} - -func newMoTranslator(name string, data []byte) (*translator, error) { - var ( - f *mo.File - err error - ) - if len(data) != 0 { - f, err = mo.LoadData(data) - } else { - f, err = mo.Load(name) - } - if err != nil { - return nil, err - } - var tr = &translator{ - MessageMap: make(map[string]mo.Message), - } - for _, v := range f.Messages { - tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = v - } - if lang := f.MimeHeader.Language; lang != "" { - tr.PluralFormula = plural.Formula(lang) - } else { - tr.PluralFormula = plural.Formula("??") - } - return tr, nil -} - -func newPoTranslator(name string, data []byte) (*translator, error) { - var ( - f *po.File - err error - ) - if len(data) != 0 { - f, err = po.LoadData(data) - } else { - f, err = po.Load(name) - } - if err != nil { - return nil, err - } - var tr = &translator{ - MessageMap: make(map[string]mo.Message), - } - for _, v := range f.Messages { - tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{ - MsgContext: v.MsgContext, - MsgId: v.MsgId, - MsgIdPlural: v.MsgIdPlural, - MsgStr: v.MsgStr, - MsgStrPlural: v.MsgStrPlural, - } - } - if lang := f.MimeHeader.Language; lang != "" { - tr.PluralFormula = plural.Formula(lang) - } else { - tr.PluralFormula = plural.Formula("??") - } - return tr, nil -} - -func (p *translator) PGettext(msgctxt, msgid string) string { - return p.PNGettext(msgctxt, msgid, "", 0) -} - -func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { - n = p.PluralFormula(n) - if ss := p.findMsgStrPlural(msgctxt, msgid, msgidPlural); len(ss) != 0 { - if n >= len(ss) { - n = len(ss) - 1 - } - if ss[n] != "" { - return ss[n] - } - } - if msgidPlural != "" && n > 0 { - return msgidPlural - } - return msgid -} - -func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string { - key := p.makeMapKey(msgctxt, msgid) - if v, ok := p.MessageMap[key]; ok { - if len(v.MsgIdPlural) != 0 { - if len(v.MsgStrPlural) != 0 { - return v.MsgStrPlural - } else { - return nil - } - } else { - if len(v.MsgStr) != 0 { - return []string{v.MsgStr} - } else { - return nil - } - } - } - return nil -} - -func (p *translator) makeMapKey(msgctxt, msgid string) string { - if msgctxt != "" { - return msgctxt + mo.EotSeparator + msgid - } - return msgid -} diff --git a/vendor/github.com/chai2010/gettext-go/locale.go b/vendor/github.com/chai2010/gettext-go/locale.go new file mode 100644 index 0000000000..e7a2d4b37b --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/locale.go @@ -0,0 +1,205 @@ +// Copyright 2020 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "fmt" + "sync" +) + +type _Locale struct { + mutex sync.Mutex + fs FileSystem + lang string + domain string + trMap map[string]*translator + trCurrent *translator +} + +var _ Gettexter = (*_Locale)(nil) + +func newLocale(domain, path string, data ...interface{}) *_Locale { + if domain == "" { + domain = "default" + } + p := &_Locale{ + lang: DefaultLanguage, + domain: domain, + } + if len(data) > 0 { + p.fs = NewFS(path, data[0]) + } else { + p.fs = NewFS(path, nil) + } + + p.syncTrMap() + return p +} + +func (p *_Locale) makeTrMapKey(domain, _Locale string) string { + return domain + "_$$$_" + _Locale +} + +func (p *_Locale) FileSystem() FileSystem { + return p.fs +} + +func (p *_Locale) GetLanguage() string { + p.mutex.Lock() + defer p.mutex.Unlock() + + return p.lang +} +func (p *_Locale) SetLanguage(lang string) Gettexter { + p.mutex.Lock() + defer p.mutex.Unlock() + + if lang == "" { + lang = DefaultLanguage + } + if lang == p.lang { + return p + } + + p.lang = lang + p.syncTrMap() + return p +} + +func (p *_Locale) GetDomain() string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.domain +} + +func (p *_Locale) SetDomain(domain string) Gettexter { + p.mutex.Lock() + defer p.mutex.Unlock() + + if domain == "" || domain == p.domain { + return p + } + + p.domain = domain + p.syncTrMap() + return p +} + +func (p *_Locale) syncTrMap() { + p.trMap = make(map[string]*translator) + trMapKey := p.makeTrMapKey(p.domain, p.lang) + + if tr, ok := p.trMap[trMapKey]; ok { + p.trCurrent = tr + return + } + + // try load po file + if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".po"); err == nil { + if tr, err := newPoTranslator(fmt.Sprintf("%s_%s.po", p.domain, p.lang), data); err == nil { + p.trMap[trMapKey] = tr + p.trCurrent = tr + return + } + } + + // try load mo file + if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".mo"); err == nil { + if tr, err := newMoTranslator(fmt.Sprintf("%s_%s.mo", p.domain, p.lang), data); err == nil { + p.trMap[trMapKey] = tr + p.trCurrent = tr + return + } + } + + // try load json file + if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".json"); err == nil { + if tr, err := newJsonTranslator(p.lang, fmt.Sprintf("%s_%s.json", p.domain, p.lang), data); err == nil { + p.trMap[trMapKey] = tr + p.trCurrent = tr + return + } + } + + // no po/mo file + p.trMap[trMapKey] = nilTranslator + p.trCurrent = nilTranslator + return +} + +func (p *_Locale) Gettext(msgid string) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.trCurrent.PGettext("", msgid) +} + +func (p *_Locale) PGettext(msgctxt, msgid string) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.trCurrent.PGettext(msgctxt, msgid) +} + +func (p *_Locale) NGettext(msgid, msgidPlural string, n int) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.trCurrent.PNGettext("", msgid, msgidPlural, n) +} + +func (p *_Locale) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.trCurrent.PNGettext(msgctxt, msgid, msgidPlural, n) +} + +func (p *_Locale) DGettext(domain, msgid string) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.gettext(domain, "", msgid, "", 0) +} + +func (p *_Locale) DNGettext(domain, msgid, msgidPlural string, n int) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.gettext(domain, "", msgid, msgidPlural, n) +} + +func (p *_Locale) DPGettext(domain, msgctxt, msgid string) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.gettext(domain, msgctxt, msgid, "", 0) +} + +func (p *_Locale) DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { + p.mutex.Lock() + defer p.mutex.Unlock() + return p.gettext(domain, msgctxt, msgid, msgidPlural, n) +} + +func (p *_Locale) Getdata(name string) []byte { + return p.getdata(p.domain, name) +} + +func (p *_Locale) DGetdata(domain, name string) []byte { + return p.getdata(domain, name) +} + +func (p *_Locale) gettext(domain, msgctxt, msgid, msgidPlural string, n int) string { + if f, ok := p.trMap[p.makeTrMapKey(domain, p.lang)]; ok { + return f.PNGettext(msgctxt, msgid, msgidPlural, n) + } + return msgid +} + +func (p *_Locale) getdata(domain, name string) []byte { + if data, err := p.fs.LoadResourceFile(domain, p.lang, name); err == nil { + return data + } + if p.lang != "default" { + if data, err := p.fs.LoadResourceFile(domain, "default", name); err == nil { + return data + } + } + return nil +} diff --git a/vendor/github.com/chai2010/gettext-go/mo/doc.go b/vendor/github.com/chai2010/gettext-go/mo/doc.go new file mode 100644 index 0000000000..5fefc18930 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/mo/doc.go @@ -0,0 +1,74 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package mo provides support for reading and writing GNU MO file. + +Examples: + import ( + "github.com/chai2010/gettext-go/mo" + ) + + func main() { + moFile, err := mo.LoadFile("test.mo") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%v", moFile) + } + +GNU MO file struct: + + byte + +------------------------------------------+ + 0 | magic number = 0x950412de | + | | + 4 | file format revision = 0 | + | | + 8 | number of strings | == N + | | + 12 | offset of table with original strings | == O + | | + 16 | offset of table with translation strings | == T + | | + 20 | size of hashing table | == S + | | + 24 | offset of hashing table | == H + | | + . . + . (possibly more entries later) . + . . + | | + O | length & offset 0th string ----------------. + O + 8 | length & offset 1st string ------------------. + ... ... | | + O + ((N-1)*8)| length & offset (N-1)th string | | | + | | | | + T | length & offset 0th translation ---------------. + T + 8 | length & offset 1st translation -----------------. + ... ... | | | | + T + ((N-1)*8)| length & offset (N-1)th translation | | | | | + | | | | | | + H | start hash table | | | | | + ... ... | | | | + H + S * 4 | end hash table | | | | | + | | | | | | + | NUL terminated 0th string <----------------' | | | + | | | | | + | NUL terminated 1st string <------------------' | | + | | | | + ... ... | | + | | | | + | NUL terminated 0th translation <---------------' | + | | | + | NUL terminated 1st translation <-----------------' + | | + ... ... + | | + +------------------------------------------+ + +The GNU MO file specification is at +http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html. +*/ +package mo diff --git a/vendor/github.com/chai2010/gettext-go/mo/encoder.go b/vendor/github.com/chai2010/gettext-go/mo/encoder.go new file mode 100644 index 0000000000..f953fd3cb8 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/mo/encoder.go @@ -0,0 +1,105 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mo + +import ( + "bytes" + "encoding/binary" + "sort" + "strings" +) + +type moHeader struct { + MagicNumber uint32 + MajorVersion uint16 + MinorVersion uint16 + MsgIdCount uint32 + MsgIdOffset uint32 + MsgStrOffset uint32 + HashSize uint32 + HashOffset uint32 +} + +type moStrPos struct { + Size uint32 // must keep fields order + Addr uint32 +} + +func encodeFile(f *File) []byte { + hdr := &moHeader{ + MagicNumber: MoMagicLittleEndian, + } + data := encodeData(hdr, f) + data = append(encodeHeader(hdr), data...) + return data +} + +// encode data and init moHeader +func encodeData(hdr *moHeader, f *File) []byte { + msgList := []Message{f.MimeHeader.toMessage()} + for _, v := range f.Messages { + if len(v.MsgId) == 0 { + continue + } + if len(v.MsgStr) == 0 && len(v.MsgStrPlural) == 0 { + continue + } + msgList = append(msgList, v) + } + sort.Slice(msgList, func(i, j int) bool { + return msgList[i].less(&msgList[j]) + }) + + var buf bytes.Buffer + var msgIdPosList = make([]moStrPos, len(msgList)) + var msgStrPosList = make([]moStrPos, len(msgList)) + for i, v := range msgList { + // write msgid + msgId := encodeMsgId(v) + msgIdPosList[i].Addr = uint32(buf.Len() + MoHeaderSize) + msgIdPosList[i].Size = uint32(len(msgId)) + buf.WriteString(msgId) + // write msgstr + msgStr := encodeMsgStr(v) + msgStrPosList[i].Addr = uint32(buf.Len() + MoHeaderSize) + msgStrPosList[i].Size = uint32(len(msgStr)) + buf.WriteString(msgStr) + } + + hdr.MsgIdOffset = uint32(buf.Len() + MoHeaderSize) + binary.Write(&buf, binary.LittleEndian, msgIdPosList) + hdr.MsgStrOffset = uint32(buf.Len() + MoHeaderSize) + binary.Write(&buf, binary.LittleEndian, msgStrPosList) + + hdr.MsgIdCount = uint32(len(msgList)) + return buf.Bytes() +} + +// must called after encodeData +func encodeHeader(hdr *moHeader) []byte { + var buf bytes.Buffer + binary.Write(&buf, binary.LittleEndian, hdr) + return buf.Bytes() +} + +func encodeMsgId(v Message) string { + if v.MsgContext != "" && v.MsgIdPlural != "" { + return v.MsgContext + EotSeparator + v.MsgId + NulSeparator + v.MsgIdPlural + } + if v.MsgContext != "" && v.MsgIdPlural == "" { + return v.MsgContext + EotSeparator + v.MsgId + } + if v.MsgContext == "" && v.MsgIdPlural != "" { + return v.MsgId + NulSeparator + v.MsgIdPlural + } + return v.MsgId +} + +func encodeMsgStr(v Message) string { + if v.MsgIdPlural != "" { + return strings.Join(v.MsgStrPlural, NulSeparator) + } + return v.MsgStr +} diff --git a/vendor/github.com/chai2010/gettext-go/mo/file.go b/vendor/github.com/chai2010/gettext-go/mo/file.go new file mode 100644 index 0000000000..6f7ed161c1 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/mo/file.go @@ -0,0 +1,197 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mo + +import ( + "bytes" + "encoding/binary" + "fmt" + "io/ioutil" + "strings" +) + +const ( + MoHeaderSize = 28 + MoMagicLittleEndian = 0x950412de + MoMagicBigEndian = 0xde120495 + + EotSeparator = "\x04" // msgctxt and msgid separator + NulSeparator = "\x00" // msgid and msgstr separator +) + +// File represents an MO File. +// +// See http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html +type File struct { + MagicNumber uint32 + MajorVersion uint16 + MinorVersion uint16 + MsgIdCount uint32 + MsgIdOffset uint32 + MsgStrOffset uint32 + HashSize uint32 + HashOffset uint32 + MimeHeader Header + Messages []Message +} + +// Load loads mo file format data. +func Load(data []byte) (*File, error) { + return loadData(data) +} + +// Load loads a named mo file. +func LoadFile(path string) (*File, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + return loadData(data) +} + +func loadData(data []byte) (*File, error) { + r := bytes.NewReader(data) + + var magicNumber uint32 + if err := binary.Read(r, binary.LittleEndian, &magicNumber); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + var bo binary.ByteOrder + switch magicNumber { + case MoMagicLittleEndian: + bo = binary.LittleEndian + case MoMagicBigEndian: + bo = binary.BigEndian + default: + return nil, fmt.Errorf("gettext: %v", "invalid magic number") + } + + var header struct { + MajorVersion uint16 + MinorVersion uint16 + MsgIdCount uint32 + MsgIdOffset uint32 + MsgStrOffset uint32 + HashSize uint32 + HashOffset uint32 + } + if err := binary.Read(r, bo, &header); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + if v := header.MajorVersion; v != 0 && v != 1 { + return nil, fmt.Errorf("gettext: %v", "invalid version number") + } + if v := header.MinorVersion; v != 0 && v != 1 { + return nil, fmt.Errorf("gettext: %v", "invalid version number") + } + + msgIdStart := make([]uint32, header.MsgIdCount) + msgIdLen := make([]uint32, header.MsgIdCount) + if _, err := r.Seek(int64(header.MsgIdOffset), 0); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + for i := 0; i < int(header.MsgIdCount); i++ { + if err := binary.Read(r, bo, &msgIdLen[i]); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + if err := binary.Read(r, bo, &msgIdStart[i]); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + } + + msgStrStart := make([]int32, header.MsgIdCount) + msgStrLen := make([]int32, header.MsgIdCount) + if _, err := r.Seek(int64(header.MsgStrOffset), 0); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + for i := 0; i < int(header.MsgIdCount); i++ { + if err := binary.Read(r, bo, &msgStrLen[i]); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + if err := binary.Read(r, bo, &msgStrStart[i]); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + } + + file := &File{ + MagicNumber: magicNumber, + MajorVersion: header.MajorVersion, + MinorVersion: header.MinorVersion, + MsgIdCount: header.MsgIdCount, + MsgIdOffset: header.MsgIdOffset, + MsgStrOffset: header.MsgStrOffset, + HashSize: header.HashSize, + HashOffset: header.HashOffset, + } + for i := 0; i < int(header.MsgIdCount); i++ { + if _, err := r.Seek(int64(msgIdStart[i]), 0); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + msgIdData := make([]byte, msgIdLen[i]) + if _, err := r.Read(msgIdData); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + + if _, err := r.Seek(int64(msgStrStart[i]), 0); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + msgStrData := make([]byte, msgStrLen[i]) + if _, err := r.Read(msgStrData); err != nil { + return nil, fmt.Errorf("gettext: %v", err) + } + + if len(msgIdData) == 0 { + var msg = Message{ + MsgId: string(msgIdData), + MsgStr: string(msgStrData), + } + file.MimeHeader.fromMessage(&msg) + } else { + var msg = Message{ + MsgId: string(msgIdData), + MsgStr: string(msgStrData), + } + // Is this a context message? + if idx := strings.Index(msg.MsgId, EotSeparator); idx != -1 { + msg.MsgContext, msg.MsgId = msg.MsgId[:idx], msg.MsgId[idx+1:] + } + // Is this a plural message? + if idx := strings.Index(msg.MsgId, NulSeparator); idx != -1 { + msg.MsgId, msg.MsgIdPlural = msg.MsgId[:idx], msg.MsgId[idx+1:] + msg.MsgStrPlural = strings.Split(msg.MsgStr, NulSeparator) + msg.MsgStr = "" + } + file.Messages = append(file.Messages, msg) + } + } + + return file, nil +} + +// Save saves a mo file. +func (f *File) Save(name string) error { + return ioutil.WriteFile(name, f.Data(), 0666) +} + +// Save returns a mo file format data. +func (f *File) Data() []byte { + return encodeFile(f) +} + +// String returns the po format file string. +func (f *File) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "# version: %d.%d\n", f.MajorVersion, f.MinorVersion) + fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) + fmt.Fprintf(&buf, "\n") + + for k, v := range f.Messages { + fmt.Fprintf(&buf, `msgid "%v"`+"\n", k) + fmt.Fprintf(&buf, `msgstr "%s"`+"\n", v.MsgStr) + fmt.Fprintf(&buf, "\n") + } + + return buf.String() +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/header.go b/vendor/github.com/chai2010/gettext-go/mo/header.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/mo/header.go rename to vendor/github.com/chai2010/gettext-go/mo/header.go diff --git a/vendor/github.com/chai2010/gettext-go/mo/message.go b/vendor/github.com/chai2010/gettext-go/mo/message.go new file mode 100644 index 0000000000..b67bde0b70 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/mo/message.go @@ -0,0 +1,52 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mo + +import ( + "bytes" + "fmt" +) + +// A MO file is made up of many entries, +// each entry holding the relation between an original untranslated string +// and its corresponding translation. +// +// See http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html +type Message struct { + MsgContext string // msgctxt context + MsgId string // msgid untranslated-string + MsgIdPlural string // msgid_plural untranslated-string-plural + MsgStr string // msgstr translated-string + MsgStrPlural []string // msgstr[0] translated-string-case-0 +} + +// String returns the po format entry string. +func (p Message) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) + if p.MsgIdPlural != "" { + fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) + } + if p.MsgStr != "" { + fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) + } + for i := 0; i < len(p.MsgStrPlural); i++ { + fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) + } + return buf.String() +} + +func (m_i *Message) less(m_j *Message) bool { + if a, b := m_i.MsgContext, m_j.MsgContext; a != b { + return a < b + } + if a, b := m_i.MsgId, m_j.MsgId; a != b { + return a < b + } + if a, b := m_i.MsgIdPlural, m_j.MsgIdPlural; a != b { + return a < b + } + return false +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/mo/util.go b/vendor/github.com/chai2010/gettext-go/mo/util.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/mo/util.go rename to vendor/github.com/chai2010/gettext-go/mo/util.go diff --git a/vendor/github.com/chai2010/gettext-go/plural/doc.go b/vendor/github.com/chai2010/gettext-go/plural/doc.go new file mode 100644 index 0000000000..31cb8fae9f --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/plural/doc.go @@ -0,0 +1,36 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package plural provides standard plural formulas. + +Examples: + import ( + "github.com/chai2010/gettext-go/plural" + ) + + func main() { + enFormula := plural.Formula("en_US") + xxFormula := plural.Formula("zh_CN") + + fmt.Printf("%s: %d\n", "en", enFormula(0)) + fmt.Printf("%s: %d\n", "en", enFormula(1)) + fmt.Printf("%s: %d\n", "en", enFormula(2)) + fmt.Printf("%s: %d\n", "??", xxFormula(0)) + fmt.Printf("%s: %d\n", "??", xxFormula(1)) + fmt.Printf("%s: %d\n", "??", xxFormula(2)) + fmt.Printf("%s: %d\n", "??", xxFormula(9)) + // Output: + // en: 0 + // en: 0 + // en: 1 + // ??: 0 + // ??: 0 + // ??: 1 + // ??: 8 + } + +See http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html +*/ +package plural diff --git a/vendor/github.com/chai2010/gettext-go/gettext/plural/formula.go b/vendor/github.com/chai2010/gettext-go/plural/formula.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/plural/formula.go rename to vendor/github.com/chai2010/gettext-go/plural/formula.go diff --git a/vendor/github.com/chai2010/gettext-go/gettext/plural/table.go b/vendor/github.com/chai2010/gettext-go/plural/table.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/plural/table.go rename to vendor/github.com/chai2010/gettext-go/plural/table.go diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/comment.go b/vendor/github.com/chai2010/gettext-go/po/comment.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/po/comment.go rename to vendor/github.com/chai2010/gettext-go/po/comment.go diff --git a/vendor/github.com/chai2010/gettext-go/po/doc.go b/vendor/github.com/chai2010/gettext-go/po/doc.go new file mode 100644 index 0000000000..6cfa2a24be --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/po/doc.go @@ -0,0 +1,24 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package po provides support for reading and writing GNU PO file. + +Examples: + import ( + "github.com/chai2010/gettext-go/po" + ) + + func main() { + poFile, err := po.LoadFile("test.po") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%v", poFile) + } + +The GNU PO file specification is at +http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html. +*/ +package po diff --git a/vendor/github.com/chai2010/gettext-go/po/file.go b/vendor/github.com/chai2010/gettext-go/po/file.go new file mode 100644 index 0000000000..4a122eeb8b --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/po/file.go @@ -0,0 +1,81 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package po + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "sort" +) + +// File represents an PO File. +// +// See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html +type File struct { + MimeHeader Header + Messages []Message +} + +// Load loads po file format data. +func Load(data []byte) (*File, error) { + return loadData(data) +} + +// LoadFile loads a named po file. +func LoadFile(path string) (*File, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + return loadData(data) +} + +func loadData(data []byte) (*File, error) { + r := newLineReader(string(data)) + var file File + for { + var msg Message + if err := msg.readPoEntry(r); err != nil { + if err == io.EOF { + return &file, nil + } + return nil, err + } + if msg.MsgId == "" { + file.MimeHeader.parseHeader(&msg) + continue + } + file.Messages = append(file.Messages, msg) + } +} + +// Save saves a po file. +func (f *File) Save(name string) error { + return ioutil.WriteFile(name, []byte(f.String()), 0666) +} + +// Save returns a po file format data. +func (f *File) Data() []byte { + // sort the massge as ReferenceFile/ReferenceLine field + var messages []Message + messages = append(messages, f.Messages...) + sort.Slice(messages, func(i, j int) bool { + return messages[i].less(&messages[j]) + }) + + var buf bytes.Buffer + fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) + for i := 0; i < len(messages); i++ { + fmt.Fprintf(&buf, "%s\n", messages[i].String()) + } + return buf.Bytes() +} + +// String returns the po format file string. +func (f *File) String() string { + return string(f.Data()) +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/header.go b/vendor/github.com/chai2010/gettext-go/po/header.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/po/header.go rename to vendor/github.com/chai2010/gettext-go/po/header.go diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/line_reader.go b/vendor/github.com/chai2010/gettext-go/po/line_reader.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/po/line_reader.go rename to vendor/github.com/chai2010/gettext-go/po/line_reader.go diff --git a/vendor/github.com/chai2010/gettext-go/po/message.go b/vendor/github.com/chai2010/gettext-go/po/message.go new file mode 100644 index 0000000000..39936dcc7b --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/po/message.go @@ -0,0 +1,193 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package po + +import ( + "bytes" + "fmt" + "io" + "strconv" + "strings" +) + +// A PO file is made up of many entries, +// each entry holding the relation between an original untranslated string +// and its corresponding translation. +// +// See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html +type Message struct { + Comment // Coments + MsgContext string // msgctxt context + MsgId string // msgid untranslated-string + MsgIdPlural string // msgid_plural untranslated-string-plural + MsgStr string // msgstr translated-string + MsgStrPlural []string // msgstr[0] translated-string-case-0 +} + +func (p *Message) less(q *Message) bool { + if p.Comment.less(&q.Comment) { + return true + } + if a, b := p.MsgContext, q.MsgContext; a != b { + return a < b + } + if a, b := p.MsgId, q.MsgId; a != b { + return a < b + } + if a, b := p.MsgIdPlural, q.MsgIdPlural; a != b { + return a < b + } + return false +} + +func (p *Message) readPoEntry(r *lineReader) (err error) { + *p = Message{} + if err = r.skipBlankLine(); err != nil { + return + } + defer func(oldPos int) { + newPos := r.currentPos() + if newPos != oldPos && err == io.EOF { + err = nil + } + }(r.currentPos()) + + if err = p.Comment.readPoComment(r); err != nil { + return + } + for { + var s string + if s, _, err = r.currentLine(); err != nil { + return + } + + if p.isInvalidLine(s) { + err = fmt.Errorf("gettext: line %d, %v", r.currentPos(), "invalid line") + return + } + if reComment.MatchString(s) || reBlankLine.MatchString(s) { + return + } + + if err = p.readMsgContext(r); err != nil { + return + } + if err = p.readMsgId(r); err != nil { + return + } + if err = p.readMsgIdPlural(r); err != nil { + return + } + if err = p.readMsgStrOrPlural(r); err != nil { + return + } + } +} + +func (p *Message) readMsgContext(r *lineReader) (err error) { + var s string + if s, _, err = r.currentLine(); err != nil { + return + } + if !reMsgContext.MatchString(s) { + return + } + p.MsgContext, err = p.readString(r) + return +} + +func (p *Message) readMsgId(r *lineReader) (err error) { + var s string + if s, _, err = r.currentLine(); err != nil { + return + } + if !reMsgId.MatchString(s) { + return + } + p.MsgId, err = p.readString(r) + return +} + +func (p *Message) readMsgIdPlural(r *lineReader) (err error) { + var s string + if s, _, err = r.currentLine(); err != nil { + return + } + if !reMsgIdPlural.MatchString(s) { + return + } + p.MsgIdPlural, err = p.readString(r) + return nil +} + +func (p *Message) readMsgStrOrPlural(r *lineReader) (err error) { + var s string + if s, _, err = r.currentLine(); err != nil { + return + } + if !reMsgStr.MatchString(s) && !reMsgStrPlural.MatchString(s) { + return + } + if reMsgStrPlural.MatchString(s) { + left, right := strings.Index(s, `[`), strings.LastIndex(s, `]`) + idx, _ := strconv.Atoi(s[left+1 : right]) + s, err = p.readString(r) + if n := len(p.MsgStrPlural); (idx + 1) > n { + p.MsgStrPlural = append(p.MsgStrPlural, make([]string, (idx+1)-n)...) + } + p.MsgStrPlural[idx] = s + } else { + p.MsgStr, err = p.readString(r) + } + return nil +} + +func (p *Message) readString(r *lineReader) (msg string, err error) { + var s string + if s, _, err = r.readLine(); err != nil { + return + } + msg += decodePoString(s) + for { + if s, _, err = r.readLine(); err != nil { + return + } + if !reStringLine.MatchString(s) { + r.unreadLine() + break + } + msg += decodePoString(s) + } + return +} + +// String returns the po format entry string. +func (p Message) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "%s", p.Comment.String()) + if p.MsgContext != "" { + fmt.Fprintf(&buf, "msgctxt %s", encodePoString(p.MsgContext)) + } + fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) + if p.MsgIdPlural != "" { + fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) + } + if len(p.MsgStrPlural) == 0 { + if p.MsgStr != "" { + fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) + } else { + fmt.Fprintf(&buf, "msgstr %s", `""`+"\n") + } + } else { + for i := 0; i < len(p.MsgStrPlural); i++ { + if p.MsgStrPlural[i] != "" { + fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) + } else { + fmt.Fprintf(&buf, "msgstr[%d] %s", i, `""`+"\n") + } + } + } + return buf.String() +} diff --git a/vendor/github.com/chai2010/gettext-go/gettext/po/re.go b/vendor/github.com/chai2010/gettext-go/po/re.go similarity index 100% rename from vendor/github.com/chai2010/gettext-go/gettext/po/re.go rename to vendor/github.com/chai2010/gettext-go/po/re.go diff --git a/vendor/github.com/chai2010/gettext-go/po/util.go b/vendor/github.com/chai2010/gettext-go/po/util.go new file mode 100644 index 0000000000..d8b3b0e254 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/po/util.go @@ -0,0 +1,114 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package po + +import ( + "bytes" + "strings" +) + +func decodePoString(text string) string { + lines := strings.Split(text, "\n") + for i := 0; i < len(lines); i++ { + left := strings.Index(lines[i], `"`) + right := strings.LastIndex(lines[i], `"`) + if left < 0 || right < 0 || left == right { + lines[i] = "" + continue + } + line := lines[i][left+1 : right] + data := make([]byte, 0, len(line)) + for i := 0; i < len(line); i++ { + if line[i] != '\\' { + data = append(data, line[i]) + continue + } + if i+1 >= len(line) { + break + } + switch line[i+1] { + case 'n': // \\n -> \n + data = append(data, '\n') + i++ + case 't': // \\t -> \n + data = append(data, '\t') + i++ + case '\\': // \\\ -> ? + data = append(data, '\\') + i++ + } + } + lines[i] = string(data) + } + return strings.Join(lines, "") +} + +func encodePoString(text string) string { + var buf bytes.Buffer + lines := strings.Split(text, "\n") + for i := 0; i < len(lines); i++ { + if lines[i] == "" { + if i != len(lines)-1 { + buf.WriteString(`"\n"` + "\n") + } + continue + } + buf.WriteRune('"') + for _, r := range lines[i] { + switch r { + case '\\': + buf.WriteString(`\\`) + case '"': + buf.WriteString(`\"`) + case '\n': + buf.WriteString(`\n`) + case '\t': + buf.WriteString(`\t`) + default: + buf.WriteRune(r) + } + } + if i < len(lines)-1 { + buf.WriteString(`\n"` + "\n") + } else { + buf.WriteString(`"` + "\n") + } + } + return buf.String() +} + +func encodeCommentPoString(text string) string { + var buf bytes.Buffer + lines := strings.Split(text, "\n") + if len(lines) > 1 { + buf.WriteString(`""` + "\n") + } + for i := 0; i < len(lines); i++ { + if len(lines) > 0 { + buf.WriteString("#| ") + } + buf.WriteRune('"') + for _, r := range lines[i] { + switch r { + case '\\': + buf.WriteString(`\\`) + case '"': + buf.WriteString(`\"`) + case '\n': + buf.WriteString(`\n`) + case '\t': + buf.WriteString(`\t`) + default: + buf.WriteRune(r) + } + } + if i < len(lines)-1 { + buf.WriteString(`\n"` + "\n") + } else { + buf.WriteString(`"`) + } + } + return buf.String() +} diff --git a/vendor/github.com/chai2010/gettext-go/tr.go b/vendor/github.com/chai2010/gettext-go/tr.go new file mode 100644 index 0000000000..5b9d08f426 --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/tr.go @@ -0,0 +1,175 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "encoding/json" + + "github.com/chai2010/gettext-go/mo" + "github.com/chai2010/gettext-go/plural" + "github.com/chai2010/gettext-go/po" +) + +var nilTranslator = &translator{ + MessageMap: make(map[string]mo.Message), + PluralFormula: plural.Formula("??"), +} + +type translator struct { + MessageMap map[string]mo.Message + PluralFormula func(n int) int +} + +func newMoTranslator(name string, data []byte) (*translator, error) { + var ( + f *mo.File + err error + ) + if len(data) != 0 { + f, err = mo.Load(data) + } else { + f, err = mo.LoadFile(name) + } + if err != nil { + return nil, err + } + var tr = &translator{ + MessageMap: make(map[string]mo.Message), + } + for _, v := range f.Messages { + tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = v + } + if lang := f.MimeHeader.Language; lang != "" { + tr.PluralFormula = plural.Formula(lang) + } else { + tr.PluralFormula = plural.Formula("??") + } + return tr, nil +} + +func newPoTranslator(name string, data []byte) (*translator, error) { + var ( + f *po.File + err error + ) + if len(data) != 0 { + f, err = po.Load(data) + } else { + f, err = po.LoadFile(name) + } + if err != nil { + return nil, err + } + var tr = &translator{ + MessageMap: make(map[string]mo.Message), + } + for _, v := range f.Messages { + tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{ + MsgContext: v.MsgContext, + MsgId: v.MsgId, + MsgIdPlural: v.MsgIdPlural, + MsgStr: v.MsgStr, + MsgStrPlural: v.MsgStrPlural, + } + } + if lang := f.MimeHeader.Language; lang != "" { + tr.PluralFormula = plural.Formula(lang) + } else { + tr.PluralFormula = plural.Formula("??") + } + return tr, nil +} + +func newJsonTranslator(lang, name string, jsonData []byte) (*translator, error) { + var msgList []struct { + MsgContext string `json:"msgctxt"` // msgctxt context + MsgId string `json:"msgid"` // msgid untranslated-string + MsgIdPlural string `json:"msgid_plural"` // msgid_plural untranslated-string-plural + MsgStr []string `json:"msgstr"` // msgstr translated-string + } + if err := json.Unmarshal(jsonData, &msgList); err != nil { + return nil, err + } + + var tr = &translator{ + MessageMap: make(map[string]mo.Message), + PluralFormula: plural.Formula(lang), + } + + for _, v := range msgList { + var v_MsgStr string + var v_MsgStrPlural = v.MsgStr + + if len(v.MsgStr) != 0 { + v_MsgStr = v.MsgStr[0] + } + + tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{ + MsgContext: v.MsgContext, + MsgId: v.MsgId, + MsgIdPlural: v.MsgIdPlural, + MsgStr: v_MsgStr, + MsgStrPlural: v_MsgStrPlural, + } + } + return tr, nil +} + +func (p *translator) PGettext(msgctxt, msgid string) string { + return p.findMsgStr(msgctxt, msgid) +} + +func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { + n = p.PluralFormula(n) + if ss := p.findMsgStrPlural(msgctxt, msgid, msgidPlural); len(ss) != 0 { + if n >= len(ss) { + n = len(ss) - 1 + } + if ss[n] != "" { + return ss[n] + } + } + if msgidPlural != "" && n > 0 { + return msgidPlural + } + return msgid +} + +func (p *translator) findMsgStr(msgctxt, msgid string) string { + key := p.makeMapKey(msgctxt, msgid) + if v, ok := p.MessageMap[key]; ok { + if v.MsgStr != "" { + return v.MsgStr + } + } + return msgid +} + +func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string { + key := p.makeMapKey(msgctxt, msgid) + if v, ok := p.MessageMap[key]; ok { + if len(v.MsgIdPlural) != 0 { + if len(v.MsgStrPlural) != 0 { + return v.MsgStrPlural + } else { + return nil + } + } else { + if len(v.MsgStr) != 0 { + return []string{v.MsgStr} + } else { + return nil + } + } + } + return nil +} + +func (p *translator) makeMapKey(msgctxt, msgid string) string { + if msgctxt != "" { + return msgctxt + mo.EotSeparator + msgid + } + return msgid +} diff --git a/vendor/github.com/chai2010/gettext-go/util.go b/vendor/github.com/chai2010/gettext-go/util.go new file mode 100644 index 0000000000..b8269a605c --- /dev/null +++ b/vendor/github.com/chai2010/gettext-go/util.go @@ -0,0 +1,34 @@ +// Copyright 2013 ChaiShushan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gettext + +import ( + "os" + "strings" +) + +func getDefaultLanguage() string { + if v := os.Getenv("LC_MESSAGES"); v != "" { + return simplifiedLanguage(v) + } + if v := os.Getenv("LANG"); v != "" { + return simplifiedLanguage(v) + } + return "default" +} + +func simplifiedLanguage(lang string) string { + // en_US/en_US.UTF-8/zh_CN/zh_TW/el_GR@euro/... + if idx := strings.Index(lang, ":"); idx != -1 { + lang = lang[:idx] + } + if idx := strings.Index(lang, "@"); idx != -1 { + lang = lang[:idx] + } + if idx := strings.Index(lang, "."); idx != -1 { + lang = lang[:idx] + } + return strings.TrimSpace(lang) +} diff --git a/vendor/github.com/containerd/containerd/archive/tar.go b/vendor/github.com/containerd/containerd/archive/tar.go index 62341d5e12..44b7949531 100644 --- a/vendor/github.com/containerd/containerd/archive/tar.go +++ b/vendor/github.com/containerd/containerd/archive/tar.go @@ -31,6 +31,7 @@ import ( "time" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/pkg/userns" "github.com/containerd/continuity/fs" ) @@ -119,6 +120,8 @@ const ( whiteoutOpaqueDir = whiteoutMetaPrefix + ".opq" paxSchilyXattr = "SCHILY.xattr." + + userXattrPrefix = "user." ) // Apply applies a tar stream of an OCI style diff tar. @@ -380,6 +383,10 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header // Lchown is not supported on Windows. if runtime.GOOS != "windows" { if err := os.Lchown(path, hdr.Uid, hdr.Gid); err != nil { + err = fmt.Errorf("failed to Lchown %q for UID %d, GID %d: %w", path, hdr.Uid, hdr.Gid, err) + if errors.Is(err, syscall.EINVAL) && userns.RunningInUserNS() { + err = fmt.Errorf("%w (Hint: try increasing the number of subordinate IDs in /etc/subuid and /etc/subgid)", err) + } return err } } @@ -388,11 +395,19 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header if strings.HasPrefix(key, paxSchilyXattr) { key = key[len(paxSchilyXattr):] if err := setxattr(path, key, value); err != nil { + if errors.Is(err, syscall.EPERM) && strings.HasPrefix(key, userXattrPrefix) { + // In the user.* namespace, only regular files and directories can have extended attributes. + // See https://man7.org/linux/man-pages/man7/xattr.7.html for details. + if fi, err := os.Lstat(path); err == nil && (!fi.Mode().IsRegular() && !fi.Mode().IsDir()) { + log.G(ctx).WithError(err).Warnf("ignored xattr %s in archive", key) + continue + } + } if errors.Is(err, syscall.ENOTSUP) { log.G(ctx).WithError(err).Warnf("ignored xattr %s in archive", key) continue } - return err + return fmt.Errorf("failed to setxattr %q for key %q: %w", path, key, err) } } } diff --git a/vendor/github.com/containerd/containerd/archive/tar_unix.go b/vendor/github.com/containerd/containerd/archive/tar_unix.go index 2f3a3a392e..854afcf0ad 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_unix.go +++ b/vendor/github.com/containerd/containerd/archive/tar_unix.go @@ -63,7 +63,7 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, fi os.FileInfo) err } // Rdev is int32 on darwin/bsd, int64 on linux/solaris - rdev := uint64(s.Rdev) // nolint: unconvert + rdev := uint64(s.Rdev) //nolint:unconvert // Currently go does not fill in the major/minors if s.Mode&syscall.S_IFBLK != 0 || diff --git a/vendor/github.com/containerd/containerd/content/helpers.go b/vendor/github.com/containerd/containerd/content/helpers.go index 3ec1ffce00..723c313917 100644 --- a/vendor/github.com/containerd/containerd/content/helpers.go +++ b/vendor/github.com/containerd/containerd/content/helpers.go @@ -26,10 +26,16 @@ import ( "time" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/log" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) +// maxResets is the no.of times the Copy() method can tolerate a reset of the body +const maxResets = 5 + +var ErrReset = errors.New("writer has been reset") + var bufPool = sync.Pool{ New: func() interface{} { buffer := make([]byte, 1<<20) @@ -80,7 +86,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, desc o return fmt.Errorf("failed to open writer: %w", err) } - return nil // all ready present + return nil // already present } defer cw.Close() @@ -131,35 +137,63 @@ func OpenWriter(ctx context.Context, cs Ingester, opts ...WriterOpt) (Writer, er // the size or digest is unknown, these values may be empty. // // Copy is buffered, so no need to wrap reader in buffered io. -func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error { +func Copy(ctx context.Context, cw Writer, or io.Reader, size int64, expected digest.Digest, opts ...Opt) error { ws, err := cw.Status() if err != nil { return fmt.Errorf("failed to get status: %w", err) } - + r := or if ws.Offset > 0 { - r, err = seekReader(r, ws.Offset, size) + r, err = seekReader(or, ws.Offset, size) if err != nil { return fmt.Errorf("unable to resume write to %v: %w", ws.Ref, err) } } - copied, err := copyWithBuffer(cw, r) - if err != nil { - return fmt.Errorf("failed to copy: %w", err) - } - if size != 0 && copied < size-ws.Offset { - // Short writes would return its own error, this indicates a read failure - return fmt.Errorf("failed to read expected number of bytes: %w", io.ErrUnexpectedEOF) - } - - if err := cw.Commit(ctx, size, expected, opts...); err != nil { - if !errdefs.IsAlreadyExists(err) { - return fmt.Errorf("failed commit on ref %q: %w", ws.Ref, err) + for i := 0; i < maxResets; i++ { + if i >= 1 { + log.G(ctx).WithField("digest", expected).Debugf("retrying copy due to reset") + } + copied, err := copyWithBuffer(cw, r) + if errors.Is(err, ErrReset) { + ws, err := cw.Status() + if err != nil { + return fmt.Errorf("failed to get status: %w", err) + } + r, err = seekReader(or, ws.Offset, size) + if err != nil { + return fmt.Errorf("unable to resume write to %v: %w", ws.Ref, err) + } + continue + } + if err != nil { + return fmt.Errorf("failed to copy: %w", err) + } + if size != 0 && copied < size-ws.Offset { + // Short writes would return its own error, this indicates a read failure + return fmt.Errorf("failed to read expected number of bytes: %w", io.ErrUnexpectedEOF) + } + if err := cw.Commit(ctx, size, expected, opts...); err != nil { + if errors.Is(err, ErrReset) { + ws, err := cw.Status() + if err != nil { + return fmt.Errorf("failed to get status: %w", err) + } + r, err = seekReader(or, ws.Offset, size) + if err != nil { + return fmt.Errorf("unable to resume write to %v: %w", ws.Ref, err) + } + continue + } + if !errdefs.IsAlreadyExists(err) { + return fmt.Errorf("failed commit on ref %q: %w", ws.Ref, err) + } } + return nil } - return nil + log.G(ctx).WithField("digest", expected).Errorf("failed to copy after %d retries", maxResets) + return fmt.Errorf("failed to copy after %d retries", maxResets) } // CopyReaderAt copies to a writer from a given reader at for the given diff --git a/vendor/github.com/containerd/containerd/content/local/store.go b/vendor/github.com/containerd/containerd/content/local/store.go index 457bbcd0eb..f41a92d04a 100644 --- a/vendor/github.com/containerd/containerd/content/local/store.go +++ b/vendor/github.com/containerd/containerd/content/local/store.go @@ -643,7 +643,6 @@ func (s *store) ingestRoot(ref string) string { // - root: entire ingest directory // - ref: name of the starting ref, must be unique // - data: file where data is written -// func (s *store) ingestPaths(ref string) (string, string, string) { var ( fp = s.ingestRoot(ref) diff --git a/vendor/github.com/containerd/containerd/filters/filter.go b/vendor/github.com/containerd/containerd/filters/filter.go index cf09d8d9e4..e13f2625c7 100644 --- a/vendor/github.com/containerd/containerd/filters/filter.go +++ b/vendor/github.com/containerd/containerd/filters/filter.go @@ -65,7 +65,6 @@ // ``` // name==foo,labels.bar // ``` -// package filters import ( diff --git a/vendor/github.com/containerd/containerd/filters/parser.go b/vendor/github.com/containerd/containerd/filters/parser.go index 49182d7b7b..32767909b1 100644 --- a/vendor/github.com/containerd/containerd/filters/parser.go +++ b/vendor/github.com/containerd/containerd/filters/parser.go @@ -45,7 +45,6 @@ field := quoted | [A-Za-z] [A-Za-z0-9_]+ operator := "==" | "!=" | "~=" value := quoted | [^\s,]+ quoted := - */ func Parse(s string) (Filter, error) { // special case empty to match all diff --git a/vendor/github.com/containerd/containerd/filters/quote.go b/vendor/github.com/containerd/containerd/filters/quote.go index b76aab9b4a..5c800ef846 100644 --- a/vendor/github.com/containerd/containerd/filters/quote.go +++ b/vendor/github.com/containerd/containerd/filters/quote.go @@ -31,10 +31,10 @@ var errQuoteSyntax = errors.New("quote syntax error") // or character literal represented by the string s. // It returns four values: // -// 1) value, the decoded Unicode code point or byte value; -// 2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation; -// 3) tail, the remainder of the string after the character; and -// 4) an error that will be nil if the character is syntactically valid. +// 1. value, the decoded Unicode code point or byte value; +// 2. multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation; +// 3. tail, the remainder of the string after the character; and +// 4. an error that will be nil if the character is syntactically valid. // // The second argument, quote, specifies the type of literal being parsed // and therefore which escaped quote character is permitted. diff --git a/vendor/github.com/containerd/containerd/leases/lease.go b/vendor/github.com/containerd/containerd/leases/lease.go index 058d065594..fc0ca3491c 100644 --- a/vendor/github.com/containerd/containerd/leases/lease.go +++ b/vendor/github.com/containerd/containerd/leases/lease.go @@ -65,10 +65,15 @@ func SynchronousDelete(ctx context.Context, o *DeleteOptions) error { return nil } -// WithLabels sets labels on a lease +// WithLabels merges labels on a lease func WithLabels(labels map[string]string) Opt { return func(l *Lease) error { - l.Labels = labels + if l.Labels == nil { + l.Labels = map[string]string{} + } + for k, v := range labels { + l.Labels[k] = v + } return nil } } diff --git a/vendor/github.com/containerd/containerd/metadata/buckets.go b/vendor/github.com/containerd/containerd/metadata/buckets.go index d23be84fea..516de1fc7a 100644 --- a/vendor/github.com/containerd/containerd/metadata/buckets.go +++ b/vendor/github.com/containerd/containerd/metadata/buckets.go @@ -26,7 +26,7 @@ // // Generically, we try to do the following: // -// /// -> +// /// -> // // version: Currently, this is "v1". Additions can be made to v1 in a backwards // compatible way. If the layout changes, a new version must be made, along @@ -46,72 +46,73 @@ // the structure is changed in addition to adding a migration and incrementing // the database version. Note that `╘══*...*` refers to maps with arbitrary // keys. -// ├──version : - Latest version, see migrations -// └──v1 - Schema version bucket -// ╘══*namespace* -// ├──labels -// │  ╘══*key* : - Label value -// ├──image -// │  ╘══*image name* -// │   ├──createdat : - Created at -// │   ├──updatedat : - Updated at -// │   ├──target -// │   │  ├──digest : - Descriptor digest -// │   │  ├──mediatype : - Descriptor media type -// │   │  └──size : - Descriptor size -// │   └──labels -// │   ╘══*key* : - Label value -// ├──containers -// │  ╘══*container id* -// │   ├──createdat : - Created at -// │   ├──updatedat : - Updated at -// │   ├──spec : - Proto marshaled spec -// │   ├──image : - Image name -// │   ├──snapshotter : - Snapshotter name -// │   ├──snapshotKey : - Snapshot key -// │   ├──runtime -// │   │  ├──name : - Runtime name -// │   │  ├──extensions -// │   │  │  ╘══*name* : - Proto marshaled extension -// │   │  └──options : - Proto marshaled options -// │   └──labels -// │   ╘══*key* : - Label value -// ├──snapshots -// │  ╘══*snapshotter* -// │   ╘══*snapshot key* -// │    ├──name : - Snapshot name in backend -// │   ├──createdat : - Created at -// │   ├──updatedat : - Updated at -// │    ├──parent : - Parent snapshot name -// │   ├──children -// │   │  ╘══*snapshot key* : - Child snapshot reference -// │   └──labels -// │   ╘══*key* : - Label value -// ├──content -// │  ├──blob -// │  │ ╘══*blob digest* -// │  │ ├──createdat : - Created at -// │  │ ├──updatedat : - Updated at -// │  │   ├──size : - Blob size -// │  │ └──labels -// │  │ ╘══*key* : - Label value -// │  └──ingests -// │   ╘══*ingest reference* -// │    ├──ref : - Ingest reference in backend -// │   ├──expireat : - Time to expire ingest -// │   └──expected : - Expected commit digest -// └──leases -// ╘══*lease id* -//   ├──createdat : - Created at -// ├──labels -// │ ╘══*key* : - Label value -//   ├──snapshots -// │  ╘══*snapshotter* -// │   ╘══*snapshot key* : - Snapshot reference -//   ├──content -// │  ╘══*blob digest* : - Content blob reference -// └──ingests -//   ╘══*ingest reference* : - Content ingest reference +// +// ├──version : - Latest version, see migrations +// └──v1 - Schema version bucket +// ╘══*namespace* +// ├──labels +// │  ╘══*key* : - Label value +// ├──image +// │  ╘══*image name* +// │   ├──createdat : - Created at +// │   ├──updatedat : - Updated at +// │   ├──target +// │   │  ├──digest : - Descriptor digest +// │   │  ├──mediatype : - Descriptor media type +// │   │  └──size : - Descriptor size +// │   └──labels +// │   ╘══*key* : - Label value +// ├──containers +// │  ╘══*container id* +// │   ├──createdat : - Created at +// │   ├──updatedat : - Updated at +// │   ├──spec : - Proto marshaled spec +// │   ├──image : - Image name +// │   ├──snapshotter : - Snapshotter name +// │   ├──snapshotKey : - Snapshot key +// │   ├──runtime +// │   │  ├──name : - Runtime name +// │   │  ├──extensions +// │   │  │  ╘══*name* : - Proto marshaled extension +// │   │  └──options : - Proto marshaled options +// │   └──labels +// │   ╘══*key* : - Label value +// ├──snapshots +// │  ╘══*snapshotter* +// │   ╘══*snapshot key* +// │    ├──name : - Snapshot name in backend +// │   ├──createdat : - Created at +// │   ├──updatedat : - Updated at +// │    ├──parent : - Parent snapshot name +// │   ├──children +// │   │  ╘══*snapshot key* : - Child snapshot reference +// │   └──labels +// │   ╘══*key* : - Label value +// ├──content +// │  ├──blob +// │  │ ╘══*blob digest* +// │  │ ├──createdat : - Created at +// │  │ ├──updatedat : - Updated at +// │  │   ├──size : - Blob size +// │  │ └──labels +// │  │ ╘══*key* : - Label value +// │  └──ingests +// │   ╘══*ingest reference* +// │    ├──ref : - Ingest reference in backend +// │   ├──expireat : - Time to expire ingest +// │   └──expected : - Expected commit digest +// └──leases +// ╘══*lease id* +//   ├──createdat : - Created at +// ├──labels +// │ ╘══*key* : - Label value +//   ├──snapshots +// │  ╘══*snapshotter* +// │   ╘══*snapshot key* : - Snapshot reference +//   ├──content +// │  ╘══*blob digest* : - Content blob reference +// └──ingests +//   ╘══*ingest reference* : - Content ingest reference package metadata import ( diff --git a/vendor/github.com/containerd/containerd/namespaces/store.go b/vendor/github.com/containerd/containerd/namespaces/store.go index 5936772cb4..a1b2571bb1 100644 --- a/vendor/github.com/containerd/containerd/namespaces/store.go +++ b/vendor/github.com/containerd/containerd/namespaces/store.go @@ -24,8 +24,6 @@ import "context" // oriented. A namespace is really just a name and a set of labels. Objects // that belong to a namespace are returned when the namespace is assigned to a // given context. -// -// type Store interface { Create(ctx context.Context, namespace string, labels map[string]string) error Labels(ctx context.Context, namespace string) (map[string]string, error) diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go index c1aaf72ca8..ff9771a600 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go @@ -46,10 +46,14 @@ type matchComparer struct { // Match matches platform with the same windows major, minor // and build version. -func (m matchComparer) Match(p imagespec.Platform) bool { - if m.defaults.Match(p) { - // TODO(windows): Figure out whether OSVersion is deprecated. - return strings.HasPrefix(p.OSVersion, m.osVersionPrefix) +func (m matchComparer) Match(p specs.Platform) bool { + match := m.defaults.Match(p) + + if match && p.OS == "windows" { + if strings.HasPrefix(p.OSVersion, m.osVersionPrefix) { + return true + } + return p.OSVersion == "" } return false } diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/containerd/platforms/platforms.go index 8f955d036d..2343099418 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms.go +++ b/vendor/github.com/containerd/containerd/platforms/platforms.go @@ -27,40 +27,40 @@ // The vast majority of use cases should simply use the match function with // user input. The first step is to parse a specifier into a matcher: // -// m, err := Parse("linux") -// if err != nil { ... } +// m, err := Parse("linux") +// if err != nil { ... } // // Once you have a matcher, use it to match against the platform declared by a // component, typically from an image or runtime. Since extracting an images // platform is a little more involved, we'll use an example against the // platform default: // -// if ok := m.Match(Default()); !ok { /* doesn't match */ } +// if ok := m.Match(Default()); !ok { /* doesn't match */ } // // This can be composed in loops for resolving runtimes or used as a filter for // fetch and select images. // // More details of the specifier syntax and platform spec follow. // -// Declaring Platform Support +// # Declaring Platform Support // // Components that have strict platform requirements should use the OCI // platform specification to declare their support. Typically, this will be // images and runtimes that should make these declaring which platform they // support specifically. This looks roughly as follows: // -// type Platform struct { -// Architecture string -// OS string -// Variant string -// } +// type Platform struct { +// Architecture string +// OS string +// Variant string +// } // // Most images and runtimes should at least set Architecture and OS, according // to their GOARCH and GOOS values, respectively (follow the OCI image // specification when in doubt). ARM should set variant under certain // discussions, which are outlined below. // -// Platform Specifiers +// # Platform Specifiers // // While the OCI platform specifications provide a tool for components to // specify structured information, user input typically doesn't need the full @@ -77,7 +77,7 @@ // where the architecture may be known but a runtime may support images from // different operating systems. // -// Normalization +// # Normalization // // Because not all users are familiar with the way the Go runtime represents // platforms, several normalizations have been provided to make this package @@ -85,17 +85,17 @@ // // The following are performed for architectures: // -// Value Normalized -// aarch64 arm64 -// armhf arm -// armel arm/v6 -// i386 386 -// x86_64 amd64 -// x86-64 amd64 +// Value Normalized +// aarch64 arm64 +// armhf arm +// armel arm/v6 +// i386 386 +// x86_64 amd64 +// x86-64 amd64 // // We also normalize the operating system `macos` to `darwin`. // -// ARM Support +// # ARM Support // // To qualify ARM architecture, the Variant field is used to qualify the arm // version. The most common arm version, v7, is represented without the variant diff --git a/vendor/github.com/containerd/containerd/remotes/docker/auth/parse.go b/vendor/github.com/containerd/containerd/remotes/docker/auth/parse.go index 223fa2d052..e4529a7761 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/auth/parse.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/auth/parse.go @@ -134,9 +134,6 @@ func parseValueAndParams(header string) (value string, params map[string]string) } var pvalue string pvalue, s = expectTokenOrQuoted(s[1:]) - if pvalue == "" { - return - } pkey = strings.ToLower(pkey) params[pkey] = pvalue s = skipSpace(s) diff --git a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go index c786ad2158..bef77fa61d 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go @@ -24,6 +24,7 @@ import ( "net/http" "net/url" "strings" + "sync" "time" "github.com/containerd/containerd/content" @@ -261,27 +262,20 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str // TODO: Support chunked upload - pr, pw := io.Pipe() - respC := make(chan response, 1) - body := io.NopCloser(pr) + pushw := newPushWriter(p.dockerBase, ref, desc.Digest, p.tracker, isManifest) req.body = func() (io.ReadCloser, error) { - if body == nil { - return nil, errors.New("cannot reuse body, request must be retried") - } - // Only use the body once since pipe cannot be seeked - ob := body - body = nil - return ob, nil + pr, pw := io.Pipe() + pushw.setPipe(pw) + return io.NopCloser(pr), nil } req.size = desc.Size go func() { - defer close(respC) resp, err := req.doWithRetries(ctx, nil) if err != nil { - respC <- response{err: err} - pr.CloseWithError(err) + pushw.setError(err) + pushw.Close() return } @@ -290,20 +284,13 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str default: err := remoteserrors.NewUnexpectedStatusErr(resp) log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response") - pr.CloseWithError(err) + pushw.setError(err) + pushw.Close() } - respC <- response{Response: resp} + pushw.setResponse(resp) }() - return &pushWriter{ - base: p.dockerBase, - ref: ref, - pipe: pw, - responseC: respC, - isManifest: isManifest, - expected: desc.Digest, - tracker: p.tracker, - }, nil + return pushw, nil } func getManifestPath(object string, dgst digest.Digest) []string { @@ -325,29 +312,89 @@ func getManifestPath(object string, dgst digest.Digest) []string { return []string{"manifests", object} } -type response struct { - *http.Response - err error -} - type pushWriter struct { base *dockerBase ref string - pipe *io.PipeWriter - responseC <-chan response + pipe *io.PipeWriter + + pipeC chan *io.PipeWriter + respC chan *http.Response + closeOnce sync.Once + errC chan error + isManifest bool expected digest.Digest tracker StatusTracker } +func newPushWriter(db *dockerBase, ref string, expected digest.Digest, tracker StatusTracker, isManifest bool) *pushWriter { + // Initialize and create response + return &pushWriter{ + base: db, + ref: ref, + expected: expected, + tracker: tracker, + pipeC: make(chan *io.PipeWriter, 1), + respC: make(chan *http.Response, 1), + errC: make(chan error, 1), + isManifest: isManifest, + } +} + +func (pw *pushWriter) setPipe(p *io.PipeWriter) { + pw.pipeC <- p +} + +func (pw *pushWriter) setError(err error) { + pw.errC <- err +} +func (pw *pushWriter) setResponse(resp *http.Response) { + pw.respC <- resp +} + func (pw *pushWriter) Write(p []byte) (n int, err error) { status, err := pw.tracker.GetStatus(pw.ref) if err != nil { return n, err } + + if pw.pipe == nil { + p, ok := <-pw.pipeC + if !ok { + return 0, io.ErrClosedPipe + } + pw.pipe = p + } else { + select { + case p, ok := <-pw.pipeC: + if !ok { + return 0, io.ErrClosedPipe + } + pw.pipe.CloseWithError(content.ErrReset) + pw.pipe = p + + // If content has already been written, the bytes + // cannot be written and the caller must reset + status.Offset = 0 + status.UpdatedAt = time.Now() + pw.tracker.SetStatus(pw.ref, status) + return 0, content.ErrReset + default: + } + } + n, err = pw.pipe.Write(p) + if errors.Is(err, io.ErrClosedPipe) { + // if the pipe is closed, we might have the original error on the error + // channel - so we should try and get it + select { + case err2 := <-pw.errC: + err = err2 + default: + } + } status.Offset += int64(n) status.UpdatedAt = time.Now() pw.tracker.SetStatus(pw.ref, status) @@ -355,13 +402,21 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) { } func (pw *pushWriter) Close() error { - status, err := pw.tracker.GetStatus(pw.ref) - if err == nil && !status.Committed { - // Closing an incomplete writer. Record this as an error so that following write can retry it. - status.ErrClosed = errors.New("closed incomplete writer") - pw.tracker.SetStatus(pw.ref, status) + // Ensure pipeC is closed but handle `Close()` being + // called multiple times without panicking + pw.closeOnce.Do(func() { + close(pw.pipeC) + }) + if pw.pipe != nil { + status, err := pw.tracker.GetStatus(pw.ref) + if err == nil && !status.Committed { + // Closing an incomplete writer. Record this as an error so that following write can retry it. + status.ErrClosed = errors.New("closed incomplete writer") + pw.tracker.SetStatus(pw.ref, status) + } + return pw.pipe.Close() } - return pw.pipe.Close() + return nil } func (pw *pushWriter) Status() (content.Status, error) { @@ -380,7 +435,7 @@ func (pw *pushWriter) Digest() digest.Digest { func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { // Check whether read has already thrown an error - if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe { + if _, err := pw.pipe.Write([]byte{}); err != nil && !errors.Is(err, io.ErrClosedPipe) { return fmt.Errorf("pipe error before commit: %w", err) } @@ -388,18 +443,40 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di return err } // TODO: timeout waiting for response - resp := <-pw.responseC - if resp.err != nil { - return resp.err + var resp *http.Response + select { + case err := <-pw.errC: + return err + case resp = <-pw.respC: + defer resp.Body.Close() + case p, ok := <-pw.pipeC: + // check whether the pipe has changed in the commit, because sometimes Write + // can complete successfully, but the pipe may have changed. In that case, the + // content needs to be reset. + if !ok { + return io.ErrClosedPipe + } + pw.pipe.CloseWithError(content.ErrReset) + pw.pipe = p + + // If content has already been written, the bytes + // cannot be written again and the caller must reset + status, err := pw.tracker.GetStatus(pw.ref) + if err != nil { + return err + } + status.Offset = 0 + status.UpdatedAt = time.Now() + pw.tracker.SetStatus(pw.ref, status) + return content.ErrReset } - defer resp.Response.Body.Close() // 201 is specified return status, some registries return // 200, 202 or 204. switch resp.StatusCode { case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted: default: - return remoteserrors.NewUnexpectedStatusErr(resp.Response) + return remoteserrors.NewUnexpectedStatusErr(resp) } status, err := pw.tracker.GetStatus(pw.ref) diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index 9bbbc26222..709fa028de 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "path" @@ -667,3 +668,17 @@ func responseFields(resp *http.Response) logrus.Fields { return logrus.Fields(fields) } + +// IsLocalhost checks if the registry host is local. +func IsLocalhost(host string) bool { + if h, _, err := net.SplitHostPort(host); err == nil { + host = h + } + + if host == "localhost" { + return true + } + + ip := net.ParseIP(host) + return ip.IsLoopback() +} diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index 8bcafb22a0..4d91ed2e54 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -257,8 +257,8 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st // An example of this kind of content would be a Windows base layer, which is not supposed to be redistributed. // // This is based on the media type of the content: -// - application/vnd.oci.image.layer.nondistributable -// - application/vnd.docker.image.rootfs.foreign +// - application/vnd.oci.image.layer.nondistributable +// - application/vnd.docker.image.rootfs.foreign func SkipNonDistributableBlobs(f images.HandlerFunc) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if images.IsNonDistributable(desc.MediaType) { diff --git a/vendor/github.com/containerd/containerd/snapshots/snapshotter.go b/vendor/github.com/containerd/containerd/snapshots/snapshotter.go index 8b0ea85e65..e144fb1583 100644 --- a/vendor/github.com/containerd/containerd/snapshots/snapshotter.go +++ b/vendor/github.com/containerd/containerd/snapshots/snapshotter.go @@ -153,10 +153,10 @@ type WalkFunc func(context.Context, Info) error // For consistency, we define the following terms to be used throughout this // interface for snapshotter implementations: // -// `ctx` - refers to a context.Context -// `key` - refers to an active snapshot -// `name` - refers to a committed snapshot -// `parent` - refers to the parent in relation +// `ctx` - refers to a context.Context +// `key` - refers to an active snapshot +// `name` - refers to a committed snapshot +// `parent` - refers to the parent in relation // // Most methods take various combinations of these identifiers. Typically, // `name` and `parent` will be used in cases where a method *only* takes @@ -168,7 +168,7 @@ type WalkFunc func(context.Context, Info) error // We cover several examples below to demonstrate the utility of a snapshot // snapshotter. // -// Importing a Layer +// # Importing a Layer // // To import a layer, we simply have the Snapshotter provide a list of // mounts to be applied such that our dst will capture a changeset. We start @@ -185,7 +185,7 @@ type WalkFunc func(context.Context, Info) error // "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), // }) // mounts, err := snapshotter.Prepare(ctx, key, "", noGcOpt) -// if err != nil { ... } +// if err != nil { ... } // // We get back a list of mounts from Snapshotter.Prepare, with the key identifying // the active snapshot. Mount this to the temporary location with the @@ -202,8 +202,8 @@ type WalkFunc func(context.Context, Info) error // // layer, err := os.Open(layerPath) // if err != nil { ... } -// digest, err := unpackLayer(tmpLocation, layer) // unpack into layer location -// if err != nil { ... } +// digest, err := unpackLayer(tmpLocation, layer) // unpack into layer location +// if err != nil { ... } // // When the above completes, we should have a filesystem the represents the // contents of the layer. Careful implementations should verify that digest @@ -221,30 +221,30 @@ type WalkFunc func(context.Context, Info) error // Now, we have a layer in the Snapshotter that can be accessed with the digest // provided during commit. // -// Importing the Next Layer +// # Importing the Next Layer // // Making a layer depend on the above is identical to the process described // above except that the parent is provided as parent when calling // Manager.Prepare, assuming a clean, unique key identifier: // -// mounts, err := snapshotter.Prepare(ctx, key, parentDigest, noGcOpt) +// mounts, err := snapshotter.Prepare(ctx, key, parentDigest, noGcOpt) // // We then mount, apply and commit, as we did above. The new snapshot will be // based on the content of the previous one. // -// Running a Container +// # Running a Container // // To run a container, we simply provide Snapshotter.Prepare the committed image // snapshot as the parent. After mounting, the prepared path can // be used directly as the container's filesystem: // -// mounts, err := snapshotter.Prepare(ctx, containerKey, imageRootFSChainID) +// mounts, err := snapshotter.Prepare(ctx, containerKey, imageRootFSChainID) // // The returned mounts can then be passed directly to the container runtime. If // one would like to create a new image from the filesystem, Manager.Commit is // called: // -// if err := snapshotter.Commit(ctx, newImageSnapshot, containerKey); err != nil { ... } +// if err := snapshotter.Commit(ctx, newImageSnapshot, containerKey); err != nil { ... } // // Alternatively, for most container runs, Snapshotter.Remove will be called to // signal the Snapshotter to abandon the changes. diff --git a/vendor/github.com/containerd/containerd/version/version.go b/vendor/github.com/containerd/containerd/version/version.go index 806e3e0d73..ca1b6773ab 100644 --- a/vendor/github.com/containerd/containerd/version/version.go +++ b/vendor/github.com/containerd/containerd/version/version.go @@ -23,7 +23,7 @@ var ( Package = "github.com/containerd/containerd" // Version holds the complete version number. Filled in at linking time. - Version = "1.6.3+unknown" + Version = "1.6.18+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build // the program at linking time. diff --git a/vendor/github.com/containerd/continuity/AUTHORS b/vendor/github.com/containerd/continuity/AUTHORS index deef28c1d7..0b4a03cd45 100644 --- a/vendor/github.com/containerd/continuity/AUTHORS +++ b/vendor/github.com/containerd/continuity/AUTHORS @@ -1,8 +1,6 @@ -Aaron Lehmann +Aaron Lehmann Akash Gupta Akihiro Suda -Akihiro Suda -Akihiro Suda Andrew Pennebaker Brandon Philips Brian Goff @@ -10,9 +8,9 @@ Christopher Jones Daniel, Dao Quang Minh Darren Stahl Derek McGowan -Derek McGowan Edward Pilatowicz Fu Wei +Gabriel Adrian Samfira Hajime Tazaki Ian Campbell Ivan Markin @@ -20,20 +18,18 @@ Jacob Blain Christen Justin Cormack Justin Cummins Kasper Fabæch Brandt +Kazuyoshi Kato Kir Kolyshkin Michael Crosby -Michael Crosby Michael Wan Mike Brown Niels de Vos -Phil Estes Phil Estes -Phil Estes Sam Whited Samuel Karp Sebastiaan van Stijn Shengjing Zhu -Stephen J Day +Stephen J Day Tibor Vass Tobias Klauser Tom Faulhaber diff --git a/vendor/github.com/containerd/continuity/fs/copy.go b/vendor/github.com/containerd/continuity/fs/copy.go index 8e23934e99..6982a761ba 100644 --- a/vendor/github.com/containerd/continuity/fs/copy.go +++ b/vendor/github.com/containerd/continuity/fs/copy.go @@ -22,6 +22,8 @@ import ( "os" "path/filepath" "sync" + + "github.com/sirupsen/logrus" ) var bufferPool = &sync.Pool{ @@ -31,7 +33,7 @@ var bufferPool = &sync.Pool{ }, } -// XAttrErrorHandlers transform a non-nil xattr error. +// XAttrErrorHandler transform a non-nil xattr error. // Return nil to ignore an error. // xattrKey can be empty for listxattr operation. type XAttrErrorHandler func(dst, src, xattrKey string, err error) error @@ -152,13 +154,15 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er if err := os.Symlink(link, target); err != nil { return fmt.Errorf("failed to create symlink: %s: %w", target, err) } - case (fi.Mode() & os.ModeDevice) == os.ModeDevice: - if err := copyDevice(target, fi); err != nil { - return fmt.Errorf("failed to create device: %w", err) + case (fi.Mode() & os.ModeDevice) == os.ModeDevice, + (fi.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe, + (fi.Mode() & os.ModeSocket) == os.ModeSocket: + if err := copyIrregular(target, fi); err != nil { + return fmt.Errorf("failed to create irregular file: %w", err) } default: - // TODO: Support pipes and sockets - return fmt.Errorf("unsupported mode %s: %w", fi.Mode(), err) + logrus.Warnf("unsupported mode: %s: %s", source, fi.Mode()) + continue } if err := copyFileInfo(fi, source, target); err != nil { diff --git a/vendor/github.com/containerd/continuity/fs/copy_darwin.go b/vendor/github.com/containerd/continuity/fs/copy_darwin.go deleted file mode 100644 index ce55f0aa24..0000000000 --- a/vendor/github.com/containerd/continuity/fs/copy_darwin.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build darwin -// +build darwin - -/* - 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. -*/ - -package fs - -import ( - "errors" - "os" - "syscall" - - "golang.org/x/sys/unix" -) - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) -} diff --git a/vendor/github.com/containerd/continuity/fs/copy_device_unix.go b/vendor/github.com/containerd/continuity/fs/copy_device_unix.go deleted file mode 100644 index f821890cb7..0000000000 --- a/vendor/github.com/containerd/continuity/fs/copy_device_unix.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build openbsd || solaris || netbsd -// +build openbsd solaris netbsd - -/* - 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. -*/ - -package fs - -import ( - "errors" - "os" - "syscall" - - "golang.org/x/sys/unix" -) - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) -} diff --git a/vendor/github.com/containerd/continuity/fs/copy_freebsd.go b/vendor/github.com/containerd/continuity/fs/copy_freebsd.go deleted file mode 100644 index 4aaf743e5a..0000000000 --- a/vendor/github.com/containerd/continuity/fs/copy_freebsd.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build freebsd -// +build freebsd - -/* - 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. -*/ - -package fs - -import ( - "errors" - "os" - "syscall" - - "golang.org/x/sys/unix" -) - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), st.Rdev) -} diff --git a/vendor/github.com/containerd/continuity/fs/copy_irregular_freebsd.go b/vendor/github.com/containerd/continuity/fs/copy_irregular_freebsd.go new file mode 100644 index 0000000000..cfe9d80204 --- /dev/null +++ b/vendor/github.com/containerd/continuity/fs/copy_irregular_freebsd.go @@ -0,0 +1,36 @@ +/* + 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. +*/ + +package fs + +import ( + "fmt" + "os" + "syscall" +) + +// copyIrregular covers devices, pipes, and sockets +func copyIrregular(dst string, fi os.FileInfo) error { + st, ok := fi.Sys().(*syscall.Stat_t) // not *unix.Stat_t + if !ok { + return fmt.Errorf("unsupported stat type: %s: %v", dst, fi.Mode()) + } + var rDev uint64 // uint64 on FreeBSD, int on other unixen + if fi.Mode()&os.ModeDevice == os.ModeDevice { + rDev = st.Rdev + } + return syscall.Mknod(dst, uint32(st.Mode), rDev) +} diff --git a/vendor/github.com/containerd/continuity/fs/copy_irregular_unix.go b/vendor/github.com/containerd/continuity/fs/copy_irregular_unix.go new file mode 100644 index 0000000000..99fc8a9651 --- /dev/null +++ b/vendor/github.com/containerd/continuity/fs/copy_irregular_unix.go @@ -0,0 +1,40 @@ +//go:build !windows && !freebsd +// +build !windows,!freebsd + +/* + 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. +*/ + +package fs + +import ( + "fmt" + "os" + "syscall" +) + +// copyIrregular covers devices, pipes, and sockets +func copyIrregular(dst string, fi os.FileInfo) error { + st, ok := fi.Sys().(*syscall.Stat_t) // not *unix.Stat_t + if !ok { + return fmt.Errorf("unsupported stat type: %s: %v", dst, fi.Mode()) + } + var rDev int + if fi.Mode()&os.ModeDevice == os.ModeDevice { + rDev = int(st.Rdev) + } + //nolint:unconvert + return syscall.Mknod(dst, uint32(st.Mode), rDev) +} diff --git a/vendor/github.com/containerd/continuity/fs/copy_linux.go b/vendor/github.com/containerd/continuity/fs/copy_linux.go index 938407662c..1906e5e011 100644 --- a/vendor/github.com/containerd/continuity/fs/copy_linux.go +++ b/vendor/github.com/containerd/continuity/fs/copy_linux.go @@ -17,7 +17,6 @@ package fs import ( - "errors" "fmt" "io" "os" @@ -144,11 +143,3 @@ func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAtt return nil } - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) -} diff --git a/vendor/github.com/containerd/continuity/fs/copy_windows.go b/vendor/github.com/containerd/continuity/fs/copy_windows.go index e3f0cdd58d..4dad9441de 100644 --- a/vendor/github.com/containerd/continuity/fs/copy_windows.go +++ b/vendor/github.com/containerd/continuity/fs/copy_windows.go @@ -85,6 +85,6 @@ func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAtt return nil } -func copyDevice(dst string, fi os.FileInfo) error { - return errors.New("device copy not supported") +func copyIrregular(dst string, fi os.FileInfo) error { + return errors.New("irregular copy not supported") } diff --git a/vendor/github.com/containerd/continuity/fs/diff.go b/vendor/github.com/containerd/continuity/fs/diff.go index e64f9e73d3..3cd4eee6fb 100644 --- a/vendor/github.com/containerd/continuity/fs/diff.go +++ b/vendor/github.com/containerd/continuity/fs/diff.go @@ -22,9 +22,8 @@ import ( "path/filepath" "strings" - "golang.org/x/sync/errgroup" - "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" ) // ChangeKind is the type of modification that diff --git a/vendor/github.com/containerd/continuity/fs/dtype_linux.go b/vendor/github.com/containerd/continuity/fs/dtype_linux.go index ddd6c79375..a8eab1db8a 100644 --- a/vendor/github.com/containerd/continuity/fs/dtype_linux.go +++ b/vendor/github.com/containerd/continuity/fs/dtype_linux.go @@ -35,7 +35,7 @@ func locateDummyIfEmpty(path string) (string, error) { if len(children) != 0 { return "", nil } - dummyFile, err := ioutil.TempFile(path, "fsutils-dummy") + dummyFile, err := os.CreateTemp(path, "fsutils-dummy") if err != nil { return "", err } diff --git a/vendor/github.com/containerd/continuity/sysx/generate.sh b/vendor/github.com/containerd/continuity/sysx/generate.sh deleted file mode 100644 index 87d708d7ae..0000000000 --- a/vendor/github.com/containerd/continuity/sysx/generate.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -# 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. - - -set -e - -mksyscall="$(go env GOROOT)/src/syscall/mksyscall.pl" - -fix() { - sed 's,^package syscall$,package sysx,' \ - | sed 's,^import "unsafe"$,import (\n\t"syscall"\n\t"unsafe"\n),' \ - | gofmt -r='BytePtrFromString -> syscall.BytePtrFromString' \ - | gofmt -r='Syscall6 -> syscall.Syscall6' \ - | gofmt -r='Syscall -> syscall.Syscall' \ - | gofmt -r='SYS_GETXATTR -> syscall.SYS_GETXATTR' \ - | gofmt -r='SYS_LISTXATTR -> syscall.SYS_LISTXATTR' \ - | gofmt -r='SYS_SETXATTR -> syscall.SYS_SETXATTR' \ - | gofmt -r='SYS_REMOVEXATTR -> syscall.SYS_REMOVEXATTR' \ - | gofmt -r='SYS_LGETXATTR -> syscall.SYS_LGETXATTR' \ - | gofmt -r='SYS_LLISTXATTR -> syscall.SYS_LLISTXATTR' \ - | gofmt -r='SYS_LSETXATTR -> syscall.SYS_LSETXATTR' \ - | gofmt -r='SYS_LREMOVEXATTR -> syscall.SYS_LREMOVEXATTR' -} - -if [ "$GOARCH" == "" ] || [ "$GOOS" == "" ]; then - echo "Must specify \$GOARCH and \$GOOS" - exit 1 -fi - -mkargs="" - -if [ "$GOARCH" == "386" ] || [ "$GOARCH" == "arm" ]; then - mkargs="-l32" -fi - -for f in "$@"; do - $mksyscall $mkargs "${f}_${GOOS}.go" | fix > "${f}_${GOOS}_${GOARCH}.go" -done - diff --git a/vendor/github.com/docker/cli/cli/config/config.go b/vendor/github.com/docker/cli/cli/config/config.go index 93275f3d98..31ad117d41 100644 --- a/vendor/github.com/docker/cli/cli/config/config.go +++ b/vendor/github.com/docker/cli/cli/config/config.go @@ -104,14 +104,18 @@ func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { return &configFile, err } -// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file -var printLegacyFileWarning bool - // Load reads the configuration files in the given directory, and sets up // the auth config information and returns values. // FIXME: use the internal golang config parser func Load(configDir string) (*configfile.ConfigFile, error) { - printLegacyFileWarning = false + cfg, _, err := load(configDir) + return cfg, err +} + +// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file +// so we can remove the bool return value and collapse this back into `Load` +func load(configDir string) (*configfile.ConfigFile, bool, error) { + printLegacyFileWarning := false if configDir == "" { configDir = Dir() @@ -127,11 +131,11 @@ func Load(configDir string) (*configfile.ConfigFile, error) { if err != nil { err = errors.Wrap(err, filename) } - return configFile, err + return configFile, printLegacyFileWarning, err } else if !os.IsNotExist(err) { // if file is there but we can't stat it for any reason other // than it doesn't exist then stop - return configFile, errors.Wrap(err, filename) + return configFile, printLegacyFileWarning, errors.Wrap(err, filename) } // Can't find latest config file so check for the old one @@ -140,16 +144,16 @@ func Load(configDir string) (*configfile.ConfigFile, error) { printLegacyFileWarning = true defer file.Close() if err := configFile.LegacyLoadFromReader(file); err != nil { - return configFile, errors.Wrap(err, filename) + return configFile, printLegacyFileWarning, errors.Wrap(err, filename) } } - return configFile, nil + return configFile, printLegacyFileWarning, nil } // LoadDefaultConfigFile attempts to load the default config file and returns // an initialized ConfigFile struct if none is found. func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { - configFile, err := Load(Dir()) + configFile, printLegacyFileWarning, err := load(Dir()) if err != nil { fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) } diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index dc9f39eb7e..d6f710817a 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -119,7 +119,7 @@ func (configFile *ConfigFile) LegacyLoadFromReader(configData io.Reader) error { // LoadFromReader reads the configuration data given and sets up the auth config // information with given directory and populates the receiver object func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error { - if err := json.NewDecoder(configData).Decode(&configFile); err != nil && !errors.Is(err, io.EOF) { + if err := json.NewDecoder(configData).Decode(configFile); err != nil && !errors.Is(err, io.EOF) { return err } var err error diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go b/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go index 3ca65c6140..6af6718126 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package configfile diff --git a/vendor/github.com/docker/cli/cli/config/credentials/default_store_unsupported.go b/vendor/github.com/docker/cli/cli/config/credentials/default_store_unsupported.go index 3028168ac2..c9630ea51b 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/default_store_unsupported.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/default_store_unsupported.go @@ -1,3 +1,4 @@ +//go:build !windows && !darwin && !linux // +build !windows,!darwin,!linux package credentials diff --git a/vendor/github.com/docker/cli/cli/config/credentials/native_store.go b/vendor/github.com/docker/cli/cli/config/credentials/native_store.go index afe542cc3c..f9619b0381 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/native_store.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/native_store.go @@ -7,7 +7,7 @@ import ( ) const ( - remoteCredentialsPrefix = "docker-credential-" + remoteCredentialsPrefix = "docker-credential-" //nolint:gosec // ignore G101: Potential hardcoded credentials tokenUsername = "" ) diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go index da8b594e7f..91d9d4bbae 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go @@ -169,8 +169,8 @@ func Erase(helper Helper, reader io.Reader) error { return helper.Delete(serverURL) } -//List returns all the serverURLs of keys in -//the OS store as a list of strings +// List returns all the serverURLs of keys in +// the OS store as a list of strings func List(helper Helper, writer io.Writer) error { accts, err := helper.List() if err != nil { @@ -179,8 +179,8 @@ func List(helper Helper, writer io.Writer) error { return json.NewEncoder(writer).Encode(accts) } -//PrintVersion outputs the current version. +// PrintVersion outputs the current version. func PrintVersion(writer io.Writer) error { - fmt.Fprintln(writer, Version) + fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version) return nil } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go index 185e367961..84377c2630 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go @@ -1,4 +1,16 @@ package credentials -// Version holds a string describing the current version -const Version = "0.6.4" +var ( + // Name is filled at linking time + Name = "" + + // Package is filled at linking time + Package = "github.com/docker/docker-credential-helpers" + + // Version holds the complete version number. Filled in at linking time. + Version = "v0.0.0+unknown" + + // Revision is filled with the VCS (e.g. git) revision being used to build + // the program at linking time. + Revision = "" +) diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go b/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go index cf6fdf4402..24c4fa8d90 100644 --- a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go +++ b/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package container // import "github.com/docker/docker/api/types/container" diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go index 07552f1cc1..5afe486779 100644 --- a/vendor/github.com/docker/docker/errdefs/http_helpers.go +++ b/vendor/github.com/docker/docker/errdefs/http_helpers.go @@ -1,78 +1,11 @@ package errdefs // import "github.com/docker/docker/errdefs" import ( - "fmt" "net/http" - containerderrors "github.com/containerd/containerd/errdefs" - "github.com/docker/distribution/registry/api/errcode" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) -// GetHTTPErrorStatusCode retrieves status code from error message. -func GetHTTPErrorStatusCode(err error) int { - if err == nil { - logrus.WithFields(logrus.Fields{"error": err}).Error("unexpected HTTP error handling") - return http.StatusInternalServerError - } - - var statusCode int - - // Stop right there - // Are you sure you should be adding a new error class here? Do one of the existing ones work? - - // Note that the below functions are already checking the error causal chain for matches. - switch { - case IsNotFound(err): - statusCode = http.StatusNotFound - case IsInvalidParameter(err): - statusCode = http.StatusBadRequest - case IsConflict(err): - statusCode = http.StatusConflict - case IsUnauthorized(err): - statusCode = http.StatusUnauthorized - case IsUnavailable(err): - statusCode = http.StatusServiceUnavailable - case IsForbidden(err): - statusCode = http.StatusForbidden - case IsNotModified(err): - statusCode = http.StatusNotModified - case IsNotImplemented(err): - statusCode = http.StatusNotImplemented - case IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) || IsCancelled(err): - statusCode = http.StatusInternalServerError - default: - statusCode = statusCodeFromGRPCError(err) - if statusCode != http.StatusInternalServerError { - return statusCode - } - statusCode = statusCodeFromContainerdError(err) - if statusCode != http.StatusInternalServerError { - return statusCode - } - statusCode = statusCodeFromDistributionError(err) - if statusCode != http.StatusInternalServerError { - return statusCode - } - if e, ok := err.(causer); ok { - return GetHTTPErrorStatusCode(e.Cause()) - } - - logrus.WithFields(logrus.Fields{ - "module": "api", - "error_type": fmt.Sprintf("%T", err), - }).Debugf("FIXME: Got an API for which error does not match any expected type!!!: %+v", err) - } - - if statusCode == 0 { - statusCode = http.StatusInternalServerError - } - - return statusCode -} - // FromStatusCode creates an errdef error, based on the provided HTTP status-code func FromStatusCode(err error, statusCode int) error { if err == nil { @@ -100,10 +33,10 @@ func FromStatusCode(err error, statusCode int) error { err = System(err) } default: - logrus.WithFields(logrus.Fields{ + logrus.WithError(err).WithFields(logrus.Fields{ "module": "api", - "status_code": fmt.Sprintf("%d", statusCode), - }).Debugf("FIXME: Got an status-code for which error does not match any expected type!!!: %d", statusCode) + "status_code": statusCode, + }).Debug("FIXME: Got an status-code for which error does not match any expected type!!!") switch { case statusCode >= 200 && statusCode < 400: @@ -118,74 +51,3 @@ func FromStatusCode(err error, statusCode int) error { } return err } - -// statusCodeFromGRPCError returns status code according to gRPC error -func statusCodeFromGRPCError(err error) int { - switch status.Code(err) { - case codes.InvalidArgument: // code 3 - return http.StatusBadRequest - case codes.NotFound: // code 5 - return http.StatusNotFound - case codes.AlreadyExists: // code 6 - return http.StatusConflict - case codes.PermissionDenied: // code 7 - return http.StatusForbidden - case codes.FailedPrecondition: // code 9 - return http.StatusBadRequest - case codes.Unauthenticated: // code 16 - return http.StatusUnauthorized - case codes.OutOfRange: // code 11 - return http.StatusBadRequest - case codes.Unimplemented: // code 12 - return http.StatusNotImplemented - case codes.Unavailable: // code 14 - return http.StatusServiceUnavailable - default: - // codes.Canceled(1) - // codes.Unknown(2) - // codes.DeadlineExceeded(4) - // codes.ResourceExhausted(8) - // codes.Aborted(10) - // codes.Internal(13) - // codes.DataLoss(15) - return http.StatusInternalServerError - } -} - -// statusCodeFromDistributionError returns status code according to registry errcode -// code is loosely based on errcode.ServeJSON() in docker/distribution -func statusCodeFromDistributionError(err error) int { - switch errs := err.(type) { - case errcode.Errors: - if len(errs) < 1 { - return http.StatusInternalServerError - } - if _, ok := errs[0].(errcode.ErrorCoder); ok { - return statusCodeFromDistributionError(errs[0]) - } - case errcode.ErrorCoder: - return errs.ErrorCode().Descriptor().HTTPStatusCode - } - return http.StatusInternalServerError -} - -// statusCodeFromContainerdError returns status code for containerd errors when -// consumed directly (not through gRPC) -func statusCodeFromContainerdError(err error) int { - switch { - case containerderrors.IsInvalidArgument(err): - return http.StatusBadRequest - case containerderrors.IsNotFound(err): - return http.StatusNotFound - case containerderrors.IsAlreadyExists(err): - return http.StatusConflict - case containerderrors.IsFailedPrecondition(err): - return http.StatusPreconditionFailed - case containerderrors.IsUnavailable(err): - return http.StatusServiceUnavailable - case containerderrors.IsNotImplemented(err): - return http.StatusNotImplemented - default: - return http.StatusInternalServerError - } -} diff --git a/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go b/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go index 67ab9e9b31..fc48e674c1 100644 --- a/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go +++ b/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package homedir // import "github.com/docker/docker/pkg/homedir" diff --git a/vendor/github.com/docker/docker/pkg/homedir/homedir_unix.go b/vendor/github.com/docker/docker/pkg/homedir/homedir_unix.go index 441bd727b6..d1732dee52 100644 --- a/vendor/github.com/docker/docker/pkg/homedir/homedir_unix.go +++ b/vendor/github.com/docker/docker/pkg/homedir/homedir_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package homedir // import "github.com/docker/docker/pkg/homedir" diff --git a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go b/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go index dc894f9131..4e67ec2f53 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package ioutils // import "github.com/docker/docker/pkg/ioutils" diff --git a/vendor/github.com/docker/docker/pkg/term/deprecated.go b/vendor/github.com/docker/docker/pkg/term/deprecated.go deleted file mode 100644 index 4d18168fc2..0000000000 --- a/vendor/github.com/docker/docker/pkg/term/deprecated.go +++ /dev/null @@ -1,84 +0,0 @@ -// Package term provides structures and helper functions to work with -// terminal (state, sizes). -// -// Deprecated: use github.com/moby/term instead -package term // import "github.com/docker/docker/pkg/term" - -import ( - "github.com/moby/term" -) - -// EscapeError is special error which returned by a TTY proxy reader's Read() -// method in case its detach escape sequence is read. -// Deprecated: use github.com/moby/term.EscapeError -type EscapeError = term.EscapeError - -// State represents the state of the terminal. -// Deprecated: use github.com/moby/term.State -type State = term.State - -// Winsize represents the size of the terminal window. -// Deprecated: use github.com/moby/term.Winsize -type Winsize = term.Winsize - -var ( - // ASCII list the possible supported ASCII key sequence - ASCII = term.ASCII - - // ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code. - // Deprecated: use github.com/moby/term.ToBytes - ToBytes = term.ToBytes - - // StdStreams returns the standard streams (stdin, stdout, stderr). - // Deprecated: use github.com/moby/term.StdStreams - StdStreams = term.StdStreams - - // GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. - // Deprecated: use github.com/moby/term.GetFdInfo - GetFdInfo = term.GetFdInfo - - // GetWinsize returns the window size based on the specified file descriptor. - // Deprecated: use github.com/moby/term.GetWinsize - GetWinsize = term.GetWinsize - - // IsTerminal returns true if the given file descriptor is a terminal. - // Deprecated: use github.com/moby/term.IsTerminal - IsTerminal = term.IsTerminal - - // RestoreTerminal restores the terminal connected to the given file descriptor - // to a previous state. - // Deprecated: use github.com/moby/term.RestoreTerminal - RestoreTerminal = term.RestoreTerminal - - // SaveState saves the state of the terminal connected to the given file descriptor. - // Deprecated: use github.com/moby/term.SaveState - SaveState = term.SaveState - - // DisableEcho applies the specified state to the terminal connected to the file - // descriptor, with echo disabled. - // Deprecated: use github.com/moby/term.DisableEcho - DisableEcho = term.DisableEcho - - // SetRawTerminal puts the terminal connected to the given file descriptor into - // raw mode and returns the previous state. On UNIX, this puts both the input - // and output into raw mode. On Windows, it only puts the input into raw mode. - // Deprecated: use github.com/moby/term.SetRawTerminal - SetRawTerminal = term.SetRawTerminal - - // SetRawTerminalOutput puts the output of terminal connected to the given file - // descriptor into raw mode. On UNIX, this does nothing and returns nil for the - // state. On Windows, it disables LF -> CRLF translation. - // Deprecated: use github.com/moby/term.SetRawTerminalOutput - SetRawTerminalOutput = term.SetRawTerminalOutput - - // MakeRaw puts the terminal connected to the given file descriptor into raw - // mode and returns the previous state of the terminal so that it can be restored. - // Deprecated: use github.com/moby/term.MakeRaw - MakeRaw = term.MakeRaw - - // NewEscapeProxy returns a new TTY proxy reader which wraps the given reader - // and detects when the specified escape keys are read, in which case the Read - // method will return an error of type EscapeError. - // Deprecated: use github.com/moby/term.NewEscapeProxy - NewEscapeProxy = term.NewEscapeProxy -) diff --git a/vendor/github.com/docker/docker/pkg/term/deprecated_unix.go b/vendor/github.com/docker/docker/pkg/term/deprecated_unix.go deleted file mode 100644 index ed9eb11862..0000000000 --- a/vendor/github.com/docker/docker/pkg/term/deprecated_unix.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !windows - -package term // import "github.com/docker/docker/pkg/term" - -import ( - "github.com/moby/term" -) - -// Termios is the Unix API for terminal I/O. -// Deprecated: use github.com/moby/term.Termios -type Termios = term.Termios - -var ( - // ErrInvalidState is returned if the state of the terminal is invalid. - ErrInvalidState = term.ErrInvalidState - - // SetWinsize tries to set the specified window size for the specified file descriptor. - // Deprecated: use github.com/moby/term.GetWinsize - SetWinsize = term.SetWinsize -) diff --git a/vendor/github.com/docker/docker/registry/config_unix.go b/vendor/github.com/docker/docker/registry/config_unix.go index 8ee8fedfc1..b5bb31cfa6 100644 --- a/vendor/github.com/docker/docker/registry/config_unix.go +++ b/vendor/github.com/docker/docker/registry/config_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package registry // import "github.com/docker/docker/registry" diff --git a/vendor/github.com/docker/docker/registry/endpoint_v1.go b/vendor/github.com/docker/docker/registry/endpoint_v1.go index db342d1412..a355a4f872 100644 --- a/vendor/github.com/docker/docker/registry/endpoint_v1.go +++ b/vendor/github.com/docker/docker/registry/endpoint_v1.go @@ -89,10 +89,7 @@ func trimV1Address(address string) (string, error) { apiVersionStr string ) - if strings.HasSuffix(address, "/") { - address = address[:len(address)-1] - } - + address = strings.TrimSuffix(address, "/") chunks = strings.Split(address, "/") apiVersionStr = chunks[len(chunks)-1] if apiVersionStr == "v1" { diff --git a/vendor/github.com/docker/docker/registry/service_v2.go b/vendor/github.com/docker/docker/registry/service_v2.go index 3e3a5b41ff..154ac7c93e 100644 --- a/vendor/github.com/docker/docker/registry/service_v2.go +++ b/vendor/github.com/docker/docker/registry/service_v2.go @@ -9,6 +9,9 @@ import ( func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { tlsConfig := tlsconfig.ServerDefault() + + ana := allowNondistributableArtifacts(s.config, hostname) + if hostname == DefaultNamespace || hostname == IndexHostname { for _, mirror := range s.config.Mirrors { if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { @@ -36,13 +39,13 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp Official: true, TrimHostname: true, TLSConfig: tlsConfig, + + AllowNondistributableArtifacts: ana, }) return endpoints, nil } - ana := allowNondistributableArtifacts(s.config, hostname) - tlsConfig, err = s.tlsConfig(hostname) if err != nil { return nil, err diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 38169cfd63..352018e703 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,6 +1,26 @@ # Change history of go-restful -## [v3.8.0] - 20221-06-06 +## [v3.10.2] - 2023-03-09 + +- introduced MergePathStrategy to be able to revert behaviour of path concatenation to 3.9.0 + see comment in Readme how to customize this behaviour. + +## [v3.10.1] - 2022-11-19 + +- fix broken 3.10.0 by using path package for joining paths + +## [v3.10.0] - 2022-10-11 - BROKEN + +- changed tokenizer to match std route match behavior; do not trimright the path (#511) +- Add MIME_ZIP (#512) +- Add MIME_ZIP and HEADER_ContentDisposition (#513) +- Changed how to get query parameter issue #510 + +## [v3.9.0] - 2022-07-21 + +- add support for http.Handler implementations to work as FilterFunction, issue #504 (thanks to https://github.com/ggicci) + +## [v3.8.0] - 2022-06-06 - use exact matching of allowed domain entries, issue #489 (#493) - this changes fixes [security] Authorization Bypass Through User-Controlled Key diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index 23166d3b47..85da90128e 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -84,6 +84,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo - Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) - Configurable (trace) logging - Customizable gzip/deflate readers and writers using CompressorProvider registration +- Inject your own http.Handler using the `HttpMiddlewareHandlerToFilter` function ## How to customize There are several hooks to customize the behavior of the go-restful package. @@ -94,7 +95,11 @@ There are several hooks to customize the behavior of the go-restful package. - Trace logging - Compression - Encoders for other serializers -- Use [jsoniter](https://github.com/json-iterator/go) by build this package using a tag, e.g. `go build -tags=jsoniter .` +- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` +- Use the variable `MergePathStrategy` to change the behaviour of composing the Route path given a root path and a local route path + - versions >= 3.10.1 has set the value to `PathJoinStrategy` that fixes a reported [security issue](https://github.com/advisories/GHSA-r48q-9g5r-8q2h) but may cause your services not to work correctly anymore. + - versions <= 3.9 had the behaviour that can be restored in newer versions by setting the value to `TrimSlashStrategy`. + - you can set value to a custom implementation (must implement MergePathStrategyFunc) ## Resources diff --git a/vendor/github.com/emicklei/go-restful/v3/constants.go b/vendor/github.com/emicklei/go-restful/v3/constants.go index 203439c5e5..2328bde6c7 100644 --- a/vendor/github.com/emicklei/go-restful/v3/constants.go +++ b/vendor/github.com/emicklei/go-restful/v3/constants.go @@ -7,12 +7,14 @@ package restful const ( MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() + MIME_ZIP = "application/zip" // Accept or Content-Type used in Consumes() and/or Produces() MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default HEADER_Allow = "Allow" HEADER_Accept = "Accept" HEADER_Origin = "Origin" HEADER_ContentType = "Content-Type" + HEADER_ContentDisposition = "Content-Disposition" HEADER_LastModified = "Last-Modified" HEADER_AcceptEncoding = "Accept-Encoding" HEADER_ContentEncoding = "Content-Encoding" diff --git a/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go b/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go new file mode 100644 index 0000000000..c246512fc0 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go @@ -0,0 +1,21 @@ +package restful + +import ( + "net/http" +) + +// HttpMiddlewareHandler is a function that takes a http.Handler and returns a http.Handler +type HttpMiddlewareHandler func(http.Handler) http.Handler + +// HttpMiddlewareHandlerToFilter converts a HttpMiddlewareHandler to a FilterFunction. +func HttpMiddlewareHandlerToFilter(middleware HttpMiddlewareHandler) FilterFunction { + return func(req *Request, resp *Response, chain *FilterChain) { + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + req.Request = r + resp.ResponseWriter = rw + chain.ProcessFilter(req, resp) + }) + + middleware(next).ServeHTTP(resp.ResponseWriter, req.Request) + } +} diff --git a/vendor/github.com/emicklei/go-restful/v3/parameter.go b/vendor/github.com/emicklei/go-restful/v3/parameter.go index 0e658af5ff..0b851bb437 100644 --- a/vendor/github.com/emicklei/go-restful/v3/parameter.go +++ b/vendor/github.com/emicklei/go-restful/v3/parameter.go @@ -22,6 +22,9 @@ const ( // FormParameterKind = indicator of Request parameter type "form" FormParameterKind + // MultiPartFormParameterKind = indicator of Request parameter type "multipart/form-data" + MultiPartFormParameterKind + // CollectionFormatCSV comma separated values `foo,bar` CollectionFormatCSV = CollectionFormat("csv") @@ -108,6 +111,11 @@ func (p *Parameter) beForm() *Parameter { return p } +func (p *Parameter) beMultiPartForm() *Parameter { + p.data.Kind = MultiPartFormParameterKind + return p +} + // Required sets the required field and returns the receiver func (p *Parameter) Required(required bool) *Parameter { p.data.Required = required diff --git a/vendor/github.com/emicklei/go-restful/v3/request.go b/vendor/github.com/emicklei/go-restful/v3/request.go index 5725a07595..0020095e86 100644 --- a/vendor/github.com/emicklei/go-restful/v3/request.go +++ b/vendor/github.com/emicklei/go-restful/v3/request.go @@ -31,7 +31,8 @@ func NewRequest(httpRequest *http.Request) *Request { // a "Unable to unmarshal content of type:" response is returned. // Valid values are restful.MIME_JSON and restful.MIME_XML // Example: -// restful.DefaultRequestContentType(restful.MIME_JSON) +// +// restful.DefaultRequestContentType(restful.MIME_JSON) func DefaultRequestContentType(mime string) { defaultRequestContentType = mime } @@ -48,7 +49,7 @@ func (r *Request) PathParameters() map[string]string { // QueryParameter returns the (first) Query parameter value by its name func (r *Request) QueryParameter(name string) string { - return r.Request.FormValue(name) + return r.Request.URL.Query().Get(name) } // QueryParameters returns the all the query parameters values by name diff --git a/vendor/github.com/emicklei/go-restful/v3/response.go b/vendor/github.com/emicklei/go-restful/v3/response.go index 8f0b56aa2d..a41a92cc2c 100644 --- a/vendor/github.com/emicklei/go-restful/v3/response.go +++ b/vendor/github.com/emicklei/go-restful/v3/response.go @@ -109,6 +109,9 @@ func (r *Response) EntityWriter() (EntityReaderWriter, bool) { if DefaultResponseMimeType == MIME_XML { return entityAccessRegistry.accessorAt(MIME_XML) } + if DefaultResponseMimeType == MIME_ZIP { + return entityAccessRegistry.accessorAt(MIME_ZIP) + } // Fallback to whatever the route says it can produce. // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for _, each := range r.routeProduces { diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go index 193f4a6b01..ea05b3da88 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route.go +++ b/vendor/github.com/emicklei/go-restful/v3/route.go @@ -164,7 +164,7 @@ func tokenizePath(path string) []string { if "/" == path { return nil } - return strings.Split(strings.Trim(path, "/"), "/") + return strings.Split(strings.TrimLeft(path, "/"), "/") } // for debugging @@ -176,3 +176,5 @@ func (r *Route) String() string { func (r *Route) EnableContentEncoding(enabled bool) { r.contentEncodingEnabled = &enabled } + +var TrimRightSlashEnabled = false diff --git a/vendor/github.com/emicklei/go-restful/v3/route_builder.go b/vendor/github.com/emicklei/go-restful/v3/route_builder.go index 23641b6dd5..827f471de0 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route_builder.go +++ b/vendor/github.com/emicklei/go-restful/v3/route_builder.go @@ -7,6 +7,7 @@ package restful import ( "fmt" "os" + "path" "reflect" "runtime" "strings" @@ -46,11 +47,12 @@ type RouteBuilder struct { // Do evaluates each argument with the RouteBuilder itself. // This allows you to follow DRY principles without breaking the fluent programming style. // Example: -// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) // -// func Returns500(b *RouteBuilder) { -// b.Returns(500, "Internal Server Error", restful.ServiceError{}) -// } +// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) +// +// func Returns500(b *RouteBuilder) { +// b.Returns(500, "Internal Server Error", restful.ServiceError{}) +// } func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder { for _, each := range oneArgBlocks { each(b) @@ -351,8 +353,28 @@ func (b *RouteBuilder) Build() Route { return route } -func concatPath(path1, path2 string) string { - return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/") +type MergePathStrategyFunc func(rootPath, routePath string) string + +var ( + // behavior >= 3.10 + PathJoinStrategy = func(rootPath, routePath string) string { + return path.Join(rootPath, routePath) + } + + // behavior <= 3.9 + TrimSlashStrategy = func(rootPath, routePath string) string { + return strings.TrimRight(rootPath, "/") + "/" + strings.TrimLeft(routePath, "/") + } + + // MergePathStrategy is the active strategy for merging a Route path when building the routing of all WebServices. + // The value is set to PathJoinStrategy + // PathJoinStrategy is a strategy that is more strict [Security - PRISMA-2022-0227] + MergePathStrategy = PathJoinStrategy +) + +// merge two paths using the current (package global) merge path strategy. +func concatPath(rootPath, routePath string) string { + return MergePathStrategy(rootPath, routePath) } var anonymousFuncCount int32 diff --git a/vendor/github.com/emicklei/go-restful/v3/web_service.go b/vendor/github.com/emicklei/go-restful/v3/web_service.go index 0bf5d1e5f7..789c4df259 100644 --- a/vendor/github.com/emicklei/go-restful/v3/web_service.go +++ b/vendor/github.com/emicklei/go-restful/v3/web_service.go @@ -165,6 +165,18 @@ func FormParameter(name, description string) *Parameter { return p } +// MultiPartFormParameter creates a new Parameter of kind Form (using multipart/form-data) for documentation purposes. +// It is initialized as required with string as its DataType. +func (w *WebService) MultiPartFormParameter(name, description string) *Parameter { + return MultiPartFormParameter(name, description) +} + +func MultiPartFormParameter(name, description string) *Parameter { + p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}} + p.beMultiPartForm() + return p +} + // Route creates a new Route using the RouteBuilder and add to the ordered list of Routes. func (w *WebService) Route(builder *RouteBuilder) *WebService { w.routesLock.Lock() diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go index dc2b7e51e6..4bce5936d5 100644 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ b/vendor/github.com/evanphx/json-patch/patch.go @@ -568,29 +568,6 @@ func (p Patch) replace(doc *container, op Operation) error { 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) if con == nil { @@ -657,25 +634,6 @@ func (p Patch) test(doc *container, op Operation) 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) if con == nil { diff --git a/vendor/github.com/felixge/httpsnoop/README.md b/vendor/github.com/felixge/httpsnoop/README.md index ae44137e9b..ddcecd13e7 100644 --- a/vendor/github.com/felixge/httpsnoop/README.md +++ b/vendor/github.com/felixge/httpsnoop/README.md @@ -65,7 +65,8 @@ being called, or called more than once, as well as concurrent calls to Unfortunately this package is not perfect either. It's possible that it is still missing some interfaces provided by the go core (let me know if you find one), and it won't work for applications adding their own interfaces into the -mix. +mix. You can however use `httpsnoop.Unwrap(w)` to access the underlying +`http.ResponseWriter` and type-assert the result to its other interfaces. However, hopefully the explanation above has sufficiently scared you of rolling your own solution to this problem. httpsnoop may still break your application, diff --git a/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/vendor/github.com/felixge/httpsnoop/capture_metrics.go index 4c45b1a8c1..b77cc7c009 100644 --- a/vendor/github.com/felixge/httpsnoop/capture_metrics.go +++ b/vendor/github.com/felixge/httpsnoop/capture_metrics.go @@ -3,7 +3,6 @@ package httpsnoop import ( "io" "net/http" - "sync" "time" ) @@ -36,17 +35,23 @@ func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Me // sugar on top of this func), but is a more usable interface if your // application doesn't use the Go http.Handler interface. func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics { + m := Metrics{Code: http.StatusOK} + m.CaptureMetrics(w, fn) + return m +} + +// CaptureMetrics wraps w and calls fn with the wrapped w and updates +// Metrics m with the resulting metrics. This is similar to CaptureMetricsFn, +// but allows one to customize starting Metrics object. +func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) { var ( start = time.Now() - m = Metrics{Code: http.StatusOK} headerWritten bool - lock sync.Mutex hooks = Hooks{ WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc { return func(code int) { next(code) - lock.Lock() - defer lock.Unlock() + if !headerWritten { m.Code = code headerWritten = true @@ -57,8 +62,7 @@ func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metri Write: func(next WriteFunc) WriteFunc { return func(p []byte) (int, error) { n, err := next(p) - lock.Lock() - defer lock.Unlock() + m.Written += int64(n) headerWritten = true return n, err @@ -68,8 +72,7 @@ func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metri ReadFrom: func(next ReadFromFunc) ReadFromFunc { return func(src io.Reader) (int64, error) { n, err := next(src) - lock.Lock() - defer lock.Unlock() + headerWritten = true m.Written += n return n, err @@ -79,6 +82,5 @@ func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metri ) fn(Wrap(w, hooks)) - m.Duration = time.Since(start) - return m + m.Duration += time.Since(start) } diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go index 41a20da9ea..31cbdfb8ef 100644 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go @@ -74,243 +74,275 @@ func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { // combination 1/32 case !i0 && !i1 && !i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter - }{rw} + }{rw, rw} // combination 2/32 case !i0 && !i1 && !i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Pusher - }{rw, rw} + }{rw, rw, rw} // combination 3/32 case !i0 && !i1 && !i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter io.ReaderFrom - }{rw, rw} + }{rw, rw, rw} // combination 4/32 case !i0 && !i1 && !i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter io.ReaderFrom http.Pusher - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 5/32 case !i0 && !i1 && i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Hijacker - }{rw, rw} + }{rw, rw, rw} // combination 6/32 case !i0 && !i1 && i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Hijacker http.Pusher - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 7/32 case !i0 && !i1 && i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Hijacker io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 8/32 case !i0 && !i1 && i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Hijacker io.ReaderFrom http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 9/32 case !i0 && i1 && !i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier - }{rw, rw} + }{rw, rw, rw} // combination 10/32 case !i0 && i1 && !i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Pusher - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 11/32 case !i0 && i1 && !i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 12/32 case !i0 && i1 && !i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier io.ReaderFrom http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 13/32 case !i0 && i1 && i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 14/32 case !i0 && i1 && i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 15/32 case !i0 && i1 && i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 16/32 case !i0 && i1 && i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker io.ReaderFrom http.Pusher - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} // combination 17/32 case i0 && !i1 && !i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher - }{rw, rw} + }{rw, rw, rw} // combination 18/32 case i0 && !i1 && !i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Pusher - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 19/32 case i0 && !i1 && !i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 20/32 case i0 && !i1 && !i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher io.ReaderFrom http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 21/32 case i0 && !i1 && i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 22/32 case i0 && !i1 && i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 23/32 case i0 && !i1 && i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 24/32 case i0 && !i1 && i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker io.ReaderFrom http.Pusher - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} // combination 25/32 case i0 && i1 && !i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 26/32 case i0 && i1 && !i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Pusher - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 27/32 case i0 && i1 && !i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 28/32 case i0 && i1 && !i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier io.ReaderFrom http.Pusher - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} // combination 29/32 case i0 && i1 && i2 && !i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 30/32 case i0 && i1 && i2 && !i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker http.Pusher - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} // combination 31/32 case i0 && i1 && i2 && i3 && !i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} // combination 32/32 case i0 && i1 && i2 && i3 && i4: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker io.ReaderFrom http.Pusher - }{rw, rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw, rw} } panic("unreachable") } @@ -320,6 +352,10 @@ type rw struct { h Hooks } +func (w *rw) Unwrap() http.ResponseWriter { + return w.w +} + func (w *rw) Header() http.Header { f := w.w.(http.ResponseWriter).Header if w.h.Header != nil { @@ -383,3 +419,18 @@ func (w *rw) Push(target string, opts *http.PushOptions) error { } return f(target, opts) } + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } else { + return w + } +} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go index 36bb59b837..ab99c07c7a 100644 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go @@ -68,115 +68,131 @@ func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { // combination 1/16 case !i0 && !i1 && !i2 && !i3: return struct { + Unwrapper http.ResponseWriter - }{rw} + }{rw, rw} // combination 2/16 case !i0 && !i1 && !i2 && i3: return struct { + Unwrapper http.ResponseWriter io.ReaderFrom - }{rw, rw} + }{rw, rw, rw} // combination 3/16 case !i0 && !i1 && i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.Hijacker - }{rw, rw} + }{rw, rw, rw} // combination 4/16 case !i0 && !i1 && i2 && i3: return struct { + Unwrapper http.ResponseWriter http.Hijacker io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 5/16 case !i0 && i1 && !i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier - }{rw, rw} + }{rw, rw, rw} // combination 6/16 case !i0 && i1 && !i2 && i3: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 7/16 case !i0 && i1 && i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 8/16 case !i0 && i1 && i2 && i3: return struct { + Unwrapper http.ResponseWriter http.CloseNotifier http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 9/16 case i0 && !i1 && !i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.Flusher - }{rw, rw} + }{rw, rw, rw} // combination 10/16 case i0 && !i1 && !i2 && i3: return struct { + Unwrapper http.ResponseWriter http.Flusher io.ReaderFrom - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 11/16 case i0 && !i1 && i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 12/16 case i0 && !i1 && i2 && i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 13/16 case i0 && i1 && !i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier - }{rw, rw, rw} + }{rw, rw, rw, rw} // combination 14/16 case i0 && i1 && !i2 && i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier io.ReaderFrom - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 15/16 case i0 && i1 && i2 && !i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker - }{rw, rw, rw, rw} + }{rw, rw, rw, rw, rw} // combination 16/16 case i0 && i1 && i2 && i3: return struct { + Unwrapper http.ResponseWriter http.Flusher http.CloseNotifier http.Hijacker io.ReaderFrom - }{rw, rw, rw, rw, rw} + }{rw, rw, rw, rw, rw, rw} } panic("unreachable") } @@ -186,6 +202,10 @@ type rw struct { h Hooks } +func (w *rw) Unwrap() http.ResponseWriter { + return w.w +} + func (w *rw) Header() http.Header { f := w.w.(http.ResponseWriter).Header if w.h.Header != nil { @@ -241,3 +261,18 @@ func (w *rw) ReadFrom(src io.Reader) (int64, error) { } return f(src) } + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } else { + return w + } +} diff --git a/vendor/github.com/fsnotify/fsnotify/.gitignore b/vendor/github.com/fsnotify/fsnotify/.gitignore index 4cd0cbaf43..1d89d85ce4 100644 --- a/vendor/github.com/fsnotify/fsnotify/.gitignore +++ b/vendor/github.com/fsnotify/fsnotify/.gitignore @@ -1,6 +1,6 @@ -# Setup a Global .gitignore for OS and editor generated files: -# https://help.github.com/articles/ignoring-files -# git config --global core.excludesfile ~/.gitignore_global +# go test -c output +*.test +*.test.exe -.vagrant -*.sublime-project +# Output of go build ./cmd/fsnotify +/fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/AUTHORS b/vendor/github.com/fsnotify/fsnotify/AUTHORS deleted file mode 100644 index 6cbabe5ef5..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/AUTHORS +++ /dev/null @@ -1,62 +0,0 @@ -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# You can update this list using the following command: -# -# $ (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 -Christoffer Buchholz -Daniel Wagner-Hall -Dave Cheney -Eric Lin -Evan Phoenix -Francisco Souza -Gautam Dey -Hari haran -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 -Rodrigo Chiossi -Slawek Ligus -Soge Zhang -Tiffany Jernigan -Tilak Sharma -Tobias Klauser -Tom Payne -Travis Cline -Tudor Golubenco -Vahe Khachikyan -Yukang -bronze1man -debrando -henrikedwards -铁哥 diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md index cc01c08f56..77f9593bd5 100644 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md @@ -7,6 +7,95 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +Nothing yet. + +## [1.6.0] - 2022-10-13 + +This version of fsnotify needs Go 1.16 (this was already the case since 1.5.1, +but not documented). It also increases the minimum Linux version to 2.6.32. + +### Additions + +- all: add `Event.Has()` and `Op.Has()` ([#477]) + + This makes checking events a lot easier; for example: + + if event.Op&Write == Write && !(event.Op&Remove == Remove) { + } + + Becomes: + + if event.Has(Write) && !event.Has(Remove) { + } + +- all: add cmd/fsnotify ([#463]) + + A command-line utility for testing and some examples. + +### Changes and fixes + +- inotify: don't ignore events for files that don't exist ([#260], [#470]) + + Previously the inotify watcher would call `os.Lstat()` to check if a file + still exists before emitting events. + + This was inconsistent with other platforms and resulted in inconsistent event + reporting (e.g. when a file is quickly removed and re-created), and generally + a source of confusion. It was added in 2013 to fix a memory leak that no + longer exists. + +- all: return `ErrNonExistentWatch` when `Remove()` is called on a path that's + not watched ([#460]) + +- inotify: replace epoll() with non-blocking inotify ([#434]) + + Non-blocking inotify was not generally available at the time this library was + written in 2014, but now it is. As a result, the minimum Linux version is + bumped from 2.6.27 to 2.6.32. This hugely simplifies the code and is faster. + +- kqueue: don't check for events every 100ms ([#480]) + + The watcher would wake up every 100ms, even when there was nothing to do. Now + it waits until there is something to do. + +- macos: retry opening files on EINTR ([#475]) + +- kqueue: skip unreadable files ([#479]) + + kqueue requires a file descriptor for every file in a directory; this would + fail if a file was unreadable by the current user. Now these files are simply + skipped. + +- windows: fix renaming a watched directory if the parent is also watched ([#370]) + +- windows: increase buffer size from 4K to 64K ([#485]) + +- windows: close file handle on Remove() ([#288]) + +- kqueue: put pathname in the error if watching a file fails ([#471]) + +- inotify, windows: calling Close() more than once could race ([#465]) + +- kqueue: improve Close() performance ([#233]) + +- all: various documentation additions and clarifications. + +[#233]: https://github.com/fsnotify/fsnotify/pull/233 +[#260]: https://github.com/fsnotify/fsnotify/pull/260 +[#288]: https://github.com/fsnotify/fsnotify/pull/288 +[#370]: https://github.com/fsnotify/fsnotify/pull/370 +[#434]: https://github.com/fsnotify/fsnotify/pull/434 +[#460]: https://github.com/fsnotify/fsnotify/pull/460 +[#463]: https://github.com/fsnotify/fsnotify/pull/463 +[#465]: https://github.com/fsnotify/fsnotify/pull/465 +[#470]: https://github.com/fsnotify/fsnotify/pull/470 +[#471]: https://github.com/fsnotify/fsnotify/pull/471 +[#475]: https://github.com/fsnotify/fsnotify/pull/475 +[#477]: https://github.com/fsnotify/fsnotify/pull/477 +[#479]: https://github.com/fsnotify/fsnotify/pull/479 +[#480]: https://github.com/fsnotify/fsnotify/pull/480 +[#485]: https://github.com/fsnotify/fsnotify/pull/485 + ## [1.5.4] - 2022-04-25 * Windows: add missing defer to `Watcher.WatchList` [#447](https://github.com/fsnotify/fsnotify/pull/447) @@ -40,6 +129,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#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.9] - 2020-03-11 + +* Move example usage to the readme #329. This may resolve #328. + +## [1.4.8] - 2020-03-10 + +* CI: test more go versions (@nathany 1d13583d846ea9d66dcabbfefbfb9d8e6fb05216) +* Tests: Queued inotify events could have been read by the test before max_queued_events was hit (@matthias-stone #265) +* Tests: t.Fatalf -> t.Errorf in go routines (@gdey #266) +* CI: Less verbosity (@nathany #267) +* Tests: Darwin: Exchangedata is deprecated on 10.13 (@nathany #267) +* Tests: Check if channels are closed in the example (@alexeykazakov #244) +* CI: Only run golint on latest version of go and fix issues (@cpuguy83 #284) +* CI: Add windows to travis matrix (@cpuguy83 #284) +* Docs: Remover appveyor badge (@nathany 11844c0959f6fff69ba325d097fce35bd85a8e93) +* Linux: create epoll and pipe fds with close-on-exec (@JohannesEbke #219) +* Linux: open files with close-on-exec (@linxiulei #273) +* Docs: Plan to support fanotify (@nathany ab058b44498e8b7566a799372a39d150d9ea0119 ) +* Project: Add go.mod (@nathany #309) +* Project: Revise editor config (@nathany #309) +* Project: Update copyright for 2019 (@nathany #309) +* CI: Drop go1.8 from CI matrix (@nathany #309) +* Docs: Updating the FAQ section for supportability with NFS & FUSE filesystems (@Pratik32 4bf2d1fec78374803a39307bfb8d340688f4f28e ) + ## [1.4.7] - 2018-01-09 * BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine) diff --git a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md index 8a642563d7..ea379759d5 100644 --- a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md +++ b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md @@ -1,60 +1,26 @@ -# Contributing +Thank you for your interest in contributing to fsnotify! We try to review and +merge PRs in a reasonable timeframe, but please be aware that: -## Issues +- To avoid "wasted" work, please discus changes on the issue tracker first. You + can just send PRs, but they may end up being rejected for one reason or the + other. -* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnotify/fsnotify/issues). -* Please indicate the platform you are using fsnotify on. -* A code example to reproduce the problem is appreciated. +- fsnotify is a cross-platform library, and changes must work reasonably well on + all supported platforms. -## Pull Requests +- Changes will need to be compatible; old code should still compile, and the + runtime behaviour can't change in ways that are likely to lead to problems for + users. -### Contributor License Agreement +Testing +------- +Just `go test ./...` runs all the tests; the CI runs this on all supported +platforms. Testing different platforms locally can be done with something like +[goon] or [Vagrant], but this isn't super-easy to set up at the moment. -fsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual). +Use the `-short` flag to make the "stress test" run faster. -Please indicate that you have signed the CLA in your pull request. -### How fsnotify is Developed - -* Development is done on feature branches. -* Tests are run on BSD, Linux, macOS and Windows. -* Pull requests are reviewed and [applied to master][am] using [hub][]. - * Maintainers may modify or squash commits rather than asking contributors to. -* To issue a new release, the maintainers will: - * Update the CHANGELOG - * Tag a version, which will become available through gopkg.in. - -### How to Fork - -For smooth sailing, always use the original import path. Installing with `go get` makes this easy. - -1. Install from GitHub (`go get -u github.com/fsnotify/fsnotify`) -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Ensure everything works and the tests pass (see below) -4. Commit your changes (`git commit -am 'Add some feature'`) - -Contribute upstream: - -1. Fork fsnotify on GitHub -2. Add your remote (`git remote add fork git@github.com:mycompany/repo.git`) -3. Push to the branch (`git push fork my-new-feature`) -4. Create a new Pull Request on GitHub - -This workflow is [thoroughly explained by Katrina Owen](https://splice.com/blog/contributing-open-source-git-repositories-go/). - -### Testing - -fsnotify uses build tags to compile different code on Linux, BSD, macOS, and Windows. - -Before doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on. - -### Maintainers - -Help maintaining fsnotify is welcome. To be a maintainer: - -* Submit a pull request and sign the CLA as above. -* You must be able to run the test suite on Mac, Windows, Linux and BSD. - -All code changes should be internal pull requests. - -Releases are tagged using [Semantic Versioning](http://semver.org/). +[goon]: https://github.com/arp242/goon +[Vagrant]: https://www.vagrantup.com/ +[integration_test.go]: /integration_test.go diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE index e180c8fb05..fb03ade750 100644 --- a/vendor/github.com/fsnotify/fsnotify/LICENSE +++ b/vendor/github.com/fsnotify/fsnotify/LICENSE @@ -1,28 +1,25 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012-2019 fsnotify Authors. All rights reserved. +Copyright © 2012 The Go Authors. All rights reserved. +Copyright © fsnotify 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: +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. +* 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. +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/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index 0731c5ef8a..d4e6080feb 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -1,120 +1,161 @@ -# File system notifications for Go +fsnotify is a Go library to provide cross-platform filesystem notifications on +Windows, Linux, macOS, and BSD systems. -[![Go Reference](https://pkg.go.dev/badge/github.com/fsnotify/fsnotify.svg)](https://pkg.go.dev/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg)](https://github.com/fsnotify/fsnotify/issues/413) +Go 1.16 or newer is required; the full documentation is at +https://pkg.go.dev/github.com/fsnotify/fsnotify -fsnotify utilizes [`golang.org/x/sys`](https://pkg.go.dev/golang.org/x/sys) rather than [`syscall`](https://pkg.go.dev/syscall) from the standard library. +**It's best to read the documentation at pkg.go.dev, as it's pinned to the last +released version, whereas this README is for the last development version which +may include additions/changes.** -Cross platform: Windows, Linux, BSD and macOS. +--- -| Adapter | OS | Status | -| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| 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/pull/371) | -| fanotify | Linux 2.6.37+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) | -| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | -| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | +Platform support: -\* Android and iOS are untested. +| Adapter | OS | Status | +| --------------------- | ---------------| -------------------------------------------------------------| +| inotify | Linux 2.6.32+ | Supported | +| kqueue | BSD, macOS | Supported | +| ReadDirectoryChangesW | Windows | Supported | +| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | +| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) | +| fanotify | Linux 5.9+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) | +| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | +| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | -Please see [the documentation](https://pkg.go.dev/github.com/fsnotify/fsnotify) and consult the [FAQ](#faq) for usage information. +Linux and macOS should include Android and iOS, but these are currently untested. -## API stability - -fsnotify is a fork of [howeyc/fsnotify](https://github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA). - -All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). - -## Usage +Usage +----- +A basic example: ```go package main import ( - "log" + "log" - "github.com/fsnotify/fsnotify" + "github.com/fsnotify/fsnotify" ) func main() { - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - defer watcher.Close() - - done := make(chan bool) - go func() { - for { - select { - case event, ok := <-watcher.Events: - if !ok { - return - } - log.Println("event:", event) - if event.Op&fsnotify.Write == fsnotify.Write { - log.Println("modified file:", event.Name) - } - case err, ok := <-watcher.Errors: - if !ok { - return - } - log.Println("error:", err) - } - } - }() - - err = watcher.Add("/tmp/foo") - if err != nil { - log.Fatal(err) - } - <-done + // Create new watcher. + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + // Start listening for events. + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + log.Println("event:", event) + if event.Has(fsnotify.Write) { + log.Println("modified file:", event.Name) + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } + }() + + // Add a path. + err = watcher.Add("/tmp") + if err != nil { + log.Fatal(err) + } + + // Block main goroutine forever. + <-make(chan struct{}) } ``` -## Contributing +Some more examples can be found in [cmd/fsnotify](cmd/fsnotify), which can be +run with: -Please refer to [CONTRIBUTING][] before opening an issue or pull request. + % go run ./cmd/fsnotify -## FAQ +FAQ +--- +### Will a file still be watched when it's moved to another directory? +No, not unless you are watching the location it was moved to. -**When a file is moved to another directory is it still being watched?** +### Are subdirectories watched too? +No, you must add watches for any directory you want to watch (a recursive +watcher is on the roadmap: [#18]). -No (it shouldn't be, unless you are watching where it was moved to). +[#18]: https://github.com/fsnotify/fsnotify/issues/18 -**When I watch a directory, are all subdirectories watched as well?** +### Do I have to watch the Error and Event channels in a goroutine? +As of now, yes (you can read both channels in the same goroutine using `select`, +you don't need a separate goroutine for both channels; see the example). -No, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap [#18][]). +### Why don't notifications work with NFS, SMB, FUSE, /proc, or /sys? +fsnotify requires support from underlying OS to work. The current NFS and SMB +protocols does not provide network level support for file notifications, and +neither do the /proc and /sys virtual filesystems. -**Do I have to watch the Error and Event channels in a separate goroutine?** +This could be fixed with a polling watcher ([#9]), but it's not yet implemented. -As of now, yes. Looking into making this single-thread friendly (see [howeyc #7][#7]) +[#9]: https://github.com/fsnotify/fsnotify/issues/9 -**Why am I receiving multiple events for the same file on OS X?** +Platform-specific notes +----------------------- +### Linux +When a file is removed a REMOVE event won't be emitted until all file +descriptors are closed; it will emit a CHMOD instead: -Spotlight indexing on OS X can result in multiple events (see [howeyc #62][#62]). A temporary workaround is to add your folder(s) to the *Spotlight Privacy settings* until we have a native FSEvents implementation (see [#11][]). + fp := os.Open("file") + os.Remove("file") // CHMOD + fp.Close() // REMOVE -**How many files can be watched at once?** +This is the event that inotify sends, so not much can be changed about this. -There are OS-specific limits as to how many watches can be created: -* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error. -* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error. +The `fs.inotify.max_user_watches` sysctl variable specifies the upper limit for +the number of watches per user, and `fs.inotify.max_user_instances` specifies +the maximum number of inotify instances per user. Every Watcher you create is an +"instance", and every path you add is a "watch". -**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?** +These are also exposed in `/proc` as `/proc/sys/fs/inotify/max_user_watches` and +`/proc/sys/fs/inotify/max_user_instances` -fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications. +To increase them you can use `sysctl` or write the value to proc file: -[#62]: https://github.com/howeyc/fsnotify/issues/62 -[#18]: https://github.com/fsnotify/fsnotify/issues/18 -[#11]: https://github.com/fsnotify/fsnotify/issues/11 -[#7]: https://github.com/howeyc/fsnotify/issues/7 + # The default values on Linux 5.18 + sysctl fs.inotify.max_user_watches=124983 + sysctl fs.inotify.max_user_instances=128 + +To make the changes persist on reboot edit `/etc/sysctl.conf` or +`/usr/lib/sysctl.d/50-default.conf` (details differ per Linux distro; check your +distro's documentation): + + fs.inotify.max_user_watches=124983 + fs.inotify.max_user_instances=128 -[contributing]: https://github.com/fsnotify/fsnotify/blob/master/CONTRIBUTING.md +Reaching the limit will result in a "no space left on device" or "too many open +files" error. -## Related Projects +### kqueue (macOS, all BSD systems) +kqueue requires opening a file descriptor for every file that's being watched; +so if you're watching a directory with five files then that's six file +descriptors. You will run in to your system's "max open files" limit faster on +these platforms. -* [notify](https://github.com/rjeczalik/notify) -* [fsevents](https://github.com/fsnotify/fsevents) +The sysctl variables `kern.maxfiles` and `kern.maxfilesperproc` can be used to +control the maximum number of open files. +### macOS +Spotlight indexing on macOS can result in multiple events (see [#15]). A temporary +workaround is to add your folder(s) to the *Spotlight Privacy settings* until we +have a native FSEvents implementation (see [#11]). + +[#11]: https://github.com/fsnotify/fsnotify/issues/11 +[#15]: https://github.com/fsnotify/fsnotify/issues/15 diff --git a/vendor/github.com/fsnotify/fsnotify/backend_fen.go b/vendor/github.com/fsnotify/fsnotify/backend_fen.go new file mode 100644 index 0000000000..1a95ad8e7c --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/backend_fen.go @@ -0,0 +1,162 @@ +//go:build solaris +// +build solaris + +package fsnotify + +import ( + "errors" +) + +// Watcher watches a set of paths, delivering events on a channel. +// +// A watcher should not be copied (e.g. pass it by pointer, rather than by +// value). +// +// # Linux notes +// +// When a file is removed a Remove event won't be emitted until all file +// descriptors are closed, and deletes will always emit a Chmod. For example: +// +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove +// +// This is the event that inotify sends, so not much can be changed about this. +// +// The fs.inotify.max_user_watches sysctl variable specifies the upper limit +// for the number of watches per user, and fs.inotify.max_user_instances +// specifies the maximum number of inotify instances per user. Every Watcher you +// create is an "instance", and every path you add is a "watch". +// +// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and +// /proc/sys/fs/inotify/max_user_instances +// +// To increase them you can use sysctl or write the value to the /proc file: +// +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 +// +// To make the changes persist on reboot edit /etc/sysctl.conf or +// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check +// your distro's documentation): +// +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 +// +// Reaching the limit will result in a "no space left on device" or "too many open +// files" error. +// +// # kqueue notes (macOS, BSD) +// +// kqueue requires opening a file descriptor for every file that's being watched; +// so if you're watching a directory with five files then that's six file +// descriptors. You will run in to your system's "max open files" limit faster on +// these platforms. +// +// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to +// control the maximum number of open files, as well as /etc/login.conf on BSD +// systems. +// +// # macOS notes +// +// Spotlight indexing on macOS can result in multiple events (see [#15]). A +// temporary workaround is to add your folder(s) to the "Spotlight Privacy +// Settings" until we have a native FSEvents implementation (see [#11]). +// +// [#11]: https://github.com/fsnotify/fsnotify/issues/11 +// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +type Watcher struct { + // Events sends the filesystem change events. + // + // fsnotify can send the following events; a "path" here can refer to a + // file, directory, symbolic link, or special file like a FIFO. + // + // fsnotify.Create A new path was created; this may be followed by one + // or more Write events if data also gets written to a + // file. + // + // fsnotify.Remove A path was removed. + // + // fsnotify.Rename A path was renamed. A rename is always sent with the + // old path as Event.Name, and a Create event will be + // sent with the new name. Renames are only sent for + // paths that are currently watched; e.g. moving an + // unmonitored file into a monitored directory will + // show up as just a Create. Similarly, renaming a file + // to outside a monitored directory will show up as + // only a Rename. + // + // fsnotify.Write A file or named pipe was written to. A Truncate will + // also trigger a Write. A single "write action" + // initiated by the user may show up as one or multiple + // writes, depending on when the system syncs things to + // disk. For example when compiling a large Go program + // you may get hundreds of Write events, so you + // probably want to wait until you've stopped receiving + // them (see the dedup example in cmd/fsnotify). + // + // fsnotify.Chmod Attributes were changed. On Linux this is also sent + // when a file is removed (or more accurately, when a + // link to an inode is removed). On kqueue it's sent + // and on kqueue when a file is truncated. On Windows + // it's never sent. + Events chan Event + + // Errors sends any errors. + Errors chan error +} + +// NewWatcher creates a new Watcher. +func NewWatcher() (*Watcher, error) { + return nil, errors.New("FEN based watcher not yet supported for fsnotify\n") +} + +// Close removes all watches and closes the events channel. +func (w *Watcher) Close() error { + return nil +} + +// Add starts monitoring the path for changes. +// +// A path can only be watched once; attempting to watch it more than once will +// return an error. Paths that do not yet exist on the filesystem cannot be +// added. A watch will be automatically removed if the path is deleted. +// +// A path will remain watched if it gets renamed to somewhere else on the same +// filesystem, but the monitor will get removed if the path gets deleted and +// re-created, or if it's moved to a different filesystem. +// +// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special +// filesystems (/proc, /sys, etc.) generally don't work. +// +// # Watching directories +// +// All files in a directory are monitored, including new files that are created +// after the watcher is started. Subdirectories are not watched (i.e. it's +// non-recursive). +// +// # Watching files +// +// Watching individual files (rather than directories) is generally not +// recommended as many tools update files atomically. Instead of "just" writing +// to the file a temporary file will be written to first, and if successful the +// temporary file is moved to to destination removing the original, or some +// variant thereof. The watcher on the original file is now lost, as it no +// longer exists. +// +// Instead, watch the parent directory and use Event.Name to filter out files +// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. +func (w *Watcher) Add(name string) error { + return nil +} + +// Remove stops monitoring the path for changes. +// +// Directories are always removed non-recursively. For example, if you added +// /tmp/dir and /tmp/dir/subdir then you will need to remove both. +// +// Removing a path that has not yet been added returns [ErrNonExistentWatch]. +func (w *Watcher) Remove(name string) error { + return nil +} diff --git a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go new file mode 100644 index 0000000000..54c77fbb0e --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go @@ -0,0 +1,459 @@ +//go:build linux +// +build linux + +package fsnotify + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "sync" + "unsafe" + + "golang.org/x/sys/unix" +) + +// Watcher watches a set of paths, delivering events on a channel. +// +// A watcher should not be copied (e.g. pass it by pointer, rather than by +// value). +// +// # Linux notes +// +// When a file is removed a Remove event won't be emitted until all file +// descriptors are closed, and deletes will always emit a Chmod. For example: +// +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove +// +// This is the event that inotify sends, so not much can be changed about this. +// +// The fs.inotify.max_user_watches sysctl variable specifies the upper limit +// for the number of watches per user, and fs.inotify.max_user_instances +// specifies the maximum number of inotify instances per user. Every Watcher you +// create is an "instance", and every path you add is a "watch". +// +// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and +// /proc/sys/fs/inotify/max_user_instances +// +// To increase them you can use sysctl or write the value to the /proc file: +// +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 +// +// To make the changes persist on reboot edit /etc/sysctl.conf or +// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check +// your distro's documentation): +// +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 +// +// Reaching the limit will result in a "no space left on device" or "too many open +// files" error. +// +// # kqueue notes (macOS, BSD) +// +// kqueue requires opening a file descriptor for every file that's being watched; +// so if you're watching a directory with five files then that's six file +// descriptors. You will run in to your system's "max open files" limit faster on +// these platforms. +// +// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to +// control the maximum number of open files, as well as /etc/login.conf on BSD +// systems. +// +// # macOS notes +// +// Spotlight indexing on macOS can result in multiple events (see [#15]). A +// temporary workaround is to add your folder(s) to the "Spotlight Privacy +// Settings" until we have a native FSEvents implementation (see [#11]). +// +// [#11]: https://github.com/fsnotify/fsnotify/issues/11 +// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +type Watcher struct { + // Events sends the filesystem change events. + // + // fsnotify can send the following events; a "path" here can refer to a + // file, directory, symbolic link, or special file like a FIFO. + // + // fsnotify.Create A new path was created; this may be followed by one + // or more Write events if data also gets written to a + // file. + // + // fsnotify.Remove A path was removed. + // + // fsnotify.Rename A path was renamed. A rename is always sent with the + // old path as Event.Name, and a Create event will be + // sent with the new name. Renames are only sent for + // paths that are currently watched; e.g. moving an + // unmonitored file into a monitored directory will + // show up as just a Create. Similarly, renaming a file + // to outside a monitored directory will show up as + // only a Rename. + // + // fsnotify.Write A file or named pipe was written to. A Truncate will + // also trigger a Write. A single "write action" + // initiated by the user may show up as one or multiple + // writes, depending on when the system syncs things to + // disk. For example when compiling a large Go program + // you may get hundreds of Write events, so you + // probably want to wait until you've stopped receiving + // them (see the dedup example in cmd/fsnotify). + // + // fsnotify.Chmod Attributes were changed. On Linux this is also sent + // when a file is removed (or more accurately, when a + // link to an inode is removed). On kqueue it's sent + // and on kqueue when a file is truncated. On Windows + // it's never sent. + Events chan Event + + // Errors sends any errors. + Errors chan error + + // Store fd here as os.File.Read() will no longer return on close after + // calling Fd(). See: https://github.com/golang/go/issues/26439 + fd int + mu sync.Mutex // Map access + inotifyFile *os.File + watches map[string]*watch // Map of inotify watches (key: path) + paths map[int]string // Map of watched paths (key: watch descriptor) + done chan struct{} // Channel for sending a "quit message" to the reader goroutine + doneResp chan struct{} // Channel to respond to Close +} + +// NewWatcher creates a new Watcher. +func NewWatcher() (*Watcher, error) { + // Create inotify fd + // Need to set the FD to nonblocking mode in order for SetDeadline methods to work + // Otherwise, blocking i/o operations won't terminate on close + fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC | unix.IN_NONBLOCK) + if fd == -1 { + return nil, errno + } + + w := &Watcher{ + fd: fd, + inotifyFile: os.NewFile(uintptr(fd), ""), + watches: make(map[string]*watch), + paths: make(map[int]string), + Events: make(chan Event), + Errors: make(chan error), + done: make(chan struct{}), + doneResp: make(chan struct{}), + } + + go w.readEvents() + return w, nil +} + +// Returns true if the event was sent, or false if watcher is closed. +func (w *Watcher) sendEvent(e Event) bool { + select { + case w.Events <- e: + return true + case <-w.done: + } + return false +} + +// Returns true if the error was sent, or false if watcher is closed. +func (w *Watcher) sendError(err error) bool { + select { + case w.Errors <- err: + return true + case <-w.done: + return false + } +} + +func (w *Watcher) isClosed() bool { + select { + case <-w.done: + return true + default: + return false + } +} + +// Close removes all watches and closes the events channel. +func (w *Watcher) Close() error { + w.mu.Lock() + if w.isClosed() { + w.mu.Unlock() + return nil + } + + // Send 'close' signal to goroutine, and set the Watcher to closed. + close(w.done) + w.mu.Unlock() + + // Causes any blocking reads to return with an error, provided the file + // still supports deadline operations. + err := w.inotifyFile.Close() + if err != nil { + return err + } + + // Wait for goroutine to close + <-w.doneResp + + return nil +} + +// Add starts monitoring the path for changes. +// +// A path can only be watched once; attempting to watch it more than once will +// return an error. Paths that do not yet exist on the filesystem cannot be +// added. A watch will be automatically removed if the path is deleted. +// +// A path will remain watched if it gets renamed to somewhere else on the same +// filesystem, but the monitor will get removed if the path gets deleted and +// re-created, or if it's moved to a different filesystem. +// +// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special +// filesystems (/proc, /sys, etc.) generally don't work. +// +// # Watching directories +// +// All files in a directory are monitored, including new files that are created +// after the watcher is started. Subdirectories are not watched (i.e. it's +// non-recursive). +// +// # Watching files +// +// Watching individual files (rather than directories) is generally not +// recommended as many tools update files atomically. Instead of "just" writing +// to the file a temporary file will be written to first, and if successful the +// temporary file is moved to to destination removing the original, or some +// variant thereof. The watcher on the original file is now lost, as it no +// longer exists. +// +// Instead, watch the parent directory and use Event.Name to filter out files +// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. +func (w *Watcher) Add(name string) error { + name = filepath.Clean(name) + if w.isClosed() { + return errors.New("inotify instance already closed") + } + + var flags uint32 = unix.IN_MOVED_TO | unix.IN_MOVED_FROM | + unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY | + unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF + + w.mu.Lock() + defer w.mu.Unlock() + watchEntry := w.watches[name] + if watchEntry != nil { + flags |= watchEntry.flags | unix.IN_MASK_ADD + } + wd, errno := unix.InotifyAddWatch(w.fd, name, flags) + if wd == -1 { + return errno + } + + if watchEntry == nil { + w.watches[name] = &watch{wd: uint32(wd), flags: flags} + w.paths[wd] = name + } else { + watchEntry.wd = uint32(wd) + watchEntry.flags = flags + } + + return nil +} + +// Remove stops monitoring the path for changes. +// +// Directories are always removed non-recursively. For example, if you added +// /tmp/dir and /tmp/dir/subdir then you will need to remove both. +// +// Removing a path that has not yet been added returns [ErrNonExistentWatch]. +func (w *Watcher) Remove(name string) error { + name = filepath.Clean(name) + + // Fetch the watch. + w.mu.Lock() + defer w.mu.Unlock() + watch, ok := w.watches[name] + + // Remove it from inotify. + if !ok { + return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) + } + + // We successfully removed the watch if InotifyRmWatch doesn't return an + // error, we need to clean up our internal state to ensure it matches + // inotify's kernel state. + delete(w.paths, int(watch.wd)) + delete(w.watches, name) + + // inotify_rm_watch will return EINVAL if the file has been deleted; + // the inotify will already have been removed. + // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously + // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE + // so that EINVAL means that the wd is being rm_watch()ed or its file removed + // by another thread and we have not received IN_IGNORE event. + success, errno := unix.InotifyRmWatch(w.fd, watch.wd) + if success == -1 { + // TODO: Perhaps it's not helpful to return an error here in every case; + // The only two possible errors are: + // + // - EBADF, which happens when w.fd is not a valid file descriptor + // of any kind. + // - EINVAL, which is when fd is not an inotify descriptor or wd + // is not a valid watch descriptor. Watch descriptors are + // invalidated when they are removed explicitly or implicitly; + // explicitly by inotify_rm_watch, implicitly when the file they + // are watching is deleted. + return errno + } + + return nil +} + +// WatchList returns all paths added with [Add] (and are not yet removed). +func (w *Watcher) WatchList() []string { + w.mu.Lock() + defer w.mu.Unlock() + + entries := make([]string, 0, len(w.watches)) + for pathname := range w.watches { + entries = append(entries, pathname) + } + + return entries +} + +type watch struct { + wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) + flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) +} + +// readEvents reads from the inotify file descriptor, converts the +// received events into Event objects and sends them via the Events channel +func (w *Watcher) readEvents() { + defer func() { + close(w.doneResp) + close(w.Errors) + close(w.Events) + }() + + var ( + buf [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events + errno error // Syscall errno + ) + for { + // See if we have been closed. + if w.isClosed() { + return + } + + n, err := w.inotifyFile.Read(buf[:]) + switch { + case errors.Unwrap(err) == os.ErrClosed: + return + case err != nil: + if !w.sendError(err) { + return + } + continue + } + + if n < unix.SizeofInotifyEvent { + var err error + if n == 0 { + // If EOF is received. This should really never happen. + err = io.EOF + } else if n < 0 { + // If an error occurred while reading. + err = errno + } else { + // Read was too short. + err = errors.New("notify: short read in readEvents()") + } + if !w.sendError(err) { + return + } + continue + } + + var offset uint32 + // We don't know how many events we just read into the buffer + // While the offset points to at least one whole event... + for offset <= uint32(n-unix.SizeofInotifyEvent) { + var ( + // Point "raw" to the event in the buffer + raw = (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset])) + mask = uint32(raw.Mask) + nameLen = uint32(raw.Len) + ) + + if mask&unix.IN_Q_OVERFLOW != 0 { + if !w.sendError(ErrEventOverflow) { + return + } + } + + // If the event happened to the watched directory or the watched file, the kernel + // doesn't append the filename to the event, but we would like to always fill the + // the "Name" field with a valid filename. We retrieve the path of the watch from + // the "paths" map. + w.mu.Lock() + name, ok := w.paths[int(raw.Wd)] + // IN_DELETE_SELF occurs when the file/directory being watched is removed. + // This is a sign to clean up the maps, otherwise we are no longer in sync + // with the inotify kernel state which has already deleted the watch + // automatically. + if ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { + delete(w.paths, int(raw.Wd)) + delete(w.watches, name) + } + w.mu.Unlock() + + if nameLen > 0 { + // Point "bytes" at the first byte of the filename + 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") + } + + event := w.newEvent(name, mask) + + // Send the events that are not ignored on the events channel + if mask&unix.IN_IGNORED == 0 { + if !w.sendEvent(event) { + return + } + } + + // Move to the next event in the buffer + offset += unix.SizeofInotifyEvent + nameLen + } + } +} + +// newEvent returns an platform-independent Event based on an inotify mask. +func (w *Watcher) newEvent(name string, mask uint32) Event { + e := Event{Name: name} + if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO { + e.Op |= Create + } + if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE { + e.Op |= Remove + } + if mask&unix.IN_MODIFY == unix.IN_MODIFY { + e.Op |= Write + } + if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM { + e.Op |= Rename + } + if mask&unix.IN_ATTRIB == unix.IN_ATTRIB { + e.Op |= Chmod + } + return e +} diff --git a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go new file mode 100644 index 0000000000..29087469bf --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go @@ -0,0 +1,707 @@ +//go:build freebsd || openbsd || netbsd || dragonfly || darwin +// +build freebsd openbsd netbsd dragonfly darwin + +package fsnotify + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "sync" + + "golang.org/x/sys/unix" +) + +// Watcher watches a set of paths, delivering events on a channel. +// +// A watcher should not be copied (e.g. pass it by pointer, rather than by +// value). +// +// # Linux notes +// +// When a file is removed a Remove event won't be emitted until all file +// descriptors are closed, and deletes will always emit a Chmod. For example: +// +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove +// +// This is the event that inotify sends, so not much can be changed about this. +// +// The fs.inotify.max_user_watches sysctl variable specifies the upper limit +// for the number of watches per user, and fs.inotify.max_user_instances +// specifies the maximum number of inotify instances per user. Every Watcher you +// create is an "instance", and every path you add is a "watch". +// +// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and +// /proc/sys/fs/inotify/max_user_instances +// +// To increase them you can use sysctl or write the value to the /proc file: +// +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 +// +// To make the changes persist on reboot edit /etc/sysctl.conf or +// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check +// your distro's documentation): +// +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 +// +// Reaching the limit will result in a "no space left on device" or "too many open +// files" error. +// +// # kqueue notes (macOS, BSD) +// +// kqueue requires opening a file descriptor for every file that's being watched; +// so if you're watching a directory with five files then that's six file +// descriptors. You will run in to your system's "max open files" limit faster on +// these platforms. +// +// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to +// control the maximum number of open files, as well as /etc/login.conf on BSD +// systems. +// +// # macOS notes +// +// Spotlight indexing on macOS can result in multiple events (see [#15]). A +// temporary workaround is to add your folder(s) to the "Spotlight Privacy +// Settings" until we have a native FSEvents implementation (see [#11]). +// +// [#11]: https://github.com/fsnotify/fsnotify/issues/11 +// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +type Watcher struct { + // Events sends the filesystem change events. + // + // fsnotify can send the following events; a "path" here can refer to a + // file, directory, symbolic link, or special file like a FIFO. + // + // fsnotify.Create A new path was created; this may be followed by one + // or more Write events if data also gets written to a + // file. + // + // fsnotify.Remove A path was removed. + // + // fsnotify.Rename A path was renamed. A rename is always sent with the + // old path as Event.Name, and a Create event will be + // sent with the new name. Renames are only sent for + // paths that are currently watched; e.g. moving an + // unmonitored file into a monitored directory will + // show up as just a Create. Similarly, renaming a file + // to outside a monitored directory will show up as + // only a Rename. + // + // fsnotify.Write A file or named pipe was written to. A Truncate will + // also trigger a Write. A single "write action" + // initiated by the user may show up as one or multiple + // writes, depending on when the system syncs things to + // disk. For example when compiling a large Go program + // you may get hundreds of Write events, so you + // probably want to wait until you've stopped receiving + // them (see the dedup example in cmd/fsnotify). + // + // fsnotify.Chmod Attributes were changed. On Linux this is also sent + // when a file is removed (or more accurately, when a + // link to an inode is removed). On kqueue it's sent + // and on kqueue when a file is truncated. On Windows + // it's never sent. + Events chan Event + + // Errors sends any errors. + Errors chan error + + done chan struct{} + kq int // File descriptor (as returned by the kqueue() syscall). + closepipe [2]int // Pipe used for closing. + mu sync.Mutex // Protects access to watcher data + watches map[string]int // Watched file descriptors (key: path). + watchesByDir map[string]map[int]struct{} // Watched file descriptors indexed by the parent directory (key: dirname(path)). + userWatches map[string]struct{} // Watches added with Watcher.Add() + dirFlags map[string]uint32 // Watched directories to fflags used in kqueue. + paths map[int]pathInfo // File descriptors to path names for processing kqueue events. + fileExists map[string]struct{} // Keep track of if we know this file exists (to stop duplicate create events). + isClosed bool // Set to true when Close() is first called +} + +type pathInfo struct { + name string + isDir bool +} + +// NewWatcher creates a new Watcher. +func NewWatcher() (*Watcher, error) { + kq, closepipe, err := newKqueue() + if err != nil { + return nil, err + } + + w := &Watcher{ + kq: kq, + closepipe: closepipe, + watches: make(map[string]int), + watchesByDir: make(map[string]map[int]struct{}), + dirFlags: make(map[string]uint32), + paths: make(map[int]pathInfo), + fileExists: make(map[string]struct{}), + userWatches: make(map[string]struct{}), + Events: make(chan Event), + Errors: make(chan error), + done: make(chan struct{}), + } + + go w.readEvents() + return w, nil +} + +// newKqueue creates a new kernel event queue and returns a descriptor. +// +// This registers a new event on closepipe, which will trigger an event when +// it's closed. This way we can use kevent() without timeout/polling; without +// the closepipe, it would block forever and we wouldn't be able to stop it at +// all. +func newKqueue() (kq int, closepipe [2]int, err error) { + kq, err = unix.Kqueue() + if kq == -1 { + return kq, closepipe, err + } + + // Register the close pipe. + err = unix.Pipe(closepipe[:]) + if err != nil { + unix.Close(kq) + return kq, closepipe, err + } + + // Register changes to listen on the closepipe. + changes := make([]unix.Kevent_t, 1) + // SetKevent converts int to the platform-specific types. + unix.SetKevent(&changes[0], closepipe[0], unix.EVFILT_READ, + unix.EV_ADD|unix.EV_ENABLE|unix.EV_ONESHOT) + + ok, err := unix.Kevent(kq, changes, nil, nil) + if ok == -1 { + unix.Close(kq) + unix.Close(closepipe[0]) + unix.Close(closepipe[1]) + return kq, closepipe, err + } + return kq, closepipe, nil +} + +// Returns true if the event was sent, or false if watcher is closed. +func (w *Watcher) sendEvent(e Event) bool { + select { + case w.Events <- e: + return true + case <-w.done: + } + return false +} + +// Returns true if the error was sent, or false if watcher is closed. +func (w *Watcher) sendError(err error) bool { + select { + case w.Errors <- err: + return true + case <-w.done: + } + return false +} + +// Close removes all watches and closes the events channel. +func (w *Watcher) Close() error { + w.mu.Lock() + if w.isClosed { + w.mu.Unlock() + return nil + } + w.isClosed = true + + // copy paths to remove while locked + pathsToRemove := make([]string, 0, len(w.watches)) + for name := range w.watches { + pathsToRemove = append(pathsToRemove, name) + } + w.mu.Unlock() // Unlock before calling Remove, which also locks + for _, name := range pathsToRemove { + w.Remove(name) + } + + // Send "quit" message to the reader goroutine. + unix.Close(w.closepipe[1]) + close(w.done) + + return nil +} + +// Add starts monitoring the path for changes. +// +// A path can only be watched once; attempting to watch it more than once will +// return an error. Paths that do not yet exist on the filesystem cannot be +// added. A watch will be automatically removed if the path is deleted. +// +// A path will remain watched if it gets renamed to somewhere else on the same +// filesystem, but the monitor will get removed if the path gets deleted and +// re-created, or if it's moved to a different filesystem. +// +// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special +// filesystems (/proc, /sys, etc.) generally don't work. +// +// # Watching directories +// +// All files in a directory are monitored, including new files that are created +// after the watcher is started. Subdirectories are not watched (i.e. it's +// non-recursive). +// +// # Watching files +// +// Watching individual files (rather than directories) is generally not +// recommended as many tools update files atomically. Instead of "just" writing +// to the file a temporary file will be written to first, and if successful the +// temporary file is moved to to destination removing the original, or some +// variant thereof. The watcher on the original file is now lost, as it no +// longer exists. +// +// Instead, watch the parent directory and use Event.Name to filter out files +// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. +func (w *Watcher) Add(name string) error { + w.mu.Lock() + w.userWatches[name] = struct{}{} + w.mu.Unlock() + _, err := w.addWatch(name, noteAllEvents) + return err +} + +// Remove stops monitoring the path for changes. +// +// Directories are always removed non-recursively. For example, if you added +// /tmp/dir and /tmp/dir/subdir then you will need to remove both. +// +// Removing a path that has not yet been added returns [ErrNonExistentWatch]. +func (w *Watcher) Remove(name string) error { + name = filepath.Clean(name) + w.mu.Lock() + watchfd, ok := w.watches[name] + w.mu.Unlock() + if !ok { + return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) + } + + err := w.register([]int{watchfd}, unix.EV_DELETE, 0) + if err != nil { + return err + } + + unix.Close(watchfd) + + w.mu.Lock() + isDir := w.paths[watchfd].isDir + delete(w.watches, name) + delete(w.userWatches, name) + + parentName := filepath.Dir(name) + delete(w.watchesByDir[parentName], watchfd) + + if len(w.watchesByDir[parentName]) == 0 { + delete(w.watchesByDir, parentName) + } + + delete(w.paths, watchfd) + delete(w.dirFlags, name) + delete(w.fileExists, name) + w.mu.Unlock() + + // Find all watched paths that are in this directory that are not external. + if isDir { + var pathsToRemove []string + w.mu.Lock() + for fd := range w.watchesByDir[name] { + path := w.paths[fd] + if _, ok := w.userWatches[path.name]; !ok { + pathsToRemove = append(pathsToRemove, path.name) + } + } + w.mu.Unlock() + for _, name := range pathsToRemove { + // Since these are internal, not much sense in propagating error + // to the user, as that will just confuse them with an error about + // a path they did not explicitly watch themselves. + w.Remove(name) + } + } + + return nil +} + +// WatchList returns all paths added with [Add] (and are not yet removed). +func (w *Watcher) WatchList() []string { + w.mu.Lock() + defer w.mu.Unlock() + + entries := make([]string, 0, len(w.userWatches)) + for pathname := range w.userWatches { + entries = append(entries, pathname) + } + + return entries +} + +// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) +const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME + +// addWatch adds name to the watched file set. +// The flags are interpreted as described in kevent(2). +// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks. +func (w *Watcher) addWatch(name string, flags uint32) (string, error) { + var isDir bool + // Make ./name and name equivalent + name = filepath.Clean(name) + + w.mu.Lock() + if w.isClosed { + w.mu.Unlock() + return "", errors.New("kevent instance already closed") + } + watchfd, alreadyWatching := w.watches[name] + // We already have a watch, but we can still override flags. + if alreadyWatching { + isDir = w.paths[watchfd].isDir + } + w.mu.Unlock() + + if !alreadyWatching { + fi, err := os.Lstat(name) + if err != nil { + return "", err + } + + // Don't watch sockets or named pipes + if (fi.Mode()&os.ModeSocket == os.ModeSocket) || (fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe) { + return "", nil + } + + // Follow Symlinks + // + // Linux can add unresolvable symlinks to the watch list without issue, + // and Windows can't do symlinks period. To maintain consistency, we + // will act like everything is fine if the link can't be resolved. + // There will simply be no file events for broken symlinks. Hence the + // returns of nil on errors. + if fi.Mode()&os.ModeSymlink == os.ModeSymlink { + name, err = filepath.EvalSymlinks(name) + if err != nil { + return "", nil + } + + w.mu.Lock() + _, alreadyWatching = w.watches[name] + w.mu.Unlock() + + if alreadyWatching { + return name, nil + } + + fi, err = os.Lstat(name) + if err != nil { + return "", nil + } + } + + // Retry on EINTR; open() can return EINTR in practice on macOS. + // See #354, and go issues 11180 and 39237. + for { + watchfd, err = unix.Open(name, openMode, 0) + if err == nil { + break + } + if errors.Is(err, unix.EINTR) { + continue + } + + return "", err + } + + isDir = fi.IsDir() + } + + err := w.register([]int{watchfd}, unix.EV_ADD|unix.EV_CLEAR|unix.EV_ENABLE, flags) + if err != nil { + unix.Close(watchfd) + return "", err + } + + if !alreadyWatching { + w.mu.Lock() + parentName := filepath.Dir(name) + w.watches[name] = watchfd + + watchesByDir, ok := w.watchesByDir[parentName] + if !ok { + watchesByDir = make(map[int]struct{}, 1) + w.watchesByDir[parentName] = watchesByDir + } + watchesByDir[watchfd] = struct{}{} + + w.paths[watchfd] = pathInfo{name: name, isDir: isDir} + w.mu.Unlock() + } + + if isDir { + // Watch the directory if it has not been watched before, + // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) + w.mu.Lock() + + watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE && + (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE) + // Store flags so this watch can be updated later + w.dirFlags[name] = flags + w.mu.Unlock() + + if watchDir { + if err := w.watchDirectoryFiles(name); err != nil { + return "", err + } + } + } + return name, nil +} + +// readEvents reads from kqueue and converts the received kevents into +// Event values that it sends down the Events channel. +func (w *Watcher) readEvents() { + defer func() { + err := unix.Close(w.kq) + if err != nil { + w.Errors <- err + } + unix.Close(w.closepipe[0]) + close(w.Events) + close(w.Errors) + }() + + eventBuffer := make([]unix.Kevent_t, 10) + for closed := false; !closed; { + kevents, err := w.read(eventBuffer) + // EINTR is okay, the syscall was interrupted before timeout expired. + if err != nil && err != unix.EINTR { + if !w.sendError(fmt.Errorf("fsnotify.readEvents: %w", err)) { + closed = true + } + continue + } + + // Flush the events we received to the Events channel + for _, kevent := range kevents { + var ( + watchfd = int(kevent.Ident) + mask = uint32(kevent.Fflags) + ) + + // Shut down the loop when the pipe is closed, but only after all + // other events have been processed. + if watchfd == w.closepipe[0] { + closed = true + continue + } + + w.mu.Lock() + path := w.paths[watchfd] + w.mu.Unlock() + + event := w.newEvent(path.name, mask) + + if path.isDir && !event.Has(Remove) { + // Double check to make sure the directory exists. This can + // happen when we do a rm -fr on a recursively watched folders + // and we receive a modification event first but the folder has + // been deleted and later receive the delete event. + if _, err := os.Lstat(event.Name); os.IsNotExist(err) { + event.Op |= Remove + } + } + + if event.Has(Rename) || event.Has(Remove) { + w.Remove(event.Name) + w.mu.Lock() + delete(w.fileExists, event.Name) + w.mu.Unlock() + } + + if path.isDir && event.Has(Write) && !event.Has(Remove) { + w.sendDirectoryChangeEvents(event.Name) + } else { + if !w.sendEvent(event) { + closed = true + continue + } + } + + if event.Has(Remove) { + // Look for a file that may have overwritten this. + // For example, mv f1 f2 will delete f2, then create f2. + if path.isDir { + fileDir := filepath.Clean(event.Name) + w.mu.Lock() + _, found := w.watches[fileDir] + w.mu.Unlock() + if found { + // make sure the directory exists before we watch for changes. When we + // do a recursive watch and perform rm -fr, the parent directory might + // have gone missing, ignore the missing directory and let the + // upcoming delete event remove the watch from the parent directory. + if _, err := os.Lstat(fileDir); err == nil { + w.sendDirectoryChangeEvents(fileDir) + } + } + } else { + filePath := filepath.Clean(event.Name) + if fileInfo, err := os.Lstat(filePath); err == nil { + w.sendFileCreatedEventIfNew(filePath, fileInfo) + } + } + } + } + } +} + +// newEvent returns an platform-independent Event based on kqueue Fflags. +func (w *Watcher) newEvent(name string, mask uint32) Event { + e := Event{Name: name} + if mask&unix.NOTE_DELETE == unix.NOTE_DELETE { + e.Op |= Remove + } + if mask&unix.NOTE_WRITE == unix.NOTE_WRITE { + e.Op |= Write + } + if mask&unix.NOTE_RENAME == unix.NOTE_RENAME { + e.Op |= Rename + } + if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB { + e.Op |= Chmod + } + return e +} + +// watchDirectoryFiles to mimic inotify when adding a watch on a directory +func (w *Watcher) watchDirectoryFiles(dirPath string) error { + // Get all files + files, err := ioutil.ReadDir(dirPath) + if err != nil { + return err + } + + for _, fileInfo := range files { + path := filepath.Join(dirPath, fileInfo.Name()) + + cleanPath, err := w.internalWatch(path, fileInfo) + if err != nil { + // No permission to read the file; that's not a problem: just skip. + // But do add it to w.fileExists to prevent it from being picked up + // as a "new" file later (it still shows up in the directory + // listing). + switch { + case errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM): + cleanPath = filepath.Clean(path) + default: + return fmt.Errorf("%q: %w", filepath.Join(dirPath, fileInfo.Name()), err) + } + } + + w.mu.Lock() + w.fileExists[cleanPath] = struct{}{} + w.mu.Unlock() + } + + return nil +} + +// Search the directory for new files and send an event for them. +// +// This functionality is to have the BSD watcher match the inotify, which sends +// a create event for files created in a watched directory. +func (w *Watcher) sendDirectoryChangeEvents(dir string) { + // Get all files + files, err := ioutil.ReadDir(dir) + if err != nil { + if !w.sendError(fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)) { + return + } + } + + // Search for new files + for _, fi := range files { + err := w.sendFileCreatedEventIfNew(filepath.Join(dir, fi.Name()), fi) + if err != nil { + return + } + } +} + +// sendFileCreatedEvent sends a create event if the file isn't already being tracked. +func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) { + w.mu.Lock() + _, doesExist := w.fileExists[filePath] + w.mu.Unlock() + if !doesExist { + if !w.sendEvent(Event{Name: filePath, Op: Create}) { + return + } + } + + // like watchDirectoryFiles (but without doing another ReadDir) + filePath, err = w.internalWatch(filePath, fileInfo) + if err != nil { + return err + } + + w.mu.Lock() + w.fileExists[filePath] = struct{}{} + w.mu.Unlock() + + return nil +} + +func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) { + if fileInfo.IsDir() { + // mimic Linux providing delete events for subdirectories + // but preserve the flags used if currently watching subdirectory + w.mu.Lock() + flags := w.dirFlags[name] + w.mu.Unlock() + + flags |= unix.NOTE_DELETE | unix.NOTE_RENAME + return w.addWatch(name, flags) + } + + // watch file to mimic Linux inotify + return w.addWatch(name, noteAllEvents) +} + +// Register events with the queue. +func (w *Watcher) register(fds []int, flags int, fflags uint32) error { + changes := make([]unix.Kevent_t, len(fds)) + for i, fd := range fds { + // SetKevent converts int to the platform-specific types. + unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags) + changes[i].Fflags = fflags + } + + // Register the events. + success, err := unix.Kevent(w.kq, changes, nil, nil) + if success == -1 { + return err + } + return nil +} + +// read retrieves pending events, or waits until an event occurs. +func (w *Watcher) read(events []unix.Kevent_t) ([]unix.Kevent_t, error) { + n, err := unix.Kevent(w.kq, nil, events, nil) + if err != nil { + return nil, err + } + return events[0:n], nil +} diff --git a/vendor/github.com/fsnotify/fsnotify/backend_other.go b/vendor/github.com/fsnotify/fsnotify/backend_other.go new file mode 100644 index 0000000000..a9bb1c3c4d --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/backend_other.go @@ -0,0 +1,66 @@ +//go:build !darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows +// +build !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows + +package fsnotify + +import ( + "fmt" + "runtime" +) + +// Watcher watches a set of files, delivering events to a channel. +type Watcher struct{} + +// NewWatcher creates a new Watcher. +func NewWatcher() (*Watcher, error) { + return nil, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS) +} + +// Close removes all watches and closes the events channel. +func (w *Watcher) Close() error { + return nil +} + +// Add starts monitoring the path for changes. +// +// A path can only be watched once; attempting to watch it more than once will +// return an error. Paths that do not yet exist on the filesystem cannot be +// added. A watch will be automatically removed if the path is deleted. +// +// A path will remain watched if it gets renamed to somewhere else on the same +// filesystem, but the monitor will get removed if the path gets deleted and +// re-created, or if it's moved to a different filesystem. +// +// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special +// filesystems (/proc, /sys, etc.) generally don't work. +// +// # Watching directories +// +// All files in a directory are monitored, including new files that are created +// after the watcher is started. Subdirectories are not watched (i.e. it's +// non-recursive). +// +// # Watching files +// +// Watching individual files (rather than directories) is generally not +// recommended as many tools update files atomically. Instead of "just" writing +// to the file a temporary file will be written to first, and if successful the +// temporary file is moved to to destination removing the original, or some +// variant thereof. The watcher on the original file is now lost, as it no +// longer exists. +// +// Instead, watch the parent directory and use Event.Name to filter out files +// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. +func (w *Watcher) Add(name string) error { + return nil +} + +// Remove stops monitoring the path for changes. +// +// Directories are always removed non-recursively. For example, if you added +// /tmp/dir and /tmp/dir/subdir then you will need to remove both. +// +// Removing a path that has not yet been added returns [ErrNonExistentWatch]. +func (w *Watcher) Remove(name string) error { + return nil +} diff --git a/vendor/github.com/fsnotify/fsnotify/backend_windows.go b/vendor/github.com/fsnotify/fsnotify/backend_windows.go new file mode 100644 index 0000000000..ae392867c0 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/backend_windows.go @@ -0,0 +1,746 @@ +//go:build windows +// +build windows + +package fsnotify + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "reflect" + "runtime" + "strings" + "sync" + "unsafe" + + "golang.org/x/sys/windows" +) + +// Watcher watches a set of paths, delivering events on a channel. +// +// A watcher should not be copied (e.g. pass it by pointer, rather than by +// value). +// +// # Linux notes +// +// When a file is removed a Remove event won't be emitted until all file +// descriptors are closed, and deletes will always emit a Chmod. For example: +// +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove +// +// This is the event that inotify sends, so not much can be changed about this. +// +// The fs.inotify.max_user_watches sysctl variable specifies the upper limit +// for the number of watches per user, and fs.inotify.max_user_instances +// specifies the maximum number of inotify instances per user. Every Watcher you +// create is an "instance", and every path you add is a "watch". +// +// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and +// /proc/sys/fs/inotify/max_user_instances +// +// To increase them you can use sysctl or write the value to the /proc file: +// +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 +// +// To make the changes persist on reboot edit /etc/sysctl.conf or +// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check +// your distro's documentation): +// +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 +// +// Reaching the limit will result in a "no space left on device" or "too many open +// files" error. +// +// # kqueue notes (macOS, BSD) +// +// kqueue requires opening a file descriptor for every file that's being watched; +// so if you're watching a directory with five files then that's six file +// descriptors. You will run in to your system's "max open files" limit faster on +// these platforms. +// +// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to +// control the maximum number of open files, as well as /etc/login.conf on BSD +// systems. +// +// # macOS notes +// +// Spotlight indexing on macOS can result in multiple events (see [#15]). A +// temporary workaround is to add your folder(s) to the "Spotlight Privacy +// Settings" until we have a native FSEvents implementation (see [#11]). +// +// [#11]: https://github.com/fsnotify/fsnotify/issues/11 +// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +type Watcher struct { + // Events sends the filesystem change events. + // + // fsnotify can send the following events; a "path" here can refer to a + // file, directory, symbolic link, or special file like a FIFO. + // + // fsnotify.Create A new path was created; this may be followed by one + // or more Write events if data also gets written to a + // file. + // + // fsnotify.Remove A path was removed. + // + // fsnotify.Rename A path was renamed. A rename is always sent with the + // old path as Event.Name, and a Create event will be + // sent with the new name. Renames are only sent for + // paths that are currently watched; e.g. moving an + // unmonitored file into a monitored directory will + // show up as just a Create. Similarly, renaming a file + // to outside a monitored directory will show up as + // only a Rename. + // + // fsnotify.Write A file or named pipe was written to. A Truncate will + // also trigger a Write. A single "write action" + // initiated by the user may show up as one or multiple + // writes, depending on when the system syncs things to + // disk. For example when compiling a large Go program + // you may get hundreds of Write events, so you + // probably want to wait until you've stopped receiving + // them (see the dedup example in cmd/fsnotify). + // + // fsnotify.Chmod Attributes were changed. On Linux this is also sent + // when a file is removed (or more accurately, when a + // link to an inode is removed). On kqueue it's sent + // and on kqueue when a file is truncated. On Windows + // it's never sent. + Events chan Event + + // Errors sends any errors. + Errors chan error + + port windows.Handle // Handle to completion port + input chan *input // Inputs to the reader are sent on this channel + quit chan chan<- error + + mu sync.Mutex // Protects access to watches, isClosed + watches watchMap // Map of watches (key: i-number) + isClosed bool // Set to true when Close() is first called +} + +// NewWatcher creates a new Watcher. +func NewWatcher() (*Watcher, error) { + port, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0) + if err != nil { + return nil, os.NewSyscallError("CreateIoCompletionPort", err) + } + w := &Watcher{ + port: port, + watches: make(watchMap), + input: make(chan *input, 1), + Events: make(chan Event, 50), + Errors: make(chan error), + quit: make(chan chan<- error, 1), + } + go w.readEvents() + return w, nil +} + +func (w *Watcher) sendEvent(name string, mask uint64) bool { + if mask == 0 { + return false + } + + event := w.newEvent(name, uint32(mask)) + select { + case ch := <-w.quit: + w.quit <- ch + case w.Events <- event: + } + return true +} + +// Returns true if the error was sent, or false if watcher is closed. +func (w *Watcher) sendError(err error) bool { + select { + case w.Errors <- err: + return true + case <-w.quit: + } + return false +} + +// Close removes all watches and closes the events channel. +func (w *Watcher) Close() error { + w.mu.Lock() + if w.isClosed { + w.mu.Unlock() + return nil + } + w.isClosed = true + w.mu.Unlock() + + // Send "quit" message to the reader goroutine + ch := make(chan error) + w.quit <- ch + if err := w.wakeupReader(); err != nil { + return err + } + return <-ch +} + +// Add starts monitoring the path for changes. +// +// A path can only be watched once; attempting to watch it more than once will +// return an error. Paths that do not yet exist on the filesystem cannot be +// added. A watch will be automatically removed if the path is deleted. +// +// A path will remain watched if it gets renamed to somewhere else on the same +// filesystem, but the monitor will get removed if the path gets deleted and +// re-created, or if it's moved to a different filesystem. +// +// Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special +// filesystems (/proc, /sys, etc.) generally don't work. +// +// # Watching directories +// +// All files in a directory are monitored, including new files that are created +// after the watcher is started. Subdirectories are not watched (i.e. it's +// non-recursive). +// +// # Watching files +// +// Watching individual files (rather than directories) is generally not +// recommended as many tools update files atomically. Instead of "just" writing +// to the file a temporary file will be written to first, and if successful the +// temporary file is moved to to destination removing the original, or some +// variant thereof. The watcher on the original file is now lost, as it no +// longer exists. +// +// Instead, watch the parent directory and use Event.Name to filter out files +// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. +func (w *Watcher) Add(name string) error { + w.mu.Lock() + if w.isClosed { + w.mu.Unlock() + return errors.New("watcher already closed") + } + w.mu.Unlock() + + in := &input{ + op: opAddWatch, + path: filepath.Clean(name), + flags: sysFSALLEVENTS, + reply: make(chan error), + } + w.input <- in + if err := w.wakeupReader(); err != nil { + return err + } + return <-in.reply +} + +// Remove stops monitoring the path for changes. +// +// Directories are always removed non-recursively. For example, if you added +// /tmp/dir and /tmp/dir/subdir then you will need to remove both. +// +// Removing a path that has not yet been added returns [ErrNonExistentWatch]. +func (w *Watcher) Remove(name string) error { + in := &input{ + op: opRemoveWatch, + path: filepath.Clean(name), + reply: make(chan error), + } + w.input <- in + if err := w.wakeupReader(); err != nil { + return err + } + return <-in.reply +} + +// WatchList returns all paths added with [Add] (and are not yet removed). +func (w *Watcher) WatchList() []string { + w.mu.Lock() + defer w.mu.Unlock() + + entries := make([]string, 0, len(w.watches)) + for _, entry := range w.watches { + for _, watchEntry := range entry { + entries = append(entries, watchEntry.path) + } + } + + return entries +} + +// These options are from the old golang.org/x/exp/winfsnotify, where you could +// add various options to the watch. This has long since been removed. +// +// The "sys" in the name is misleading as they're not part of any "system". +// +// This should all be removed at some point, and just use windows.FILE_NOTIFY_* +const ( + sysFSALLEVENTS = 0xfff + sysFSATTRIB = 0x4 + sysFSCREATE = 0x100 + sysFSDELETE = 0x200 + sysFSDELETESELF = 0x400 + sysFSMODIFY = 0x2 + sysFSMOVE = 0xc0 + sysFSMOVEDFROM = 0x40 + sysFSMOVEDTO = 0x80 + sysFSMOVESELF = 0x800 + sysFSIGNORED = 0x8000 +) + +func (w *Watcher) newEvent(name string, mask uint32) Event { + e := Event{Name: name} + if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO { + e.Op |= Create + } + if mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF { + e.Op |= Remove + } + if mask&sysFSMODIFY == sysFSMODIFY { + e.Op |= Write + } + if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM { + e.Op |= Rename + } + if mask&sysFSATTRIB == sysFSATTRIB { + e.Op |= Chmod + } + return e +} + +const ( + opAddWatch = iota + opRemoveWatch +) + +const ( + provisional uint64 = 1 << (32 + iota) +) + +type input struct { + op int + path string + flags uint32 + reply chan error +} + +type inode struct { + handle windows.Handle + volume uint32 + index uint64 +} + +type watch struct { + ov windows.Overlapped + ino *inode // i-number + path string // Directory path + mask uint64 // Directory itself is being watched with these notify flags + names map[string]uint64 // Map of names being watched and their notify flags + rename string // Remembers the old name while renaming a file + buf [65536]byte // 64K buffer +} + +type ( + indexMap map[uint64]*watch + watchMap map[uint32]indexMap +) + +func (w *Watcher) wakeupReader() error { + err := windows.PostQueuedCompletionStatus(w.port, 0, 0, nil) + if err != nil { + return os.NewSyscallError("PostQueuedCompletionStatus", err) + } + return nil +} + +func (w *Watcher) getDir(pathname string) (dir string, err error) { + attr, err := windows.GetFileAttributes(windows.StringToUTF16Ptr(pathname)) + if err != nil { + return "", os.NewSyscallError("GetFileAttributes", err) + } + if attr&windows.FILE_ATTRIBUTE_DIRECTORY != 0 { + dir = pathname + } else { + dir, _ = filepath.Split(pathname) + dir = filepath.Clean(dir) + } + return +} + +func (w *Watcher) getIno(path string) (ino *inode, err error) { + h, err := windows.CreateFile(windows.StringToUTF16Ptr(path), + windows.FILE_LIST_DIRECTORY, + windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE, + nil, windows.OPEN_EXISTING, + windows.FILE_FLAG_BACKUP_SEMANTICS|windows.FILE_FLAG_OVERLAPPED, 0) + if err != nil { + return nil, os.NewSyscallError("CreateFile", err) + } + + var fi windows.ByHandleFileInformation + err = windows.GetFileInformationByHandle(h, &fi) + if err != nil { + windows.CloseHandle(h) + return nil, os.NewSyscallError("GetFileInformationByHandle", err) + } + ino = &inode{ + handle: h, + volume: fi.VolumeSerialNumber, + index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow), + } + return ino, nil +} + +// Must run within the I/O thread. +func (m watchMap) get(ino *inode) *watch { + if i := m[ino.volume]; i != nil { + return i[ino.index] + } + return nil +} + +// Must run within the I/O thread. +func (m watchMap) set(ino *inode, watch *watch) { + i := m[ino.volume] + if i == nil { + i = make(indexMap) + m[ino.volume] = i + } + i[ino.index] = watch +} + +// Must run within the I/O thread. +func (w *Watcher) addWatch(pathname string, flags uint64) error { + dir, err := w.getDir(pathname) + if err != nil { + return err + } + + ino, err := w.getIno(dir) + if err != nil { + return err + } + w.mu.Lock() + watchEntry := w.watches.get(ino) + w.mu.Unlock() + if watchEntry == nil { + _, err := windows.CreateIoCompletionPort(ino.handle, w.port, 0, 0) + if err != nil { + windows.CloseHandle(ino.handle) + return os.NewSyscallError("CreateIoCompletionPort", err) + } + watchEntry = &watch{ + ino: ino, + path: dir, + names: make(map[string]uint64), + } + w.mu.Lock() + w.watches.set(ino, watchEntry) + w.mu.Unlock() + flags |= provisional + } else { + windows.CloseHandle(ino.handle) + } + if pathname == dir { + watchEntry.mask |= flags + } else { + watchEntry.names[filepath.Base(pathname)] |= flags + } + + err = w.startRead(watchEntry) + if err != nil { + return err + } + + if pathname == dir { + watchEntry.mask &= ^provisional + } else { + watchEntry.names[filepath.Base(pathname)] &= ^provisional + } + return nil +} + +// Must run within the I/O thread. +func (w *Watcher) remWatch(pathname string) error { + dir, err := w.getDir(pathname) + if err != nil { + return err + } + ino, err := w.getIno(dir) + if err != nil { + return err + } + + w.mu.Lock() + watch := w.watches.get(ino) + w.mu.Unlock() + + err = windows.CloseHandle(ino.handle) + if err != nil { + w.sendError(os.NewSyscallError("CloseHandle", err)) + } + if watch == nil { + return fmt.Errorf("%w: %s", ErrNonExistentWatch, pathname) + } + if pathname == dir { + w.sendEvent(watch.path, watch.mask&sysFSIGNORED) + watch.mask = 0 + } else { + name := filepath.Base(pathname) + w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED) + delete(watch.names, name) + } + + return w.startRead(watch) +} + +// Must run within the I/O thread. +func (w *Watcher) deleteWatch(watch *watch) { + for name, mask := range watch.names { + if mask&provisional == 0 { + w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED) + } + delete(watch.names, name) + } + if watch.mask != 0 { + if watch.mask&provisional == 0 { + w.sendEvent(watch.path, watch.mask&sysFSIGNORED) + } + watch.mask = 0 + } +} + +// Must run within the I/O thread. +func (w *Watcher) startRead(watch *watch) error { + err := windows.CancelIo(watch.ino.handle) + if err != nil { + w.sendError(os.NewSyscallError("CancelIo", err)) + w.deleteWatch(watch) + } + mask := w.toWindowsFlags(watch.mask) + for _, m := range watch.names { + mask |= w.toWindowsFlags(m) + } + if mask == 0 { + err := windows.CloseHandle(watch.ino.handle) + if err != nil { + w.sendError(os.NewSyscallError("CloseHandle", err)) + } + w.mu.Lock() + delete(w.watches[watch.ino.volume], watch.ino.index) + w.mu.Unlock() + return nil + } + + rdErr := windows.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], + uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) + if rdErr != nil { + err := os.NewSyscallError("ReadDirectoryChanges", rdErr) + if rdErr == windows.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { + // Watched directory was probably removed + w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) + err = nil + } + w.deleteWatch(watch) + w.startRead(watch) + return err + } + return nil +} + +// readEvents reads from the I/O completion port, converts the +// received events into Event objects and sends them via the Events channel. +// Entry point to the I/O thread. +func (w *Watcher) readEvents() { + var ( + n uint32 + key uintptr + ov *windows.Overlapped + ) + runtime.LockOSThread() + + for { + qErr := windows.GetQueuedCompletionStatus(w.port, &n, &key, &ov, windows.INFINITE) + // This error is handled after the watch == nil check below. NOTE: this + // seems odd, note sure if it's correct. + + watch := (*watch)(unsafe.Pointer(ov)) + if watch == nil { + select { + case ch := <-w.quit: + w.mu.Lock() + var indexes []indexMap + for _, index := range w.watches { + indexes = append(indexes, index) + } + w.mu.Unlock() + for _, index := range indexes { + for _, watch := range index { + w.deleteWatch(watch) + w.startRead(watch) + } + } + + err := windows.CloseHandle(w.port) + if err != nil { + err = os.NewSyscallError("CloseHandle", err) + } + close(w.Events) + close(w.Errors) + ch <- err + return + case in := <-w.input: + switch in.op { + case opAddWatch: + in.reply <- w.addWatch(in.path, uint64(in.flags)) + case opRemoveWatch: + in.reply <- w.remWatch(in.path) + } + default: + } + continue + } + + switch qErr { + case windows.ERROR_MORE_DATA: + if watch == nil { + w.sendError(errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer")) + } else { + // The i/o succeeded but the buffer is full. + // In theory we should be building up a full packet. + // In practice we can get away with just carrying on. + n = uint32(unsafe.Sizeof(watch.buf)) + } + case windows.ERROR_ACCESS_DENIED: + // Watched directory was probably removed + w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) + w.deleteWatch(watch) + w.startRead(watch) + continue + case windows.ERROR_OPERATION_ABORTED: + // CancelIo was called on this handle + continue + default: + w.sendError(os.NewSyscallError("GetQueuedCompletionPort", qErr)) + continue + case nil: + } + + var offset uint32 + for { + if n == 0 { + w.sendError(errors.New("short read in readEvents()")) + break + } + + // Point "raw" to the event in the buffer + raw := (*windows.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) + + // Create a buf that is the size of the path name + size := int(raw.FileNameLength / 2) + var buf []uint16 + // TODO: Use unsafe.Slice in Go 1.17; https://stackoverflow.com/questions/51187973 + sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + sh.Data = uintptr(unsafe.Pointer(&raw.FileName)) + sh.Len = size + sh.Cap = size + name := windows.UTF16ToString(buf) + fullname := filepath.Join(watch.path, name) + + var mask uint64 + switch raw.Action { + case windows.FILE_ACTION_REMOVED: + mask = sysFSDELETESELF + case windows.FILE_ACTION_MODIFIED: + mask = sysFSMODIFY + case windows.FILE_ACTION_RENAMED_OLD_NAME: + watch.rename = name + case windows.FILE_ACTION_RENAMED_NEW_NAME: + // Update saved path of all sub-watches. + old := filepath.Join(watch.path, watch.rename) + w.mu.Lock() + for _, watchMap := range w.watches { + for _, ww := range watchMap { + if strings.HasPrefix(ww.path, old) { + ww.path = filepath.Join(fullname, strings.TrimPrefix(ww.path, old)) + } + } + } + w.mu.Unlock() + + if watch.names[watch.rename] != 0 { + watch.names[name] |= watch.names[watch.rename] + delete(watch.names, watch.rename) + mask = sysFSMOVESELF + } + } + + sendNameEvent := func() { + w.sendEvent(fullname, watch.names[name]&mask) + } + if raw.Action != windows.FILE_ACTION_RENAMED_NEW_NAME { + sendNameEvent() + } + if raw.Action == windows.FILE_ACTION_REMOVED { + w.sendEvent(fullname, watch.names[name]&sysFSIGNORED) + delete(watch.names, name) + } + + w.sendEvent(fullname, watch.mask&w.toFSnotifyFlags(raw.Action)) + if raw.Action == windows.FILE_ACTION_RENAMED_NEW_NAME { + fullname = filepath.Join(watch.path, watch.rename) + sendNameEvent() + } + + // Move to the next event in the buffer + if raw.NextEntryOffset == 0 { + break + } + offset += raw.NextEntryOffset + + // Error! + if offset >= n { + w.sendError(errors.New( + "Windows system assumed buffer larger than it is, events have likely been missed.")) + break + } + } + + if err := w.startRead(watch); err != nil { + w.sendError(err) + } + } +} + +func (w *Watcher) toWindowsFlags(mask uint64) uint32 { + var m uint32 + if mask&sysFSMODIFY != 0 { + m |= windows.FILE_NOTIFY_CHANGE_LAST_WRITE + } + if mask&sysFSATTRIB != 0 { + m |= windows.FILE_NOTIFY_CHANGE_ATTRIBUTES + } + if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 { + m |= windows.FILE_NOTIFY_CHANGE_FILE_NAME | windows.FILE_NOTIFY_CHANGE_DIR_NAME + } + return m +} + +func (w *Watcher) toFSnotifyFlags(action uint32) uint64 { + switch action { + case windows.FILE_ACTION_ADDED: + return sysFSCREATE + case windows.FILE_ACTION_REMOVED: + return sysFSDELETE + case windows.FILE_ACTION_MODIFIED: + return sysFSMODIFY + case windows.FILE_ACTION_RENAMED_OLD_NAME: + return sysFSMOVEDFROM + case windows.FILE_ACTION_RENAMED_NEW_NAME: + return sysFSMOVEDTO + } + return 0 +} diff --git a/vendor/github.com/fsnotify/fsnotify/fen.go b/vendor/github.com/fsnotify/fsnotify/fen.go deleted file mode 100644 index b3ac3d8f55..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/fen.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2010 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. - -//go:build solaris -// +build solaris - -package fsnotify - -import ( - "errors" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - return nil, errors.New("FEN based watcher not yet supported for fsnotify\n") -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - return nil -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - return nil -} diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 0f4ee52e8a..30a5bf0f07 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -1,29 +1,37 @@ -// 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. - //go:build !plan9 // +build !plan9 -// Package fsnotify provides a platform-independent interface for file system notifications. +// Package fsnotify provides a cross-platform interface for file system +// notifications. package fsnotify import ( - "bytes" "errors" "fmt" + "strings" ) -// Event represents a single file system notification. +// Event represents a file system notification. type Event struct { - Name string // Relative path to the file or directory. - Op Op // File operation that triggered the event. + // Path to the file or directory. + // + // Paths are relative to the input; for example with Add("dir") the Name + // will be set to "dir/file" if you create that file, but if you use + // Add("/path/to/dir") it will be "/path/to/dir/file". + Name string + + // File operation that triggered the event. + // + // This is a bitmask and some systems may send multiple operations at once. + // Use the Event.Has() method instead of comparing with ==. + Op Op } // Op describes a set of file operations. type Op uint32 -// These are the generalized file operations that can trigger a notification. +// The operations fsnotify can trigger; see the documentation on [Watcher] for a +// full description, and check them with [Event.Has]. const ( Create Op = 1 << iota Write @@ -32,38 +40,42 @@ const ( Chmod ) -func (op Op) String() string { - // Use a buffer for efficient string concatenation - var buffer bytes.Buffer +// Common errors that can be reported by a watcher +var ( + ErrNonExistentWatch = errors.New("can't remove non-existent watcher") + ErrEventOverflow = errors.New("fsnotify queue overflow") +) - if op&Create == Create { - buffer.WriteString("|CREATE") +func (op Op) String() string { + var b strings.Builder + if op.Has(Create) { + b.WriteString("|CREATE") } - if op&Remove == Remove { - buffer.WriteString("|REMOVE") + if op.Has(Remove) { + b.WriteString("|REMOVE") } - if op&Write == Write { - buffer.WriteString("|WRITE") + if op.Has(Write) { + b.WriteString("|WRITE") } - if op&Rename == Rename { - buffer.WriteString("|RENAME") + if op.Has(Rename) { + b.WriteString("|RENAME") } - if op&Chmod == Chmod { - buffer.WriteString("|CHMOD") + if op.Has(Chmod) { + b.WriteString("|CHMOD") } - if buffer.Len() == 0 { - return "" + if b.Len() == 0 { + return "[no events]" } - return buffer.String()[1:] // Strip leading pipe + return b.String()[1:] } -// String returns a string representation of the event in the form -// "file: REMOVE|WRITE|..." +// Has reports if this operation has the given operation. +func (o Op) Has(h Op) bool { return o&h == h } + +// Has reports if this event has the given operation. +func (e Event) Has(op Op) bool { return e.Op.Has(op) } + +// String returns a string representation of the event with their path. func (e Event) String() string { - return fmt.Sprintf("%q: %s", e.Name, e.Op.String()) + return fmt.Sprintf("%-13s %q", e.Op.String(), e.Name) } - -// Common errors that can be reported by a watcher -var ( - ErrEventOverflow = errors.New("fsnotify queue overflow") -) diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go b/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go deleted file mode 100644 index 5968855983..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2022 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. - -//go:build !darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows -// +build !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows - -package fsnotify - -import ( - "fmt" - "runtime" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct{} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - return nil, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS) -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - return nil -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - return nil -} diff --git a/vendor/github.com/fsnotify/fsnotify/inotify.go b/vendor/github.com/fsnotify/fsnotify/inotify.go deleted file mode 100644 index a6d0e0ec8c..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/inotify.go +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright 2010 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. - -//go:build linux -// +build linux - -package fsnotify - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "sync" - "unsafe" - - "golang.org/x/sys/unix" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - mu sync.Mutex // Map access - fd int - poller *fdPoller - watches map[string]*watch // Map of inotify watches (key: path) - paths map[int]string // Map of watched paths (key: watch descriptor) - done chan struct{} // Channel for sending a "quit message" to the reader goroutine - doneResp chan struct{} // Channel to respond to Close -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - // Create inotify fd - fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC) - if fd == -1 { - return nil, errno - } - // Create epoll - poller, err := newFdPoller(fd) - if err != nil { - unix.Close(fd) - return nil, err - } - w := &Watcher{ - fd: fd, - poller: poller, - watches: make(map[string]*watch), - paths: make(map[int]string), - Events: make(chan Event), - Errors: make(chan error), - done: make(chan struct{}), - doneResp: make(chan struct{}), - } - - go w.readEvents() - return w, nil -} - -func (w *Watcher) isClosed() bool { - select { - case <-w.done: - return true - default: - return false - } -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - if w.isClosed() { - return nil - } - - // Send 'close' signal to goroutine, and set the Watcher to closed. - close(w.done) - - // Wake up goroutine - w.poller.wake() - - // Wait for goroutine to close - <-w.doneResp - - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - name = filepath.Clean(name) - if w.isClosed() { - return errors.New("inotify instance already closed") - } - - const agnosticEvents = unix.IN_MOVED_TO | unix.IN_MOVED_FROM | - unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY | - unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF - - var flags uint32 = agnosticEvents - - w.mu.Lock() - defer w.mu.Unlock() - watchEntry := w.watches[name] - if watchEntry != nil { - flags |= watchEntry.flags | unix.IN_MASK_ADD - } - wd, errno := unix.InotifyAddWatch(w.fd, name, flags) - if wd == -1 { - return errno - } - - if watchEntry == nil { - w.watches[name] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = name - } else { - watchEntry.wd = uint32(wd) - watchEntry.flags = flags - } - - return nil -} - -// Remove stops watching the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - name = filepath.Clean(name) - - // Fetch the watch. - w.mu.Lock() - defer w.mu.Unlock() - watch, ok := w.watches[name] - - // Remove it from inotify. - if !ok { - return fmt.Errorf("can't remove non-existent inotify watch for: %s", name) - } - - // We successfully removed the watch if InotifyRmWatch doesn't return an - // error, we need to clean up our internal state to ensure it matches - // inotify's kernel state. - delete(w.paths, int(watch.wd)) - delete(w.watches, name) - - // inotify_rm_watch will return EINVAL if the file has been deleted; - // the inotify will already have been removed. - // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously - // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE - // so that EINVAL means that the wd is being rm_watch()ed or its file removed - // by another thread and we have not received IN_IGNORE event. - success, errno := unix.InotifyRmWatch(w.fd, watch.wd) - if success == -1 { - // TODO: Perhaps it's not helpful to return an error here in every case. - // the only two possible errors are: - // EBADF, which happens when w.fd is not a valid file descriptor of any kind. - // EINVAL, which is when fd is not an inotify descriptor or wd is not a valid watch descriptor. - // Watch descriptors are invalidated when they are removed explicitly or implicitly; - // explicitly by inotify_rm_watch, implicitly when the file they are watching is deleted. - return errno - } - - return nil -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for pathname := range w.watches { - entries = append(entries, pathname) - } - - return entries -} - -type watch struct { - wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) - flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) -} - -// readEvents reads from the inotify file descriptor, converts the -// received events into Event objects and sends them via the Events channel -func (w *Watcher) readEvents() { - var ( - buf [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events - n int // Number of bytes read with read() - errno error // Syscall errno - ok bool // For poller.wait - ) - - defer close(w.doneResp) - defer close(w.Errors) - defer close(w.Events) - defer unix.Close(w.fd) - defer w.poller.close() - - for { - // See if we have been closed. - if w.isClosed() { - return - } - - ok, errno = w.poller.wait() - if errno != nil { - select { - case w.Errors <- errno: - case <-w.done: - return - } - continue - } - - if !ok { - continue - } - - n, errno = unix.Read(w.fd, buf[:]) - // If a signal interrupted execution, see if we've been asked to close, and try again. - // http://man7.org/linux/man-pages/man7/signal.7.html : - // "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable" - if errno == unix.EINTR { - continue - } - - // unix.Read might have been woken up by Close. If so, we're done. - if w.isClosed() { - return - } - - if n < unix.SizeofInotifyEvent { - var err error - if n == 0 { - // If EOF is received. This should really never happen. - err = io.EOF - } else if n < 0 { - // If an error occurred while reading. - err = errno - } else { - // Read was too short. - err = errors.New("notify: short read in readEvents()") - } - select { - case w.Errors <- err: - case <-w.done: - return - } - continue - } - - var offset uint32 - // We don't know how many events we just read into the buffer - // While the offset points to at least one whole event... - for offset <= uint32(n-unix.SizeofInotifyEvent) { - // Point "raw" to the event in the buffer - raw := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset])) - - mask := uint32(raw.Mask) - nameLen := uint32(raw.Len) - - if mask&unix.IN_Q_OVERFLOW != 0 { - select { - case w.Errors <- ErrEventOverflow: - case <-w.done: - return - } - } - - // If the event happened to the watched directory or the watched file, the kernel - // doesn't append the filename to the event, but we would like to always fill the - // the "Name" field with a valid filename. We retrieve the path of the watch from - // the "paths" map. - w.mu.Lock() - name, ok := w.paths[int(raw.Wd)] - // IN_DELETE_SELF occurs when the file/directory being watched is removed. - // This is a sign to clean up the maps, otherwise we are no longer in sync - // with the inotify kernel state which has already deleted the watch - // automatically. - if ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { - delete(w.paths, int(raw.Wd)) - delete(w.watches, name) - } - w.mu.Unlock() - - if nameLen > 0 { - // Point "bytes" at the first byte of the filename - 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") - } - - event := newEvent(name, mask) - - // Send the events that are not ignored on the events channel - if !event.ignoreLinux(mask) { - select { - case w.Events <- event: - case <-w.done: - return - } - } - - // Move to the next event in the buffer - offset += unix.SizeofInotifyEvent + nameLen - } - } -} - -// Certain types of events can be "ignored" and not sent over the Events -// channel. Such as events marked ignore by the kernel, or MODIFY events -// against files that do not exist. -func (e *Event) ignoreLinux(mask uint32) bool { - // Ignore anything the inotify API says to ignore - if mask&unix.IN_IGNORED == unix.IN_IGNORED { - return true - } - - // If the event is not a DELETE or RENAME, the file must exist. - // Otherwise the event is ignored. - // *Note*: this was put in place because it was seen that a MODIFY - // event was sent after the DELETE. This ignores that MODIFY and - // assumes a DELETE will come or has come if the file doesn't exist. - if !(e.Op&Remove == Remove || e.Op&Rename == Rename) { - _, statErr := os.Lstat(e.Name) - return os.IsNotExist(statErr) - } - return false -} - -// newEvent returns an platform-independent Event based on an inotify mask. -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO { - e.Op |= Create - } - if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE { - e.Op |= Remove - } - if mask&unix.IN_MODIFY == unix.IN_MODIFY { - e.Op |= Write - } - if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM { - e.Op |= Rename - } - if mask&unix.IN_ATTRIB == unix.IN_ATTRIB { - e.Op |= Chmod - } - return e -} diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go deleted file mode 100644 index b572a37c3f..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2015 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. - -//go:build linux -// +build linux - -package fsnotify - -import ( - "errors" - - "golang.org/x/sys/unix" -) - -type fdPoller struct { - fd int // File descriptor (as returned by the inotify_init() syscall) - epfd int // Epoll file descriptor - pipe [2]int // Pipe for waking up -} - -func emptyPoller(fd int) *fdPoller { - poller := new(fdPoller) - poller.fd = fd - poller.epfd = -1 - poller.pipe[0] = -1 - poller.pipe[1] = -1 - return poller -} - -// Create a new inotify poller. -// This creates an inotify handler, and an epoll handler. -func newFdPoller(fd int) (*fdPoller, error) { - var errno error - poller := emptyPoller(fd) - defer func() { - if errno != nil { - poller.close() - } - }() - - // Create epoll fd - poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC) - if poller.epfd == -1 { - return nil, errno - } - // Create pipe; pipe[0] is the read end, pipe[1] the write end. - errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC) - if errno != nil { - return nil, errno - } - - // Register inotify fd with epoll - event := unix.EpollEvent{ - Fd: int32(poller.fd), - Events: unix.EPOLLIN, - } - errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.fd, &event) - if errno != nil { - return nil, errno - } - - // Register pipe fd with epoll - event = unix.EpollEvent{ - Fd: int32(poller.pipe[0]), - Events: unix.EPOLLIN, - } - errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.pipe[0], &event) - if errno != nil { - return nil, errno - } - - return poller, nil -} - -// Wait using epoll. -// Returns true if something is ready to be read, -// false if there is not. -func (poller *fdPoller) wait() (bool, error) { - // 3 possible events per fd, and 2 fds, makes a maximum of 6 events. - // I don't know whether epoll_wait returns the number of events returned, - // or the total number of events ready. - // I decided to catch both by making the buffer one larger than the maximum. - events := make([]unix.EpollEvent, 7) - for { - n, errno := unix.EpollWait(poller.epfd, events, -1) - if n == -1 { - if errno == unix.EINTR { - continue - } - return false, errno - } - if n == 0 { - // If there are no events, try again. - continue - } - if n > 6 { - // This should never happen. More events were returned than should be possible. - return false, errors.New("epoll_wait returned more events than I know what to do with") - } - ready := events[:n] - epollhup := false - epollerr := false - epollin := false - for _, event := range ready { - if event.Fd == int32(poller.fd) { - if event.Events&unix.EPOLLHUP != 0 { - // This should not happen, but if it does, treat it as a wakeup. - epollhup = true - } - if event.Events&unix.EPOLLERR != 0 { - // If an error is waiting on the file descriptor, we should pretend - // something is ready to read, and let unix.Read pick up the error. - epollerr = true - } - if event.Events&unix.EPOLLIN != 0 { - // There is data to read. - epollin = true - } - } - if event.Fd == int32(poller.pipe[0]) { - if event.Events&unix.EPOLLHUP != 0 { - // Write pipe descriptor was closed, by us. This means we're closing down the - // watcher, and we should wake up. - } - if event.Events&unix.EPOLLERR != 0 { - // If an error is waiting on the pipe file descriptor. - // This is an absolute mystery, and should never ever happen. - return false, errors.New("Error on the pipe descriptor.") - } - if event.Events&unix.EPOLLIN != 0 { - // This is a regular wakeup, so we have to clear the buffer. - err := poller.clearWake() - if err != nil { - return false, err - } - } - } - } - - if epollhup || epollerr || epollin { - return true, nil - } - return false, nil - } -} - -// Close the write end of the poller. -func (poller *fdPoller) wake() error { - buf := make([]byte, 1) - n, errno := unix.Write(poller.pipe[1], buf) - if n == -1 { - if errno == unix.EAGAIN { - // Buffer is full, poller will wake. - return nil - } - return errno - } - return nil -} - -func (poller *fdPoller) clearWake() error { - // You have to be woken up a LOT in order to get to 100! - buf := make([]byte, 100) - n, errno := unix.Read(poller.pipe[0], buf) - if n == -1 { - if errno == unix.EAGAIN { - // Buffer is empty, someone else cleared our wake. - return nil - } - return errno - } - return nil -} - -// Close all poller file descriptors, but not the one passed to it. -func (poller *fdPoller) close() { - if poller.pipe[1] != -1 { - unix.Close(poller.pipe[1]) - } - if poller.pipe[0] != -1 { - unix.Close(poller.pipe[0]) - } - if poller.epfd != -1 { - unix.Close(poller.epfd) - } -} diff --git a/vendor/github.com/fsnotify/fsnotify/kqueue.go b/vendor/github.com/fsnotify/fsnotify/kqueue.go deleted file mode 100644 index 6fb8d8532e..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/kqueue.go +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright 2010 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. - -//go:build freebsd || openbsd || netbsd || dragonfly || darwin -// +build freebsd openbsd netbsd dragonfly darwin - -package fsnotify - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sync" - "time" - - "golang.org/x/sys/unix" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - done chan struct{} // Channel for sending a "quit message" to the reader goroutine - - kq int // File descriptor (as returned by the kqueue() syscall). - - mu sync.Mutex // Protects access to watcher data - watches map[string]int // Map of watched file descriptors (key: path). - externalWatches map[string]bool // Map of watches added by user of the library. - dirFlags map[string]uint32 // Map of watched directories to fflags used in kqueue. - paths map[int]pathInfo // Map file descriptors to path names for processing kqueue events. - fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events). - isClosed bool // Set to true when Close() is first called -} - -type pathInfo struct { - name string - isDir bool -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - kq, err := kqueue() - if err != nil { - return nil, err - } - - w := &Watcher{ - kq: kq, - watches: make(map[string]int), - dirFlags: make(map[string]uint32), - paths: make(map[int]pathInfo), - fileExists: make(map[string]bool), - externalWatches: make(map[string]bool), - Events: make(chan Event), - Errors: make(chan error), - done: make(chan struct{}), - } - - go w.readEvents() - return w, nil -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return nil - } - w.isClosed = true - - // copy paths to remove while locked - var pathsToRemove = make([]string, 0, len(w.watches)) - for name := range w.watches { - pathsToRemove = append(pathsToRemove, name) - } - w.mu.Unlock() - // unlock before calling Remove, which also locks - - for _, name := range pathsToRemove { - w.Remove(name) - } - - // send a "quit" message to the reader goroutine - close(w.done) - - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - w.mu.Lock() - w.externalWatches[name] = true - w.mu.Unlock() - _, err := w.addWatch(name, noteAllEvents) - return err -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - name = filepath.Clean(name) - w.mu.Lock() - watchfd, ok := w.watches[name] - w.mu.Unlock() - if !ok { - return fmt.Errorf("can't remove non-existent kevent watch for: %s", name) - } - - const registerRemove = unix.EV_DELETE - if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil { - return err - } - - unix.Close(watchfd) - - w.mu.Lock() - isDir := w.paths[watchfd].isDir - delete(w.watches, name) - delete(w.paths, watchfd) - delete(w.dirFlags, name) - w.mu.Unlock() - - // Find all watched paths that are in this directory that are not external. - if isDir { - var pathsToRemove []string - w.mu.Lock() - for _, path := range w.paths { - wdir, _ := filepath.Split(path.name) - if filepath.Clean(wdir) == name { - if !w.externalWatches[path.name] { - pathsToRemove = append(pathsToRemove, path.name) - } - } - } - w.mu.Unlock() - for _, name := range pathsToRemove { - // Since these are internal, not much sense in propagating error - // to the user, as that will just confuse them with an error about - // a path they did not explicitly watch themselves. - w.Remove(name) - } - } - - return nil -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for pathname := range w.watches { - entries = append(entries, pathname) - } - - return entries -} - -// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) -const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME - -// keventWaitTime to block on each read from kevent -var keventWaitTime = durationToTimespec(100 * time.Millisecond) - -// addWatch adds name to the watched file set. -// The flags are interpreted as described in kevent(2). -// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks. -func (w *Watcher) addWatch(name string, flags uint32) (string, error) { - var isDir bool - // Make ./name and name equivalent - name = filepath.Clean(name) - - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return "", errors.New("kevent instance already closed") - } - watchfd, alreadyWatching := w.watches[name] - // We already have a watch, but we can still override flags. - if alreadyWatching { - isDir = w.paths[watchfd].isDir - } - w.mu.Unlock() - - if !alreadyWatching { - fi, err := os.Lstat(name) - if err != nil { - return "", err - } - - // Don't watch sockets. - if fi.Mode()&os.ModeSocket == os.ModeSocket { - return "", nil - } - - // Don't watch named pipes. - if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe { - return "", nil - } - - // Follow Symlinks - // Unfortunately, Linux can add bogus symlinks to watch list without - // issue, and Windows can't do symlinks period (AFAIK). To maintain - // consistency, we will act like everything is fine. There will simply - // be no file events for broken symlinks. - // Hence the returns of nil on errors. - if fi.Mode()&os.ModeSymlink == os.ModeSymlink { - name, err = filepath.EvalSymlinks(name) - if err != nil { - return "", nil - } - - w.mu.Lock() - _, alreadyWatching = w.watches[name] - w.mu.Unlock() - - if alreadyWatching { - return name, nil - } - - fi, err = os.Lstat(name) - if err != nil { - return "", nil - } - } - - watchfd, err = unix.Open(name, openMode, 0700) - if watchfd == -1 { - return "", err - } - - isDir = fi.IsDir() - } - - const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE - if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil { - unix.Close(watchfd) - return "", err - } - - if !alreadyWatching { - w.mu.Lock() - w.watches[name] = watchfd - w.paths[watchfd] = pathInfo{name: name, isDir: isDir} - w.mu.Unlock() - } - - if isDir { - // Watch the directory if it has not been watched before, - // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) - w.mu.Lock() - - watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE && - (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE) - // Store flags so this watch can be updated later - w.dirFlags[name] = flags - w.mu.Unlock() - - if watchDir { - if err := w.watchDirectoryFiles(name); err != nil { - return "", err - } - } - } - return name, nil -} - -// readEvents reads from kqueue and converts the received kevents into -// Event values that it sends down the Events channel. -func (w *Watcher) readEvents() { - eventBuffer := make([]unix.Kevent_t, 10) - -loop: - for { - // See if there is a message on the "done" channel - select { - case <-w.done: - break loop - default: - } - - // Get new events - kevents, err := read(w.kq, eventBuffer, &keventWaitTime) - // EINTR is okay, the syscall was interrupted before timeout expired. - if err != nil && err != unix.EINTR { - select { - case w.Errors <- err: - case <-w.done: - break loop - } - continue - } - - // Flush the events we received to the Events channel - for len(kevents) > 0 { - kevent := &kevents[0] - watchfd := int(kevent.Ident) - mask := uint32(kevent.Fflags) - w.mu.Lock() - path := w.paths[watchfd] - w.mu.Unlock() - event := newEvent(path.name, mask) - - if path.isDir && !(event.Op&Remove == Remove) { - // Double check to make sure the directory exists. This can happen when - // we do a rm -fr on a recursively watched folders and we receive a - // modification event first but the folder has been deleted and later - // receive the delete event - if _, err := os.Lstat(event.Name); os.IsNotExist(err) { - // mark is as delete event - event.Op |= Remove - } - } - - if event.Op&Rename == Rename || event.Op&Remove == Remove { - w.Remove(event.Name) - w.mu.Lock() - delete(w.fileExists, event.Name) - w.mu.Unlock() - } - - if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) { - w.sendDirectoryChangeEvents(event.Name) - } else { - // Send the event on the Events channel. - select { - case w.Events <- event: - case <-w.done: - break loop - } - } - - if event.Op&Remove == Remove { - // Look for a file that may have overwritten this. - // For example, mv f1 f2 will delete f2, then create f2. - if path.isDir { - fileDir := filepath.Clean(event.Name) - w.mu.Lock() - _, found := w.watches[fileDir] - w.mu.Unlock() - if found { - // make sure the directory exists before we watch for changes. When we - // do a recursive watch and perform rm -fr, the parent directory might - // have gone missing, ignore the missing directory and let the - // upcoming delete event remove the watch from the parent directory. - if _, err := os.Lstat(fileDir); err == nil { - w.sendDirectoryChangeEvents(fileDir) - } - } - } else { - filePath := filepath.Clean(event.Name) - if fileInfo, err := os.Lstat(filePath); err == nil { - w.sendFileCreatedEventIfNew(filePath, fileInfo) - } - } - } - - // Move to next event - kevents = kevents[1:] - } - } - - // cleanup - err := unix.Close(w.kq) - if err != nil { - // only way the previous loop breaks is if w.done was closed so we need to async send to w.Errors. - select { - case w.Errors <- err: - default: - } - } - close(w.Events) - close(w.Errors) -} - -// newEvent returns an platform-independent Event based on kqueue Fflags. -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&unix.NOTE_DELETE == unix.NOTE_DELETE { - e.Op |= Remove - } - if mask&unix.NOTE_WRITE == unix.NOTE_WRITE { - e.Op |= Write - } - if mask&unix.NOTE_RENAME == unix.NOTE_RENAME { - e.Op |= Rename - } - if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB { - e.Op |= Chmod - } - return e -} - -func newCreateEvent(name string) Event { - return Event{Name: name, Op: Create} -} - -// watchDirectoryFiles to mimic inotify when adding a watch on a directory -func (w *Watcher) watchDirectoryFiles(dirPath string) error { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - return err - } - - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - filePath, err = w.internalWatch(filePath, fileInfo) - if err != nil { - return err - } - - w.mu.Lock() - w.fileExists[filePath] = true - w.mu.Unlock() - } - - return nil -} - -// sendDirectoryEvents searches the directory for newly created files -// and sends them over the event channel. This functionality is to have -// the BSD version of fsnotify match Linux inotify which provides a -// create event for files created in a watched directory. -func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - select { - case w.Errors <- err: - case <-w.done: - return - } - } - - // Search for new files - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - err := w.sendFileCreatedEventIfNew(filePath, fileInfo) - - if err != nil { - return - } - } -} - -// sendFileCreatedEvent sends a create event if the file isn't already being tracked. -func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) { - w.mu.Lock() - _, doesExist := w.fileExists[filePath] - w.mu.Unlock() - if !doesExist { - // Send create event - select { - case w.Events <- newCreateEvent(filePath): - case <-w.done: - return - } - } - - // like watchDirectoryFiles (but without doing another ReadDir) - filePath, err = w.internalWatch(filePath, fileInfo) - if err != nil { - return err - } - - w.mu.Lock() - w.fileExists[filePath] = true - w.mu.Unlock() - - return nil -} - -func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) { - if fileInfo.IsDir() { - // mimic Linux providing delete events for subdirectories - // but preserve the flags used if currently watching subdirectory - w.mu.Lock() - flags := w.dirFlags[name] - w.mu.Unlock() - - flags |= unix.NOTE_DELETE | unix.NOTE_RENAME - return w.addWatch(name, flags) - } - - // watch file to mimic Linux inotify - return w.addWatch(name, noteAllEvents) -} - -// kqueue creates a new kernel event queue and returns a descriptor. -func kqueue() (kq int, err error) { - kq, err = unix.Kqueue() - if kq == -1 { - return kq, err - } - return kq, nil -} - -// register events with the queue -func register(kq int, fds []int, flags int, fflags uint32) error { - changes := make([]unix.Kevent_t, len(fds)) - - for i, fd := range fds { - // SetKevent converts int to the platform-specific types: - unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags) - changes[i].Fflags = fflags - } - - // register the events - success, err := unix.Kevent(kq, changes, nil, nil) - if success == -1 { - return err - } - return nil -} - -// read retrieves pending events, or waits until an event occurs. -// A timeout of nil blocks indefinitely, while 0 polls the queue. -func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) { - n, err := unix.Kevent(kq, nil, events, timeout) - if err != nil { - return nil, err - } - return events[0:n], nil -} - -// durationToTimespec prepares a timeout value -func durationToTimespec(d time.Duration) unix.Timespec { - return unix.NsecToTimespec(d.Nanoseconds()) -} diff --git a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh new file mode 100644 index 0000000000..b09ef76834 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh @@ -0,0 +1,208 @@ +#!/usr/bin/env zsh +[ "${ZSH_VERSION:-}" = "" ] && echo >&2 "Only works with zsh" && exit 1 +setopt err_exit no_unset pipefail extended_glob + +# Simple script to update the godoc comments on all watchers. Probably took me +# more time to write this than doing it manually, but ah well 🙃 + +watcher=$(</tmp/x + print -r -- $cmt >>/tmp/x + tail -n+$(( end + 1 )) $file >>/tmp/x + mv /tmp/x $file + done +} + +set-cmt '^type Watcher struct ' $watcher +set-cmt '^func NewWatcher(' $new +set-cmt '^func (w \*Watcher) Add(' $add +set-cmt '^func (w \*Watcher) Remove(' $remove +set-cmt '^func (w \*Watcher) Close(' $close +set-cmt '^func (w \*Watcher) WatchList(' $watchlist +set-cmt '^[[:space:]]*Events *chan Event$' $events +set-cmt '^[[:space:]]*Errors *chan error$' $errors diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go deleted file mode 100644 index 36cc3845b6..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -//go:build freebsd || openbsd || netbsd || dragonfly -// +build freebsd openbsd netbsd dragonfly - -package fsnotify - -import "golang.org/x/sys/unix" - -const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go deleted file mode 100644 index 98cd8476ff..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -//go:build darwin -// +build darwin - -package fsnotify - -import "golang.org/x/sys/unix" - -// note: this constant is not defined on BSD -const openMode = unix.O_EVTONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/system_bsd.go b/vendor/github.com/fsnotify/fsnotify/system_bsd.go new file mode 100644 index 0000000000..4322b0b885 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/system_bsd.go @@ -0,0 +1,8 @@ +//go:build freebsd || openbsd || netbsd || dragonfly +// +build freebsd openbsd netbsd dragonfly + +package fsnotify + +import "golang.org/x/sys/unix" + +const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/system_darwin.go b/vendor/github.com/fsnotify/fsnotify/system_darwin.go new file mode 100644 index 0000000000..5da5ffa78f --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/system_darwin.go @@ -0,0 +1,9 @@ +//go:build darwin +// +build darwin + +package fsnotify + +import "golang.org/x/sys/unix" + +// note: this constant is not defined on BSD +const openMode = unix.O_EVTONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/windows.go b/vendor/github.com/fsnotify/fsnotify/windows.go deleted file mode 100644 index 02ce7deb0b..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/windows.go +++ /dev/null @@ -1,586 +0,0 @@ -// 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. - -//go:build windows -// +build windows - -package fsnotify - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "reflect" - "runtime" - "sync" - "syscall" - "unsafe" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - isClosed bool // Set to true when Close() is first called - mu sync.Mutex // Map access - port syscall.Handle // Handle to completion port - watches watchMap // Map of watches (key: i-number) - input chan *input // Inputs to the reader are sent on this channel - quit chan chan<- error -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0) - if e != nil { - return nil, os.NewSyscallError("CreateIoCompletionPort", e) - } - w := &Watcher{ - port: port, - watches: make(watchMap), - input: make(chan *input, 1), - Events: make(chan Event, 50), - Errors: make(chan error), - quit: make(chan chan<- error, 1), - } - go w.readEvents() - return w, nil -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - // Send "quit" message to the reader goroutine - ch := make(chan error) - w.quit <- ch - if err := w.wakeupReader(); err != nil { - return err - } - return <-ch -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - if w.isClosed { - return errors.New("watcher already closed") - } - in := &input{ - op: opAddWatch, - path: filepath.Clean(name), - flags: sysFSALLEVENTS, - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - in := &input{ - op: opRemoveWatch, - path: filepath.Clean(name), - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for _, entry := range w.watches { - for _, watchEntry := range entry { - entries = append(entries, watchEntry.path) - } - } - - return entries -} - -const ( - // Options for AddWatch - sysFSONESHOT = 0x80000000 - sysFSONLYDIR = 0x1000000 - - // Events - sysFSACCESS = 0x1 - sysFSALLEVENTS = 0xfff - sysFSATTRIB = 0x4 - sysFSCLOSE = 0x18 - sysFSCREATE = 0x100 - sysFSDELETE = 0x200 - sysFSDELETESELF = 0x400 - sysFSMODIFY = 0x2 - sysFSMOVE = 0xc0 - sysFSMOVEDFROM = 0x40 - sysFSMOVEDTO = 0x80 - sysFSMOVESELF = 0x800 - - // Special events - sysFSIGNORED = 0x8000 - sysFSQOVERFLOW = 0x4000 -) - -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO { - e.Op |= Create - } - if mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF { - e.Op |= Remove - } - if mask&sysFSMODIFY == sysFSMODIFY { - e.Op |= Write - } - if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM { - e.Op |= Rename - } - if mask&sysFSATTRIB == sysFSATTRIB { - e.Op |= Chmod - } - return e -} - -const ( - opAddWatch = iota - opRemoveWatch -) - -const ( - provisional uint64 = 1 << (32 + iota) -) - -type input struct { - op int - path string - flags uint32 - reply chan error -} - -type inode struct { - handle syscall.Handle - volume uint32 - index uint64 -} - -type watch struct { - ov syscall.Overlapped - ino *inode // i-number - path string // Directory path - mask uint64 // Directory itself is being watched with these notify flags - names map[string]uint64 // Map of names being watched and their notify flags - rename string // Remembers the old name while renaming a file - buf [4096]byte -} - -type indexMap map[uint64]*watch -type watchMap map[uint32]indexMap - -func (w *Watcher) wakeupReader() error { - e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil) - if e != nil { - return os.NewSyscallError("PostQueuedCompletionStatus", e) - } - return nil -} - -func getDir(pathname string) (dir string, err error) { - attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname)) - if e != nil { - return "", os.NewSyscallError("GetFileAttributes", e) - } - if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { - dir = pathname - } else { - dir, _ = filepath.Split(pathname) - dir = filepath.Clean(dir) - } - return -} - -func getIno(path string) (ino *inode, err error) { - h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(path), - syscall.FILE_LIST_DIRECTORY, - syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, - nil, syscall.OPEN_EXISTING, - syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0) - if e != nil { - return nil, os.NewSyscallError("CreateFile", e) - } - var fi syscall.ByHandleFileInformation - if e = syscall.GetFileInformationByHandle(h, &fi); e != nil { - syscall.CloseHandle(h) - return nil, os.NewSyscallError("GetFileInformationByHandle", e) - } - ino = &inode{ - handle: h, - volume: fi.VolumeSerialNumber, - index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow), - } - return ino, nil -} - -// Must run within the I/O thread. -func (m watchMap) get(ino *inode) *watch { - if i := m[ino.volume]; i != nil { - return i[ino.index] - } - return nil -} - -// Must run within the I/O thread. -func (m watchMap) set(ino *inode, watch *watch) { - i := m[ino.volume] - if i == nil { - i = make(indexMap) - m[ino.volume] = i - } - i[ino.index] = watch -} - -// Must run within the I/O thread. -func (w *Watcher) addWatch(pathname string, flags uint64) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - if flags&sysFSONLYDIR != 0 && pathname != dir { - return nil - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watchEntry := w.watches.get(ino) - w.mu.Unlock() - if watchEntry == nil { - if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil { - syscall.CloseHandle(ino.handle) - return os.NewSyscallError("CreateIoCompletionPort", e) - } - watchEntry = &watch{ - ino: ino, - path: dir, - names: make(map[string]uint64), - } - w.mu.Lock() - w.watches.set(ino, watchEntry) - w.mu.Unlock() - flags |= provisional - } else { - syscall.CloseHandle(ino.handle) - } - if pathname == dir { - watchEntry.mask |= flags - } else { - watchEntry.names[filepath.Base(pathname)] |= flags - } - if err = w.startRead(watchEntry); err != nil { - return err - } - if pathname == dir { - watchEntry.mask &= ^provisional - } else { - watchEntry.names[filepath.Base(pathname)] &= ^provisional - } - return nil -} - -// Must run within the I/O thread. -func (w *Watcher) remWatch(pathname string) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watch := w.watches.get(ino) - w.mu.Unlock() - if watch == nil { - return fmt.Errorf("can't remove non-existent watch for: %s", pathname) - } - if pathname == dir { - w.sendEvent(watch.path, watch.mask&sysFSIGNORED) - watch.mask = 0 - } else { - name := filepath.Base(pathname) - w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED) - delete(watch.names, name) - } - return w.startRead(watch) -} - -// Must run within the I/O thread. -func (w *Watcher) deleteWatch(watch *watch) { - for name, mask := range watch.names { - if mask&provisional == 0 { - w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED) - } - delete(watch.names, name) - } - if watch.mask != 0 { - if watch.mask&provisional == 0 { - w.sendEvent(watch.path, watch.mask&sysFSIGNORED) - } - watch.mask = 0 - } -} - -// Must run within the I/O thread. -func (w *Watcher) startRead(watch *watch) error { - if e := syscall.CancelIo(watch.ino.handle); e != nil { - w.Errors <- os.NewSyscallError("CancelIo", e) - w.deleteWatch(watch) - } - mask := toWindowsFlags(watch.mask) - for _, m := range watch.names { - mask |= toWindowsFlags(m) - } - if mask == 0 { - if e := syscall.CloseHandle(watch.ino.handle); e != nil { - w.Errors <- os.NewSyscallError("CloseHandle", e) - } - w.mu.Lock() - delete(w.watches[watch.ino.volume], watch.ino.index) - w.mu.Unlock() - return nil - } - e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], - uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) - if e != nil { - err := os.NewSyscallError("ReadDirectoryChanges", e) - if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { - // Watched directory was probably removed - if w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) { - if watch.mask&sysFSONESHOT != 0 { - watch.mask = 0 - } - } - err = nil - } - w.deleteWatch(watch) - w.startRead(watch) - return err - } - return nil -} - -// readEvents reads from the I/O completion port, converts the -// received events into Event objects and sends them via the Events channel. -// Entry point to the I/O thread. -func (w *Watcher) readEvents() { - var ( - n, key uint32 - ov *syscall.Overlapped - ) - runtime.LockOSThread() - - for { - e := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE) - watch := (*watch)(unsafe.Pointer(ov)) - - if watch == nil { - select { - case ch := <-w.quit: - w.mu.Lock() - var indexes []indexMap - for _, index := range w.watches { - indexes = append(indexes, index) - } - w.mu.Unlock() - for _, index := range indexes { - for _, watch := range index { - w.deleteWatch(watch) - w.startRead(watch) - } - } - var err error - if e := syscall.CloseHandle(w.port); e != nil { - err = os.NewSyscallError("CloseHandle", e) - } - close(w.Events) - close(w.Errors) - ch <- err - return - case in := <-w.input: - switch in.op { - case opAddWatch: - in.reply <- w.addWatch(in.path, uint64(in.flags)) - case opRemoveWatch: - in.reply <- w.remWatch(in.path) - } - default: - } - continue - } - - switch e { - case syscall.ERROR_MORE_DATA: - if watch == nil { - w.Errors <- errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer") - } else { - // The i/o succeeded but the buffer is full. - // In theory we should be building up a full packet. - // In practice we can get away with just carrying on. - n = uint32(unsafe.Sizeof(watch.buf)) - } - case syscall.ERROR_ACCESS_DENIED: - // Watched directory was probably removed - w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) - w.deleteWatch(watch) - w.startRead(watch) - continue - case syscall.ERROR_OPERATION_ABORTED: - // CancelIo was called on this handle - continue - default: - w.Errors <- os.NewSyscallError("GetQueuedCompletionPort", e) - continue - case nil: - } - - var offset uint32 - for { - if n == 0 { - w.Events <- newEvent("", sysFSQOVERFLOW) - w.Errors <- errors.New("short read in readEvents()") - break - } - - // Point "raw" to the event in the buffer - raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) - // TODO: Consider using unsafe.Slice that is available from go1.17 - // https://stackoverflow.com/questions/51187973/how-to-create-an-array-or-a-slice-from-an-array-unsafe-pointer-in-golang - // instead of using a fixed syscall.MAX_PATH buf, we create a buf that is the size of the path name - size := int(raw.FileNameLength / 2) - var buf []uint16 - sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) - sh.Data = uintptr(unsafe.Pointer(&raw.FileName)) - sh.Len = size - sh.Cap = size - name := syscall.UTF16ToString(buf) - fullname := filepath.Join(watch.path, name) - - var mask uint64 - switch raw.Action { - case syscall.FILE_ACTION_REMOVED: - mask = sysFSDELETESELF - case syscall.FILE_ACTION_MODIFIED: - mask = sysFSMODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - watch.rename = name - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - if watch.names[watch.rename] != 0 { - watch.names[name] |= watch.names[watch.rename] - delete(watch.names, watch.rename) - mask = sysFSMOVESELF - } - } - - sendNameEvent := func() { - if w.sendEvent(fullname, watch.names[name]&mask) { - if watch.names[name]&sysFSONESHOT != 0 { - delete(watch.names, name) - } - } - } - if raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME { - sendNameEvent() - } - if raw.Action == syscall.FILE_ACTION_REMOVED { - w.sendEvent(fullname, watch.names[name]&sysFSIGNORED) - delete(watch.names, name) - } - if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) { - if watch.mask&sysFSONESHOT != 0 { - watch.mask = 0 - } - } - if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME { - fullname = filepath.Join(watch.path, watch.rename) - sendNameEvent() - } - - // Move to the next event in the buffer - if raw.NextEntryOffset == 0 { - break - } - offset += raw.NextEntryOffset - - // Error! - if offset >= n { - w.Errors <- errors.New("Windows system assumed buffer larger than it is, events have likely been missed.") - break - } - } - - if err := w.startRead(watch); err != nil { - w.Errors <- err - } - } -} - -func (w *Watcher) sendEvent(name string, mask uint64) bool { - if mask == 0 { - return false - } - event := newEvent(name, uint32(mask)) - select { - case ch := <-w.quit: - w.quit <- ch - case w.Events <- event: - } - return true -} - -func toWindowsFlags(mask uint64) uint32 { - var m uint32 - if mask&sysFSACCESS != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS - } - if mask&sysFSMODIFY != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE - } - if mask&sysFSATTRIB != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES - } - if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME - } - return m -} - -func toFSnotifyFlags(action uint32) uint64 { - switch action { - case syscall.FILE_ACTION_ADDED: - return sysFSCREATE - case syscall.FILE_ACTION_REMOVED: - return sysFSDELETE - case syscall.FILE_ACTION_MODIFIED: - return sysFSMODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - return sysFSMOVEDFROM - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - return sysFSMOVEDTO - } - return 0 -} diff --git a/vendor/github.com/fvbommel/sortorder/.gitignore b/vendor/github.com/fvbommel/sortorder/.gitignore new file mode 100644 index 0000000000..c021733e25 --- /dev/null +++ b/vendor/github.com/fvbommel/sortorder/.gitignore @@ -0,0 +1,19 @@ +# 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 diff --git a/vendor/github.com/fvbommel/sortorder/LICENSE b/vendor/github.com/fvbommel/sortorder/LICENSE new file mode 100644 index 0000000000..5c695fb590 --- /dev/null +++ b/vendor/github.com/fvbommel/sortorder/LICENSE @@ -0,0 +1,17 @@ +The MIT License (MIT) +Copyright (c) 2015 Frits van Bommel +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/fvbommel/sortorder/README.md b/vendor/github.com/fvbommel/sortorder/README.md new file mode 100644 index 0000000000..7ebcab1d16 --- /dev/null +++ b/vendor/github.com/fvbommel/sortorder/README.md @@ -0,0 +1,5 @@ +# sortorder [![PkgGoDev](https://pkg.go.dev/badge/github.com/fvbommel/sortorder)](https://pkg.go.dev/github.com/fvbommel/sortorder) + + import "github.com/fvbommel/sortorder" + +Sort orders and comparison functions. diff --git a/vendor/github.com/fvbommel/sortorder/doc.go b/vendor/github.com/fvbommel/sortorder/doc.go new file mode 100644 index 0000000000..75d5a2928f --- /dev/null +++ b/vendor/github.com/fvbommel/sortorder/doc.go @@ -0,0 +1,5 @@ +// Package sortorder implements sort orders and comparison functions. +// +// Currently, it only implements so-called "natural order", where integers +// embedded in strings are compared by value. +package sortorder diff --git a/vendor/github.com/fvbommel/sortorder/natsort.go b/vendor/github.com/fvbommel/sortorder/natsort.go new file mode 100644 index 0000000000..66a52c7125 --- /dev/null +++ b/vendor/github.com/fvbommel/sortorder/natsort.go @@ -0,0 +1,76 @@ +package sortorder + +// Natural implements sort.Interface to sort strings in natural order. This +// means that e.g. "abc2" < "abc12". +// +// Non-digit sequences and numbers are compared separately. The former are +// compared bytewise, while the latter are compared numerically (except that +// the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02") +// +// Limitation: only ASCII digits (0-9) are considered. +type Natural []string + +func (n Natural) Len() int { return len(n) } +func (n Natural) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func (n Natural) Less(i, j int) bool { return NaturalLess(n[i], n[j]) } + +func isdigit(b byte) bool { return '0' <= b && b <= '9' } + +// NaturalLess compares two strings using natural ordering. This means that e.g. +// "abc2" < "abc12". +// +// Non-digit sequences and numbers are compared separately. The former are +// compared bytewise, while the latter are compared numerically (except that +// the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02") +// +// Limitation: only ASCII digits (0-9) are considered. +func NaturalLess(str1, str2 string) bool { + idx1, idx2 := 0, 0 + for idx1 < len(str1) && idx2 < len(str2) { + c1, c2 := str1[idx1], str2[idx2] + dig1, dig2 := isdigit(c1), isdigit(c2) + switch { + case dig1 != dig2: // Digits before other characters. + return dig1 // True if LHS is a digit, false if the RHS is one. + case !dig1: // && !dig2, because dig1 == dig2 + // UTF-8 compares bytewise-lexicographically, no need to decode + // codepoints. + if c1 != c2 { + return c1 < c2 + } + idx1++ + idx2++ + default: // Digits + // Eat zeros. + for ; idx1 < len(str1) && str1[idx1] == '0'; idx1++ { + } + for ; idx2 < len(str2) && str2[idx2] == '0'; idx2++ { + } + // Eat all digits. + nonZero1, nonZero2 := idx1, idx2 + for ; idx1 < len(str1) && isdigit(str1[idx1]); idx1++ { + } + for ; idx2 < len(str2) && isdigit(str2[idx2]); idx2++ { + } + // If lengths of numbers with non-zero prefix differ, the shorter + // one is less. + if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 { + return len1 < len2 + } + // If they're equal, string comparison is correct. + if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 { + return nr1 < nr2 + } + // Otherwise, the one with less zeros is less. + // Because everything up to the number is equal, comparing the index + // after the zeros is sufficient. + if nonZero1 != nonZero2 { + return nonZero1 < nonZero2 + } + } + // They're identical so far, so continue comparing. + } + // So far they are identical. At least one is ended. If the other continues, + // it sorts last. + return len(str1) < len(str2) +} diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go new file mode 100644 index 0000000000..7accdb0c40 --- /dev/null +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -0,0 +1,787 @@ +/* +Copyright 2021 The logr 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 funcr implements formatting of structured log messages and +// optionally captures the call site and timestamp. +// +// The simplest way to use it is via its implementation of a +// github.com/go-logr/logr.LogSink with output through an arbitrary +// "write" function. See New and NewJSON for details. +// +// Custom LogSinks +// +// For users who need more control, a funcr.Formatter can be embedded inside +// your own custom LogSink implementation. This is useful when the LogSink +// needs to implement additional methods, for example. +// +// Formatting +// +// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for +// values which are being logged. When rendering a struct, funcr will use Go's +// standard JSON tags (all except "string"). +package funcr + +import ( + "bytes" + "encoding" + "fmt" + "path/filepath" + "reflect" + "runtime" + "strconv" + "strings" + "time" + + "github.com/go-logr/logr" +) + +// New returns a logr.Logger which is implemented by an arbitrary function. +func New(fn func(prefix, args string), opts Options) logr.Logger { + return logr.New(newSink(fn, NewFormatter(opts))) +} + +// NewJSON returns a logr.Logger which is implemented by an arbitrary function +// and produces JSON output. +func NewJSON(fn func(obj string), opts Options) logr.Logger { + fnWrapper := func(_, obj string) { + fn(obj) + } + return logr.New(newSink(fnWrapper, NewFormatterJSON(opts))) +} + +// Underlier exposes access to the underlying logging function. Since +// callers only have a logr.Logger, they have to know which +// implementation is in use, so this interface is less of an +// abstraction and more of a way to test type conversion. +type Underlier interface { + GetUnderlying() func(prefix, args string) +} + +func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink { + l := &fnlogger{ + Formatter: formatter, + write: fn, + } + // For skipping fnlogger.Info and fnlogger.Error. + l.Formatter.AddCallDepth(1) + return l +} + +// Options carries parameters which influence the way logs are generated. +type Options struct { + // LogCaller tells funcr to add a "caller" key to some or all log lines. + // This has some overhead, so some users might not want it. + LogCaller MessageClass + + // LogCallerFunc tells funcr to also log the calling function name. This + // has no effect if caller logging is not enabled (see Options.LogCaller). + LogCallerFunc bool + + // LogTimestamp tells funcr to add a "ts" key to log lines. This has some + // overhead, so some users might not want it. + LogTimestamp bool + + // TimestampFormat tells funcr how to render timestamps when LogTimestamp + // is enabled. If not specified, a default format will be used. For more + // details, see docs for Go's time.Layout. + TimestampFormat string + + // Verbosity tells funcr which V logs to produce. Higher values enable + // more logs. Info logs at or below this level will be written, while logs + // above this level will be discarded. + Verbosity int + + // RenderBuiltinsHook allows users to mutate the list of key-value pairs + // while a log line is being rendered. The kvList argument follows logr + // conventions - each pair of slice elements is comprised of a string key + // and an arbitrary value (verified and sanitized before calling this + // hook). The value returned must follow the same conventions. This hook + // can be used to audit or modify logged data. For example, you might want + // to prefix all of funcr's built-in keys with some string. This hook is + // only called for built-in (provided by funcr itself) key-value pairs. + // Equivalent hooks are offered for key-value pairs saved via + // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and + // for user-provided pairs (see RenderArgsHook). + RenderBuiltinsHook func(kvList []interface{}) []interface{} + + // RenderValuesHook is the same as RenderBuiltinsHook, except that it is + // only called for key-value pairs saved via logr.Logger.WithValues. See + // RenderBuiltinsHook for more details. + RenderValuesHook func(kvList []interface{}) []interface{} + + // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only + // called for key-value pairs passed directly to Info and Error. See + // RenderBuiltinsHook for more details. + RenderArgsHook func(kvList []interface{}) []interface{} + + // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct + // that contains a struct, etc.) it may log. Every time it finds a struct, + // slice, array, or map the depth is increased by one. When the maximum is + // reached, the value will be converted to a string indicating that the max + // depth has been exceeded. If this field is not specified, a default + // value will be used. + MaxLogDepth int +} + +// MessageClass indicates which category or categories of messages to consider. +type MessageClass int + +const ( + // None ignores all message classes. + None MessageClass = iota + // All considers all message classes. + All + // Info only considers info messages. + Info + // Error only considers error messages. + Error +) + +// fnlogger inherits some of its LogSink implementation from Formatter +// and just needs to add some glue code. +type fnlogger struct { + Formatter + write func(prefix, args string) +} + +func (l fnlogger) WithName(name string) logr.LogSink { + l.Formatter.AddName(name) + return &l +} + +func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { + l.Formatter.AddValues(kvList) + return &l +} + +func (l fnlogger) WithCallDepth(depth int) logr.LogSink { + l.Formatter.AddCallDepth(depth) + return &l +} + +func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { + prefix, args := l.FormatInfo(level, msg, kvList) + l.write(prefix, args) +} + +func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { + prefix, args := l.FormatError(err, msg, kvList) + l.write(prefix, args) +} + +func (l fnlogger) GetUnderlying() func(prefix, args string) { + return l.write +} + +// Assert conformance to the interfaces. +var _ logr.LogSink = &fnlogger{} +var _ logr.CallDepthLogSink = &fnlogger{} +var _ Underlier = &fnlogger{} + +// NewFormatter constructs a Formatter which emits a JSON-like key=value format. +func NewFormatter(opts Options) Formatter { + return newFormatter(opts, outputKeyValue) +} + +// NewFormatterJSON constructs a Formatter which emits strict JSON. +func NewFormatterJSON(opts Options) Formatter { + return newFormatter(opts, outputJSON) +} + +// Defaults for Options. +const defaultTimestampFormat = "2006-01-02 15:04:05.000000" +const defaultMaxLogDepth = 16 + +func newFormatter(opts Options, outfmt outputFormat) Formatter { + if opts.TimestampFormat == "" { + opts.TimestampFormat = defaultTimestampFormat + } + if opts.MaxLogDepth == 0 { + opts.MaxLogDepth = defaultMaxLogDepth + } + f := Formatter{ + outputFormat: outfmt, + prefix: "", + values: nil, + depth: 0, + opts: opts, + } + return f +} + +// Formatter is an opaque struct which can be embedded in a LogSink +// implementation. It should be constructed with NewFormatter. Some of +// its methods directly implement logr.LogSink. +type Formatter struct { + outputFormat outputFormat + prefix string + values []interface{} + valuesStr string + depth int + opts Options +} + +// outputFormat indicates which outputFormat to use. +type outputFormat int + +const ( + // outputKeyValue emits a JSON-like key=value format, but not strict JSON. + outputKeyValue outputFormat = iota + // outputJSON emits strict JSON. + outputJSON +) + +// PseudoStruct is a list of key-value pairs that gets logged as a struct. +type PseudoStruct []interface{} + +// render produces a log line, ready to use. +func (f Formatter) render(builtins, args []interface{}) string { + // Empirically bytes.Buffer is faster than strings.Builder for this. + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + if f.outputFormat == outputJSON { + buf.WriteByte('{') + } + vals := builtins + if hook := f.opts.RenderBuiltinsHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + f.flatten(buf, vals, false, false) // keys are ours, no need to escape + continuing := len(builtins) > 0 + if len(f.valuesStr) > 0 { + if continuing { + if f.outputFormat == outputJSON { + buf.WriteByte(',') + } else { + buf.WriteByte(' ') + } + } + continuing = true + buf.WriteString(f.valuesStr) + } + vals = args + if hook := f.opts.RenderArgsHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + f.flatten(buf, vals, continuing, true) // escape user-provided keys + if f.outputFormat == outputJSON { + buf.WriteByte('}') + } + return buf.String() +} + +// flatten renders a list of key-value pairs into a buffer. If continuing is +// true, it assumes that the buffer has previous values and will emit a +// separator (which depends on the output format) before the first pair it +// writes. If escapeKeys is true, the keys are assumed to have +// non-JSON-compatible characters in them and must be evaluated for escapes. +// +// This function returns a potentially modified version of kvList, which +// ensures that there is a value for every key (adding a value if needed) and +// that each key is a string (substituting a key if needed). +func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { + // This logic overlaps with sanitize() but saves one type-cast per key, + // which can be measurable. + if len(kvList)%2 != 0 { + kvList = append(kvList, noValue) + } + for i := 0; i < len(kvList); i += 2 { + k, ok := kvList[i].(string) + if !ok { + k = f.nonStringKey(kvList[i]) + kvList[i] = k + } + v := kvList[i+1] + + if i > 0 || continuing { + if f.outputFormat == outputJSON { + buf.WriteByte(',') + } else { + // In theory the format could be something we don't understand. In + // practice, we control it, so it won't be. + buf.WriteByte(' ') + } + } + + if escapeKeys { + buf.WriteString(prettyString(k)) + } else { + // this is faster + buf.WriteByte('"') + buf.WriteString(k) + buf.WriteByte('"') + } + if f.outputFormat == outputJSON { + buf.WriteByte(':') + } else { + buf.WriteByte('=') + } + buf.WriteString(f.pretty(v)) + } + return kvList +} + +func (f Formatter) pretty(value interface{}) string { + return f.prettyWithFlags(value, 0, 0) +} + +const ( + flagRawStruct = 0x1 // do not print braces on structs +) + +// TODO: This is not fast. Most of the overhead goes here. +func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { + if depth > f.opts.MaxLogDepth { + return `""` + } + + // Handle types that take full control of logging. + if v, ok := value.(logr.Marshaler); ok { + // Replace the value with what the type wants to get logged. + // That then gets handled below via reflection. + value = invokeMarshaler(v) + } + + // Handle types that want to format themselves. + switch v := value.(type) { + case fmt.Stringer: + value = invokeStringer(v) + case error: + value = invokeError(v) + } + + // Handling the most common types without reflect is a small perf win. + switch v := value.(type) { + case bool: + return strconv.FormatBool(v) + case string: + return prettyString(v) + case int: + return strconv.FormatInt(int64(v), 10) + case int8: + return strconv.FormatInt(int64(v), 10) + case int16: + return strconv.FormatInt(int64(v), 10) + case int32: + return strconv.FormatInt(int64(v), 10) + case int64: + return strconv.FormatInt(int64(v), 10) + case uint: + return strconv.FormatUint(uint64(v), 10) + case uint8: + return strconv.FormatUint(uint64(v), 10) + case uint16: + return strconv.FormatUint(uint64(v), 10) + case uint32: + return strconv.FormatUint(uint64(v), 10) + case uint64: + return strconv.FormatUint(v, 10) + case uintptr: + return strconv.FormatUint(uint64(v), 10) + case float32: + return strconv.FormatFloat(float64(v), 'f', -1, 32) + case float64: + return strconv.FormatFloat(v, 'f', -1, 64) + case complex64: + return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"` + case complex128: + return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"` + case PseudoStruct: + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + v = f.sanitize(v) + if flags&flagRawStruct == 0 { + buf.WriteByte('{') + } + for i := 0; i < len(v); i += 2 { + if i > 0 { + buf.WriteByte(',') + } + k, _ := v[i].(string) // sanitize() above means no need to check success + // arbitrary keys might need escaping + buf.WriteString(prettyString(k)) + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1)) + } + if flags&flagRawStruct == 0 { + buf.WriteByte('}') + } + return buf.String() + } + + buf := bytes.NewBuffer(make([]byte, 0, 256)) + t := reflect.TypeOf(value) + if t == nil { + return "null" + } + v := reflect.ValueOf(value) + switch t.Kind() { + case reflect.Bool: + return strconv.FormatBool(v.Bool()) + case reflect.String: + return prettyString(v.String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(int64(v.Int()), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(uint64(v.Uint()), 10) + case reflect.Float32: + return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32) + case reflect.Float64: + return strconv.FormatFloat(v.Float(), 'f', -1, 64) + case reflect.Complex64: + return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"` + case reflect.Complex128: + return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"` + case reflect.Struct: + if flags&flagRawStruct == 0 { + buf.WriteByte('{') + } + for i := 0; i < t.NumField(); i++ { + fld := t.Field(i) + if fld.PkgPath != "" { + // reflect says this field is only defined for non-exported fields. + continue + } + if !v.Field(i).CanInterface() { + // reflect isn't clear exactly what this means, but we can't use it. + continue + } + name := "" + omitempty := false + if tag, found := fld.Tag.Lookup("json"); found { + if tag == "-" { + continue + } + if comma := strings.Index(tag, ","); comma != -1 { + if n := tag[:comma]; n != "" { + name = n + } + rest := tag[comma:] + if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") { + omitempty = true + } + } else { + name = tag + } + } + if omitempty && isEmpty(v.Field(i)) { + continue + } + if i > 0 { + buf.WriteByte(',') + } + if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" { + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1)) + continue + } + if name == "" { + name = fld.Name + } + // field names can't contain characters which need escaping + buf.WriteByte('"') + buf.WriteString(name) + buf.WriteByte('"') + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1)) + } + if flags&flagRawStruct == 0 { + buf.WriteByte('}') + } + return buf.String() + case reflect.Slice, reflect.Array: + buf.WriteByte('[') + for i := 0; i < v.Len(); i++ { + if i > 0 { + buf.WriteByte(',') + } + e := v.Index(i) + buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1)) + } + buf.WriteByte(']') + return buf.String() + case reflect.Map: + buf.WriteByte('{') + // This does not sort the map keys, for best perf. + it := v.MapRange() + i := 0 + for it.Next() { + if i > 0 { + buf.WriteByte(',') + } + // If a map key supports TextMarshaler, use it. + keystr := "" + if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok { + txt, err := m.MarshalText() + if err != nil { + keystr = fmt.Sprintf("", err.Error()) + } else { + keystr = string(txt) + } + keystr = prettyString(keystr) + } else { + // prettyWithFlags will produce already-escaped values + keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1) + if t.Key().Kind() != reflect.String { + // JSON only does string keys. Unlike Go's standard JSON, we'll + // convert just about anything to a string. + keystr = prettyString(keystr) + } + } + buf.WriteString(keystr) + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1)) + i++ + } + buf.WriteByte('}') + return buf.String() + case reflect.Ptr, reflect.Interface: + if v.IsNil() { + return "null" + } + return f.prettyWithFlags(v.Elem().Interface(), 0, depth) + } + return fmt.Sprintf(`""`, t.Kind().String()) +} + +func prettyString(s string) string { + // Avoid escaping (which does allocations) if we can. + if needsEscape(s) { + return strconv.Quote(s) + } + b := bytes.NewBuffer(make([]byte, 0, 1024)) + b.WriteByte('"') + b.WriteString(s) + b.WriteByte('"') + return b.String() +} + +// needsEscape determines whether the input string needs to be escaped or not, +// without doing any allocations. +func needsEscape(s string) bool { + for _, r := range s { + if !strconv.IsPrint(r) || r == '\\' || r == '"' { + return true + } + } + return false +} + +func isEmpty(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Complex64, reflect.Complex128: + return v.Complex() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} + +func invokeMarshaler(m logr.Marshaler) (ret interface{}) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return m.MarshalLog() +} + +func invokeStringer(s fmt.Stringer) (ret string) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return s.String() +} + +func invokeError(e error) (ret string) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return e.Error() +} + +// Caller represents the original call site for a log line, after considering +// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and +// Line fields will always be provided, while the Func field is optional. +// Users can set the render hook fields in Options to examine logged key-value +// pairs, one of which will be {"caller", Caller} if the Options.LogCaller +// field is enabled for the given MessageClass. +type Caller struct { + // File is the basename of the file for this call site. + File string `json:"file"` + // Line is the line number in the file for this call site. + Line int `json:"line"` + // Func is the function name for this call site, or empty if + // Options.LogCallerFunc is not enabled. + Func string `json:"function,omitempty"` +} + +func (f Formatter) caller() Caller { + // +1 for this frame, +1 for Info/Error. + pc, file, line, ok := runtime.Caller(f.depth + 2) + if !ok { + return Caller{"", 0, ""} + } + fn := "" + if f.opts.LogCallerFunc { + if fp := runtime.FuncForPC(pc); fp != nil { + fn = fp.Name() + } + } + + return Caller{filepath.Base(file), line, fn} +} + +const noValue = "" + +func (f Formatter) nonStringKey(v interface{}) string { + return fmt.Sprintf("", f.snippet(v)) +} + +// snippet produces a short snippet string of an arbitrary value. +func (f Formatter) snippet(v interface{}) string { + const snipLen = 16 + + snip := f.pretty(v) + if len(snip) > snipLen { + snip = snip[:snipLen] + } + return snip +} + +// sanitize ensures that a list of key-value pairs has a value for every key +// (adding a value if needed) and that each key is a string (substituting a key +// if needed). +func (f Formatter) sanitize(kvList []interface{}) []interface{} { + if len(kvList)%2 != 0 { + kvList = append(kvList, noValue) + } + for i := 0; i < len(kvList); i += 2 { + _, ok := kvList[i].(string) + if !ok { + kvList[i] = f.nonStringKey(kvList[i]) + } + } + return kvList +} + +// Init configures this Formatter from runtime info, such as the call depth +// imposed by logr itself. +// Note that this receiver is a pointer, so depth can be saved. +func (f *Formatter) Init(info logr.RuntimeInfo) { + f.depth += info.CallDepth +} + +// Enabled checks whether an info message at the given level should be logged. +func (f Formatter) Enabled(level int) bool { + return level <= f.opts.Verbosity +} + +// GetDepth returns the current depth of this Formatter. This is useful for +// implementations which do their own caller attribution. +func (f Formatter) GetDepth() int { + return f.depth +} + +// FormatInfo renders an Info log message into strings. The prefix will be +// empty when no names were set (via AddNames), or when the output is +// configured for JSON. +func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { + args := make([]interface{}, 0, 64) // using a constant here impacts perf + prefix = f.prefix + if f.outputFormat == outputJSON { + args = append(args, "logger", prefix) + prefix = "" + } + if f.opts.LogTimestamp { + args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) + } + if policy := f.opts.LogCaller; policy == All || policy == Info { + args = append(args, "caller", f.caller()) + } + args = append(args, "level", level, "msg", msg) + return prefix, f.render(args, kvList) +} + +// FormatError renders an Error log message into strings. The prefix will be +// empty when no names were set (via AddNames), or when the output is +// configured for JSON. +func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { + args := make([]interface{}, 0, 64) // using a constant here impacts perf + prefix = f.prefix + if f.outputFormat == outputJSON { + args = append(args, "logger", prefix) + prefix = "" + } + if f.opts.LogTimestamp { + args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) + } + if policy := f.opts.LogCaller; policy == All || policy == Error { + args = append(args, "caller", f.caller()) + } + args = append(args, "msg", msg) + var loggableErr interface{} + if err != nil { + loggableErr = err.Error() + } + args = append(args, "error", loggableErr) + return f.prefix, f.render(args, kvList) +} + +// AddName appends the specified name. funcr uses '/' characters to separate +// name elements. Callers should not pass '/' in the provided name string, but +// this library does not actually enforce that. +func (f *Formatter) AddName(name string) { + if len(f.prefix) > 0 { + f.prefix += "/" + } + f.prefix += name +} + +// AddValues adds key-value pairs to the set of saved values to be logged with +// each log line. +func (f *Formatter) AddValues(kvList []interface{}) { + // Three slice args forces a copy. + n := len(f.values) + f.values = append(f.values[:n:n], kvList...) + + vals := f.values + if hook := f.opts.RenderValuesHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + + // Pre-render values, so we don't have to do it on each Info/Error call. + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + f.flatten(buf, vals, false, true) // escape user-provided keys + f.valuesStr = buf.String() +} + +// AddCallDepth increases the number of stack-frames to skip when attributing +// the log line to a file and line. +func (f *Formatter) AddCallDepth(depth int) { + f.depth += depth +} diff --git a/vendor/go.opentelemetry.io/contrib/LICENSE b/vendor/github.com/go-logr/stdr/LICENSE similarity index 100% rename from vendor/go.opentelemetry.io/contrib/LICENSE rename to vendor/github.com/go-logr/stdr/LICENSE diff --git a/vendor/github.com/go-logr/stdr/README.md b/vendor/github.com/go-logr/stdr/README.md new file mode 100644 index 0000000000..5158667890 --- /dev/null +++ b/vendor/github.com/go-logr/stdr/README.md @@ -0,0 +1,6 @@ +# Minimal Go logging using logr and Go's standard library + +[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/stdr.svg)](https://pkg.go.dev/github.com/go-logr/stdr) + +This package implements the [logr interface](https://github.com/go-logr/logr) +in terms of Go's standard log package(https://pkg.go.dev/log). diff --git a/vendor/github.com/go-logr/stdr/stdr.go b/vendor/github.com/go-logr/stdr/stdr.go new file mode 100644 index 0000000000..93a8aab51b --- /dev/null +++ b/vendor/github.com/go-logr/stdr/stdr.go @@ -0,0 +1,170 @@ +/* +Copyright 2019 The logr 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 stdr implements github.com/go-logr/logr.Logger in terms of +// Go's standard log package. +package stdr + +import ( + "log" + "os" + + "github.com/go-logr/logr" + "github.com/go-logr/logr/funcr" +) + +// The global verbosity level. See SetVerbosity(). +var globalVerbosity int + +// SetVerbosity sets the global level against which all info logs will be +// compared. If this is greater than or equal to the "V" of the logger, the +// message will be logged. A higher value here means more logs will be written. +// The previous verbosity value is returned. This is not concurrent-safe - +// callers must be sure to call it from only one goroutine. +func SetVerbosity(v int) int { + old := globalVerbosity + globalVerbosity = v + return old +} + +// New returns a logr.Logger which is implemented by Go's standard log package, +// or something like it. If std is nil, this will use a default logger +// instead. +// +// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))) +func New(std StdLogger) logr.Logger { + return NewWithOptions(std, Options{}) +} + +// NewWithOptions returns a logr.Logger which is implemented by Go's standard +// log package, or something like it. See New for details. +func NewWithOptions(std StdLogger, opts Options) logr.Logger { + if std == nil { + // Go's log.Default() is only available in 1.16 and higher. + std = log.New(os.Stderr, "", log.LstdFlags) + } + + if opts.Depth < 0 { + opts.Depth = 0 + } + + fopts := funcr.Options{ + LogCaller: funcr.MessageClass(opts.LogCaller), + } + + sl := &logger{ + Formatter: funcr.NewFormatter(fopts), + std: std, + } + + // For skipping our own logger.Info/Error. + sl.Formatter.AddCallDepth(1 + opts.Depth) + + return logr.New(sl) +} + +// Options carries parameters which influence the way logs are generated. +type Options struct { + // Depth biases the assumed number of call frames to the "true" caller. + // This is useful when the calling code calls a function which then calls + // stdr (e.g. a logging shim to another API). Values less than zero will + // be treated as zero. + Depth int + + // LogCaller tells stdr to add a "caller" key to some or all log lines. + // Go's log package has options to log this natively, too. + LogCaller MessageClass + + // TODO: add an option to log the date/time +} + +// MessageClass indicates which category or categories of messages to consider. +type MessageClass int + +const ( + // None ignores all message classes. + None MessageClass = iota + // All considers all message classes. + All + // Info only considers info messages. + Info + // Error only considers error messages. + Error +) + +// StdLogger is the subset of the Go stdlib log.Logger API that is needed for +// this adapter. +type StdLogger interface { + // Output is the same as log.Output and log.Logger.Output. + Output(calldepth int, logline string) error +} + +type logger struct { + funcr.Formatter + std StdLogger +} + +var _ logr.LogSink = &logger{} +var _ logr.CallDepthLogSink = &logger{} + +func (l logger) Enabled(level int) bool { + return globalVerbosity >= level +} + +func (l logger) Info(level int, msg string, kvList ...interface{}) { + prefix, args := l.FormatInfo(level, msg, kvList) + if prefix != "" { + args = prefix + ": " + args + } + _ = l.std.Output(l.Formatter.GetDepth()+1, args) +} + +func (l logger) Error(err error, msg string, kvList ...interface{}) { + prefix, args := l.FormatError(err, msg, kvList) + if prefix != "" { + args = prefix + ": " + args + } + _ = l.std.Output(l.Formatter.GetDepth()+1, args) +} + +func (l logger) WithName(name string) logr.LogSink { + l.Formatter.AddName(name) + return &l +} + +func (l logger) WithValues(kvList ...interface{}) logr.LogSink { + l.Formatter.AddValues(kvList) + return &l +} + +func (l logger) WithCallDepth(depth int) logr.LogSink { + l.Formatter.AddCallDepth(depth) + return &l +} + +// Underlier exposes access to the underlying logging implementation. Since +// callers only have a logr.Logger, they have to know which implementation is +// in use, so this interface is less of an abstraction and more of way to test +// type conversion. +type Underlier interface { + GetUnderlying() StdLogger +} + +// GetUnderlying returns the StdLogger underneath this logger. Since StdLogger +// is itself an interface, the result may or may not be a Go log.Logger. +func (l logger) GetUnderlying() StdLogger { + return l.std +} diff --git a/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/vendor/github.com/go-openapi/jsonpointer/.travis.yml deleted file mode 100644 index 03a22fe06f..0000000000 --- a/vendor/github.com/go-openapi/jsonpointer/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.15.x -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml index f9381aee54..013fc1943a 100644 --- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml @@ -1,8 +1,6 @@ linters-settings: govet: check-shadowing: true - golint: - min-confidence: 0 gocyclo: min-complexity: 30 maligned: @@ -12,6 +10,8 @@ linters-settings: goconst: min-len: 2 min-occurrences: 4 + paralleltest: + ignore-missing: true linters: enable-all: true disable: @@ -39,3 +39,12 @@ linters: - nestif - godot - errorlint + - varcheck + - interfacer + - deadcode + - golint + - ifshort + - structcheck + - nosnakecase + - varnamelen + - exhaustruct diff --git a/vendor/github.com/go-openapi/jsonreference/.travis.yml b/vendor/github.com/go-openapi/jsonreference/.travis.yml deleted file mode 100644 index 05482f4b90..0000000000 --- a/vendor/github.com/go-openapi/jsonreference/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -install: -- go get gotest.tools/gotestsum -jobs: - include: - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go new file mode 100644 index 0000000000..f0610cf1e5 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go @@ -0,0 +1,69 @@ +package internal + +import ( + "net/url" + "regexp" + "strings" +) + +const ( + defaultHTTPPort = ":80" + defaultHTTPSPort = ":443" +) + +// Regular expressions used by the normalizations +var rxPort = regexp.MustCompile(`(:\d+)/?$`) +var rxDupSlashes = regexp.MustCompile(`/{2,}`) + +// NormalizeURL will normalize the specified URL +// This was added to replace a previous call to the no longer maintained purell library: +// The call that was used looked like the following: +// +// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) +// +// To explain all that was included in the call above, purell.FlagsSafe was really just the following: +// - FlagLowercaseScheme +// - FlagLowercaseHost +// - FlagRemoveDefaultPort +// - FlagRemoveDuplicateSlashes (and this was mixed in with the |) +// +// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment. +func NormalizeURL(u *url.URL) { + lowercaseScheme(u) + lowercaseHost(u) + removeDefaultPort(u) + removeDuplicateSlashes(u) + + u.RawPath = "" + u.RawFragment = "" +} + +func lowercaseScheme(u *url.URL) { + if len(u.Scheme) > 0 { + u.Scheme = strings.ToLower(u.Scheme) + } +} + +func lowercaseHost(u *url.URL) { + if len(u.Host) > 0 { + u.Host = strings.ToLower(u.Host) + } +} + +func removeDefaultPort(u *url.URL) { + if len(u.Host) > 0 { + scheme := strings.ToLower(u.Scheme) + u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { + if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) { + return "" + } + return val + }) + } +} + +func removeDuplicateSlashes(u *url.URL) { + if len(u.Path) > 0 { + u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") + } +} diff --git a/vendor/github.com/go-openapi/jsonreference/reference.go b/vendor/github.com/go-openapi/jsonreference/reference.go index 3bc0a6e26f..cfdef03e5d 100644 --- a/vendor/github.com/go-openapi/jsonreference/reference.go +++ b/vendor/github.com/go-openapi/jsonreference/reference.go @@ -30,8 +30,8 @@ import ( "net/url" "strings" - "github.com/PuerkitoBio/purell" "github.com/go-openapi/jsonpointer" + "github.com/go-openapi/jsonreference/internal" ) const ( @@ -114,7 +114,9 @@ func (r *Ref) parse(jsonReferenceString string) error { return err } - r.referenceURL, _ = url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) + internal.NormalizeURL(parsed) + + r.referenceURL = parsed refURL := r.referenceURL if refURL.Scheme != "" && refURL.Host != "" { diff --git a/vendor/github.com/go-openapi/swag/.gitattributes b/vendor/github.com/go-openapi/swag/.gitattributes new file mode 100644 index 0000000000..49ad52766a --- /dev/null +++ b/vendor/github.com/go-openapi/swag/.gitattributes @@ -0,0 +1,2 @@ +# gofmt always uses LF, whereas Git uses CRLF on Windows. +*.go text eol=lf diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index 813c47aa64..bf503e4000 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -37,3 +37,18 @@ linters: - gci - gocognit - paralleltest + - thelper + - ifshort + - gomoddirectives + - cyclop + - forcetypeassert + - ireturn + - tagliatelle + - varnamelen + - goimports + - tenv + - golint + - exhaustruct + - nilnil + - nonamedreturns + - nosnakecase diff --git a/vendor/github.com/go-openapi/swag/.travis.yml b/vendor/github.com/go-openapi/swag/.travis.yml deleted file mode 100644 index fc25a88728..0000000000 --- a/vendor/github.com/go-openapi/swag/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -arch: -- amd64 -jobs: - include: - # include arch ppc, but only for latest go version - skip testing for race - - go: 1.x - arch: ppc64le - install: ~ - script: - - go test -v - - #- go: 1.x - # arch: arm - # install: ~ - # script: - # - go test -v - - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -language: go -notifications: - slack: - secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/swag/doc.go b/vendor/github.com/go-openapi/swag/doc.go index 8d2c8c5014..55094cb74c 100644 --- a/vendor/github.com/go-openapi/swag/doc.go +++ b/vendor/github.com/go-openapi/swag/doc.go @@ -17,16 +17,15 @@ Package swag contains a bunch of helper functions for go-openapi and go-swagger You may also use it standalone for your projects. - * convert between value and pointers for builtin types - * convert from string to builtin types (wraps strconv) - * fast json concatenation - * search in path - * load from file or http - * name mangling - + - convert between value and pointers for builtin types + - convert from string to builtin types (wraps strconv) + - fast json concatenation + - search in path + - load from file or http + - name mangling This repo has only few dependencies outside of the standard library: - * YAML utilities depend on gopkg.in/yaml.v2 + - YAML utilities depend on gopkg.in/yaml.v2 */ package swag diff --git a/vendor/github.com/go-openapi/swag/file.go b/vendor/github.com/go-openapi/swag/file.go new file mode 100644 index 0000000000..16accc55f8 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/file.go @@ -0,0 +1,33 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 swag + +import "mime/multipart" + +// File represents an uploaded file. +type File struct { + Data multipart.File + Header *multipart.FileHeader +} + +// Read bytes from the file +func (f *File) Read(p []byte) (n int, err error) { + return f.Data.Read(p) +} + +// Close the file +func (f *File) Close() error { + return f.Data.Close() +} diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go index 9a60409725..00038c3773 100644 --- a/vendor/github.com/go-openapi/swag/loading.go +++ b/vendor/github.com/go-openapi/swag/loading.go @@ -16,10 +16,11 @@ package swag import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/url" + "os" "path/filepath" "runtime" "strings" @@ -40,13 +41,13 @@ var LoadHTTPCustomHeaders = map[string]string{} // LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in func LoadFromFileOrHTTP(path string) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) + return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) } // LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in // timeout arg allows for per request overriding of the request timeout func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path) + return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path) } // LoadStrategy returns a loader function for a given path or uri @@ -86,7 +87,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func( func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { return func(path string) ([]byte, error) { client := &http.Client{Timeout: timeout} - req, err := http.NewRequest("GET", path, nil) // nolint: noctx + req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx if err != nil { return nil, err } @@ -115,6 +116,6 @@ func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status) } - return ioutil.ReadAll(resp.Body) + return io.ReadAll(resp.Body) } } diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/go-openapi/swag/post_go18.go index c2e686d313..f5228b82c0 100644 --- a/vendor/github.com/go-openapi/swag/post_go18.go +++ b/vendor/github.com/go-openapi/swag/post_go18.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build go1.8 // +build go1.8 package swag diff --git a/vendor/github.com/go-openapi/swag/post_go19.go b/vendor/github.com/go-openapi/swag/post_go19.go index eb2f2d8bc7..7c7da9c088 100644 --- a/vendor/github.com/go-openapi/swag/post_go19.go +++ b/vendor/github.com/go-openapi/swag/post_go19.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build go1.9 // +build go1.9 package swag diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/go-openapi/swag/pre_go18.go index 6607f33935..2757d9b95f 100644 --- a/vendor/github.com/go-openapi/swag/pre_go18.go +++ b/vendor/github.com/go-openapi/swag/pre_go18.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !go1.8 // +build !go1.8 package swag diff --git a/vendor/github.com/go-openapi/swag/pre_go19.go b/vendor/github.com/go-openapi/swag/pre_go19.go index 4bae187d1e..0565db377b 100644 --- a/vendor/github.com/go-openapi/swag/pre_go19.go +++ b/vendor/github.com/go-openapi/swag/pre_go19.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !go1.9 // +build !go1.9 package swag diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go index 193702f2ce..f78ab684a0 100644 --- a/vendor/github.com/go-openapi/swag/util.go +++ b/vendor/github.com/go-openapi/swag/util.go @@ -99,10 +99,11 @@ const ( ) // JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) +// +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) func JoinByFormat(data []string, format string) []string { if len(data) == 0 { return data @@ -124,11 +125,11 @@ func JoinByFormat(data []string, format string) []string { } // SplitByFormat splits a string by a known format: -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) // +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) func SplitByFormat(data, format string) []string { if data == "" { return nil diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go index ec96914405..f09ee609f3 100644 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ b/vendor/github.com/go-openapi/swag/yaml.go @@ -22,7 +22,7 @@ import ( "github.com/mailru/easyjson/jlexer" "github.com/mailru/easyjson/jwriter" - yaml "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v3" ) // YAMLMatcher matches yaml @@ -43,16 +43,126 @@ func YAMLToJSON(data interface{}) (json.RawMessage, error) { // BytesToYAMLDoc converts a byte slice into a YAML document func BytesToYAMLDoc(data []byte) (interface{}, error) { - var canary map[interface{}]interface{} // validate this is an object and not a different type - if err := yaml.Unmarshal(data, &canary); err != nil { + var document yaml.Node // preserve order that is present in the document + if err := yaml.Unmarshal(data, &document); err != nil { return nil, err } + if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { + return nil, fmt.Errorf("only YAML documents that are objects are supported") + } + return &document, nil +} - var document yaml.MapSlice // preserve order that is present in the document - if err := yaml.Unmarshal(data, &document); err != nil { - return nil, err +func yamlNode(root *yaml.Node) (interface{}, error) { + switch root.Kind { + case yaml.DocumentNode: + return yamlDocument(root) + case yaml.SequenceNode: + return yamlSequence(root) + case yaml.MappingNode: + return yamlMapping(root) + case yaml.ScalarNode: + return yamlScalar(root) + case yaml.AliasNode: + return yamlNode(root.Alias) + default: + return nil, fmt.Errorf("unsupported YAML node type: %v", root.Kind) + } +} + +func yamlDocument(node *yaml.Node) (interface{}, error) { + if len(node.Content) != 1 { + return nil, fmt.Errorf("unexpected YAML Document node content length: %d", len(node.Content)) + } + return yamlNode(node.Content[0]) +} + +func yamlMapping(node *yaml.Node) (interface{}, error) { + m := make(JSONMapSlice, len(node.Content)/2) + + var j int + for i := 0; i < len(node.Content); i += 2 { + var nmi JSONMapItem + k, err := yamlStringScalarC(node.Content[i]) + if err != nil { + return nil, fmt.Errorf("unable to decode YAML map key: %w", err) + } + nmi.Key = k + v, err := yamlNode(node.Content[i+1]) + if err != nil { + return nil, fmt.Errorf("unable to process YAML map value for key %q: %w", k, err) + } + nmi.Value = v + m[j] = nmi + j++ + } + return m, nil +} + +func yamlSequence(node *yaml.Node) (interface{}, error) { + s := make([]interface{}, 0) + + for i := 0; i < len(node.Content); i++ { + + v, err := yamlNode(node.Content[i]) + if err != nil { + return nil, fmt.Errorf("unable to decode YAML sequence value: %w", err) + } + s = append(s, v) + } + return s, nil +} + +const ( // See https://yaml.org/type/ + yamlStringScalar = "tag:yaml.org,2002:str" + yamlIntScalar = "tag:yaml.org,2002:int" + yamlBoolScalar = "tag:yaml.org,2002:bool" + yamlFloatScalar = "tag:yaml.org,2002:float" + yamlTimestamp = "tag:yaml.org,2002:timestamp" + yamlNull = "tag:yaml.org,2002:null" +) + +func yamlScalar(node *yaml.Node) (interface{}, error) { + switch node.LongTag() { + case yamlStringScalar: + return node.Value, nil + case yamlBoolScalar: + b, err := strconv.ParseBool(node.Value) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w", node.Value, err) + } + return b, nil + case yamlIntScalar: + i, err := strconv.ParseInt(node.Value, 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w", node.Value, err) + } + return i, nil + case yamlFloatScalar: + f, err := strconv.ParseFloat(node.Value, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w", node.Value, err) + } + return f, nil + case yamlTimestamp: + return node.Value, nil + case yamlNull: + return nil, nil + default: + return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag()) + } +} + +func yamlStringScalarC(node *yaml.Node) (string, error) { + if node.Kind != yaml.ScalarNode { + return "", fmt.Errorf("expecting a string scalar but got %q", node.Kind) + } + switch node.LongTag() { + case yamlStringScalar, yamlIntScalar, yamlFloatScalar: + return node.Value, nil + default: + return "", fmt.Errorf("YAML tag %q is not supported as map key", node.LongTag()) } - return document, nil } // JSONMapSlice represent a JSON object, with the order of keys maintained @@ -105,6 +215,113 @@ func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) { *s = result } +func (s JSONMapSlice) MarshalYAML() (interface{}, error) { + var n yaml.Node + n.Kind = yaml.DocumentNode + var nodes []*yaml.Node + for _, item := range s { + nn, err := json2yaml(item.Value) + if err != nil { + return nil, err + } + ns := []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: item.Key, + }, + nn, + } + nodes = append(nodes, ns...) + } + + n.Content = []*yaml.Node{ + { + Kind: yaml.MappingNode, + Content: nodes, + }, + } + + return yaml.Marshal(&n) +} + +func json2yaml(item interface{}) (*yaml.Node, error) { + switch val := item.(type) { + case JSONMapSlice: + var n yaml.Node + n.Kind = yaml.MappingNode + for i := range val { + childNode, err := json2yaml(&val[i].Value) + if err != nil { + return nil, err + } + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: val[i].Key, + }, childNode) + } + return &n, nil + case map[string]interface{}: + var n yaml.Node + n.Kind = yaml.MappingNode + for k, v := range val { + childNode, err := json2yaml(v) + if err != nil { + return nil, err + } + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: k, + }, childNode) + } + return &n, nil + case []interface{}: + var n yaml.Node + n.Kind = yaml.SequenceNode + for i := range val { + childNode, err := json2yaml(val[i]) + if err != nil { + return nil, err + } + n.Content = append(n.Content, childNode) + } + return &n, nil + case string: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: val, + }, nil + case float64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlFloatScalar, + Value: strconv.FormatFloat(val, 'f', -1, 64), + }, nil + case int64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: strconv.FormatInt(val, 10), + }, nil + case uint64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: strconv.FormatUint(val, 10), + }, nil + case bool: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlBoolScalar, + Value: strconv.FormatBool(val), + }, nil + } + return nil, nil +} + // JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice type JSONMapItem struct { Key string @@ -173,23 +390,10 @@ func transformData(input interface{}) (out interface{}, err error) { } switch in := input.(type) { - case yaml.MapSlice: - - o := make(JSONMapSlice, len(in)) - for i, mi := range in { - var nmi JSONMapItem - if nmi.Key, err = format(mi.Key); err != nil { - return nil, err - } - - v, ert := transformData(mi.Value) - if ert != nil { - return nil, ert - } - nmi.Value = v - o[i] = nmi - } - return o, nil + case yaml.Node: + return yamlNode(&in) + case *yaml.Node: + return yamlNode(in) case map[interface{}]interface{}: o := make(JSONMapSlice, 0, len(in)) for ke, va := range in { diff --git a/vendor/github.com/golang-jwt/jwt/v4/.gitignore b/vendor/github.com/golang-jwt/jwt/v4/.gitignore deleted file mode 100644 index 09573e0169..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -bin -.idea/ - diff --git a/vendor/github.com/golang-jwt/jwt/v4/LICENSE b/vendor/github.com/golang-jwt/jwt/v4/LICENSE deleted file mode 100644 index 35dbc25204..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2012 Dave Grijalva -Copyright (c) 2021 golang-jwt maintainers - -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/golang-jwt/jwt/v4/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v4/MIGRATION_GUIDE.md deleted file mode 100644 index 32966f5981..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/MIGRATION_GUIDE.md +++ /dev/null @@ -1,22 +0,0 @@ -## Migration Guide (v4.0.0) - -Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0), the import path will be: - - "github.com/golang-jwt/jwt/v4" - -The `/v4` version will be backwards compatible with existing `v3.x.y` tags in this repo, as well as -`github.com/dgrijalva/jwt-go`. For most users this should be a drop-in replacement, if you're having -troubles migrating, please open an issue. - -You can replace all occurrences of `github.com/dgrijalva/jwt-go` or `github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v4`, either manually or by using tools such as `sed` or `gofmt`. - -And then you'd typically run: - -``` -go get github.com/golang-jwt/jwt/v4 -go mod tidy -``` - -## Older releases (before v3.2.0) - -The original migration guide for older releases can be found at https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md. diff --git a/vendor/github.com/golang-jwt/jwt/v4/README.md b/vendor/github.com/golang-jwt/jwt/v4/README.md deleted file mode 100644 index 3072d24a9d..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/README.md +++ /dev/null @@ -1,114 +0,0 @@ -# jwt-go - -[![build](https://github.com/golang-jwt/jwt/actions/workflows/build.yml/badge.svg)](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) -[![Go Reference](https://pkg.go.dev/badge/github.com/golang-jwt/jwt/v4.svg)](https://pkg.go.dev/github.com/golang-jwt/jwt/v4) - -A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](https://datatracker.ietf.org/doc/html/rfc7519). - -Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) this project adds Go module support, but maintains backwards compatibility with older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. -See the [`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. - -> After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic. - - -**SECURITY NOTICE:** Some older versions of Go have a security issue in the crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue [dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more detail. - -**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. - -### Supported Go versions - -Our support of Go versions is aligned with Go's [version release policy](https://golang.org/doc/devel/release#policy). -So we will support a major version of Go until there are two newer major releases. -We no longer support building jwt-go with unsupported Go versions, as these contain security vulnerabilities -which will not be fixed. - -## What the heck is a JWT? - -JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens. - -In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](https://datatracker.ietf.org/doc/html/rfc4648) encoded. The last part is the signature, encoded the same way. - -The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used. - -The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) for information about reserved keys and the proper way to add your own. - -## What's in the box? - -This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own. - -## Examples - -See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt) for examples of usage: - -* [Simple example of parsing and validating a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-Parse-Hmac) -* [Simple example of building and signing a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-New-Hmac) -* [Directory of Examples](https://pkg.go.dev/github.com/golang-jwt/jwt#pkg-examples) - -## Extensions - -This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`. - -Here's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go - -## Compliance - -This library was last reviewed to comply with [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few notable differences: - -* In order to protect against accidental use of [Unsecured JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. - -## Project Status & Versioning - -This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason). - -This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `main`. Periodically, versions will be tagged from `main`. You can find all the releases on [the project releases page](https://github.com/golang-jwt/jwt/releases). - -**BREAKING CHANGES:*** -A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. - -## Usage Tips - -### Signing vs Encryption - -A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data: - -* The author of the token was in the possession of the signing secret -* The data has not been modified since it was signed - -It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library. - -### Choosing a Signing Method - -There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric. - -Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation. - -Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification. - -### Signing Methods and Key Types - -Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones: - -* The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation -* The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation -* The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation -* The [EdDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodEd25519) (`Ed25519`) expect `ed25519.PrivateKey` for signing and `ed25519.PublicKey` for validation - -### JWT and OAuth - -It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication. - -Without going too far down the rabbit hole, here's a description of the interaction of these technologies: - -* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. -* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. -* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. - -### Troubleshooting - -This library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types. - -## More - -Documentation can be found [on pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt). - -The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation. diff --git a/vendor/github.com/golang-jwt/jwt/v4/VERSION_HISTORY.md b/vendor/github.com/golang-jwt/jwt/v4/VERSION_HISTORY.md deleted file mode 100644 index afbfc4e408..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/VERSION_HISTORY.md +++ /dev/null @@ -1,135 +0,0 @@ -## `jwt-go` Version History - -#### 4.0.0 - -* Introduces support for Go modules. The `v4` version will be backwards compatible with `v3.x.y`. - -#### 3.2.2 - -* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)). -* Fixed a potential issue that could occur when the verification of `exp`, `iat` or `nbf` was not required and contained invalid contents, i.e. non-numeric/date. Thanks for @thaJeztah for making us aware of that and @giorgos-f3 for originally reporting it to the formtech fork ([#40](https://github.com/golang-jwt/jwt/pull/40)). -* Added support for EdDSA / ED25519 ([#36](https://github.com/golang-jwt/jwt/pull/36)). -* Optimized allocations ([#33](https://github.com/golang-jwt/jwt/pull/33)). - -#### 3.2.1 - -* **Import Path Change**: See MIGRATION_GUIDE.md for tips on updating your code - * Changed the import path from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt` -* Fixed type confusing issue between `string` and `[]string` in `VerifyAudience` ([#12](https://github.com/golang-jwt/jwt/pull/12)). This fixes CVE-2020-26160 - -#### 3.2.0 - -* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation -* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate -* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. -* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. - -#### 3.1.0 - -* Improvements to `jwt` command line tool -* Added `SkipClaimsValidation` option to `Parser` -* Documentation updates - -#### 3.0.0 - -* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code - * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. - * `ParseFromRequest` has been moved to `request` subpackage and usage has changed - * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. -* Other Additions and Changes - * Added `Claims` interface type to allow users to decode the claims into a custom type - * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. - * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage - * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` - * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. - * Added several new, more specific, validation errors to error type bitmask - * Moved examples from README to executable example files - * Signing method registry is now thread safe - * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) - -#### 2.7.0 - -This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. - -* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying -* Error text for expired tokens includes how long it's been expired -* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` -* Documentation updates - -#### 2.6.0 - -* Exposed inner error within ValidationError -* Fixed validation errors when using UseJSONNumber flag -* Added several unit tests - -#### 2.5.0 - -* Added support for signing method none. You shouldn't use this. The API tries to make this clear. -* Updated/fixed some documentation -* Added more helpful error message when trying to parse tokens that begin with `BEARER ` - -#### 2.4.0 - -* Added new type, Parser, to allow for configuration of various parsing parameters - * You can now specify a list of valid signing methods. Anything outside this set will be rejected. - * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON -* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) -* Fixed some bugs with ECDSA parsing - -#### 2.3.0 - -* Added support for ECDSA signing methods -* Added support for RSA PSS signing methods (requires go v1.4) - -#### 2.2.0 - -* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. - -#### 2.1.0 - -Backwards compatible API change that was missed in 2.0.0. - -* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` - -#### 2.0.0 - -There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. - -The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. - -It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. - -* **Compatibility Breaking Changes** - * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` - * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` - * `KeyFunc` now returns `interface{}` instead of `[]byte` - * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key - * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key -* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. - * Added public package global `SigningMethodHS256` - * Added public package global `SigningMethodHS384` - * Added public package global `SigningMethodHS512` -* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. - * Added public package global `SigningMethodRS256` - * Added public package global `SigningMethodRS384` - * Added public package global `SigningMethodRS512` -* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. -* Refactored the RSA implementation to be easier to read -* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` - -#### 1.0.2 - -* Fixed bug in parsing public keys from certificates -* Added more tests around the parsing of keys for RS256 -* Code refactoring in RS256 implementation. No functional changes - -#### 1.0.1 - -* Fixed panic if RS256 signing method was passed an invalid key - -#### 1.0.0 - -* First versioned release -* API stabilized -* Supports creating, signing, parsing, and validating JWT tokens -* Supports RS256 and HS256 signing methods diff --git a/vendor/github.com/golang-jwt/jwt/v4/claims.go b/vendor/github.com/golang-jwt/jwt/v4/claims.go deleted file mode 100644 index 41cc826563..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/claims.go +++ /dev/null @@ -1,273 +0,0 @@ -package jwt - -import ( - "crypto/subtle" - "fmt" - "time" -) - -// Claims must just have a Valid method that determines -// if the token is invalid for any supported reason -type Claims interface { - Valid() error -} - -// RegisteredClaims are a structured version of the JWT Claims Set, -// restricted to Registered Claim Names, as referenced at -// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 -// -// This type can be used on its own, but then additional private and -// public claims embedded in the JWT will not be parsed. The typical usecase -// therefore is to embedded this in a user-defined claim type. -// -// See examples for how to use this with your own claim types. -type RegisteredClaims struct { - // the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 - Issuer string `json:"iss,omitempty"` - - // the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 - Subject string `json:"sub,omitempty"` - - // the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 - Audience ClaimStrings `json:"aud,omitempty"` - - // the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 - ExpiresAt *NumericDate `json:"exp,omitempty"` - - // the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5 - NotBefore *NumericDate `json:"nbf,omitempty"` - - // the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6 - IssuedAt *NumericDate `json:"iat,omitempty"` - - // the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 - ID string `json:"jti,omitempty"` -} - -// Valid validates time based claims "exp, iat, nbf". -// There is no accounting for clock skew. -// As well, if any of the above claims are not in the token, it will still -// be considered a valid claim. -func (c RegisteredClaims) Valid() error { - vErr := new(ValidationError) - now := TimeFunc() - - // The claims below are optional, by default, so if they are set to the - // default value in Go, let's not fail the verification for them. - if !c.VerifyExpiresAt(now, false) { - delta := now.Sub(c.ExpiresAt.Time) - vErr.Inner = fmt.Errorf("token is expired by %v", delta) - vErr.Errors |= ValidationErrorExpired - } - - if !c.VerifyIssuedAt(now, false) { - vErr.Inner = fmt.Errorf("token used before issued") - vErr.Errors |= ValidationErrorIssuedAt - } - - if !c.VerifyNotBefore(now, false) { - vErr.Inner = fmt.Errorf("token is not valid yet") - vErr.Errors |= ValidationErrorNotValidYet - } - - if vErr.valid() { - return nil - } - - return vErr -} - -// VerifyAudience compares the aud claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (c *RegisteredClaims) VerifyAudience(cmp string, req bool) bool { - return verifyAud(c.Audience, cmp, req) -} - -// VerifyExpiresAt compares the exp claim against cmp (cmp < exp). -// If req is false, it will return true, if exp is unset. -func (c *RegisteredClaims) VerifyExpiresAt(cmp time.Time, req bool) bool { - if c.ExpiresAt == nil { - return verifyExp(nil, cmp, req) - } - - return verifyExp(&c.ExpiresAt.Time, cmp, req) -} - -// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat). -// If req is false, it will return true, if iat is unset. -func (c *RegisteredClaims) VerifyIssuedAt(cmp time.Time, req bool) bool { - if c.IssuedAt == nil { - return verifyIat(nil, cmp, req) - } - - return verifyIat(&c.IssuedAt.Time, cmp, req) -} - -// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf). -// If req is false, it will return true, if nbf is unset. -func (c *RegisteredClaims) VerifyNotBefore(cmp time.Time, req bool) bool { - if c.NotBefore == nil { - return verifyNbf(nil, cmp, req) - } - - return verifyNbf(&c.NotBefore.Time, cmp, req) -} - -// VerifyIssuer compares the iss claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (c *RegisteredClaims) VerifyIssuer(cmp string, req bool) bool { - return verifyIss(c.Issuer, cmp, req) -} - -// StandardClaims are a structured version of the JWT Claims Set, as referenced at -// https://datatracker.ietf.org/doc/html/rfc7519#section-4. They do not follow the -// specification exactly, since they were based on an earlier draft of the -// specification and not updated. The main difference is that they only -// support integer-based date fields and singular audiences. This might lead to -// incompatibilities with other JWT implementations. The use of this is discouraged, instead -// the newer RegisteredClaims struct should be used. -// -// Deprecated: Use RegisteredClaims instead for a forward-compatible way to access registered claims in a struct. -type StandardClaims struct { - Audience string `json:"aud,omitempty"` - ExpiresAt int64 `json:"exp,omitempty"` - Id string `json:"jti,omitempty"` - IssuedAt int64 `json:"iat,omitempty"` - Issuer string `json:"iss,omitempty"` - NotBefore int64 `json:"nbf,omitempty"` - Subject string `json:"sub,omitempty"` -} - -// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew. -// As well, if any of the above claims are not in the token, it will still -// be considered a valid claim. -func (c StandardClaims) Valid() error { - vErr := new(ValidationError) - now := TimeFunc().Unix() - - // The claims below are optional, by default, so if they are set to the - // default value in Go, let's not fail the verification for them. - if !c.VerifyExpiresAt(now, false) { - delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0)) - vErr.Inner = fmt.Errorf("token is expired by %v", delta) - vErr.Errors |= ValidationErrorExpired - } - - if !c.VerifyIssuedAt(now, false) { - vErr.Inner = fmt.Errorf("token used before issued") - vErr.Errors |= ValidationErrorIssuedAt - } - - if !c.VerifyNotBefore(now, false) { - vErr.Inner = fmt.Errorf("token is not valid yet") - vErr.Errors |= ValidationErrorNotValidYet - } - - if vErr.valid() { - return nil - } - - return vErr -} - -// VerifyAudience compares the aud claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { - return verifyAud([]string{c.Audience}, cmp, req) -} - -// VerifyExpiresAt compares the exp claim against cmp (cmp < exp). -// If req is false, it will return true, if exp is unset. -func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { - if c.ExpiresAt == 0 { - return verifyExp(nil, time.Unix(cmp, 0), req) - } - - t := time.Unix(c.ExpiresAt, 0) - return verifyExp(&t, time.Unix(cmp, 0), req) -} - -// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat). -// If req is false, it will return true, if iat is unset. -func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { - if c.IssuedAt == 0 { - return verifyIat(nil, time.Unix(cmp, 0), req) - } - - t := time.Unix(c.IssuedAt, 0) - return verifyIat(&t, time.Unix(cmp, 0), req) -} - -// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf). -// If req is false, it will return true, if nbf is unset. -func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { - if c.NotBefore == 0 { - return verifyNbf(nil, time.Unix(cmp, 0), req) - } - - t := time.Unix(c.NotBefore, 0) - return verifyNbf(&t, time.Unix(cmp, 0), req) -} - -// VerifyIssuer compares the iss claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool { - return verifyIss(c.Issuer, cmp, req) -} - -// ----- helpers - -func verifyAud(aud []string, cmp string, required bool) bool { - if len(aud) == 0 { - return !required - } - // use a var here to keep constant time compare when looping over a number of claims - result := false - - var stringClaims string - for _, a := range aud { - if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 { - result = true - } - stringClaims = stringClaims + a - } - - // case where "" is sent in one or many aud claims - if len(stringClaims) == 0 { - return !required - } - - return result -} - -func verifyExp(exp *time.Time, now time.Time, required bool) bool { - if exp == nil { - return !required - } - return now.Before(*exp) -} - -func verifyIat(iat *time.Time, now time.Time, required bool) bool { - if iat == nil { - return !required - } - return now.After(*iat) || now.Equal(*iat) -} - -func verifyNbf(nbf *time.Time, now time.Time, required bool) bool { - if nbf == nil { - return !required - } - return now.After(*nbf) || now.Equal(*nbf) -} - -func verifyIss(iss string, cmp string, required bool) bool { - if iss == "" { - return !required - } - if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 { - return true - } else { - return false - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/doc.go b/vendor/github.com/golang-jwt/jwt/v4/doc.go deleted file mode 100644 index a86dc1a3b3..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html -// -// See README.md for more info. -package jwt diff --git a/vendor/github.com/golang-jwt/jwt/v4/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v4/ecdsa.go deleted file mode 100644 index eac023fc6c..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/ecdsa.go +++ /dev/null @@ -1,142 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rand" - "errors" - "math/big" -) - -var ( - // Sadly this is missing from crypto/ecdsa compared to crypto/rsa - ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") -) - -// SigningMethodECDSA implements the ECDSA family of signing methods. -// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification -type SigningMethodECDSA struct { - Name string - Hash crypto.Hash - KeySize int - CurveBits int -} - -// Specific instances for EC256 and company -var ( - SigningMethodES256 *SigningMethodECDSA - SigningMethodES384 *SigningMethodECDSA - SigningMethodES512 *SigningMethodECDSA -) - -func init() { - // ES256 - SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} - RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { - return SigningMethodES256 - }) - - // ES384 - SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} - RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { - return SigningMethodES384 - }) - - // ES512 - SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} - RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { - return SigningMethodES512 - }) -} - -func (m *SigningMethodECDSA) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an ecdsa.PublicKey struct -func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error { - var err error - - // Decode the signature - var sig []byte - if sig, err = DecodeSegment(signature); err != nil { - return err - } - - // Get the key - var ecdsaKey *ecdsa.PublicKey - switch k := key.(type) { - case *ecdsa.PublicKey: - ecdsaKey = k - default: - return ErrInvalidKeyType - } - - if len(sig) != 2*m.KeySize { - return ErrECDSAVerification - } - - r := big.NewInt(0).SetBytes(sig[:m.KeySize]) - s := big.NewInt(0).SetBytes(sig[m.KeySize:]) - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Verify the signature - if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus { - return nil - } - - return ErrECDSAVerification -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an ecdsa.PrivateKey struct -func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) { - // Get the key - var ecdsaKey *ecdsa.PrivateKey - switch k := key.(type) { - case *ecdsa.PrivateKey: - ecdsaKey = k - default: - return "", ErrInvalidKeyType - } - - // Create the hasher - if !m.Hash.Available() { - return "", ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return r, s - if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { - curveBits := ecdsaKey.Curve.Params().BitSize - - if m.CurveBits != curveBits { - return "", ErrInvalidKey - } - - keyBytes := curveBits / 8 - if curveBits%8 > 0 { - keyBytes += 1 - } - - // We serialize the outputs (r and s) into big-endian byte arrays - // padded with zeros on the left to make sure the sizes work out. - // Output must be 2*keyBytes long. - out := make([]byte, 2*keyBytes) - r.FillBytes(out[0:keyBytes]) // r is assigned to the first half of output. - s.FillBytes(out[keyBytes:]) // s is assigned to the second half of output. - - return EncodeSegment(out), nil - } else { - return "", err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v4/ecdsa_utils.go deleted file mode 100644 index 5700636d35..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/ecdsa_utils.go +++ /dev/null @@ -1,69 +0,0 @@ -package jwt - -import ( - "crypto/ecdsa" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrNotECPublicKey = errors.New("key is not a valid ECDSA public key") - ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key") -) - -// ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure -func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - } - - var pkey *ecdsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { - return nil, ErrNotECPrivateKey - } - - return pkey, nil -} - -// ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key -func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - if cert, err := x509.ParseCertificate(block.Bytes); err == nil { - parsedKey = cert.PublicKey - } else { - return nil, err - } - } - - var pkey *ecdsa.PublicKey - var ok bool - if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { - return nil, ErrNotECPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/ed25519.go b/vendor/github.com/golang-jwt/jwt/v4/ed25519.go deleted file mode 100644 index 07d3aacd63..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/ed25519.go +++ /dev/null @@ -1,85 +0,0 @@ -package jwt - -import ( - "errors" - - "crypto" - "crypto/ed25519" - "crypto/rand" -) - -var ( - ErrEd25519Verification = errors.New("ed25519: verification error") -) - -// SigningMethodEd25519 implements the EdDSA family. -// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification -type SigningMethodEd25519 struct{} - -// Specific instance for EdDSA -var ( - SigningMethodEdDSA *SigningMethodEd25519 -) - -func init() { - SigningMethodEdDSA = &SigningMethodEd25519{} - RegisterSigningMethod(SigningMethodEdDSA.Alg(), func() SigningMethod { - return SigningMethodEdDSA - }) -} - -func (m *SigningMethodEd25519) Alg() string { - return "EdDSA" -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an ed25519.PublicKey -func (m *SigningMethodEd25519) Verify(signingString, signature string, key interface{}) error { - var err error - var ed25519Key ed25519.PublicKey - var ok bool - - if ed25519Key, ok = key.(ed25519.PublicKey); !ok { - return ErrInvalidKeyType - } - - if len(ed25519Key) != ed25519.PublicKeySize { - return ErrInvalidKey - } - - // Decode the signature - var sig []byte - if sig, err = DecodeSegment(signature); err != nil { - return err - } - - // Verify the signature - if !ed25519.Verify(ed25519Key, []byte(signingString), sig) { - return ErrEd25519Verification - } - - return nil -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an ed25519.PrivateKey -func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) { - var ed25519Key crypto.Signer - var ok bool - - if ed25519Key, ok = key.(crypto.Signer); !ok { - return "", ErrInvalidKeyType - } - - if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok { - return "", ErrInvalidKey - } - - // Sign the string and return the encoded result - // ed25519 performs a two-pass hash as part of its algorithm. Therefore, we need to pass a non-prehashed message into the Sign function, as indicated by crypto.Hash(0) - sig, err := ed25519Key.Sign(rand.Reader, []byte(signingString), crypto.Hash(0)) - if err != nil { - return "", err - } - return EncodeSegment(sig), nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v4/ed25519_utils.go deleted file mode 100644 index cdb5e68e87..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/ed25519_utils.go +++ /dev/null @@ -1,64 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/ed25519" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrNotEdPrivateKey = errors.New("key is not a valid Ed25519 private key") - ErrNotEdPublicKey = errors.New("key is not a valid Ed25519 public key") -) - -// ParseEdPrivateKeyFromPEM parses a PEM-encoded Edwards curve private key -func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - - var pkey ed25519.PrivateKey - var ok bool - if pkey, ok = parsedKey.(ed25519.PrivateKey); !ok { - return nil, ErrNotEdPrivateKey - } - - return pkey, nil -} - -// ParseEdPublicKeyFromPEM parses a PEM-encoded Edwards curve public key -func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - return nil, err - } - - var pkey ed25519.PublicKey - var ok bool - if pkey, ok = parsedKey.(ed25519.PublicKey); !ok { - return nil, ErrNotEdPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/errors.go b/vendor/github.com/golang-jwt/jwt/v4/errors.go deleted file mode 100644 index b9d18e498e..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/errors.go +++ /dev/null @@ -1,64 +0,0 @@ -package jwt - -import ( - "errors" -) - -// Error constants -var ( - ErrInvalidKey = errors.New("key is invalid") - ErrInvalidKeyType = errors.New("key is of invalid type") - ErrHashUnavailable = errors.New("the requested hash function is unavailable") -) - -// The errors that might occur when parsing and validating a token -const ( - ValidationErrorMalformed uint32 = 1 << iota // Token is malformed - ValidationErrorUnverifiable // Token could not be verified because of signing problems - ValidationErrorSignatureInvalid // Signature validation failed - - // Standard Claim validation errors - ValidationErrorAudience // AUD validation failed - ValidationErrorExpired // EXP validation failed - ValidationErrorIssuedAt // IAT validation failed - ValidationErrorIssuer // ISS validation failed - ValidationErrorNotValidYet // NBF validation failed - ValidationErrorId // JTI validation failed - ValidationErrorClaimsInvalid // Generic claims validation error -) - -// NewValidationError is a helper for constructing a ValidationError with a string error message -func NewValidationError(errorText string, errorFlags uint32) *ValidationError { - return &ValidationError{ - text: errorText, - Errors: errorFlags, - } -} - -// ValidationError represents an error from Parse if token is not valid -type ValidationError struct { - Inner error // stores the error returned by external dependencies, i.e.: KeyFunc - Errors uint32 // bitfield. see ValidationError... constants - text string // errors that do not have a valid error just have text -} - -// Error is the implementation of the err interface. -func (e ValidationError) Error() string { - if e.Inner != nil { - return e.Inner.Error() - } else if e.text != "" { - return e.text - } else { - return "token is invalid" - } -} - -// Unwrap gives errors.Is and errors.As access to the inner error. -func (e *ValidationError) Unwrap() error { - return e.Inner -} - -// No errors -func (e *ValidationError) valid() bool { - return e.Errors == 0 -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/hmac.go b/vendor/github.com/golang-jwt/jwt/v4/hmac.go deleted file mode 100644 index 011f68a274..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/hmac.go +++ /dev/null @@ -1,95 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/hmac" - "errors" -) - -// SigningMethodHMAC implements the HMAC-SHA family of signing methods. -// Expects key type of []byte for both signing and validation -type SigningMethodHMAC struct { - Name string - Hash crypto.Hash -} - -// Specific instances for HS256 and company -var ( - SigningMethodHS256 *SigningMethodHMAC - SigningMethodHS384 *SigningMethodHMAC - SigningMethodHS512 *SigningMethodHMAC - ErrSignatureInvalid = errors.New("signature is invalid") -) - -func init() { - // HS256 - SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} - RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { - return SigningMethodHS256 - }) - - // HS384 - SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} - RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { - return SigningMethodHS384 - }) - - // HS512 - SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} - RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { - return SigningMethodHS512 - }) -} - -func (m *SigningMethodHMAC) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod. Returns nil if the signature is valid. -func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error { - // Verify the key is the right type - keyBytes, ok := key.([]byte) - if !ok { - return ErrInvalidKeyType - } - - // Decode signature, for comparison - sig, err := DecodeSegment(signature) - if err != nil { - return err - } - - // Can we use the specified hashing method? - if !m.Hash.Available() { - return ErrHashUnavailable - } - - // This signing method is symmetric, so we validate the signature - // by reproducing the signature from the signing string and key, then - // comparing that against the provided signature. - hasher := hmac.New(m.Hash.New, keyBytes) - hasher.Write([]byte(signingString)) - if !hmac.Equal(sig, hasher.Sum(nil)) { - return ErrSignatureInvalid - } - - // No validation errors. Signature is good. - return nil -} - -// Sign implements token signing for the SigningMethod. -// Key must be []byte -func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) { - if keyBytes, ok := key.([]byte); ok { - if !m.Hash.Available() { - return "", ErrHashUnavailable - } - - hasher := hmac.New(m.Hash.New, keyBytes) - hasher.Write([]byte(signingString)) - - return EncodeSegment(hasher.Sum(nil)), nil - } - - return "", ErrInvalidKeyType -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/map_claims.go b/vendor/github.com/golang-jwt/jwt/v4/map_claims.go deleted file mode 100644 index e7da633b93..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/map_claims.go +++ /dev/null @@ -1,148 +0,0 @@ -package jwt - -import ( - "encoding/json" - "errors" - "time" - // "fmt" -) - -// MapClaims is a claims type that uses the map[string]interface{} for JSON decoding. -// This is the default claims type if you don't supply one -type MapClaims map[string]interface{} - -// VerifyAudience Compares the aud claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (m MapClaims) VerifyAudience(cmp string, req bool) bool { - var aud []string - switch v := m["aud"].(type) { - case string: - aud = append(aud, v) - case []string: - aud = v - case []interface{}: - for _, a := range v { - vs, ok := a.(string) - if !ok { - return false - } - aud = append(aud, vs) - } - } - return verifyAud(aud, cmp, req) -} - -// VerifyExpiresAt compares the exp claim against cmp (cmp <= exp). -// If req is false, it will return true, if exp is unset. -func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { - cmpTime := time.Unix(cmp, 0) - - v, ok := m["exp"] - if !ok { - return !req - } - - switch exp := v.(type) { - case float64: - if exp == 0 { - return verifyExp(nil, cmpTime, req) - } - - return verifyExp(&newNumericDateFromSeconds(exp).Time, cmpTime, req) - case json.Number: - v, _ := exp.Float64() - - return verifyExp(&newNumericDateFromSeconds(v).Time, cmpTime, req) - } - - return false -} - -// VerifyIssuedAt compares the exp claim against cmp (cmp >= iat). -// If req is false, it will return true, if iat is unset. -func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { - cmpTime := time.Unix(cmp, 0) - - v, ok := m["iat"] - if !ok { - return !req - } - - switch iat := v.(type) { - case float64: - if iat == 0 { - return verifyIat(nil, cmpTime, req) - } - - return verifyIat(&newNumericDateFromSeconds(iat).Time, cmpTime, req) - case json.Number: - v, _ := iat.Float64() - - return verifyIat(&newNumericDateFromSeconds(v).Time, cmpTime, req) - } - - return false -} - -// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf). -// If req is false, it will return true, if nbf is unset. -func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { - cmpTime := time.Unix(cmp, 0) - - v, ok := m["nbf"] - if !ok { - return !req - } - - switch nbf := v.(type) { - case float64: - if nbf == 0 { - return verifyNbf(nil, cmpTime, req) - } - - return verifyNbf(&newNumericDateFromSeconds(nbf).Time, cmpTime, req) - case json.Number: - v, _ := nbf.Float64() - - return verifyNbf(&newNumericDateFromSeconds(v).Time, cmpTime, req) - } - - return false -} - -// VerifyIssuer compares the iss claim against cmp. -// If required is false, this method will return true if the value matches or is unset -func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { - iss, _ := m["iss"].(string) - return verifyIss(iss, cmp, req) -} - -// Valid validates time based claims "exp, iat, nbf". -// There is no accounting for clock skew. -// As well, if any of the above claims are not in the token, it will still -// be considered a valid claim. -func (m MapClaims) Valid() error { - vErr := new(ValidationError) - now := TimeFunc().Unix() - - if !m.VerifyExpiresAt(now, false) { - vErr.Inner = errors.New("Token is expired") - vErr.Errors |= ValidationErrorExpired - } - - if !m.VerifyIssuedAt(now, false) { - vErr.Inner = errors.New("Token used before issued") - vErr.Errors |= ValidationErrorIssuedAt - } - - if !m.VerifyNotBefore(now, false) { - vErr.Inner = errors.New("Token is not valid yet") - vErr.Errors |= ValidationErrorNotValidYet - } - - if vErr.valid() { - return nil - } - - return vErr -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/none.go b/vendor/github.com/golang-jwt/jwt/v4/none.go deleted file mode 100644 index f19835d207..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/none.go +++ /dev/null @@ -1,52 +0,0 @@ -package jwt - -// SigningMethodNone implements the none signing method. This is required by the spec -// but you probably should never use it. -var SigningMethodNone *signingMethodNone - -const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" - -var NoneSignatureTypeDisallowedError error - -type signingMethodNone struct{} -type unsafeNoneMagicConstant string - -func init() { - SigningMethodNone = &signingMethodNone{} - NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid) - - RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { - return SigningMethodNone - }) -} - -func (m *signingMethodNone) Alg() string { - return "none" -} - -// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key -func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) { - // Key must be UnsafeAllowNoneSignatureType to prevent accidentally - // accepting 'none' signing method - if _, ok := key.(unsafeNoneMagicConstant); !ok { - return NoneSignatureTypeDisallowedError - } - // If signing method is none, signature must be an empty string - if signature != "" { - return NewValidationError( - "'none' signing method with non-empty signature", - ValidationErrorSignatureInvalid, - ) - } - - // Accept 'none' signing method. - return nil -} - -// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key -func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) { - if _, ok := key.(unsafeNoneMagicConstant); ok { - return "", nil - } - return "", NoneSignatureTypeDisallowedError -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/parser.go b/vendor/github.com/golang-jwt/jwt/v4/parser.go deleted file mode 100644 index 2f61a69d7f..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/parser.go +++ /dev/null @@ -1,170 +0,0 @@ -package jwt - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" -) - -type Parser struct { - // If populated, only these methods will be considered valid. - // - // Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead. - ValidMethods []string - - // Use JSON Number format in JSON decoder. - // - // Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead. - UseJSONNumber bool - - // Skip claims validation during token parsing. - // - // Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead. - SkipClaimsValidation bool -} - -// NewParser creates a new Parser with the specified options -func NewParser(options ...ParserOption) *Parser { - p := &Parser{} - - // loop through our parsing options and apply them - for _, option := range options { - option(p) - } - - return p -} - -// Parse parses, validates, verifies the signature and returns the parsed token. -// keyFunc will receive the parsed token and should return the key for validating. -func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { - return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) -} - -func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { - token, parts, err := p.ParseUnverified(tokenString, claims) - if err != nil { - return token, err - } - - // Verify signing method is in the required set - if p.ValidMethods != nil { - var signingMethodValid = false - var alg = token.Method.Alg() - for _, m := range p.ValidMethods { - if m == alg { - signingMethodValid = true - break - } - } - if !signingMethodValid { - // signing method is not in the listed set - return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid) - } - } - - // Lookup key - var key interface{} - if keyFunc == nil { - // keyFunc was not provided. short circuiting validation - return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable) - } - if key, err = keyFunc(token); err != nil { - // keyFunc returned an error - if ve, ok := err.(*ValidationError); ok { - return token, ve - } - return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} - } - - vErr := &ValidationError{} - - // Validate Claims - if !p.SkipClaimsValidation { - if err := token.Claims.Valid(); err != nil { - - // If the Claims Valid returned an error, check if it is a validation error, - // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set - if e, ok := err.(*ValidationError); !ok { - vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} - } else { - vErr = e - } - } - } - - // Perform validation - token.Signature = parts[2] - if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil { - vErr.Inner = err - vErr.Errors |= ValidationErrorSignatureInvalid - } - - if vErr.valid() { - token.Valid = true - return token, nil - } - - return token, vErr -} - -// ParseUnverified parses the token but doesn't validate the signature. -// -// WARNING: Don't use this method unless you know what you're doing. -// -// It's only ever useful in cases where you know the signature is valid (because it has -// been checked previously in the stack) and you want to extract values from it. -func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { - parts = strings.Split(tokenString, ".") - if len(parts) != 3 { - return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) - } - - token = &Token{Raw: tokenString} - - // parse Header - var headerBytes []byte - if headerBytes, err = DecodeSegment(parts[0]); err != nil { - if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { - return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) - } - return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - if err = json.Unmarshal(headerBytes, &token.Header); err != nil { - return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // parse Claims - var claimBytes []byte - token.Claims = claims - - if claimBytes, err = DecodeSegment(parts[1]); err != nil { - return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) - if p.UseJSONNumber { - dec.UseNumber() - } - // JSON Decode. Special case for map type to avoid weird pointer behavior - if c, ok := token.Claims.(MapClaims); ok { - err = dec.Decode(&c) - } else { - err = dec.Decode(&claims) - } - // Handle decode error - if err != nil { - return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} - } - - // Lookup signature method - if method, ok := token.Header["alg"].(string); ok { - if token.Method = GetSigningMethod(method); token.Method == nil { - return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) - } - } else { - return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) - } - - return token, parts, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/parser_option.go b/vendor/github.com/golang-jwt/jwt/v4/parser_option.go deleted file mode 100644 index 0fede4f15c..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/parser_option.go +++ /dev/null @@ -1,29 +0,0 @@ -package jwt - -// ParserOption is used to implement functional-style options that modify the behaviour of the parser. To add -// new options, just create a function (ideally beginning with With or Without) that returns an anonymous function that -// takes a *Parser type as input and manipulates its configuration accordingly. -type ParserOption func(*Parser) - -// WithValidMethods is an option to supply algorithm methods that the parser will check. Only those methods will be considered valid. -// It is heavily encouraged to use this option in order to prevent attacks such as https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. -func WithValidMethods(methods []string) ParserOption { - return func(p *Parser) { - p.ValidMethods = methods - } -} - -// WithJSONNumber is an option to configure the underyling JSON parser with UseNumber -func WithJSONNumber() ParserOption { - return func(p *Parser) { - p.UseJSONNumber = true - } -} - -// WithoutClaimsValidation is an option to disable claims validation. This option should only be used if you exactly know -// what you are doing. -func WithoutClaimsValidation() ParserOption { - return func(p *Parser) { - p.SkipClaimsValidation = true - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/rsa.go b/vendor/github.com/golang-jwt/jwt/v4/rsa.go deleted file mode 100644 index b910b19c0b..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/rsa.go +++ /dev/null @@ -1,101 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" -) - -// SigningMethodRSA implements the RSA family of signing methods. -// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation -type SigningMethodRSA struct { - Name string - Hash crypto.Hash -} - -// Specific instances for RS256 and company -var ( - SigningMethodRS256 *SigningMethodRSA - SigningMethodRS384 *SigningMethodRSA - SigningMethodRS512 *SigningMethodRSA -) - -func init() { - // RS256 - SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} - RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { - return SigningMethodRS256 - }) - - // RS384 - SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} - RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { - return SigningMethodRS384 - }) - - // RS512 - SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} - RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { - return SigningMethodRS512 - }) -} - -func (m *SigningMethodRSA) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod -// For this signing method, must be an *rsa.PublicKey structure. -func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { - var err error - - // Decode the signature - var sig []byte - if sig, err = DecodeSegment(signature); err != nil { - return err - } - - var rsaKey *rsa.PublicKey - var ok bool - - if rsaKey, ok = key.(*rsa.PublicKey); !ok { - return ErrInvalidKeyType - } - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Verify the signature - return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) -} - -// Sign implements token signing for the SigningMethod -// For this signing method, must be an *rsa.PrivateKey structure. -func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { - var rsaKey *rsa.PrivateKey - var ok bool - - // Validate type of key - if rsaKey, ok = key.(*rsa.PrivateKey); !ok { - return "", ErrInvalidKey - } - - // Create the hasher - if !m.Hash.Available() { - return "", ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return the encoded bytes - if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { - return EncodeSegment(sigBytes), nil - } else { - return "", err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v4/rsa_pss.go deleted file mode 100644 index 5a8502feb3..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/rsa_pss.go +++ /dev/null @@ -1,142 +0,0 @@ -// +build go1.4 - -package jwt - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" -) - -// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods -type SigningMethodRSAPSS struct { - *SigningMethodRSA - Options *rsa.PSSOptions - // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS. - // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow - // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously. - // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details. - VerifyOptions *rsa.PSSOptions -} - -// Specific instances for RS/PS and company. -var ( - SigningMethodPS256 *SigningMethodRSAPSS - SigningMethodPS384 *SigningMethodRSAPSS - SigningMethodPS512 *SigningMethodRSAPSS -) - -func init() { - // PS256 - SigningMethodPS256 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS256", - Hash: crypto.SHA256, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { - return SigningMethodPS256 - }) - - // PS384 - SigningMethodPS384 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS384", - Hash: crypto.SHA384, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { - return SigningMethodPS384 - }) - - // PS512 - SigningMethodPS512 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS512", - Hash: crypto.SHA512, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { - return SigningMethodPS512 - }) -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an rsa.PublicKey struct -func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error { - var err error - - // Decode the signature - var sig []byte - if sig, err = DecodeSegment(signature); err != nil { - return err - } - - var rsaKey *rsa.PublicKey - switch k := key.(type) { - case *rsa.PublicKey: - rsaKey = k - default: - return ErrInvalidKey - } - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - opts := m.Options - if m.VerifyOptions != nil { - opts = m.VerifyOptions - } - - return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts) -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an rsa.PrivateKey struct -func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) { - var rsaKey *rsa.PrivateKey - - switch k := key.(type) { - case *rsa.PrivateKey: - rsaKey = k - default: - return "", ErrInvalidKeyType - } - - // Create the hasher - if !m.Hash.Available() { - return "", ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return the encoded bytes - if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { - return EncodeSegment(sigBytes), nil - } else { - return "", err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v4/rsa_utils.go deleted file mode 100644 index 1966c450bf..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/rsa_utils.go +++ /dev/null @@ -1,105 +0,0 @@ -package jwt - -import ( - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key") - ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key") - ErrNotRSAPublicKey = errors.New("key is not a valid RSA public key") -) - -// ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key -func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - var parsedKey interface{} - if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - } - - var pkey *rsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { - return nil, ErrNotRSAPrivateKey - } - - return pkey, nil -} - -// ParseRSAPrivateKeyFromPEMWithPassword parses a PEM encoded PKCS1 or PKCS8 private key protected with password -// -// Deprecated: This function is deprecated and should not be used anymore. It uses the deprecated x509.DecryptPEMBlock -// function, which was deprecated since RFC 1423 is regarded insecure by design. Unfortunately, there is no alternative -// in the Go standard library for now. See https://github.com/golang/go/issues/8860. -func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - var parsedKey interface{} - - var blockDecrypted []byte - if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { - return nil, err - } - - if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { - return nil, err - } - } - - var pkey *rsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { - return nil, ErrNotRSAPrivateKey - } - - return pkey, nil -} - -// ParseRSAPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key -func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - if cert, err := x509.ParseCertificate(block.Bytes); err == nil { - parsedKey = cert.PublicKey - } else { - return nil, err - } - } - - var pkey *rsa.PublicKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { - return nil, ErrNotRSAPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/signing_method.go b/vendor/github.com/golang-jwt/jwt/v4/signing_method.go deleted file mode 100644 index 241ae9c60d..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/signing_method.go +++ /dev/null @@ -1,46 +0,0 @@ -package jwt - -import ( - "sync" -) - -var signingMethods = map[string]func() SigningMethod{} -var signingMethodLock = new(sync.RWMutex) - -// SigningMethod can be used add new methods for signing or verifying tokens. -type SigningMethod interface { - Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid - Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error - Alg() string // returns the alg identifier for this method (example: 'HS256') -} - -// RegisterSigningMethod registers the "alg" name and a factory function for signing method. -// This is typically done during init() in the method's implementation -func RegisterSigningMethod(alg string, f func() SigningMethod) { - signingMethodLock.Lock() - defer signingMethodLock.Unlock() - - signingMethods[alg] = f -} - -// GetSigningMethod retrieves a signing method from an "alg" string -func GetSigningMethod(alg string) (method SigningMethod) { - signingMethodLock.RLock() - defer signingMethodLock.RUnlock() - - if methodF, ok := signingMethods[alg]; ok { - method = methodF() - } - return -} - -// GetAlgorithms returns a list of registered "alg" names -func GetAlgorithms() (algs []string) { - signingMethodLock.RLock() - defer signingMethodLock.RUnlock() - - for alg := range signingMethods { - algs = append(algs, alg) - } - return -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/staticcheck.conf b/vendor/github.com/golang-jwt/jwt/v4/staticcheck.conf deleted file mode 100644 index 53745d51d7..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/staticcheck.conf +++ /dev/null @@ -1 +0,0 @@ -checks = ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1023"] diff --git a/vendor/github.com/golang-jwt/jwt/v4/token.go b/vendor/github.com/golang-jwt/jwt/v4/token.go deleted file mode 100644 index 12344138be..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/token.go +++ /dev/null @@ -1,131 +0,0 @@ -package jwt - -import ( - "encoding/base64" - "encoding/json" - "strings" - "time" -) - - -// DecodePaddingAllowed will switch the codec used for decoding JWTs respectively. Note that the JWS RFC7515 -// states that the tokens will utilize a Base64url encoding with no padding. Unfortunately, some implementations -// of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global -// variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe. -// To use the non-recommended decoding, set this boolean to `true` prior to using this package. -var DecodePaddingAllowed bool - -// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). -// You can override it to use another time value. This is useful for testing or if your -// server uses a different time zone than your tokens. -var TimeFunc = time.Now - -// Keyfunc will be used by the Parse methods as a callback function to supply -// the key for verification. The function receives the parsed, -// but unverified Token. This allows you to use properties in the -// Header of the token (such as `kid`) to identify which key to use. -type Keyfunc func(*Token) (interface{}, error) - -// Token represents a JWT Token. Different fields will be used depending on whether you're -// creating or parsing/verifying a token. -type Token struct { - Raw string // The raw token. Populated when you Parse a token - Method SigningMethod // The signing method used or to be used - Header map[string]interface{} // The first segment of the token - Claims Claims // The second segment of the token - Signature string // The third segment of the token. Populated when you Parse a token - Valid bool // Is the token valid? Populated when you Parse/Verify a token -} - -// New creates a new Token with the specified signing method and an empty map of claims. -func New(method SigningMethod) *Token { - return NewWithClaims(method, MapClaims{}) -} - -// NewWithClaims creates a new Token with the specified signing method and claims. -func NewWithClaims(method SigningMethod, claims Claims) *Token { - return &Token{ - Header: map[string]interface{}{ - "typ": "JWT", - "alg": method.Alg(), - }, - Claims: claims, - Method: method, - } -} - -// SignedString creates and returns a complete, signed JWT. -// The token is signed using the SigningMethod specified in the token. -func (t *Token) SignedString(key interface{}) (string, error) { - var sig, sstr string - var err error - if sstr, err = t.SigningString(); err != nil { - return "", err - } - if sig, err = t.Method.Sign(sstr, key); err != nil { - return "", err - } - return strings.Join([]string{sstr, sig}, "."), nil -} - -// SigningString generates the signing string. This is the -// most expensive part of the whole deal. Unless you -// need this for something special, just go straight for -// the SignedString. -func (t *Token) SigningString() (string, error) { - var err error - parts := make([]string, 2) - for i := range parts { - var jsonValue []byte - if i == 0 { - if jsonValue, err = json.Marshal(t.Header); err != nil { - return "", err - } - } else { - if jsonValue, err = json.Marshal(t.Claims); err != nil { - return "", err - } - } - - parts[i] = EncodeSegment(jsonValue) - } - return strings.Join(parts, "."), nil -} - -// Parse parses, validates, verifies the signature and returns the parsed token. -// keyFunc will receive the parsed token and should return the cryptographic key -// for verifying the signature. -// The caller is strongly encouraged to set the WithValidMethods option to -// validate the 'alg' claim in the token matches the expected algorithm. -// For more details about the importance of validating the 'alg' claim, -// see https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ -func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { - return NewParser(options...).Parse(tokenString, keyFunc) -} - -func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { - return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) -} - -// EncodeSegment encodes a JWT specific base64url encoding with padding stripped -// -// Deprecated: In a future release, we will demote this function to a non-exported function, since it -// should only be used internally -func EncodeSegment(seg []byte) string { - return base64.RawURLEncoding.EncodeToString(seg) -} - -// DecodeSegment decodes a JWT specific base64url encoding with padding stripped -// -// Deprecated: In a future release, we will demote this function to a non-exported function, since it -// should only be used internally -func DecodeSegment(seg string) ([]byte, error) { - if DecodePaddingAllowed { - if l := len(seg) % 4; l > 0 { - seg += strings.Repeat("=", 4-l) - } - return base64.URLEncoding.DecodeString(seg) - } - - return base64.RawURLEncoding.DecodeString(seg) -} diff --git a/vendor/github.com/golang-jwt/jwt/v4/types.go b/vendor/github.com/golang-jwt/jwt/v4/types.go deleted file mode 100644 index 80b1b96948..0000000000 --- a/vendor/github.com/golang-jwt/jwt/v4/types.go +++ /dev/null @@ -1,127 +0,0 @@ -package jwt - -import ( - "encoding/json" - "fmt" - "math" - "reflect" - "strconv" - "time" -) - -// TimePrecision sets the precision of times and dates within this library. -// This has an influence on the precision of times when comparing expiry or -// other related time fields. Furthermore, it is also the precision of times -// when serializing. -// -// For backwards compatibility the default precision is set to seconds, so that -// no fractional timestamps are generated. -var TimePrecision = time.Second - -// MarshalSingleStringAsArray modifies the behaviour of the ClaimStrings type, especially -// its MarshalJSON function. -// -// If it is set to true (the default), it will always serialize the type as an -// array of strings, even if it just contains one element, defaulting to the behaviour -// of the underlying []string. If it is set to false, it will serialize to a single -// string, if it contains one element. Otherwise, it will serialize to an array of strings. -var MarshalSingleStringAsArray = true - -// NumericDate represents a JSON numeric date value, as referenced at -// https://datatracker.ietf.org/doc/html/rfc7519#section-2. -type NumericDate struct { - time.Time -} - -// NewNumericDate constructs a new *NumericDate from a standard library time.Time struct. -// It will truncate the timestamp according to the precision specified in TimePrecision. -func NewNumericDate(t time.Time) *NumericDate { - return &NumericDate{t.Truncate(TimePrecision)} -} - -// newNumericDateFromSeconds creates a new *NumericDate out of a float64 representing a -// UNIX epoch with the float fraction representing non-integer seconds. -func newNumericDateFromSeconds(f float64) *NumericDate { - round, frac := math.Modf(f) - return NewNumericDate(time.Unix(int64(round), int64(frac*1e9))) -} - -// MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch -// represented in NumericDate to a byte array, using the precision specified in TimePrecision. -func (date NumericDate) MarshalJSON() (b []byte, err error) { - f := float64(date.Truncate(TimePrecision).UnixNano()) / float64(time.Second) - - return []byte(strconv.FormatFloat(f, 'f', -1, 64)), nil -} - -// UnmarshalJSON is an implementation of the json.RawMessage interface and deserializses a -// NumericDate from a JSON representation, i.e. a json.Number. This number represents an UNIX epoch -// with either integer or non-integer seconds. -func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { - var ( - number json.Number - f float64 - ) - - if err = json.Unmarshal(b, &number); err != nil { - return fmt.Errorf("could not parse NumericData: %w", err) - } - - if f, err = number.Float64(); err != nil { - return fmt.Errorf("could not convert json number value to float: %w", err) - } - - n := newNumericDateFromSeconds(f) - *date = *n - - return nil -} - -// ClaimStrings is basically just a slice of strings, but it can be either serialized from a string array or just a string. -// This type is necessary, since the "aud" claim can either be a single string or an array. -type ClaimStrings []string - -func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { - var value interface{} - - if err = json.Unmarshal(data, &value); err != nil { - return err - } - - var aud []string - - switch v := value.(type) { - case string: - aud = append(aud, v) - case []string: - aud = ClaimStrings(v) - case []interface{}: - for _, vv := range v { - vs, ok := vv.(string) - if !ok { - return &json.UnsupportedTypeError{Type: reflect.TypeOf(vv)} - } - aud = append(aud, vs) - } - case nil: - return nil - default: - return &json.UnsupportedTypeError{Type: reflect.TypeOf(v)} - } - - *s = aud - - return -} - -func (s ClaimStrings) MarshalJSON() (b []byte, err error) { - // This handles a special case in the JWT RFC. If the string array, e.g. used by the "aud" field, - // only contains one element, it MAY be serialized as a single string. This may or may not be - // desired based on the ecosystem of other JWT library used, so we make it configurable by the - // variable MarshalSingleStringAsArray. - if len(s) == 1 && !MarshalSingleStringAsArray { - return json.Marshal(s[0]) - } - - return json.Marshal([]string(s)) -} diff --git a/vendor/github.com/golang/protobuf/descriptor/descriptor.go b/vendor/github.com/golang/protobuf/descriptor/descriptor.go deleted file mode 100644 index ffde8a6508..0000000000 --- a/vendor/github.com/golang/protobuf/descriptor/descriptor.go +++ /dev/null @@ -1,180 +0,0 @@ -// 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 descriptor provides functions for obtaining the protocol buffer -// descriptors of generated Go types. -// -// Deprecated: See the "google.golang.org/protobuf/reflect/protoreflect" package -// for how to obtain an EnumDescriptor or MessageDescriptor in order to -// programatically interact with the protobuf type system. -package descriptor - -import ( - "bytes" - "compress/gzip" - "io/ioutil" - "sync" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protodesc" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoimpl" - - descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" -) - -// Message is proto.Message with a method to return its descriptor. -// -// Deprecated: The Descriptor method may not be generated by future -// versions of protoc-gen-go, meaning that this interface may not -// be implemented by many concrete message types. -type Message interface { - proto.Message - Descriptor() ([]byte, []int) -} - -// ForMessage returns the file descriptor proto containing -// the message and the message descriptor proto for the message itself. -// The returned proto messages must not be mutated. -// -// Deprecated: Not all concrete message types satisfy the Message interface. -// Use MessageDescriptorProto instead. If possible, the calling code should -// be rewritten to use protobuf reflection instead. -// See package "google.golang.org/protobuf/reflect/protoreflect" for details. -func ForMessage(m Message) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { - return MessageDescriptorProto(m) -} - -type rawDesc struct { - fileDesc []byte - indexes []int -} - -var rawDescCache sync.Map // map[protoreflect.Descriptor]*rawDesc - -func deriveRawDescriptor(d protoreflect.Descriptor) ([]byte, []int) { - // Fast-path: check whether raw descriptors are already cached. - origDesc := d - if v, ok := rawDescCache.Load(origDesc); ok { - return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes - } - - // Slow-path: derive the raw descriptor from the v2 descriptor. - - // Start with the leaf (a given enum or message declaration) and - // ascend upwards until we hit the parent file descriptor. - var idxs []int - for { - idxs = append(idxs, d.Index()) - d = d.Parent() - if d == nil { - // TODO: We could construct a FileDescriptor stub for standalone - // descriptors to satisfy the API. - return nil, nil - } - if _, ok := d.(protoreflect.FileDescriptor); ok { - break - } - } - - // Obtain the raw file descriptor. - fd := d.(protoreflect.FileDescriptor) - b, _ := proto.Marshal(protodesc.ToFileDescriptorProto(fd)) - file := protoimpl.X.CompressGZIP(b) - - // Reverse the indexes, since we populated it in reverse. - for i, j := 0, len(idxs)-1; i < j; i, j = i+1, j-1 { - idxs[i], idxs[j] = idxs[j], idxs[i] - } - - if v, ok := rawDescCache.LoadOrStore(origDesc, &rawDesc{file, idxs}); ok { - return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes - } - return file, idxs -} - -// EnumRawDescriptor returns the GZIP'd raw file descriptor representing -// the enum and the index path to reach the enum declaration. -// The returned slices must not be mutated. -func EnumRawDescriptor(e proto.GeneratedEnum) ([]byte, []int) { - if ev, ok := e.(interface{ EnumDescriptor() ([]byte, []int) }); ok { - return ev.EnumDescriptor() - } - ed := protoimpl.X.EnumTypeOf(e) - return deriveRawDescriptor(ed.Descriptor()) -} - -// MessageRawDescriptor returns the GZIP'd raw file descriptor representing -// the message and the index path to reach the message declaration. -// The returned slices must not be mutated. -func MessageRawDescriptor(m proto.GeneratedMessage) ([]byte, []int) { - if mv, ok := m.(interface{ Descriptor() ([]byte, []int) }); ok { - return mv.Descriptor() - } - md := protoimpl.X.MessageTypeOf(m) - return deriveRawDescriptor(md.Descriptor()) -} - -var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto - -func deriveFileDescriptor(rawDesc []byte) *descriptorpb.FileDescriptorProto { - // Fast-path: check whether descriptor protos are already cached. - if v, ok := fileDescCache.Load(&rawDesc[0]); ok { - return v.(*descriptorpb.FileDescriptorProto) - } - - // Slow-path: derive the descriptor proto from the GZIP'd message. - zr, err := gzip.NewReader(bytes.NewReader(rawDesc)) - if err != nil { - panic(err) - } - b, err := ioutil.ReadAll(zr) - if err != nil { - panic(err) - } - fd := new(descriptorpb.FileDescriptorProto) - if err := proto.Unmarshal(b, fd); err != nil { - panic(err) - } - if v, ok := fileDescCache.LoadOrStore(&rawDesc[0], fd); ok { - return v.(*descriptorpb.FileDescriptorProto) - } - return fd -} - -// EnumDescriptorProto returns the file descriptor proto representing -// the enum and the enum descriptor proto for the enum itself. -// The returned proto messages must not be mutated. -func EnumDescriptorProto(e proto.GeneratedEnum) (*descriptorpb.FileDescriptorProto, *descriptorpb.EnumDescriptorProto) { - rawDesc, idxs := EnumRawDescriptor(e) - if rawDesc == nil || idxs == nil { - return nil, nil - } - fd := deriveFileDescriptor(rawDesc) - if len(idxs) == 1 { - return fd, fd.EnumType[idxs[0]] - } - md := fd.MessageType[idxs[0]] - for _, i := range idxs[1 : len(idxs)-1] { - md = md.NestedType[i] - } - ed := md.EnumType[idxs[len(idxs)-1]] - return fd, ed -} - -// MessageDescriptorProto returns the file descriptor proto representing -// the message and the message descriptor proto for the message itself. -// The returned proto messages must not be mutated. -func MessageDescriptorProto(m proto.GeneratedMessage) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { - rawDesc, idxs := MessageRawDescriptor(m) - if rawDesc == nil || idxs == nil { - return nil, nil - } - fd := deriveFileDescriptor(rawDesc) - md := fd.MessageType[idxs[0]] - for _, i := range idxs[1:] { - md = md.NestedType[i] - } - return fd, md -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go index 60e82caa9a..6c16c255ff 100644 --- a/vendor/github.com/golang/protobuf/jsonpb/decode.go +++ b/vendor/github.com/golang/protobuf/jsonpb/decode.go @@ -386,8 +386,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error } func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { + if fd.Cardinality() == protoreflect.Repeated { + return false + } if md := fd.Message(); md != nil { - return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated + return md.FullName() == "google.protobuf.Value" + } + if ed := fd.Enum(); ed != nil { + return ed.FullName() == "google.protobuf.NullValue" } return false } diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go deleted file mode 100644 index 63dc057851..0000000000 --- a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto - -package descriptor - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/descriptor.proto. - -type FieldDescriptorProto_Type = descriptorpb.FieldDescriptorProto_Type - -const FieldDescriptorProto_TYPE_DOUBLE = descriptorpb.FieldDescriptorProto_TYPE_DOUBLE -const FieldDescriptorProto_TYPE_FLOAT = descriptorpb.FieldDescriptorProto_TYPE_FLOAT -const FieldDescriptorProto_TYPE_INT64 = descriptorpb.FieldDescriptorProto_TYPE_INT64 -const FieldDescriptorProto_TYPE_UINT64 = descriptorpb.FieldDescriptorProto_TYPE_UINT64 -const FieldDescriptorProto_TYPE_INT32 = descriptorpb.FieldDescriptorProto_TYPE_INT32 -const FieldDescriptorProto_TYPE_FIXED64 = descriptorpb.FieldDescriptorProto_TYPE_FIXED64 -const FieldDescriptorProto_TYPE_FIXED32 = descriptorpb.FieldDescriptorProto_TYPE_FIXED32 -const FieldDescriptorProto_TYPE_BOOL = descriptorpb.FieldDescriptorProto_TYPE_BOOL -const FieldDescriptorProto_TYPE_STRING = descriptorpb.FieldDescriptorProto_TYPE_STRING -const FieldDescriptorProto_TYPE_GROUP = descriptorpb.FieldDescriptorProto_TYPE_GROUP -const FieldDescriptorProto_TYPE_MESSAGE = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE -const FieldDescriptorProto_TYPE_BYTES = descriptorpb.FieldDescriptorProto_TYPE_BYTES -const FieldDescriptorProto_TYPE_UINT32 = descriptorpb.FieldDescriptorProto_TYPE_UINT32 -const FieldDescriptorProto_TYPE_ENUM = descriptorpb.FieldDescriptorProto_TYPE_ENUM -const FieldDescriptorProto_TYPE_SFIXED32 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED32 -const FieldDescriptorProto_TYPE_SFIXED64 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED64 -const FieldDescriptorProto_TYPE_SINT32 = descriptorpb.FieldDescriptorProto_TYPE_SINT32 -const FieldDescriptorProto_TYPE_SINT64 = descriptorpb.FieldDescriptorProto_TYPE_SINT64 - -var FieldDescriptorProto_Type_name = descriptorpb.FieldDescriptorProto_Type_name -var FieldDescriptorProto_Type_value = descriptorpb.FieldDescriptorProto_Type_value - -type FieldDescriptorProto_Label = descriptorpb.FieldDescriptorProto_Label - -const FieldDescriptorProto_LABEL_OPTIONAL = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL -const FieldDescriptorProto_LABEL_REQUIRED = descriptorpb.FieldDescriptorProto_LABEL_REQUIRED -const FieldDescriptorProto_LABEL_REPEATED = descriptorpb.FieldDescriptorProto_LABEL_REPEATED - -var FieldDescriptorProto_Label_name = descriptorpb.FieldDescriptorProto_Label_name -var FieldDescriptorProto_Label_value = descriptorpb.FieldDescriptorProto_Label_value - -type FileOptions_OptimizeMode = descriptorpb.FileOptions_OptimizeMode - -const FileOptions_SPEED = descriptorpb.FileOptions_SPEED -const FileOptions_CODE_SIZE = descriptorpb.FileOptions_CODE_SIZE -const FileOptions_LITE_RUNTIME = descriptorpb.FileOptions_LITE_RUNTIME - -var FileOptions_OptimizeMode_name = descriptorpb.FileOptions_OptimizeMode_name -var FileOptions_OptimizeMode_value = descriptorpb.FileOptions_OptimizeMode_value - -type FieldOptions_CType = descriptorpb.FieldOptions_CType - -const FieldOptions_STRING = descriptorpb.FieldOptions_STRING -const FieldOptions_CORD = descriptorpb.FieldOptions_CORD -const FieldOptions_STRING_PIECE = descriptorpb.FieldOptions_STRING_PIECE - -var FieldOptions_CType_name = descriptorpb.FieldOptions_CType_name -var FieldOptions_CType_value = descriptorpb.FieldOptions_CType_value - -type FieldOptions_JSType = descriptorpb.FieldOptions_JSType - -const FieldOptions_JS_NORMAL = descriptorpb.FieldOptions_JS_NORMAL -const FieldOptions_JS_STRING = descriptorpb.FieldOptions_JS_STRING -const FieldOptions_JS_NUMBER = descriptorpb.FieldOptions_JS_NUMBER - -var FieldOptions_JSType_name = descriptorpb.FieldOptions_JSType_name -var FieldOptions_JSType_value = descriptorpb.FieldOptions_JSType_value - -type MethodOptions_IdempotencyLevel = descriptorpb.MethodOptions_IdempotencyLevel - -const MethodOptions_IDEMPOTENCY_UNKNOWN = descriptorpb.MethodOptions_IDEMPOTENCY_UNKNOWN -const MethodOptions_NO_SIDE_EFFECTS = descriptorpb.MethodOptions_NO_SIDE_EFFECTS -const MethodOptions_IDEMPOTENT = descriptorpb.MethodOptions_IDEMPOTENT - -var MethodOptions_IdempotencyLevel_name = descriptorpb.MethodOptions_IdempotencyLevel_name -var MethodOptions_IdempotencyLevel_value = descriptorpb.MethodOptions_IdempotencyLevel_value - -type FileDescriptorSet = descriptorpb.FileDescriptorSet -type FileDescriptorProto = descriptorpb.FileDescriptorProto -type DescriptorProto = descriptorpb.DescriptorProto -type ExtensionRangeOptions = descriptorpb.ExtensionRangeOptions -type FieldDescriptorProto = descriptorpb.FieldDescriptorProto -type OneofDescriptorProto = descriptorpb.OneofDescriptorProto -type EnumDescriptorProto = descriptorpb.EnumDescriptorProto -type EnumValueDescriptorProto = descriptorpb.EnumValueDescriptorProto -type ServiceDescriptorProto = descriptorpb.ServiceDescriptorProto -type MethodDescriptorProto = descriptorpb.MethodDescriptorProto - -const Default_MethodDescriptorProto_ClientStreaming = descriptorpb.Default_MethodDescriptorProto_ClientStreaming -const Default_MethodDescriptorProto_ServerStreaming = descriptorpb.Default_MethodDescriptorProto_ServerStreaming - -type FileOptions = descriptorpb.FileOptions - -const Default_FileOptions_JavaMultipleFiles = descriptorpb.Default_FileOptions_JavaMultipleFiles -const Default_FileOptions_JavaStringCheckUtf8 = descriptorpb.Default_FileOptions_JavaStringCheckUtf8 -const Default_FileOptions_OptimizeFor = descriptorpb.Default_FileOptions_OptimizeFor -const Default_FileOptions_CcGenericServices = descriptorpb.Default_FileOptions_CcGenericServices -const Default_FileOptions_JavaGenericServices = descriptorpb.Default_FileOptions_JavaGenericServices -const Default_FileOptions_PyGenericServices = descriptorpb.Default_FileOptions_PyGenericServices -const Default_FileOptions_PhpGenericServices = descriptorpb.Default_FileOptions_PhpGenericServices -const Default_FileOptions_Deprecated = descriptorpb.Default_FileOptions_Deprecated -const Default_FileOptions_CcEnableArenas = descriptorpb.Default_FileOptions_CcEnableArenas - -type MessageOptions = descriptorpb.MessageOptions - -const Default_MessageOptions_MessageSetWireFormat = descriptorpb.Default_MessageOptions_MessageSetWireFormat -const Default_MessageOptions_NoStandardDescriptorAccessor = descriptorpb.Default_MessageOptions_NoStandardDescriptorAccessor -const Default_MessageOptions_Deprecated = descriptorpb.Default_MessageOptions_Deprecated - -type FieldOptions = descriptorpb.FieldOptions - -const Default_FieldOptions_Ctype = descriptorpb.Default_FieldOptions_Ctype -const Default_FieldOptions_Jstype = descriptorpb.Default_FieldOptions_Jstype -const Default_FieldOptions_Lazy = descriptorpb.Default_FieldOptions_Lazy -const Default_FieldOptions_Deprecated = descriptorpb.Default_FieldOptions_Deprecated -const Default_FieldOptions_Weak = descriptorpb.Default_FieldOptions_Weak - -type OneofOptions = descriptorpb.OneofOptions -type EnumOptions = descriptorpb.EnumOptions - -const Default_EnumOptions_Deprecated = descriptorpb.Default_EnumOptions_Deprecated - -type EnumValueOptions = descriptorpb.EnumValueOptions - -const Default_EnumValueOptions_Deprecated = descriptorpb.Default_EnumValueOptions_Deprecated - -type ServiceOptions = descriptorpb.ServiceOptions - -const Default_ServiceOptions_Deprecated = descriptorpb.Default_ServiceOptions_Deprecated - -type MethodOptions = descriptorpb.MethodOptions - -const Default_MethodOptions_Deprecated = descriptorpb.Default_MethodOptions_Deprecated -const Default_MethodOptions_IdempotencyLevel = descriptorpb.Default_MethodOptions_IdempotencyLevel - -type UninterpretedOption = descriptorpb.UninterpretedOption -type SourceCodeInfo = descriptorpb.SourceCodeInfo -type GeneratedCodeInfo = descriptorpb.GeneratedCodeInfo -type DescriptorProto_ExtensionRange = descriptorpb.DescriptorProto_ExtensionRange -type DescriptorProto_ReservedRange = descriptorpb.DescriptorProto_ReservedRange -type EnumDescriptorProto_EnumReservedRange = descriptorpb.EnumDescriptorProto_EnumReservedRange -type UninterpretedOption_NamePart = descriptorpb.UninterpretedOption_NamePart -type SourceCodeInfo_Location = descriptorpb.SourceCodeInfo_Location -type GeneratedCodeInfo_Annotation = descriptorpb.GeneratedCodeInfo_Annotation - -var File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = []byte{ - 0x0a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, - 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x32, -} - -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() } -func file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() { - if File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto = out.File - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = nil - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = nil - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go deleted file mode 100644 index cc40f27ad3..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/wrappers/wrappers.proto - -package wrappers - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/wrappers.proto. - -type DoubleValue = wrapperspb.DoubleValue -type FloatValue = wrapperspb.FloatValue -type Int64Value = wrapperspb.Int64Value -type UInt64Value = wrapperspb.UInt64Value -type Int32Value = wrapperspb.Int32Value -type UInt32Value = wrapperspb.UInt32Value -type BoolValue = wrapperspb.BoolValue -type StringValue = wrapperspb.StringValue -type BytesValue = wrapperspb.BytesValue - -var File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = []byte{ - 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2f, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x3b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x73, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() } -func file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() { - if File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto = out.File - file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = nil -} diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go index 672c83ef71..6219a4da58 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/github.com/google/cel-go/cel/program.go @@ -213,7 +213,10 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) { factory := func(state interpreter.EvalState, costTracker *interpreter.CostTracker) (Program, error) { costTracker.Estimator = p.callCostEstimator costTracker.Limit = p.costLimit - decs := decorators + // Limit capacity to guarantee a reallocation when calling 'append(decs, ...)' below. This + // prevents the underlying memory from being shared between factory function calls causing + // undesired mutations. + decs := decorators[:len(decorators):len(decorators)] var observers []interpreter.EvalObserver if p.evalOpts&(OptExhaustiveEval|OptTrackState) != 0 { diff --git a/vendor/github.com/google/gnostic/jsonschema/display.go b/vendor/github.com/google/gnostic/jsonschema/display.go index 028a760a91..8677ed49a0 100644 --- a/vendor/github.com/google/gnostic/jsonschema/display.go +++ b/vendor/github.com/google/gnostic/jsonschema/display.go @@ -46,8 +46,23 @@ func (schema *Schema) describeSchema(indent string) string { if schema.Schema != nil { result += indent + "$schema: " + *(schema.Schema) + "\n" } + if schema.ReadOnly != nil && *schema.ReadOnly { + result += indent + fmt.Sprintf("readOnly: %+v\n", *(schema.ReadOnly)) + } + if schema.WriteOnly != nil && *schema.WriteOnly { + result += indent + fmt.Sprintf("writeOnly: %+v\n", *(schema.WriteOnly)) + } if schema.ID != nil { - result += indent + "id: " + *(schema.ID) + "\n" + switch strings.TrimSuffix(*schema.Schema, "#") { + case "http://json-schema.org/draft-04/schema#": + fallthrough + case "#": + fallthrough + case "": + result += indent + "id: " + *(schema.ID) + "\n" + default: + result += indent + "$id: " + *(schema.ID) + "\n" + } } if schema.MultipleOf != nil { result += indent + fmt.Sprintf("multipleOf: %+v\n", *(schema.MultipleOf)) diff --git a/vendor/github.com/google/gnostic/jsonschema/models.go b/vendor/github.com/google/gnostic/jsonschema/models.go index 4781bdc5f5..0d877249ab 100644 --- a/vendor/github.com/google/gnostic/jsonschema/models.go +++ b/vendor/github.com/google/gnostic/jsonschema/models.go @@ -23,9 +23,11 @@ import "gopkg.in/yaml.v3" // All fields are pointers and are nil if the associated values // are not specified. type Schema struct { - Schema *string // $schema - ID *string // id keyword used for $ref resolution scope - Ref *string // $ref, i.e. JSON Pointers + Schema *string // $schema + ID *string // id keyword used for $ref resolution scope + Ref *string // $ref, i.e. JSON Pointers + ReadOnly *bool + WriteOnly *bool // http://json-schema.org/latest/json-schema-validation.html // 5.1. Validation keywords for numeric instances (number and integer) diff --git a/vendor/github.com/google/gnostic/jsonschema/reader.go b/vendor/github.com/google/gnostic/jsonschema/reader.go index b8583d4660..a909a34128 100644 --- a/vendor/github.com/google/gnostic/jsonschema/reader.go +++ b/vendor/github.com/google/gnostic/jsonschema/reader.go @@ -165,7 +165,6 @@ func NewSchemaFromObject(jsonData *yaml.Node) *Schema { default: fmt.Printf("schemaValue: unexpected node %+v\n", jsonData) - return nil } return nil diff --git a/vendor/github.com/google/gnostic/jsonschema/writer.go b/vendor/github.com/google/gnostic/jsonschema/writer.go index 340dc5f933..15b1f90506 100644 --- a/vendor/github.com/google/gnostic/jsonschema/writer.go +++ b/vendor/github.com/google/gnostic/jsonschema/writer.go @@ -16,6 +16,7 @@ package jsonschema import ( "fmt" + "strings" "gopkg.in/yaml.v3" ) @@ -33,7 +34,11 @@ func renderMappingNode(node *yaml.Node, indent string) (result string) { value := node.Content[i+1] switch value.Kind { case yaml.ScalarNode: - result += "\"" + value.Value + "\"" + if value.Tag == "!!bool" { + result += value.Value + } else { + result += "\"" + value.Value + "\"" + } case yaml.MappingNode: result += renderMappingNode(value, innerIndent) case yaml.SequenceNode: @@ -58,7 +63,11 @@ func renderSequenceNode(node *yaml.Node, indent string) (result string) { item := node.Content[i] switch item.Kind { case yaml.ScalarNode: - result += innerIndent + "\"" + item.Value + "\"" + if item.Tag == "!!bool" { + result += innerIndent + item.Value + } else { + result += innerIndent + "\"" + item.Value + "\"" + } case yaml.MappingNode: result += innerIndent + renderMappingNode(item, innerIndent) + "" default: @@ -260,11 +269,26 @@ func (schema *Schema) nodeValue() *yaml.Node { content = appendPair(content, "title", nodeForString(*schema.Title)) } if schema.ID != nil { - content = appendPair(content, "id", nodeForString(*schema.ID)) + switch strings.TrimSuffix(*schema.Schema, "#") { + case "http://json-schema.org/draft-04/schema": + fallthrough + case "#": + fallthrough + case "": + content = appendPair(content, "id", nodeForString(*schema.ID)) + default: + content = appendPair(content, "$id", nodeForString(*schema.ID)) + } } if schema.Schema != nil { content = appendPair(content, "$schema", nodeForString(*schema.Schema)) } + if schema.ReadOnly != nil && *schema.ReadOnly { + content = appendPair(content, "readOnly", nodeForBoolean(*schema.ReadOnly)) + } + if schema.WriteOnly != nil && *schema.WriteOnly { + content = appendPair(content, "writeOnly", nodeForBoolean(*schema.WriteOnly)) + } if schema.Type != nil { content = appendPair(content, "type", schema.Type.nodeValue()) } diff --git a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go b/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go index 0f17907667..28c2777d51 100644 --- a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go +++ b/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go @@ -7887,7 +7887,12 @@ func (m *Oauth2Scopes) ToRawInfo() *yaml.Node { if m == nil { return info } - // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} + if m.AdditionalProperties != nil { + for _, item := range m.AdditionalProperties { + info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name)) + info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Value)) + } + } return info } diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go index 5f4a7025ea..d54a84db7c 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go @@ -8560,7 +8560,12 @@ func (m *Strings) ToRawInfo() *yaml.Node { if m == nil { return info } - // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} + if m.AdditionalProperties != nil { + for _, item := range m.AdditionalProperties { + info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name)) + info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Value)) + } + } return info } diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go index 499e7f932d..90a56f5526 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go @@ -16,8 +16,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.18.1 +// protoc-gen-go v1.28.0 +// protoc v3.19.4 // source: openapiv3/OpenAPIv3.proto package openapi_v3 @@ -6760,12 +6760,13 @@ var file_openapiv3_OpenAPIv3_proto_rawDesc = []byte{ 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x56, 0x0a, 0x0e, 0x6f, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, - 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, + 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto index 1be335b89b..7aede5ed90 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto @@ -42,7 +42,7 @@ option java_package = "org.openapi_v3"; option objc_class_prefix = "OAS"; // The Go package name. -option go_package = "./openapiv3;openapi_v3"; +option go_package = "github.com/google/gnostic/openapiv3;openapi_v3"; message AdditionalPropertiesItem { oneof oneof { diff --git a/vendor/github.com/google/gnostic/openapiv3/README.md b/vendor/github.com/google/gnostic/openapiv3/README.md index 5ee12d92e2..83603b82aa 100644 --- a/vendor/github.com/google/gnostic/openapiv3/README.md +++ b/vendor/github.com/google/gnostic/openapiv3/README.md @@ -19,3 +19,7 @@ for OpenAPI. The schema-generator directory contains support code which generates openapi-3.1.json from the OpenAPI 3.1 specification document (Markdown). + +### How to rebuild + +`protoc -I=. -I=third_party --go_out=. --go_opt=paths=source_relative openapiv3/*.proto` \ No newline at end of file diff --git a/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go b/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go new file mode 100644 index 0000000000..ae242f3043 --- /dev/null +++ b/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go @@ -0,0 +1,183 @@ +// Copyright 2022 Google LLC. All Rights Reserved. +// +// 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.19.4 +// source: openapiv3/annotations.proto + +package openapi_v3 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_openapiv3_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*Document)(nil), + Field: 1143, + Name: "openapi.v3.document", + Tag: "bytes,1143,opt,name=document", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*Operation)(nil), + Field: 1143, + Name: "openapi.v3.operation", + Tag: "bytes,1143,opt,name=operation", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*Schema)(nil), + Field: 1143, + Name: "openapi.v3.schema", + Tag: "bytes,1143,opt,name=schema", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*Schema)(nil), + Field: 1143, + Name: "openapi.v3.property", + Tag: "bytes,1143,opt,name=property", + Filename: "openapiv3/annotations.proto", + }, +} + +// Extension fields to descriptorpb.FileOptions. +var ( + // optional openapi.v3.Document document = 1143; + E_Document = &file_openapiv3_annotations_proto_extTypes[0] +) + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional openapi.v3.Operation operation = 1143; + E_Operation = &file_openapiv3_annotations_proto_extTypes[1] +) + +// Extension fields to descriptorpb.MessageOptions. +var ( + // optional openapi.v3.Schema schema = 1143; + E_Schema = &file_openapiv3_annotations_proto_extTypes[2] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // optional openapi.v3.Schema property = 1143; + E_Property = &file_openapiv3_annotations_proto_extTypes[3] +) + +var File_openapiv3_annotations_proto protoreflect.FileDescriptor + +var file_openapiv3_annotations_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, + 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x1a, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x61, + 0x70, 0x69, 0x76, 0x33, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x76, 0x33, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x4f, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x54, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, + 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x4e, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x42, 0x5a, 0x0a, 0x0e, 0x6f, + 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x10, 0x41, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x6f, 0x70, 0x65, + 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, + 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_openapiv3_annotations_proto_goTypes = []interface{}{ + (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions + (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions + (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions + (*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions + (*Document)(nil), // 4: openapi.v3.Document + (*Operation)(nil), // 5: openapi.v3.Operation + (*Schema)(nil), // 6: openapi.v3.Schema +} +var file_openapiv3_annotations_proto_depIdxs = []int32{ + 0, // 0: openapi.v3.document:extendee -> google.protobuf.FileOptions + 1, // 1: openapi.v3.operation:extendee -> google.protobuf.MethodOptions + 2, // 2: openapi.v3.schema:extendee -> google.protobuf.MessageOptions + 3, // 3: openapi.v3.property:extendee -> google.protobuf.FieldOptions + 4, // 4: openapi.v3.document:type_name -> openapi.v3.Document + 5, // 5: openapi.v3.operation:type_name -> openapi.v3.Operation + 6, // 6: openapi.v3.schema:type_name -> openapi.v3.Schema + 6, // 7: openapi.v3.property:type_name -> openapi.v3.Schema + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 4, // [4:8] is the sub-list for extension type_name + 0, // [0:4] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_openapiv3_annotations_proto_init() } +func file_openapiv3_annotations_proto_init() { + if File_openapiv3_annotations_proto != nil { + return + } + file_openapiv3_OpenAPIv3_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_openapiv3_annotations_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 4, + NumServices: 0, + }, + GoTypes: file_openapiv3_annotations_proto_goTypes, + DependencyIndexes: file_openapiv3_annotations_proto_depIdxs, + ExtensionInfos: file_openapiv3_annotations_proto_extTypes, + }.Build() + File_openapiv3_annotations_proto = out.File + file_openapiv3_annotations_proto_rawDesc = nil + file_openapiv3_annotations_proto_goTypes = nil + file_openapiv3_annotations_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/gnostic/openapiv3/annotations.proto b/vendor/github.com/google/gnostic/openapiv3/annotations.proto new file mode 100644 index 0000000000..0bd87810db --- /dev/null +++ b/vendor/github.com/google/gnostic/openapiv3/annotations.proto @@ -0,0 +1,60 @@ +// Copyright 2022 Google LLC. All Rights Reserved. +// +// 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. + +syntax = "proto3"; + +package openapi.v3; + +import "openapiv3/OpenAPIv3.proto"; +import "google/protobuf/descriptor.proto"; + +// This option lets the proto compiler generate Java code inside the package +// name (see below) instead of inside an outer class. It creates a simpler +// developer experience by reducing one-level of name nesting and be +// consistent with most programming languages that don't support outer classes. +option java_multiple_files = true; + +// The Java outer classname should be the filename in UpperCamelCase. This +// class is only used to hold proto descriptor, so developers don't need to +// work with it directly. +option java_outer_classname = "AnnotationsProto"; + +// The Java package name must be proto package name with proper prefix. +option java_package = "org.openapi_v3"; + +// A reasonable prefix for the Objective-C symbols generated from the package. +// It should at a minimum be 3 characters long, all uppercase, and convention +// is to use an abbreviation of the package name. Something short, but +// hopefully unique enough to not conflict with things that may come along in +// the future. 'GPB' is reserved for the protocol buffer implementation itself. +option objc_class_prefix = "OAS"; + +// The Go package name. +option go_package = "github.com/google/gnostic/openapiv3;openapi_v3"; + +extend google.protobuf.FileOptions { + Document document = 1143; +} + +extend google.protobuf.MethodOptions { + Operation operation = 1143; +} + +extend google.protobuf.MessageOptions { + Schema schema = 1143; +} + +extend google.protobuf.FieldOptions { + Schema property = 1143; +} \ No newline at end of file diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index fd2b3a42b2..087320da7f 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -13,21 +13,21 @@ // // The primary features of cmp are: // -// • When the default behavior of equality does not suit the needs of the test, -// custom equality functions can override the equality operation. -// For example, an equality function may report floats as equal so long as they -// are within some tolerance of each other. +// - When the default behavior of equality does not suit the test's needs, +// custom equality functions can override the equality operation. +// For example, an equality function may report floats as equal so long as +// they are within some tolerance of each other. // -// • Types that have an Equal method may use that method to determine equality. -// This allows package authors to determine the equality operation for the types -// that they define. +// - Types with an Equal method may use that method to determine equality. +// This allows package authors to determine the equality operation +// for the types that they define. // -// • If no custom equality functions are used and no Equal method is defined, -// equality is determined by recursively comparing the primitive kinds on both -// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported -// fields are not compared by default; they result in panics unless suppressed -// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly -// compared using the Exporter option. +// - If no custom equality functions are used and no Equal method is defined, +// equality is determined by recursively comparing the primitive kinds on +// both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, +// unexported fields are not compared by default; they result in panics +// unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported) +// or explicitly compared using the Exporter option. package cmp import ( @@ -45,25 +45,25 @@ import ( // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // -// • Let S be the set of all Ignore, Transformer, and Comparer options that -// remain after applying all path filters, value filters, and type filters. -// If at least one Ignore exists in S, then the comparison is ignored. -// If the number of Transformer and Comparer options in S is greater than one, -// then Equal panics because it is ambiguous which option to use. -// If S contains a single Transformer, then use that to transform the current -// values and recursively call Equal on the output values. -// If S contains a single Comparer, then use that to compare the current values. -// Otherwise, evaluation proceeds to the next rule. +// - Let S be the set of all Ignore, Transformer, and Comparer options that +// remain after applying all path filters, value filters, and type filters. +// If at least one Ignore exists in S, then the comparison is ignored. +// If the number of Transformer and Comparer options in S is non-zero, +// then Equal panics because it is ambiguous which option to use. +// If S contains a single Transformer, then use that to transform +// the current values and recursively call Equal on the output values. +// If S contains a single Comparer, then use that to compare the current values. +// Otherwise, evaluation proceeds to the next rule. // -// • If the values have an Equal method of the form "(T) Equal(T) bool" or -// "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and -// evaluation proceeds to the next rule. +// - If the values have an Equal method of the form "(T) Equal(T) bool" or +// "(T) Equal(I) bool" where T is assignable to I, then use the result of +// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and +// evaluation proceeds to the next rule. // -// • Lastly, try to compare x and y based on their basic kinds. -// Simple kinds like booleans, integers, floats, complex numbers, strings, and -// channels are compared using the equivalent of the == operator in Go. -// Functions are only equal if they are both nil, otherwise they are unequal. +// - Lastly, try to compare x and y based on their basic kinds. +// Simple kinds like booleans, integers, floats, complex numbers, strings, +// and channels are compared using the equivalent of the == operator in Go. +// Functions are only equal if they are both nil, otherwise they are unequal. // // Structs are equal if recursively calling Equal on all fields report equal. // If a struct contains unexported fields, Equal panics unless an Ignore option @@ -144,7 +144,7 @@ func rootStep(x, y interface{}) PathStep { // so that they have the same parent type. var t reflect.Type if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { - t = reflect.TypeOf((*interface{})(nil)).Elem() + t = anyType if vx.IsValid() { vvx := reflect.New(t).Elem() vvx.Set(vx) @@ -639,7 +639,9 @@ type dynChecker struct{ curr, next int } // Next increments the state and reports whether a check should be performed. // // Checks occur every Nth function call, where N is a triangular number: +// // 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... +// // See https://en.wikipedia.org/wiki/Triangular_number // // This sequence ensures that the cost of checks drops significantly as diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go index bc196b16cf..a248e5436d 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -127,9 +127,9 @@ var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 // This function returns an edit-script, which is a sequence of operations // needed to convert one list into the other. The following invariants for // the edit-script are maintained: -// • eq == (es.Dist()==0) -// • nx == es.LenX() -// • ny == es.LenY() +// - eq == (es.Dist()==0) +// - nx == es.LenX() +// - ny == es.LenY() // // This algorithm is not guaranteed to be an optimal solution (i.e., one that // produces an edit-script with a minimal Levenshtein distance). This algorithm @@ -169,12 +169,13 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // A diagonal edge is equivalent to a matching symbol between both X and Y. // Invariants: - // • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx - // • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny + // - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx + // - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny // // In general: - // • fwdFrontier.X < revFrontier.X - // • fwdFrontier.Y < revFrontier.Y + // - fwdFrontier.X < revFrontier.X + // - fwdFrontier.Y < revFrontier.Y + // // Unless, it is time for the algorithm to terminate. fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} revPath := path{-1, point{nx, ny}, make(EditScript, 0)} @@ -195,19 +196,21 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) { // computing sub-optimal edit-scripts between two lists. // // The algorithm is approximately as follows: - // • Searching for differences switches back-and-forth between - // a search that starts at the beginning (the top-left corner), and - // a search that starts at the end (the bottom-right corner). The goal of - // the search is connect with the search from the opposite corner. - // • As we search, we build a path in a greedy manner, where the first - // match seen is added to the path (this is sub-optimal, but provides a - // decent result in practice). When matches are found, we try the next pair - // of symbols in the lists and follow all matches as far as possible. - // • When searching for matches, we search along a diagonal going through - // through the "frontier" point. If no matches are found, we advance the - // frontier towards the opposite corner. - // • This algorithm terminates when either the X coordinates or the - // Y coordinates of the forward and reverse frontier points ever intersect. + // - Searching for differences switches back-and-forth between + // a search that starts at the beginning (the top-left corner), and + // a search that starts at the end (the bottom-right corner). + // The goal of the search is connect with the search + // from the opposite corner. + // - As we search, we build a path in a greedy manner, + // where the first match seen is added to the path (this is sub-optimal, + // but provides a decent result in practice). When matches are found, + // we try the next pair of symbols in the lists and follow all matches + // as far as possible. + // - When searching for matches, we search along a diagonal going through + // through the "frontier" point. If no matches are found, + // we advance the frontier towards the opposite corner. + // - This algorithm terminates when either the X coordinates or the + // Y coordinates of the forward and reverse frontier points ever intersect. // This algorithm is correct even if searching only in the forward direction // or in the reverse direction. We do both because it is commonly observed @@ -389,6 +392,7 @@ type point struct{ X, Y int } func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } // zigzag maps a consecutive sequence of integers to a zig-zag sequence. +// // [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] func zigzag(x int) int { if x&1 != 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go deleted file mode 100644 index 9147a29973..0000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017, 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 value - -import ( - "math" - "reflect" -) - -// IsZero reports whether v is the zero value. -// This does not rely on Interface and so can be used on unexported fields. -func IsZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return v.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return math.Float64bits(v.Float()) == 0 - case reflect.Complex64, reflect.Complex128: - return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0 - case reflect.String: - return v.String() == "" - case reflect.UnsafePointer: - return v.Pointer() == 0 - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !IsZero(v.Index(i)) { - return false - } - } - return true - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !IsZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go index e57b9eb539..1f9ca9c489 100644 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -33,6 +33,7 @@ type Option interface { } // applicableOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Grouping: Options type applicableOption interface { @@ -43,6 +44,7 @@ type applicableOption interface { } // coreOption represents the following types: +// // Fundamental: ignore | validator | *comparer | *transformer // Filters: *pathFilter | *valuesFilter type coreOption interface { @@ -336,9 +338,9 @@ func (tr transformer) String() string { // both implement T. // // The equality function must be: -// • Symmetric: equal(x, y) == equal(y, x) -// • Deterministic: equal(x, y) == equal(x, y) -// • Pure: equal(x, y) does not modify x or y +// - Symmetric: equal(x, y) == equal(y, x) +// - Deterministic: equal(x, y) == equal(x, y) +// - Pure: equal(x, y) does not modify x or y func Comparer(f interface{}) Option { v := reflect.ValueOf(f) if !function.IsType(v.Type(), function.Equal) || v.IsNil() { @@ -430,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option { } // Result represents the comparison result for a single node and -// is provided by cmp when calling Result (see Reporter). +// is provided by cmp when calling Report (see Reporter). type Result struct { _ [0]func() // Make Result incomparable flags resultFlags diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index c710034632..a0a588502e 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -41,13 +41,13 @@ type PathStep interface { // The type of each valid value is guaranteed to be identical to Type. // // In some cases, one or both may be invalid or have restrictions: - // • For StructField, both are not interface-able if the current field - // is unexported and the struct type is not explicitly permitted by - // an Exporter to traverse unexported fields. - // • For SliceIndex, one may be invalid if an element is missing from - // either the x or y slice. - // • For MapIndex, one may be invalid if an entry is missing from - // either the x or y map. + // - For StructField, both are not interface-able if the current field + // is unexported and the struct type is not explicitly permitted by + // an Exporter to traverse unexported fields. + // - For SliceIndex, one may be invalid if an element is missing from + // either the x or y slice. + // - For MapIndex, one may be invalid if an entry is missing from + // either the x or y map. // // The provided values must not be mutated. Values() (vx, vy reflect.Value) @@ -94,6 +94,7 @@ func (pa Path) Index(i int) PathStep { // The simplified path only contains struct field accesses. // // For example: +// // MyMap.MySlices.MyField func (pa Path) String() string { var ss []string @@ -108,6 +109,7 @@ func (pa Path) String() string { // GoString returns the path to a specific node using Go syntax. // // For example: +// // (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField func (pa Path) GoString() string { var ssPre, ssPost []string @@ -159,7 +161,7 @@ func (ps pathStep) String() string { if ps.typ == nil { return "" } - s := ps.typ.String() + s := value.TypeString(ps.typ, false) if s == "" || strings.ContainsAny(s, "{}\n") { return "root" // Type too simple or complex to print } @@ -282,7 +284,7 @@ type typeAssertion struct { func (ta TypeAssertion) Type() reflect.Type { return ta.typ } func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } -func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } +func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } // Transform is a transformation from the parent type to the current type. type Transform struct{ *transform } diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go index 1ef65ac1db..2050bf6b46 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_compare.go +++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go @@ -7,8 +7,6 @@ package cmp import ( "fmt" "reflect" - - "github.com/google/go-cmp/cmp/internal/value" ) // numContextRecords is the number of surrounding equal records to print. @@ -117,7 +115,7 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out // For leaf nodes, format the value based on the reflect.Values alone. // As a special case, treat equal []byte as a leaf nodes. - isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == reflect.TypeOf(byte(0)) + isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 if v.MaxDepth == 0 || isEqualBytes { switch opts.DiffMode { @@ -248,11 +246,11 @@ func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, pt var isZero bool switch opts.DiffMode { case diffIdentical: - isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero() case diffRemoved: - isZero = value.IsZero(r.Value.ValueX) + isZero = r.Value.ValueX.IsZero() case diffInserted: - isZero = value.IsZero(r.Value.ValueY) + isZero = r.Value.ValueY.IsZero() } if isZero { continue diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go index 287b893588..2ab41fad3f 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -16,6 +16,13 @@ import ( "github.com/google/go-cmp/cmp/internal/value" ) +var ( + anyType = reflect.TypeOf((*interface{})(nil)).Elem() + stringType = reflect.TypeOf((*string)(nil)).Elem() + bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() + byteType = reflect.TypeOf((*byte)(nil)).Elem() +) + type formatValueOptions struct { // AvoidStringer controls whether to avoid calling custom stringer // methods like error.Error or fmt.Stringer.String. @@ -184,7 +191,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } for i := 0; i < v.NumField(); i++ { vv := v.Field(i) - if value.IsZero(vv) { + if vv.IsZero() { continue // Elide fields with zero values } if len(list) == maxLen { @@ -205,7 +212,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } // Check whether this is a []byte of text data. - if t.Elem() == reflect.TypeOf(byte(0)) { + if t.Elem() == byteType { b := v.Bytes() isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go index 68b5c1ae16..23e444f62f 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_slices.go +++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go @@ -104,7 +104,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { case t.Kind() == reflect.String: sx, sy = vx.String(), vy.String() isString = true - case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)): + case t.Kind() == reflect.Slice && t.Elem() == byteType: sx, sy = string(vx.Bytes()), string(vy.Bytes()) isString = true case t.Kind() == reflect.Array: @@ -147,7 +147,10 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { }) efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) - isPureLinedText = efficiencyLines < 4*efficiencyBytes + quotedLength := len(strconv.Quote(sx + sy)) + unquotedLength := len(sx) + len(sy) + escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength) + isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1 } } @@ -171,12 +174,13 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { // differences in a string literal. This format is more readable, // but has edge-cases where differences are visually indistinguishable. // This format is avoided under the following conditions: - // • A line starts with `"""` - // • A line starts with "..." - // • A line contains non-printable characters - // • Adjacent different lines differ only by whitespace + // - A line starts with `"""` + // - A line starts with "..." + // - A line contains non-printable characters + // - Adjacent different lines differ only by whitespace // // For example: + // // """ // ... // 3 identical lines // foo @@ -231,7 +235,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} switch t.Kind() { case reflect.String: - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: @@ -326,12 +330,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { switch t.Kind() { case reflect.String: out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf(string("")) { + if t != stringType { out = opts.FormatType(t, out) } case reflect.Slice: out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != reflect.TypeOf([]byte(nil)) { + if t != bytesType { out = opts.FormatType(t, out) } } @@ -446,7 +450,6 @@ func (opts formatOptions) formatDiffSlice( // {NumIdentical: 3}, // {NumInserted: 1}, // ] -// func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { var prevMode byte lastStats := func(mode byte) *diffStats { @@ -503,7 +506,6 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) // {NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, // {NumIdentical: 63}, // ] -// func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { groups, groupsOrig := groups[:0], groups for i, ds := range groupsOrig { @@ -548,7 +550,6 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat // {NumRemoved: 9}, // {NumIdentical: 64}, // incremented by 10 // ] -// func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { var ix, iy int // indexes into sequence x and y for i, ds := range groups { diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go index 0fd46d7ffb..388fcf5712 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_text.go +++ b/vendor/github.com/google/go-cmp/cmp/report_text.go @@ -393,6 +393,7 @@ func (s diffStats) Append(ds diffStats) diffStats { // String prints a humanly-readable summary of coalesced records. // // Example: +// // diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" func (s diffStats) String() string { var ss []string diff --git a/vendor/github.com/google/pprof/profile/encode.go b/vendor/github.com/google/pprof/profile/encode.go index ab7f03ae26..c8a1beb8a8 100644 --- a/vendor/github.com/google/pprof/profile/encode.go +++ b/vendor/github.com/google/pprof/profile/encode.go @@ -17,6 +17,7 @@ package profile import ( "errors" "sort" + "strings" ) func (p *Profile) decoder() []decoder { @@ -183,12 +184,13 @@ var profileDecoder = []decoder{ // repeated Location location = 4 func(b *buffer, m message) error { x := new(Location) - x.Line = make([]Line, 0, 8) // Pre-allocate Line buffer + x.Line = b.tmpLines[:0] // Use shared space temporarily pp := m.(*Profile) pp.Location = append(pp.Location, x) err := decodeMessage(b, x) - var tmp []Line - x.Line = append(tmp, x.Line...) // Shrink to allocated size + b.tmpLines = x.Line[:0] + // Copy to shrink size and detach from shared space. + x.Line = append([]Line(nil), x.Line...) return err }, // repeated Function function = 5 @@ -252,6 +254,14 @@ func (p *Profile) postDecode() error { } else { mappings[m.ID] = m } + + // If this a main linux kernel mapping with a relocation symbol suffix + // ("[kernel.kallsyms]_text"), extract said suffix. + // It is fairly hacky to handle at this level, but the alternatives appear even worse. + if strings.HasPrefix(m.File, "[kernel.kallsyms]") { + m.KernelRelocationSymbol = strings.ReplaceAll(m.File, "[kernel.kallsyms]", "") + } + } functions := make(map[uint64]*Function, len(p.Function)) @@ -298,41 +308,52 @@ func (p *Profile) postDecode() error { st.Unit, err = getString(p.stringTable, &st.unitX, err) } + // Pre-allocate space for all locations. + numLocations := 0 + for _, s := range p.Sample { + numLocations += len(s.locationIDX) + } + locBuffer := make([]*Location, numLocations) + for _, s := range p.Sample { - labels := make(map[string][]string, len(s.labelX)) - numLabels := make(map[string][]int64, len(s.labelX)) - numUnits := make(map[string][]string, len(s.labelX)) - for _, l := range s.labelX { - var key, value string - key, err = getString(p.stringTable, &l.keyX, err) - if l.strX != 0 { - value, err = getString(p.stringTable, &l.strX, err) - labels[key] = append(labels[key], value) - } else if l.numX != 0 || l.unitX != 0 { - numValues := numLabels[key] - units := numUnits[key] - if l.unitX != 0 { - var unit string - unit, err = getString(p.stringTable, &l.unitX, err) - units = padStringArray(units, len(numValues)) - numUnits[key] = append(units, unit) + if len(s.labelX) > 0 { + labels := make(map[string][]string, len(s.labelX)) + numLabels := make(map[string][]int64, len(s.labelX)) + numUnits := make(map[string][]string, len(s.labelX)) + for _, l := range s.labelX { + var key, value string + key, err = getString(p.stringTable, &l.keyX, err) + if l.strX != 0 { + value, err = getString(p.stringTable, &l.strX, err) + labels[key] = append(labels[key], value) + } else if l.numX != 0 || l.unitX != 0 { + numValues := numLabels[key] + units := numUnits[key] + if l.unitX != 0 { + var unit string + unit, err = getString(p.stringTable, &l.unitX, err) + units = padStringArray(units, len(numValues)) + numUnits[key] = append(units, unit) + } + numLabels[key] = append(numLabels[key], l.numX) } - numLabels[key] = append(numLabels[key], l.numX) } - } - if len(labels) > 0 { - s.Label = labels - } - if len(numLabels) > 0 { - s.NumLabel = numLabels - for key, units := range numUnits { - if len(units) > 0 { - numUnits[key] = padStringArray(units, len(numLabels[key])) + if len(labels) > 0 { + s.Label = labels + } + if len(numLabels) > 0 { + s.NumLabel = numLabels + for key, units := range numUnits { + if len(units) > 0 { + numUnits[key] = padStringArray(units, len(numLabels[key])) + } } + s.NumUnit = numUnits } - s.NumUnit = numUnits } - s.Location = make([]*Location, len(s.locationIDX)) + + s.Location = locBuffer[:len(s.locationIDX)] + locBuffer = locBuffer[len(s.locationIDX):] for i, lid := range s.locationIDX { if lid < uint64(len(locationIds)) { s.Location[i] = locationIds[lid] diff --git a/vendor/github.com/google/pprof/profile/filter.go b/vendor/github.com/google/pprof/profile/filter.go index ea8e66c68d..c794b93906 100644 --- a/vendor/github.com/google/pprof/profile/filter.go +++ b/vendor/github.com/google/pprof/profile/filter.go @@ -22,6 +22,10 @@ import "regexp" // samples where at least one frame matches focus but none match ignore. // Returns true is the corresponding regexp matched at least one sample. func (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp) (fm, im, hm, hnm bool) { + if focus == nil && ignore == nil && hide == nil && show == nil { + fm = true // Missing focus implies a match + return + } focusOrIgnore := make(map[uint64]bool) hidden := make(map[uint64]bool) for _, l := range p.Location { diff --git a/vendor/github.com/google/pprof/profile/legacy_profile.go b/vendor/github.com/google/pprof/profile/legacy_profile.go index 0c8f3bb5b7..8d07fd6c27 100644 --- a/vendor/github.com/google/pprof/profile/legacy_profile.go +++ b/vendor/github.com/google/pprof/profile/legacy_profile.go @@ -295,11 +295,12 @@ func get64b(b []byte) (uint64, []byte) { // // The general format for profilez samples is a sequence of words in // binary format. The first words are a header with the following data: -// 1st word -- 0 -// 2nd word -- 3 -// 3rd word -- 0 if a c++ application, 1 if a java application. -// 4th word -- Sampling period (in microseconds). -// 5th word -- Padding. +// +// 1st word -- 0 +// 2nd word -- 3 +// 3rd word -- 0 if a c++ application, 1 if a java application. +// 4th word -- Sampling period (in microseconds). +// 5th word -- Padding. func parseCPU(b []byte) (*Profile, error) { var parse func([]byte) (uint64, []byte) var n1, n2, n3, n4, n5 uint64 @@ -403,15 +404,18 @@ func cleanupDuplicateLocations(p *Profile) { // // profilez samples are a repeated sequence of stack frames of the // form: -// 1st word -- The number of times this stack was encountered. -// 2nd word -- The size of the stack (StackSize). -// 3rd word -- The first address on the stack. -// ... -// StackSize + 2 -- The last address on the stack +// +// 1st word -- The number of times this stack was encountered. +// 2nd word -- The size of the stack (StackSize). +// 3rd word -- The first address on the stack. +// ... +// StackSize + 2 -- The last address on the stack +// // The last stack trace is of the form: -// 1st word -- 0 -// 2nd word -- 1 -// 3rd word -- 0 +// +// 1st word -- 0 +// 2nd word -- 1 +// 3rd word -- 0 // // Addresses from stack traces may point to the next instruction after // each call. Optionally adjust by -1 to land somewhere on the actual @@ -861,7 +865,6 @@ func parseThread(b []byte) (*Profile, error) { // Recognize each thread and populate profile samples. for !isMemoryMapSentinel(line) { if strings.HasPrefix(line, "---- no stack trace for") { - line = "" break } if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { diff --git a/vendor/github.com/google/pprof/profile/merge.go b/vendor/github.com/google/pprof/profile/merge.go index 9978e7330e..4b66282cb8 100644 --- a/vendor/github.com/google/pprof/profile/merge.go +++ b/vendor/github.com/google/pprof/profile/merge.go @@ -15,6 +15,7 @@ package profile import ( + "encoding/binary" "fmt" "sort" "strconv" @@ -58,7 +59,7 @@ func Merge(srcs []*Profile) (*Profile, error) { for _, src := range srcs { // Clear the profile-specific hash tables - pm.locationsByID = make(map[uint64]*Location, len(src.Location)) + pm.locationsByID = makeLocationIDMap(len(src.Location)) pm.functionsByID = make(map[uint64]*Function, len(src.Function)) pm.mappingsByID = make(map[uint64]mapInfo, len(src.Mapping)) @@ -136,7 +137,7 @@ type profileMerger struct { p *Profile // Memoization tables within a profile. - locationsByID map[uint64]*Location + locationsByID locationIDMap functionsByID map[uint64]*Function mappingsByID map[uint64]mapInfo @@ -153,6 +154,16 @@ type mapInfo struct { } func (pm *profileMerger) mapSample(src *Sample) *Sample { + // Check memoization table + k := pm.sampleKey(src) + if ss, ok := pm.samples[k]; ok { + for i, v := range src.Value { + ss.Value[i] += v + } + return ss + } + + // Make new sample. s := &Sample{ Location: make([]*Location, len(src.Location)), Value: make([]int64, len(src.Value)), @@ -177,52 +188,98 @@ func (pm *profileMerger) mapSample(src *Sample) *Sample { s.NumLabel[k] = vv s.NumUnit[k] = uu } - // Check memoization table. Must be done on the remapped location to - // account for the remapped mapping. Add current values to the - // existing sample. - k := s.key() - if ss, ok := pm.samples[k]; ok { - for i, v := range src.Value { - ss.Value[i] += v - } - return ss - } copy(s.Value, src.Value) pm.samples[k] = s pm.p.Sample = append(pm.p.Sample, s) return s } -// key generates sampleKey to be used as a key for maps. -func (sample *Sample) key() sampleKey { - ids := make([]string, len(sample.Location)) - for i, l := range sample.Location { - ids[i] = strconv.FormatUint(l.ID, 16) +func (pm *profileMerger) sampleKey(sample *Sample) sampleKey { + // Accumulate contents into a string. + var buf strings.Builder + buf.Grow(64) // Heuristic to avoid extra allocs + + // encode a number + putNumber := func(v uint64) { + var num [binary.MaxVarintLen64]byte + n := binary.PutUvarint(num[:], v) + buf.Write(num[:n]) + } + + // encode a string prefixed with its length. + putDelimitedString := func(s string) { + putNumber(uint64(len(s))) + buf.WriteString(s) + } + + for _, l := range sample.Location { + // Get the location in the merged profile, which may have a different ID. + if loc := pm.mapLocation(l); loc != nil { + putNumber(loc.ID) + } } + putNumber(0) // Delimiter - labels := make([]string, 0, len(sample.Label)) - for k, v := range sample.Label { - labels = append(labels, fmt.Sprintf("%q%q", k, v)) + for _, l := range sortedKeys1(sample.Label) { + putDelimitedString(l) + values := sample.Label[l] + putNumber(uint64(len(values))) + for _, v := range values { + putDelimitedString(v) + } } - sort.Strings(labels) - numlabels := make([]string, 0, len(sample.NumLabel)) - for k, v := range sample.NumLabel { - numlabels = append(numlabels, fmt.Sprintf("%q%x%x", k, v, sample.NumUnit[k])) + for _, l := range sortedKeys2(sample.NumLabel) { + putDelimitedString(l) + values := sample.NumLabel[l] + putNumber(uint64(len(values))) + for _, v := range values { + putNumber(uint64(v)) + } + units := sample.NumUnit[l] + putNumber(uint64(len(units))) + for _, v := range units { + putDelimitedString(v) + } } - sort.Strings(numlabels) - return sampleKey{ - strings.Join(ids, "|"), - strings.Join(labels, ""), - strings.Join(numlabels, ""), + return sampleKey(buf.String()) +} + +type sampleKey string + +// sortedKeys1 returns the sorted keys found in a string->[]string map. +// +// Note: this is currently non-generic since github pprof runs golint, +// which does not support generics. When that issue is fixed, it can +// be merged with sortedKeys2 and made into a generic function. +func sortedKeys1(m map[string][]string) []string { + if len(m) == 0 { + return nil } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys } -type sampleKey struct { - locations string - labels string - numlabels string +// sortedKeys2 returns the sorted keys found in a string->[]int64 map. +// +// Note: this is currently non-generic since github pprof runs golint, +// which does not support generics. When that issue is fixed, it can +// be merged with sortedKeys1 and made into a generic function. +func sortedKeys2(m map[string][]int64) []string { + if len(m) == 0 { + return nil + } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys } func (pm *profileMerger) mapLocation(src *Location) *Location { @@ -230,7 +287,7 @@ func (pm *profileMerger) mapLocation(src *Location) *Location { return nil } - if l, ok := pm.locationsByID[src.ID]; ok { + if l := pm.locationsByID.get(src.ID); l != nil { return l } @@ -249,10 +306,10 @@ func (pm *profileMerger) mapLocation(src *Location) *Location { // account for the remapped mapping ID. k := l.key() if ll, ok := pm.locations[k]; ok { - pm.locationsByID[src.ID] = ll + pm.locationsByID.set(src.ID, ll) return ll } - pm.locationsByID[src.ID] = l + pm.locationsByID.set(src.ID, l) pm.locations[k] = l pm.p.Location = append(pm.p.Location, l) return l @@ -303,16 +360,17 @@ func (pm *profileMerger) mapMapping(src *Mapping) mapInfo { return mi } m := &Mapping{ - ID: uint64(len(pm.p.Mapping) + 1), - Start: src.Start, - Limit: src.Limit, - Offset: src.Offset, - File: src.File, - BuildID: src.BuildID, - HasFunctions: src.HasFunctions, - HasFilenames: src.HasFilenames, - HasLineNumbers: src.HasLineNumbers, - HasInlineFrames: src.HasInlineFrames, + ID: uint64(len(pm.p.Mapping) + 1), + Start: src.Start, + Limit: src.Limit, + Offset: src.Offset, + File: src.File, + KernelRelocationSymbol: src.KernelRelocationSymbol, + BuildID: src.BuildID, + HasFunctions: src.HasFunctions, + HasFilenames: src.HasFilenames, + HasLineNumbers: src.HasLineNumbers, + HasInlineFrames: src.HasInlineFrames, } pm.p.Mapping = append(pm.p.Mapping, m) @@ -479,3 +537,131 @@ func (p *Profile) compatible(pb *Profile) error { func equalValueType(st1, st2 *ValueType) bool { return st1.Type == st2.Type && st1.Unit == st2.Unit } + +// locationIDMap is like a map[uint64]*Location, but provides efficiency for +// ids that are densely numbered, which is often the case. +type locationIDMap struct { + dense []*Location // indexed by id for id < len(dense) + sparse map[uint64]*Location // indexed by id for id >= len(dense) +} + +func makeLocationIDMap(n int) locationIDMap { + return locationIDMap{ + dense: make([]*Location, n), + sparse: map[uint64]*Location{}, + } +} + +func (lm locationIDMap) get(id uint64) *Location { + if id < uint64(len(lm.dense)) { + return lm.dense[int(id)] + } + return lm.sparse[id] +} + +func (lm locationIDMap) set(id uint64, loc *Location) { + if id < uint64(len(lm.dense)) { + lm.dense[id] = loc + return + } + lm.sparse[id] = loc +} + +// CompatibilizeSampleTypes makes profiles compatible to be compared/merged. It +// keeps sample types that appear in all profiles only and drops/reorders the +// sample types as necessary. +// +// In the case of sample types order is not the same for given profiles the +// order is derived from the first profile. +// +// Profiles are modified in-place. +// +// It returns an error if the sample type's intersection is empty. +func CompatibilizeSampleTypes(ps []*Profile) error { + sTypes := commonSampleTypes(ps) + if len(sTypes) == 0 { + return fmt.Errorf("profiles have empty common sample type list") + } + for _, p := range ps { + if err := compatibilizeSampleTypes(p, sTypes); err != nil { + return err + } + } + return nil +} + +// commonSampleTypes returns sample types that appear in all profiles in the +// order how they ordered in the first profile. +func commonSampleTypes(ps []*Profile) []string { + if len(ps) == 0 { + return nil + } + sTypes := map[string]int{} + for _, p := range ps { + for _, st := range p.SampleType { + sTypes[st.Type]++ + } + } + var res []string + for _, st := range ps[0].SampleType { + if sTypes[st.Type] == len(ps) { + res = append(res, st.Type) + } + } + return res +} + +// compatibilizeSampleTypes drops sample types that are not present in sTypes +// list and reorder them if needed. +// +// It sets DefaultSampleType to sType[0] if it is not in sType list. +// +// It assumes that all sample types from the sTypes list are present in the +// given profile otherwise it returns an error. +func compatibilizeSampleTypes(p *Profile, sTypes []string) error { + if len(sTypes) == 0 { + return fmt.Errorf("sample type list is empty") + } + defaultSampleType := sTypes[0] + reMap, needToModify := make([]int, len(sTypes)), false + for i, st := range sTypes { + if st == p.DefaultSampleType { + defaultSampleType = p.DefaultSampleType + } + idx := searchValueType(p.SampleType, st) + if idx < 0 { + return fmt.Errorf("%q sample type is not found in profile", st) + } + reMap[i] = idx + if idx != i { + needToModify = true + } + } + if !needToModify && len(sTypes) == len(p.SampleType) { + return nil + } + p.DefaultSampleType = defaultSampleType + oldSampleTypes := p.SampleType + p.SampleType = make([]*ValueType, len(sTypes)) + for i, idx := range reMap { + p.SampleType[i] = oldSampleTypes[idx] + } + values := make([]int64, len(sTypes)) + for _, s := range p.Sample { + for i, idx := range reMap { + values[i] = s.Value[idx] + } + s.Value = s.Value[:len(values)] + copy(s.Value, values) + } + return nil +} + +func searchValueType(vts []*ValueType, s string) int { + for i, vt := range vts { + if vt.Type == s { + return i + } + } + return -1 +} diff --git a/vendor/github.com/google/pprof/profile/profile.go b/vendor/github.com/google/pprof/profile/profile.go index 2590c8ddb4..60ef7e9268 100644 --- a/vendor/github.com/google/pprof/profile/profile.go +++ b/vendor/github.com/google/pprof/profile/profile.go @@ -21,7 +21,6 @@ import ( "compress/gzip" "fmt" "io" - "io/ioutil" "math" "path/filepath" "regexp" @@ -73,9 +72,23 @@ type ValueType struct { type Sample struct { Location []*Location Value []int64 - Label map[string][]string + // Label is a per-label-key map to values for string labels. + // + // In general, having multiple values for the given label key is strongly + // discouraged - see docs for the sample label field in profile.proto. The + // main reason this unlikely state is tracked here is to make the + // decoding->encoding roundtrip not lossy. But we expect that the value + // slices present in this map are always of length 1. + Label map[string][]string + // NumLabel is a per-label-key map to values for numeric labels. See a note + // above on handling multiple values for a label. NumLabel map[string][]int64 - NumUnit map[string][]string + // NumUnit is a per-label-key map to the unit names of corresponding numeric + // label values. The unit info may be missing even if the label is in + // NumLabel, see the docs in profile.proto for details. When the value is + // slice is present and not nil, its length must be equal to the length of + // the corresponding value slice in NumLabel. + NumUnit map[string][]string locationIDX []uint64 labelX []label @@ -106,6 +119,15 @@ type Mapping struct { fileX int64 buildIDX int64 + + // Name of the kernel relocation symbol ("_text" or "_stext"), extracted from File. + // For linux kernel mappings generated by some tools, correct symbolization depends + // on knowing which of the two possible relocation symbols was used for `Start`. + // This is given to us as a suffix in `File` (e.g. "[kernel.kallsyms]_stext"). + // + // Note, this public field is not persisted in the proto. For the purposes of + // copying / merging / hashing profiles, it is considered subsumed by `File`. + KernelRelocationSymbol string } // Location corresponds to Profile.Location @@ -144,7 +166,7 @@ type Function struct { // may be a gzip-compressed encoded protobuf or one of many legacy // profile formats which may be unsupported in the future. func Parse(r io.Reader) (*Profile, error) { - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { return nil, err } @@ -159,7 +181,7 @@ func ParseData(data []byte) (*Profile, error) { if len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err == nil { - data, err = ioutil.ReadAll(gz) + data, err = io.ReadAll(gz) } if err != nil { return nil, fmt.Errorf("decompressing profile: %v", err) @@ -707,6 +729,35 @@ func (s *Sample) HasLabel(key, value string) bool { return false } +// SetNumLabel sets the specified key to the specified value for all samples in the +// profile. "unit" is a slice that describes the units that each corresponding member +// of "values" is measured in (e.g. bytes or seconds). If there is no relevant +// unit for a given value, that member of "unit" should be the empty string. +// "unit" must either have the same length as "value", or be nil. +func (p *Profile) SetNumLabel(key string, value []int64, unit []string) { + for _, sample := range p.Sample { + if sample.NumLabel == nil { + sample.NumLabel = map[string][]int64{key: value} + } else { + sample.NumLabel[key] = value + } + if sample.NumUnit == nil { + sample.NumUnit = map[string][]string{key: unit} + } else { + sample.NumUnit[key] = unit + } + } +} + +// RemoveNumLabel removes all numerical labels associated with the specified key for all +// samples in the profile. +func (p *Profile) RemoveNumLabel(key string) { + for _, sample := range p.Sample { + delete(sample.NumLabel, key) + delete(sample.NumUnit, key) + } +} + // DiffBaseSample returns true if a sample belongs to the diff base and false // otherwise. func (s *Sample) DiffBaseSample() bool { diff --git a/vendor/github.com/google/pprof/profile/proto.go b/vendor/github.com/google/pprof/profile/proto.go index 539ad3ab33..a15696ba16 100644 --- a/vendor/github.com/google/pprof/profile/proto.go +++ b/vendor/github.com/google/pprof/profile/proto.go @@ -39,11 +39,12 @@ import ( ) type buffer struct { - field int // field tag - typ int // proto wire type code for field - u64 uint64 - data []byte - tmp [16]byte + field int // field tag + typ int // proto wire type code for field + u64 uint64 + data []byte + tmp [16]byte + tmpLines []Line // temporary storage used while decoding "repeated Line". } type decoder func(*buffer, message) error @@ -286,7 +287,6 @@ func decodeInt64s(b *buffer, x *[]int64) error { if b.typ == 2 { // Packed encoding data := b.data - tmp := make([]int64, 0, len(data)) // Maximally sized for len(data) > 0 { var u uint64 var err error @@ -294,9 +294,8 @@ func decodeInt64s(b *buffer, x *[]int64) error { if u, data, err = decodeVarint(data); err != nil { return err } - tmp = append(tmp, int64(u)) + *x = append(*x, int64(u)) } - *x = append(*x, tmp...) return nil } var i int64 @@ -319,7 +318,6 @@ func decodeUint64s(b *buffer, x *[]uint64) error { if b.typ == 2 { data := b.data // Packed encoding - tmp := make([]uint64, 0, len(data)) // Maximally sized for len(data) > 0 { var u uint64 var err error @@ -327,9 +325,8 @@ func decodeUint64s(b *buffer, x *[]uint64) error { if u, data, err = decodeVarint(data); err != nil { return err } - tmp = append(tmp, u) + *x = append(*x, u) } - *x = append(*x, tmp...) return nil } var u uint64 diff --git a/vendor/github.com/google/pprof/profile/prune.go b/vendor/github.com/google/pprof/profile/prune.go index 02d21a8184..b2f9fd5466 100644 --- a/vendor/github.com/google/pprof/profile/prune.go +++ b/vendor/github.com/google/pprof/profile/prune.go @@ -62,15 +62,31 @@ func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) { prune := make(map[uint64]bool) pruneBeneath := make(map[uint64]bool) + // simplifyFunc can be expensive, so cache results. + // Note that the same function name can be encountered many times due + // different lines and addresses in the same function. + pruneCache := map[string]bool{} // Map from function to whether or not to prune + pruneFromHere := func(s string) bool { + if r, ok := pruneCache[s]; ok { + return r + } + funcName := simplifyFunc(s) + if dropRx.MatchString(funcName) { + if keepRx == nil || !keepRx.MatchString(funcName) { + pruneCache[s] = true + return true + } + } + pruneCache[s] = false + return false + } + for _, loc := range p.Location { var i int for i = len(loc.Line) - 1; i >= 0; i-- { if fn := loc.Line[i].Function; fn != nil && fn.Name != "" { - funcName := simplifyFunc(fn.Name) - if dropRx.MatchString(funcName) { - if keepRx == nil || !keepRx.MatchString(funcName) { - break - } + if pruneFromHere(fn.Name) { + break } } } diff --git a/vendor/github.com/google/uuid/null.go b/vendor/github.com/google/uuid/null.go new file mode 100644 index 0000000000..d7fcbf2865 --- /dev/null +++ b/vendor/github.com/google/uuid/null.go @@ -0,0 +1,118 @@ +// Copyright 2021 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "fmt" +) + +var jsonNull = []byte("null") + +// NullUUID represents a UUID that may be null. +// NullUUID implements the SQL driver.Scanner interface so +// it can be used as a scan destination: +// +// var u uuid.NullUUID +// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) +// ... +// if u.Valid { +// // use u.UUID +// } else { +// // NULL value +// } +// +type NullUUID struct { + UUID UUID + Valid bool // Valid is true if UUID is not NULL +} + +// Scan implements the SQL driver.Scanner interface. +func (nu *NullUUID) Scan(value interface{}) error { + if value == nil { + nu.UUID, nu.Valid = Nil, false + return nil + } + + err := nu.UUID.Scan(value) + if err != nil { + nu.Valid = false + return err + } + + nu.Valid = true + return nil +} + +// Value implements the driver Valuer interface. +func (nu NullUUID) Value() (driver.Value, error) { + if !nu.Valid { + return nil, nil + } + // Delegate to UUID Value function + return nu.UUID.Value() +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (nu NullUUID) MarshalBinary() ([]byte, error) { + if nu.Valid { + return nu.UUID[:], nil + } + + return []byte(nil), nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (nu *NullUUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(nu.UUID[:], data) + nu.Valid = true + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (nu NullUUID) MarshalText() ([]byte, error) { + if nu.Valid { + return nu.UUID.MarshalText() + } + + return jsonNull, nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (nu *NullUUID) UnmarshalText(data []byte) error { + id, err := ParseBytes(data) + if err != nil { + nu.Valid = false + return err + } + nu.UUID = id + nu.Valid = true + return nil +} + +// MarshalJSON implements json.Marshaler. +func (nu NullUUID) MarshalJSON() ([]byte, error) { + if nu.Valid { + return json.Marshal(nu.UUID) + } + + return jsonNull, nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (nu *NullUUID) UnmarshalJSON(data []byte) error { + if bytes.Equal(data, jsonNull) { + *nu = NullUUID{} + return nil // valid null UUID + } + err := json.Unmarshal(data, &nu.UUID) + nu.Valid = err == nil + return err +} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index 60d26bb50c..a57207aeb6 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -12,6 +12,7 @@ import ( "fmt" "io" "strings" + "sync" ) // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC @@ -33,7 +34,15 @@ const ( Future // Reserved for future definition. ) -var rander = rand.Reader // random function +const randPoolSize = 16 * 16 + +var ( + rander = rand.Reader // random function + poolEnabled = false + poolMu sync.Mutex + poolPos = randPoolSize // protected with poolMu + pool [randPoolSize]byte // protected with poolMu +) type invalidLengthError struct{ len int } @@ -41,6 +50,12 @@ func (err invalidLengthError) Error() string { return fmt.Sprintf("invalid UUID length: %d", err.len) } +// IsInvalidLengthError is matcher function for custom error invalidLengthError +func IsInvalidLengthError(err error) bool { + _, ok := err.(invalidLengthError) + return ok +} + // Parse decodes s into a UUID or returns an error. Both the standard UUID // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the @@ -249,3 +264,31 @@ func SetRand(r io.Reader) { } rander = r } + +// EnableRandPool enables internal randomness pool used for Random +// (Version 4) UUID generation. The pool contains random bytes read from +// the random number generator on demand in batches. Enabling the pool +// may improve the UUID generation throughput significantly. +// +// Since the pool is stored on the Go heap, this feature may be a bad fit +// for security sensitive applications. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func EnableRandPool() { + poolEnabled = true +} + +// DisableRandPool disables the randomness pool if it was previously +// enabled with EnableRandPool. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func DisableRandPool() { + poolEnabled = false + defer poolMu.Unlock() + poolMu.Lock() + poolPos = randPoolSize +} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go index 86160fbd07..7697802e4d 100644 --- a/vendor/github.com/google/uuid/version4.go +++ b/vendor/github.com/google/uuid/version4.go @@ -27,6 +27,8 @@ func NewString() string { // The strength of the UUIDs is based on the strength of the crypto/rand // package. // +// Uses the randomness pool if it was enabled with EnableRandPool. +// // A note about uniqueness derived from the UUID Wikipedia entry: // // Randomly generated UUIDs have 122 random bits. One's annual risk of being @@ -35,7 +37,10 @@ func NewString() string { // equivalent to the odds of creating a few tens of trillions of UUIDs in a // year and having one duplicate. func NewRandom() (UUID, error) { - return NewRandomFromReader(rander) + if !poolEnabled { + return NewRandomFromReader(rander) + } + return newRandomFromPool() } // NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. @@ -49,3 +54,23 @@ func NewRandomFromReader(r io.Reader) (UUID, error) { uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 return uuid, nil } + +func newRandomFromPool() (UUID, error) { + var uuid UUID + poolMu.Lock() + if poolPos == randPoolSize { + _, err := io.ReadFull(rander, pool[:]) + if err != nil { + poolMu.Unlock() + return Nil, err + } + poolPos = 0 + } + copy(uuid[:], pool[poolPos:(poolPos+16)]) + poolPos += 16 + poolMu.Unlock() + + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel deleted file mode 100644 index 5242751fb2..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel +++ /dev/null @@ -1,23 +0,0 @@ -load("@rules_proto//proto:defs.bzl", "proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") - -package(default_visibility = ["//visibility:public"]) - -proto_library( - name = "internal_proto", - srcs = ["errors.proto"], - deps = ["@com_google_protobuf//:any_proto"], -) - -go_proto_library( - name = "internal_go_proto", - importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", - proto = ":internal_proto", -) - -go_library( - name = "go_default_library", - embed = [":internal_go_proto"], - importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go deleted file mode 100644 index 61101d7177..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go +++ /dev/null @@ -1,189 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: internal/errors.proto - -package internal - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - any "github.com/golang/protobuf/ptypes/any" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Error is the generic error returned from unary RPCs. -type Error struct { - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - // This is to make the error more compatible with users that expect errors to be Status objects: - // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto - // It should be the exact same message as the Error field. - Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - Details []*any.Any `protobuf:"bytes,4,rep,name=details,proto3" json:"details,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Error) Reset() { *m = Error{} } -func (m *Error) String() string { return proto.CompactTextString(m) } -func (*Error) ProtoMessage() {} -func (*Error) Descriptor() ([]byte, []int) { - return fileDescriptor_9b093362ca6d1e03, []int{0} -} - -func (m *Error) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Error.Unmarshal(m, b) -} -func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Error.Marshal(b, m, deterministic) -} -func (m *Error) XXX_Merge(src proto.Message) { - xxx_messageInfo_Error.Merge(m, src) -} -func (m *Error) XXX_Size() int { - return xxx_messageInfo_Error.Size(m) -} -func (m *Error) XXX_DiscardUnknown() { - xxx_messageInfo_Error.DiscardUnknown(m) -} - -var xxx_messageInfo_Error proto.InternalMessageInfo - -func (m *Error) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *Error) GetCode() int32 { - if m != nil { - return m.Code - } - return 0 -} - -func (m *Error) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *Error) GetDetails() []*any.Any { - if m != nil { - return m.Details - } - return nil -} - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -type StreamError struct { - GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"` - HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"` - Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *StreamError) Reset() { *m = StreamError{} } -func (m *StreamError) String() string { return proto.CompactTextString(m) } -func (*StreamError) ProtoMessage() {} -func (*StreamError) Descriptor() ([]byte, []int) { - return fileDescriptor_9b093362ca6d1e03, []int{1} -} - -func (m *StreamError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StreamError.Unmarshal(m, b) -} -func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StreamError.Marshal(b, m, deterministic) -} -func (m *StreamError) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamError.Merge(m, src) -} -func (m *StreamError) XXX_Size() int { - return xxx_messageInfo_StreamError.Size(m) -} -func (m *StreamError) XXX_DiscardUnknown() { - xxx_messageInfo_StreamError.DiscardUnknown(m) -} - -var xxx_messageInfo_StreamError proto.InternalMessageInfo - -func (m *StreamError) GetGrpcCode() int32 { - if m != nil { - return m.GrpcCode - } - return 0 -} - -func (m *StreamError) GetHttpCode() int32 { - if m != nil { - return m.HttpCode - } - return 0 -} - -func (m *StreamError) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *StreamError) GetHttpStatus() string { - if m != nil { - return m.HttpStatus - } - return "" -} - -func (m *StreamError) GetDetails() []*any.Any { - if m != nil { - return m.Details - } - return nil -} - -func init() { - proto.RegisterType((*Error)(nil), "grpc.gateway.runtime.Error") - proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError") -} - -func init() { proto.RegisterFile("internal/errors.proto", fileDescriptor_9b093362ca6d1e03) } - -var fileDescriptor_9b093362ca6d1e03 = []byte{ - // 252 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xc1, 0x4a, 0xc4, 0x30, - 0x10, 0x86, 0x89, 0xbb, 0x75, 0xdb, 0xe9, 0x2d, 0x54, 0x88, 0xee, 0xc1, 0xb2, 0xa7, 0x9e, 0x52, - 0xd0, 0x27, 0xd0, 0xc5, 0x17, 0xe8, 0xde, 0xbc, 0x2c, 0xd9, 0xdd, 0x31, 0x16, 0xda, 0xa4, 0x24, - 0x53, 0xa4, 0xf8, 0x56, 0x3e, 0xa1, 0x24, 0xa5, 0xb0, 0x27, 0xf1, 0xd6, 0xf9, 0xfb, 0xcf, 0x7c, - 0x1f, 0x81, 0xbb, 0xd6, 0x10, 0x3a, 0xa3, 0xba, 0x1a, 0x9d, 0xb3, 0xce, 0xcb, 0xc1, 0x59, 0xb2, - 0xbc, 0xd0, 0x6e, 0x38, 0x4b, 0xad, 0x08, 0xbf, 0xd4, 0x24, 0xdd, 0x68, 0xa8, 0xed, 0xf1, 0xe1, - 0x5e, 0x5b, 0xab, 0x3b, 0xac, 0x63, 0xe7, 0x34, 0x7e, 0xd4, 0xca, 0x4c, 0xf3, 0xc2, 0xee, 0x1b, - 0x92, 0xb7, 0x70, 0x80, 0x17, 0x90, 0xc4, 0x4b, 0x82, 0x95, 0xac, 0xca, 0x9a, 0x79, 0xe0, 0x1c, - 0xd6, 0x67, 0x7b, 0x41, 0x71, 0x53, 0xb2, 0x2a, 0x69, 0xe2, 0x37, 0x17, 0xb0, 0xe9, 0xd1, 0x7b, - 0xa5, 0x51, 0xac, 0x62, 0x77, 0x19, 0xb9, 0x84, 0xcd, 0x05, 0x49, 0xb5, 0x9d, 0x17, 0xeb, 0x72, - 0x55, 0xe5, 0x4f, 0x85, 0x9c, 0xc9, 0x72, 0x21, 0xcb, 0x17, 0x33, 0x35, 0x4b, 0x69, 0xf7, 0xc3, - 0x20, 0x3f, 0x90, 0x43, 0xd5, 0xcf, 0x0e, 0x5b, 0xc8, 0x82, 0xff, 0x31, 0x22, 0x59, 0x44, 0xa6, - 0x21, 0xd8, 0x07, 0xec, 0x16, 0xb2, 0x4f, 0xa2, 0xe1, 0x78, 0xe5, 0x93, 0x86, 0x60, 0xff, 0xb7, - 0xd3, 0x23, 0xe4, 0x71, 0xcd, 0x93, 0xa2, 0x31, 0x78, 0x85, 0xbf, 0x10, 0xa2, 0x43, 0x4c, 0xae, - 0xa5, 0x93, 0x7f, 0x48, 0xbf, 0xc2, 0x7b, 0xba, 0xbc, 0xfd, 0xe9, 0x36, 0x56, 0x9e, 0x7f, 0x03, - 0x00, 0x00, 0xff, 0xff, 0xde, 0x72, 0x6b, 0x83, 0x8e, 0x01, 0x00, 0x00, -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto deleted file mode 100644 index 4fb212c6b6..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; -package grpc.gateway.runtime; -option go_package = "internal"; - -import "google/protobuf/any.proto"; - -// Error is the generic error returned from unary RPCs. -message Error { - string error = 1; - // This is to make the error more compatible with users that expect errors to be Status objects: - // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto - // It should be the exact same message as the Error field. - int32 code = 2; - string message = 3; - repeated google.protobuf.Any details = 4; -} - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -message StreamError { - int32 grpc_code = 1; - int32 http_code = 2; - string message = 3; - string http_status = 4; - repeated google.protobuf.Any details = 5; -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel deleted file mode 100644 index 58b72b9cf7..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel +++ /dev/null @@ -1,85 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -package(default_visibility = ["//visibility:public"]) - -go_library( - name = "go_default_library", - srcs = [ - "context.go", - "convert.go", - "doc.go", - "errors.go", - "fieldmask.go", - "handler.go", - "marshal_httpbodyproto.go", - "marshal_json.go", - "marshal_jsonpb.go", - "marshal_proto.go", - "marshaler.go", - "marshaler_registry.go", - "mux.go", - "pattern.go", - "proto2_convert.go", - "proto_errors.go", - "query.go", - ], - importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime", - deps = [ - "//internal:go_default_library", - "//utilities:go_default_library", - "@com_github_golang_protobuf//descriptor:go_default_library_gen", - "@com_github_golang_protobuf//jsonpb:go_default_library_gen", - "@com_github_golang_protobuf//proto:go_default_library", - "@go_googleapis//google/api:httpbody_go_proto", - "@io_bazel_rules_go//proto/wkt:any_go_proto", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", - "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//grpclog:go_default_library", - "@org_golang_google_grpc//metadata:go_default_library", - "@org_golang_google_grpc//status:go_default_library", - ], -) - -go_test( - name = "go_default_test", - size = "small", - srcs = [ - "context_test.go", - "convert_test.go", - "errors_test.go", - "fieldmask_test.go", - "handler_test.go", - "marshal_httpbodyproto_test.go", - "marshal_json_test.go", - "marshal_jsonpb_test.go", - "marshal_proto_test.go", - "marshaler_registry_test.go", - "mux_test.go", - "pattern_test.go", - "query_test.go", - ], - embed = [":go_default_library"], - deps = [ - "//internal:go_default_library", - "//runtime/internal/examplepb:go_default_library", - "//utilities:go_default_library", - "@com_github_golang_protobuf//jsonpb:go_default_library_gen", - "@com_github_golang_protobuf//proto:go_default_library", - "@com_github_golang_protobuf//ptypes:go_default_library_gen", - "@go_googleapis//google/api:httpbody_go_proto", - "@go_googleapis//google/rpc:errdetails_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", - "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//metadata:go_default_library", - "@org_golang_google_grpc//status:go_default_library", - ], -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go deleted file mode 100644 index d8cbd4cc96..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go +++ /dev/null @@ -1,291 +0,0 @@ -package runtime - -import ( - "context" - "encoding/base64" - "fmt" - "net" - "net/http" - "net/textproto" - "strconv" - "strings" - "sync" - "time" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// MetadataHeaderPrefix is the http prefix that represents custom metadata -// parameters to or from a gRPC call. -const MetadataHeaderPrefix = "Grpc-Metadata-" - -// MetadataPrefix is prepended to permanent HTTP header keys (as specified -// by the IANA) when added to the gRPC context. -const MetadataPrefix = "grpcgateway-" - -// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to -// HTTP headers in a response handled by grpc-gateway -const MetadataTrailerPrefix = "Grpc-Trailer-" - -const metadataGrpcTimeout = "Grpc-Timeout" -const metadataHeaderBinarySuffix = "-Bin" - -const xForwardedFor = "X-Forwarded-For" -const xForwardedHost = "X-Forwarded-Host" - -var ( - // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound - // header isn't present. If the value is 0 the sent `context` will not have a timeout. - DefaultContextTimeout = 0 * time.Second -) - -func decodeBinHeader(v string) ([]byte, error) { - if len(v)%4 == 0 { - // Input was padded, or padding was not necessary. - return base64.StdEncoding.DecodeString(v) - } - return base64.RawStdEncoding.DecodeString(v) -} - -/* -AnnotateContext adds context information such as metadata from the request. - -At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", -except that the forwarded destination is not another HTTP service but rather -a gRPC service. -*/ -func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) { - ctx, md, err := annotateContext(ctx, mux, req) - if err != nil { - return nil, err - } - if md == nil { - return ctx, nil - } - - return metadata.NewOutgoingContext(ctx, md), nil -} - -// AnnotateIncomingContext adds context information such as metadata from the request. -// Attach metadata as incoming context. -func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) { - ctx, md, err := annotateContext(ctx, mux, req) - if err != nil { - return nil, err - } - if md == nil { - return ctx, nil - } - - return metadata.NewIncomingContext(ctx, md), nil -} - -func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, metadata.MD, error) { - var pairs []string - timeout := DefaultContextTimeout - if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { - var err error - timeout, err = timeoutDecode(tm) - if err != nil { - return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) - } - } - - for key, vals := range req.Header { - key = textproto.CanonicalMIMEHeaderKey(key) - for _, val := range vals { - // For backwards-compatibility, pass through 'authorization' header with no prefix. - if key == "Authorization" { - pairs = append(pairs, "authorization", val) - } - if h, ok := mux.incomingHeaderMatcher(key); ok { - // Handles "-bin" metadata in grpc, since grpc will do another base64 - // encode before sending to server, we need to decode it first. - if strings.HasSuffix(key, metadataHeaderBinarySuffix) { - b, err := decodeBinHeader(val) - if err != nil { - return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err) - } - - val = string(b) - } - pairs = append(pairs, h, val) - } - } - } - if host := req.Header.Get(xForwardedHost); host != "" { - pairs = append(pairs, strings.ToLower(xForwardedHost), host) - } else if req.Host != "" { - pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) - } - - if addr := req.RemoteAddr; addr != "" { - if remoteIP, _, err := net.SplitHostPort(addr); err == nil { - if fwd := req.Header.Get(xForwardedFor); fwd == "" { - pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) - } else { - pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) - } - } - } - - if timeout != 0 { - ctx, _ = context.WithTimeout(ctx, timeout) - } - if len(pairs) == 0 { - return ctx, nil, nil - } - md := metadata.Pairs(pairs...) - for _, mda := range mux.metadataAnnotators { - md = metadata.Join(md, mda(ctx, req)) - } - return ctx, md, nil -} - -// ServerMetadata consists of metadata sent from gRPC server. -type ServerMetadata struct { - HeaderMD metadata.MD - TrailerMD metadata.MD -} - -type serverMetadataKey struct{} - -// NewServerMetadataContext creates a new context with ServerMetadata -func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { - return context.WithValue(ctx, serverMetadataKey{}, md) -} - -// ServerMetadataFromContext returns the ServerMetadata in ctx -func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { - md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) - return -} - -// ServerTransportStream implements grpc.ServerTransportStream. -// It should only be used by the generated files to support grpc.SendHeader -// outside of gRPC server use. -type ServerTransportStream struct { - mu sync.Mutex - header metadata.MD - trailer metadata.MD -} - -// Method returns the method for the stream. -func (s *ServerTransportStream) Method() string { - return "" -} - -// Header returns the header metadata of the stream. -func (s *ServerTransportStream) Header() metadata.MD { - s.mu.Lock() - defer s.mu.Unlock() - return s.header.Copy() -} - -// SetHeader sets the header metadata. -func (s *ServerTransportStream) SetHeader(md metadata.MD) error { - if md.Len() == 0 { - return nil - } - - s.mu.Lock() - s.header = metadata.Join(s.header, md) - s.mu.Unlock() - return nil -} - -// SendHeader sets the header metadata. -func (s *ServerTransportStream) SendHeader(md metadata.MD) error { - return s.SetHeader(md) -} - -// Trailer returns the cached trailer metadata. -func (s *ServerTransportStream) Trailer() metadata.MD { - s.mu.Lock() - defer s.mu.Unlock() - return s.trailer.Copy() -} - -// SetTrailer sets the trailer metadata. -func (s *ServerTransportStream) SetTrailer(md metadata.MD) error { - if md.Len() == 0 { - return nil - } - - s.mu.Lock() - s.trailer = metadata.Join(s.trailer, md) - s.mu.Unlock() - return nil -} - -func timeoutDecode(s string) (time.Duration, error) { - size := len(s) - if size < 2 { - return 0, fmt.Errorf("timeout string is too short: %q", s) - } - d, ok := timeoutUnitToDuration(s[size-1]) - if !ok { - return 0, fmt.Errorf("timeout unit is not recognized: %q", s) - } - t, err := strconv.ParseInt(s[:size-1], 10, 64) - if err != nil { - return 0, err - } - return d * time.Duration(t), nil -} - -func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { - switch u { - case 'H': - return time.Hour, true - case 'M': - return time.Minute, true - case 'S': - return time.Second, true - case 'm': - return time.Millisecond, true - case 'u': - return time.Microsecond, true - case 'n': - return time.Nanosecond, true - default: - } - return -} - -// isPermanentHTTPHeader checks whether hdr belongs to the list of -// permanent request headers maintained by IANA. -// http://www.iana.org/assignments/message-headers/message-headers.xml -func isPermanentHTTPHeader(hdr string) bool { - switch hdr { - case - "Accept", - "Accept-Charset", - "Accept-Language", - "Accept-Ranges", - "Authorization", - "Cache-Control", - "Content-Type", - "Cookie", - "Date", - "Expect", - "From", - "Host", - "If-Match", - "If-Modified-Since", - "If-None-Match", - "If-Schedule-Tag-Match", - "If-Unmodified-Since", - "Max-Forwards", - "Origin", - "Pragma", - "Referer", - "User-Agent", - "Via", - "Warning": - return true - } - return false -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go deleted file mode 100644 index b2ce743bdd..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go +++ /dev/null @@ -1,186 +0,0 @@ -package runtime - -import ( - "context" - "io" - "net/http" - "strings" - - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. -// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto -func HTTPStatusFromCode(code codes.Code) int { - switch code { - case codes.OK: - return http.StatusOK - case codes.Canceled: - return http.StatusRequestTimeout - case codes.Unknown: - return http.StatusInternalServerError - case codes.InvalidArgument: - return http.StatusBadRequest - case codes.DeadlineExceeded: - return http.StatusGatewayTimeout - case codes.NotFound: - return http.StatusNotFound - case codes.AlreadyExists: - return http.StatusConflict - case codes.PermissionDenied: - return http.StatusForbidden - case codes.Unauthenticated: - return http.StatusUnauthorized - case codes.ResourceExhausted: - return http.StatusTooManyRequests - case codes.FailedPrecondition: - // Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status. - return http.StatusBadRequest - case codes.Aborted: - return http.StatusConflict - case codes.OutOfRange: - return http.StatusBadRequest - case codes.Unimplemented: - return http.StatusNotImplemented - case codes.Internal: - return http.StatusInternalServerError - case codes.Unavailable: - return http.StatusServiceUnavailable - case codes.DataLoss: - return http.StatusInternalServerError - } - - grpclog.Infof("Unknown gRPC error code: %v", code) - return http.StatusInternalServerError -} - -var ( - // HTTPError replies to the request with an error. - // - // HTTPError is called: - // - From generated per-endpoint gateway handler code, when calling the backend results in an error. - // - From gateway runtime code, when forwarding the response message results in an error. - // - // The default value for HTTPError calls the custom error handler configured on the ServeMux via the - // WithProtoErrorHandler serve option if that option was used, calling GlobalHTTPErrorHandler otherwise. - // - // To customize the error handling of a particular ServeMux instance, use the WithProtoErrorHandler - // serve option. - // - // To customize the error format for all ServeMux instances not using the WithProtoErrorHandler serve - // option, set GlobalHTTPErrorHandler to a custom function. - // - // Setting this variable directly to customize error format is deprecated. - HTTPError = MuxOrGlobalHTTPError - - // GlobalHTTPErrorHandler is the HTTPError handler for all ServeMux instances not using the - // WithProtoErrorHandler serve option. - // - // You can set a custom function to this variable to customize error format. - GlobalHTTPErrorHandler = DefaultHTTPError - - // OtherErrorHandler handles gateway errors from parsing and routing client requests for all - // ServeMux instances not using the WithProtoErrorHandler serve option. - // - // It returns the following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest - // - // To customize parsing and routing error handling of a particular ServeMux instance, use the - // WithProtoErrorHandler serve option. - // - // To customize parsing and routing error handling of all ServeMux instances not using the - // WithProtoErrorHandler serve option, set a custom function to this variable. - OtherErrorHandler = DefaultOtherErrorHandler -) - -// MuxOrGlobalHTTPError uses the mux-configured error handler, falling back to GlobalErrorHandler. -func MuxOrGlobalHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { - if mux.protoErrorHandler != nil { - mux.protoErrorHandler(ctx, mux, marshaler, w, r, err) - } else { - GlobalHTTPErrorHandler(ctx, mux, marshaler, w, r, err) - } -} - -// DefaultHTTPError is the default implementation of HTTPError. -// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. -// If otherwise, it replies with http.StatusInternalServerError. -// -// The response body returned by this function is a JSON object, -// which contains a member whose key is "error" and whose value is err.Error(). -func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { - const fallback = `{"error": "failed to marshal error message"}` - - s, ok := status.FromError(err) - if !ok { - s = status.New(codes.Unknown, err.Error()) - } - - w.Header().Del("Trailer") - w.Header().Del("Transfer-Encoding") - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - pb := s.Proto() - contentType = typeMarshaler.ContentTypeFromMessage(pb) - } - w.Header().Set("Content-Type", contentType) - - body := &internal.Error{ - Error: s.Message(), - Message: s.Message(), - Code: int32(s.Code()), - Details: s.Proto().GetDetails(), - } - - buf, merr := marshaler.Marshal(body) - if merr != nil { - grpclog.Infof("Failed to marshal error message %q: %v", body, merr) - w.WriteHeader(http.StatusInternalServerError) - if _, err := io.WriteString(w, fallback); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - - // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 - // Unless the request includes a TE header field indicating "trailers" - // is acceptable, as described in Section 4.3, a server SHOULD NOT - // generate trailer fields that it believes are necessary for the user - // agent to receive. - var wantsTrailers bool - - if te := r.Header.Get("TE"); strings.Contains(strings.ToLower(te), "trailers") { - wantsTrailers = true - handleForwardResponseTrailerHeader(w, md) - w.Header().Set("Transfer-Encoding", "chunked") - } - - st := HTTPStatusFromCode(s.Code()) - w.WriteHeader(st) - if _, err := w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - if wantsTrailers { - handleForwardResponseTrailer(w, md) - } -} - -// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler. -// It simply writes a string representation of the given error into "w". -func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) { - http.Error(w, msg, code) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go deleted file mode 100644 index aef645e40b..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go +++ /dev/null @@ -1,89 +0,0 @@ -package runtime - -import ( - "encoding/json" - "io" - "strings" - - descriptor2 "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/protoc-gen-go/descriptor" - "google.golang.org/genproto/protobuf/field_mask" -) - -func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) { - // TODO - should really gate this with a test that the marshaller has used json names - if md != nil { - for _, f := range md.Field { - if f.JsonName != nil && f.Name != nil && *f.JsonName == name { - var subType *descriptor.DescriptorProto - - // If the field has a TypeName then we retrieve the nested type for translating the embedded message names. - if f.TypeName != nil { - typeSplit := strings.Split(*f.TypeName, ".") - typeName := typeSplit[len(typeSplit)-1] - for _, t := range md.NestedType { - if typeName == *t.Name { - subType = t - } - } - } - return *f.Name, subType - } - } - } - return name, nil -} - -// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body. -func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) { - fm := &field_mask.FieldMask{} - var root interface{} - if err := json.NewDecoder(r).Decode(&root); err != nil { - if err == io.EOF { - return fm, nil - } - return nil, err - } - - queue := []fieldMaskPathItem{{node: root, md: md}} - for len(queue) > 0 { - // dequeue an item - item := queue[0] - queue = queue[1:] - - if m, ok := item.node.(map[string]interface{}); ok { - // if the item is an object, then enqueue all of its children - for k, v := range m { - protoName, subMd := translateName(k, item.md) - if subMsg, ok := v.(descriptor2.Message); ok { - _, subMd = descriptor2.ForMessage(subMsg) - } - - var path string - if item.path == "" { - path = protoName - } else { - path = item.path + "." + protoName - } - queue = append(queue, fieldMaskPathItem{path: path, node: v, md: subMd}) - } - } else if len(item.path) > 0 { - // otherwise, it's a leaf node so print its path - fm.Paths = append(fm.Paths, item.path) - } - } - - return fm, nil -} - -// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask -type fieldMaskPathItem struct { - // the list of prior fields leading up to node connected by dots - path string - - // a generic decoded json object the current item to inspect for further path extraction - node interface{} - - // descriptor for parent message - md *descriptor.DescriptorProto -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go deleted file mode 100644 index e6e8f286e1..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go +++ /dev/null @@ -1,212 +0,0 @@ -package runtime - -import ( - "context" - "errors" - "fmt" - "io" - "net/http" - "net/textproto" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/grpclog" -) - -var errEmptyResponse = errors.New("empty response") - -// ForwardResponseStream forwards the stream from gRPC server to REST client. -func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { - f, ok := w.(http.Flusher) - if !ok { - grpclog.Infof("Flush not supported in %T", w) - http.Error(w, "unexpected type of web server", http.StatusInternalServerError) - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - http.Error(w, "unexpected error", http.StatusInternalServerError) - return - } - handleForwardResponseServerMetadata(w, mux, md) - - w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Content-Type", marshaler.ContentType()) - if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - - var delimiter []byte - if d, ok := marshaler.(Delimited); ok { - delimiter = d.Delimiter() - } else { - delimiter = []byte("\n") - } - - var wroteHeader bool - for { - resp, err := recv() - if err == io.EOF { - return - } - if err != nil { - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - - var buf []byte - switch { - case resp == nil: - buf, err = marshaler.Marshal(errorChunk(streamError(ctx, mux.streamErrorHandler, errEmptyResponse))) - default: - result := map[string]interface{}{"result": resp} - if rb, ok := resp.(responseBody); ok { - result["result"] = rb.XXX_ResponseBody() - } - - buf, err = marshaler.Marshal(result) - } - - if err != nil { - grpclog.Infof("Failed to marshal response chunk: %v", err) - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - if _, err = w.Write(buf); err != nil { - grpclog.Infof("Failed to send response chunk: %v", err) - return - } - wroteHeader = true - if _, err = w.Write(delimiter); err != nil { - grpclog.Infof("Failed to send delimiter chunk: %v", err) - return - } - f.Flush() - } -} - -func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) { - for k, vs := range md.HeaderMD { - if h, ok := mux.outgoingHeaderMatcher(k); ok { - for _, v := range vs { - w.Header().Add(h, v) - } - } - } -} - -func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { - for k := range md.TrailerMD { - tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) - w.Header().Add("Trailer", tKey) - } -} - -func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { - for k, vs := range md.TrailerMD { - tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) - for _, v := range vs { - w.Header().Add(tKey, v) - } - } -} - -// responseBody interface contains method for getting field for marshaling to the response body -// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule` -type responseBody interface { - XXX_ResponseBody() interface{} -} - -// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. -func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - handleForwardResponseTrailerHeader(w, md) - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - contentType = typeMarshaler.ContentTypeFromMessage(resp) - } - w.Header().Set("Content-Type", contentType) - - if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - var buf []byte - var err error - if rb, ok := resp.(responseBody); ok { - buf, err = marshaler.Marshal(rb.XXX_ResponseBody()) - } else { - buf, err = marshaler.Marshal(resp) - } - if err != nil { - grpclog.Infof("Marshal error: %v", err) - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - - if _, err = w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - handleForwardResponseTrailer(w, md) -} - -func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { - if len(opts) == 0 { - return nil - } - for _, opt := range opts { - if err := opt(ctx, w, resp); err != nil { - grpclog.Infof("Error handling ForwardResponseOptions: %v", err) - return err - } - } - return nil -} - -func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) { - serr := streamError(ctx, mux.streamErrorHandler, err) - if !wroteHeader { - w.WriteHeader(int(serr.HttpCode)) - } - buf, merr := marshaler.Marshal(errorChunk(serr)) - if merr != nil { - grpclog.Infof("Failed to marshal an error: %v", merr) - return - } - if _, werr := w.Write(buf); werr != nil { - grpclog.Infof("Failed to notify error to client: %v", werr) - return - } -} - -// streamError returns the payload for the final message in a response stream -// that represents the given err. -func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError { - serr := errHandler(ctx, err) - if serr != nil { - return serr - } - // TODO: log about misbehaving stream error handler? - return DefaultHTTPStreamErrorHandler(ctx, err) -} - -func errorChunk(err *StreamError) map[string]proto.Message { - return map[string]proto.Message{"error": (*internal.StreamError)(err)} -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go deleted file mode 100644 index 525b0338c7..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go +++ /dev/null @@ -1,43 +0,0 @@ -package runtime - -import ( - "google.golang.org/genproto/googleapis/api/httpbody" -) - -// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler -func SetHTTPBodyMarshaler(serveMux *ServeMux) { - serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{ - Marshaler: &JSONPb{OrigName: true}, - } -} - -// HTTPBodyMarshaler is a Marshaler which supports marshaling of a -// google.api.HttpBody message as the full response body if it is -// the actual message used as the response. If not, then this will -// simply fallback to the Marshaler specified as its default Marshaler. -type HTTPBodyMarshaler struct { - Marshaler -} - -// ContentType implementation to keep backwards compatibility with marshal interface -func (h *HTTPBodyMarshaler) ContentType() string { - return h.ContentTypeFromMessage(nil) -} - -// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns -// its specified content type otherwise fall back to the default Marshaler. -func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string { - if httpBody, ok := v.(*httpbody.HttpBody); ok { - return httpBody.GetContentType() - } - return h.Marshaler.ContentType() -} - -// Marshal marshals "v" by returning the body bytes if v is a -// google.api.HttpBody message, otherwise it falls back to the default Marshaler. -func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { - if httpBody, ok := v.(*httpbody.HttpBody); ok { - return httpBody.Data, nil - } - return h.Marshaler.Marshal(v) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go deleted file mode 100644 index f0de351b21..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go +++ /dev/null @@ -1,262 +0,0 @@ -package runtime - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "reflect" - - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/proto" -) - -// JSONPb is a Marshaler which marshals/unmarshals into/from JSON -// with the "github.com/golang/protobuf/jsonpb". -// It supports fully functionality of protobuf unlike JSONBuiltin. -// -// The NewDecoder method returns a DecoderWrapper, so the underlying -// *json.Decoder methods can be used. -type JSONPb jsonpb.Marshaler - -// ContentType always returns "application/json". -func (*JSONPb) ContentType() string { - return "application/json" -} - -// Marshal marshals "v" into JSON. -func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { - if _, ok := v.(proto.Message); !ok { - return j.marshalNonProtoField(v) - } - - var buf bytes.Buffer - if err := j.marshalTo(&buf, v); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { - p, ok := v.(proto.Message) - if !ok { - buf, err := j.marshalNonProtoField(v) - if err != nil { - return err - } - _, err = w.Write(buf) - return err - } - return (*jsonpb.Marshaler)(j).Marshal(w, p) -} - -var ( - // protoMessageType is stored to prevent constant lookup of the same type at runtime. - protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() -) - -// marshalNonProto marshals a non-message field of a protobuf message. -// This function does not correctly marshals arbitrary data structure into JSON, -// but it is only capable of marshaling non-message field values of protobuf, -// i.e. primitive types, enums; pointers to primitives or enums; maps from -// integer/string types to primitives/enums/pointers to messages. -func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { - if v == nil { - return []byte("null"), nil - } - rv := reflect.ValueOf(v) - for rv.Kind() == reflect.Ptr { - if rv.IsNil() { - return []byte("null"), nil - } - rv = rv.Elem() - } - - if rv.Kind() == reflect.Slice { - if rv.IsNil() { - if j.EmitDefaults { - return []byte("[]"), nil - } - return []byte("null"), nil - } - - if rv.Type().Elem().Implements(protoMessageType) { - var buf bytes.Buffer - err := buf.WriteByte('[') - if err != nil { - return nil, err - } - for i := 0; i < rv.Len(); i++ { - if i != 0 { - err = buf.WriteByte(',') - if err != nil { - return nil, err - } - } - if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { - return nil, err - } - } - err = buf.WriteByte(']') - if err != nil { - return nil, err - } - - return buf.Bytes(), nil - } - } - - if rv.Kind() == reflect.Map { - m := make(map[string]*json.RawMessage) - for _, k := range rv.MapKeys() { - buf, err := j.Marshal(rv.MapIndex(k).Interface()) - if err != nil { - return nil, err - } - m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) - } - if j.Indent != "" { - return json.MarshalIndent(m, "", j.Indent) - } - return json.Marshal(m) - } - if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts { - return json.Marshal(enum.String()) - } - return json.Marshal(rv.Interface()) -} - -// Unmarshal unmarshals JSON "data" into "v" -func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { - return unmarshalJSONPb(data, v) -} - -// NewDecoder returns a Decoder which reads JSON stream from "r". -func (j *JSONPb) NewDecoder(r io.Reader) Decoder { - d := json.NewDecoder(r) - return DecoderWrapper{Decoder: d} -} - -// DecoderWrapper is a wrapper around a *json.Decoder that adds -// support for protos to the Decode method. -type DecoderWrapper struct { - *json.Decoder -} - -// Decode wraps the embedded decoder's Decode method to support -// protos using a jsonpb.Unmarshaler. -func (d DecoderWrapper) Decode(v interface{}) error { - return decodeJSONPb(d.Decoder, v) -} - -// NewEncoder returns an Encoder which writes JSON stream into "w". -func (j *JSONPb) NewEncoder(w io.Writer) Encoder { - return EncoderFunc(func(v interface{}) error { - if err := j.marshalTo(w, v); err != nil { - return err - } - // mimic json.Encoder by adding a newline (makes output - // easier to read when it contains multiple encoded items) - _, err := w.Write(j.Delimiter()) - return err - }) -} - -func unmarshalJSONPb(data []byte, v interface{}) error { - d := json.NewDecoder(bytes.NewReader(data)) - return decodeJSONPb(d, v) -} - -func decodeJSONPb(d *json.Decoder, v interface{}) error { - p, ok := v.(proto.Message) - if !ok { - return decodeNonProtoField(d, v) - } - unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields} - return unmarshaler.UnmarshalNext(d, p) -} - -func decodeNonProtoField(d *json.Decoder, v interface{}) error { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return fmt.Errorf("%T is not a pointer", v) - } - for rv.Kind() == reflect.Ptr { - if rv.IsNil() { - rv.Set(reflect.New(rv.Type().Elem())) - } - if rv.Type().ConvertibleTo(typeProtoMessage) { - unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields} - return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message)) - } - rv = rv.Elem() - } - if rv.Kind() == reflect.Map { - if rv.IsNil() { - rv.Set(reflect.MakeMap(rv.Type())) - } - conv, ok := convFromType[rv.Type().Key().Kind()] - if !ok { - return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) - } - - m := make(map[string]*json.RawMessage) - if err := d.Decode(&m); err != nil { - return err - } - for k, v := range m { - result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - bk := result[0] - bv := reflect.New(rv.Type().Elem()) - if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil { - return err - } - rv.SetMapIndex(bk, bv.Elem()) - } - return nil - } - if _, ok := rv.Interface().(protoEnum); ok { - var repr interface{} - if err := d.Decode(&repr); err != nil { - return err - } - switch repr.(type) { - case string: - // TODO(yugui) Should use proto.StructProperties? - return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) - case float64: - rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type())) - return nil - default: - return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) - } - } - return d.Decode(v) -} - -type protoEnum interface { - fmt.Stringer - EnumDescriptor() ([]byte, []int) -} - -var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() - -// Delimiter for newline encoded JSON streams. -func (j *JSONPb) Delimiter() []byte { - return []byte("\n") -} - -// allowUnknownFields helps not to return an error when the destination -// is a struct and the input contains object keys which do not match any -// non-ignored, exported fields in the destination. -var allowUnknownFields = true - -// DisallowUnknownFields enables option in decoder (unmarshaller) to -// return an error when it finds an unknown field. This function must be -// called before using the JSON marshaller. -func DisallowUnknownFields() { - allowUnknownFields = false -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go deleted file mode 100644 index 523a9cb43c..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go +++ /dev/null @@ -1,300 +0,0 @@ -package runtime - -import ( - "context" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/golang/protobuf/proto" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// A HandlerFunc handles a specific pair of path pattern and HTTP method. -type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) - -// ErrUnknownURI is the error supplied to a custom ProtoErrorHandlerFunc when -// a request is received with a URI path that does not match any registered -// service method. -// -// Since gRPC servers return an "Unimplemented" code for requests with an -// unrecognized URI path, this error also has a gRPC "Unimplemented" code. -var ErrUnknownURI = status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented)) - -// ServeMux is a request multiplexer for grpc-gateway. -// It matches http requests to patterns and invokes the corresponding handler. -type ServeMux struct { - // handlers maps HTTP method to a list of handlers. - handlers map[string][]handler - forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error - marshalers marshalerRegistry - incomingHeaderMatcher HeaderMatcherFunc - outgoingHeaderMatcher HeaderMatcherFunc - metadataAnnotators []func(context.Context, *http.Request) metadata.MD - streamErrorHandler StreamErrorHandlerFunc - protoErrorHandler ProtoErrorHandlerFunc - disablePathLengthFallback bool - lastMatchWins bool -} - -// ServeMuxOption is an option that can be given to a ServeMux on construction. -type ServeMuxOption func(*ServeMux) - -// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. -// -// forwardResponseOption is an option that will be called on the relevant context.Context, -// http.ResponseWriter, and proto.Message before every forwarded response. -// -// The message may be nil in the case where just a header is being sent. -func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) - } -} - -// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters. -// Configuring this will mean the generated swagger output is no longer correct, and it should be -// done with careful consideration. -func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption { - return func(serveMux *ServeMux) { - currentQueryParser = queryParameterParser - } -} - -// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context. -type HeaderMatcherFunc func(string) (string, bool) - -// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header -// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with -// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. -func DefaultHeaderMatcher(key string) (string, bool) { - key = textproto.CanonicalMIMEHeaderKey(key) - if isPermanentHTTPHeader(key) { - return MetadataPrefix + key, true - } else if strings.HasPrefix(key, MetadataHeaderPrefix) { - return key[len(MetadataHeaderPrefix):], true - } - return "", false -} - -// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway. -// -// This matcher will be called with each header in http.Request. If matcher returns true, that header will be -// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. -func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { - return func(mux *ServeMux) { - mux.incomingHeaderMatcher = fn - } -} - -// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. -// -// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be -// passed to http response returned from gateway. To transform the header before passing to response, -// matcher should return modified header. -func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { - return func(mux *ServeMux) { - mux.outgoingHeaderMatcher = fn - } -} - -// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context. -// -// This can be used by services that need to read from http.Request and modify gRPC context. A common use case -// is reading token from cookie and adding it in gRPC context. -func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator) - } -} - -// WithProtoErrorHandler returns a ServeMuxOption for configuring a custom error handler. -// -// This can be used to handle an error as general proto message defined by gRPC. -// When this option is used, the mux uses the configured error handler instead of HTTPError and -// OtherErrorHandler. -func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.protoErrorHandler = fn - } -} - -// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback. -func WithDisablePathLengthFallback() ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.disablePathLengthFallback = true - } -} - -// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream -// error handler, which allows for customizing the error trailer for server-streaming -// calls. -// -// For stream errors that occur before any response has been written, the mux's -// ProtoErrorHandler will be invoked. However, once data has been written, the errors must -// be handled differently: they must be included in the response body. The response body's -// final message will include the error details returned by the stream error handler. -func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.streamErrorHandler = fn - } -} - -// WithLastMatchWins returns a ServeMuxOption that will enable "last -// match wins" behavior, where if multiple path patterns match a -// request path, the last one defined in the .proto file will be used. -func WithLastMatchWins() ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.lastMatchWins = true - } -} - -// NewServeMux returns a new ServeMux whose internal mapping is empty. -func NewServeMux(opts ...ServeMuxOption) *ServeMux { - serveMux := &ServeMux{ - handlers: make(map[string][]handler), - forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), - marshalers: makeMarshalerMIMERegistry(), - streamErrorHandler: DefaultHTTPStreamErrorHandler, - } - - for _, opt := range opts { - opt(serveMux) - } - - if serveMux.incomingHeaderMatcher == nil { - serveMux.incomingHeaderMatcher = DefaultHeaderMatcher - } - - if serveMux.outgoingHeaderMatcher == nil { - serveMux.outgoingHeaderMatcher = func(key string) (string, bool) { - return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true - } - } - - return serveMux -} - -// Handle associates "h" to the pair of HTTP method and path pattern. -func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { - if s.lastMatchWins { - s.handlers[meth] = append([]handler{handler{pat: pat, h: h}}, s.handlers[meth]...) - } else { - s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h}) - } -} - -// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. -func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - path := r.URL.Path - if !strings.HasPrefix(path, "/") { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest)) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - } - return - } - - components := strings.Split(path[1:], "/") - l := len(components) - var verb string - if idx := strings.LastIndex(components[l-1], ":"); idx == 0 { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } - return - } else if idx > 0 { - c := components[l-1] - components[l-1], verb = c[:idx], c[idx+1:] - } - - if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { - r.Method = strings.ToUpper(override) - if err := r.ParseForm(); err != nil { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, err.Error()) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) - } - return - } - } - for _, h := range s.handlers[r.Method] { - pathParams, err := h.pat.Match(components, verb) - if err != nil { - continue - } - h.h(w, r, pathParams) - return - } - - // lookup other methods to handle fallback from GET to POST and - // to determine if it is MethodNotAllowed or NotFound. - for m, handlers := range s.handlers { - if m == r.Method { - continue - } - for _, h := range handlers { - pathParams, err := h.pat.Match(components, verb) - if err != nil { - continue - } - // X-HTTP-Method-Override is optional. Always allow fallback to POST. - if s.isPathLengthFallback(r) { - if err := r.ParseForm(); err != nil { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, err.Error()) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) - } - return - } - h.h(w, r, pathParams) - return - } - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) - } - return - } - } - - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } -} - -// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. -func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { - return s.forwardResponseOptions -} - -func (s *ServeMux) isPathLengthFallback(r *http.Request) bool { - return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" -} - -type handler struct { - pat Pattern - h HandlerFunc -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go deleted file mode 100644 index 09053695da..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go +++ /dev/null @@ -1,262 +0,0 @@ -package runtime - -import ( - "errors" - "fmt" - "strings" - - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc/grpclog" -) - -var ( - // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. - ErrNotMatch = errors.New("not match to the path pattern") - // ErrInvalidPattern indicates that the given definition of Pattern is not valid. - ErrInvalidPattern = errors.New("invalid pattern") -) - -type op struct { - code utilities.OpCode - operand int -} - -// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto. -type Pattern struct { - // ops is a list of operations - ops []op - // pool is a constant pool indexed by the operands or vars. - pool []string - // vars is a list of variables names to be bound by this pattern - vars []string - // stacksize is the max depth of the stack - stacksize int - // tailLen is the length of the fixed-size segments after a deep wildcard - tailLen int - // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. - verb string - // assumeColonVerb indicates whether a path suffix after a final - // colon may only be interpreted as a verb. - assumeColonVerb bool -} - -type patternOptions struct { - assumeColonVerb bool -} - -// PatternOpt is an option for creating Patterns. -type PatternOpt func(*patternOptions) - -// NewPattern returns a new Pattern from the given definition values. -// "ops" is a sequence of op codes. "pool" is a constant pool. -// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. -// "version" must be 1 for now. -// It returns an error if the given definition is invalid. -func NewPattern(version int, ops []int, pool []string, verb string, opts ...PatternOpt) (Pattern, error) { - options := patternOptions{ - assumeColonVerb: true, - } - for _, o := range opts { - o(&options) - } - - if version != 1 { - grpclog.Infof("unsupported version: %d", version) - return Pattern{}, ErrInvalidPattern - } - - l := len(ops) - if l%2 != 0 { - grpclog.Infof("odd number of ops codes: %d", l) - return Pattern{}, ErrInvalidPattern - } - - var ( - typedOps []op - stack, maxstack int - tailLen int - pushMSeen bool - vars []string - ) - for i := 0; i < l; i += 2 { - op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush: - if pushMSeen { - tailLen++ - } - stack++ - case utilities.OpPushM: - if pushMSeen { - grpclog.Infof("pushM appears twice") - return Pattern{}, ErrInvalidPattern - } - pushMSeen = true - stack++ - case utilities.OpLitPush: - if op.operand < 0 || len(pool) <= op.operand { - grpclog.Infof("negative literal index: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - if pushMSeen { - tailLen++ - } - stack++ - case utilities.OpConcatN: - if op.operand <= 0 { - grpclog.Infof("negative concat size: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - stack -= op.operand - if stack < 0 { - grpclog.Print("stack underflow") - return Pattern{}, ErrInvalidPattern - } - stack++ - case utilities.OpCapture: - if op.operand < 0 || len(pool) <= op.operand { - grpclog.Infof("variable name index out of bound: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - v := pool[op.operand] - op.operand = len(vars) - vars = append(vars, v) - stack-- - if stack < 0 { - grpclog.Infof("stack underflow") - return Pattern{}, ErrInvalidPattern - } - default: - grpclog.Infof("invalid opcode: %d", op.code) - return Pattern{}, ErrInvalidPattern - } - - if maxstack < stack { - maxstack = stack - } - typedOps = append(typedOps, op) - } - return Pattern{ - ops: typedOps, - pool: pool, - vars: vars, - stacksize: maxstack, - tailLen: tailLen, - verb: verb, - assumeColonVerb: options.assumeColonVerb, - }, nil -} - -// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. -func MustPattern(p Pattern, err error) Pattern { - if err != nil { - grpclog.Fatalf("Pattern initialization failed: %v", err) - } - return p -} - -// Match examines components if it matches to the Pattern. -// If it matches, the function returns a mapping from field paths to their captured values. -// If otherwise, the function returns an error. -func (p Pattern) Match(components []string, verb string) (map[string]string, error) { - if p.verb != verb { - if p.assumeColonVerb || p.verb != "" { - return nil, ErrNotMatch - } - if len(components) == 0 { - components = []string{":" + verb} - } else { - components = append([]string{}, components...) - components[len(components)-1] += ":" + verb - } - verb = "" - } - - var pos int - stack := make([]string, 0, p.stacksize) - captured := make([]string, len(p.vars)) - l := len(components) - for _, op := range p.ops { - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush, utilities.OpLitPush: - if pos >= l { - return nil, ErrNotMatch - } - c := components[pos] - if op.code == utilities.OpLitPush { - if lit := p.pool[op.operand]; c != lit { - return nil, ErrNotMatch - } - } - stack = append(stack, c) - pos++ - case utilities.OpPushM: - end := len(components) - if end < pos+p.tailLen { - return nil, ErrNotMatch - } - end -= p.tailLen - stack = append(stack, strings.Join(components[pos:end], "/")) - pos = end - case utilities.OpConcatN: - n := op.operand - l := len(stack) - n - stack = append(stack[:l], strings.Join(stack[l:], "/")) - case utilities.OpCapture: - n := len(stack) - 1 - captured[op.operand] = stack[n] - stack = stack[:n] - } - } - if pos < l { - return nil, ErrNotMatch - } - bindings := make(map[string]string) - for i, val := range captured { - bindings[p.vars[i]] = val - } - return bindings, nil -} - -// Verb returns the verb part of the Pattern. -func (p Pattern) Verb() string { return p.verb } - -func (p Pattern) String() string { - var stack []string - for _, op := range p.ops { - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush: - stack = append(stack, "*") - case utilities.OpLitPush: - stack = append(stack, p.pool[op.operand]) - case utilities.OpPushM: - stack = append(stack, "**") - case utilities.OpConcatN: - n := op.operand - l := len(stack) - n - stack = append(stack[:l], strings.Join(stack[l:], "/")) - case utilities.OpCapture: - n := len(stack) - 1 - stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) - } - } - segs := strings.Join(stack, "/") - if p.verb != "" { - return fmt.Sprintf("/%s:%s", segs, p.verb) - } - return "/" + segs -} - -// AssumeColonVerbOpt indicates whether a path suffix after a final -// colon may only be interpreted as a verb. -func AssumeColonVerbOpt(val bool) PatternOpt { - return PatternOpt(func(o *patternOptions) { - o.assumeColonVerb = val - }) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go deleted file mode 100644 index 3fd30da22a..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go +++ /dev/null @@ -1,106 +0,0 @@ -package runtime - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/ptypes/any" - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a -// a proto struct used to represent error at the end of a stream. -type StreamErrorHandlerFunc func(context.Context, error) *StreamError - -// StreamError is the payload for the final message in a server stream in the event that the server returns an -// error after a response message has already been sent. -type StreamError internal.StreamError - -// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request. -type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) - -var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler - -// DefaultHTTPProtoErrorHandler is an implementation of HTTPError. -// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. -// If otherwise, it replies with http.StatusInternalServerError. -// -// The response body returned by this function is a Status message marshaled by a Marshaler. -// -// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead. -func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) { - // return Internal when Marshal failed - const fallback = `{"code": 13, "message": "failed to marshal error message"}` - - s, ok := status.FromError(err) - if !ok { - s = status.New(codes.Unknown, err.Error()) - } - - w.Header().Del("Trailer") - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - pb := s.Proto() - contentType = typeMarshaler.ContentTypeFromMessage(pb) - } - w.Header().Set("Content-Type", contentType) - - buf, merr := marshaler.Marshal(s.Proto()) - if merr != nil { - grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr) - w.WriteHeader(http.StatusInternalServerError) - if _, err := io.WriteString(w, fallback); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - handleForwardResponseTrailerHeader(w, md) - st := HTTPStatusFromCode(s.Code()) - w.WriteHeader(st) - if _, err := w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - handleForwardResponseTrailer(w, md) -} - -// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via -// default logic. -// -// It extracts the gRPC status from err if possible. The fields of the status are -// used to populate the returned StreamError, and the HTTP status code is derived -// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a -// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code. -func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError { - grpcCode := codes.Unknown - grpcMessage := err.Error() - var grpcDetails []*any.Any - if s, ok := status.FromError(err); ok { - grpcCode = s.Code() - grpcMessage = s.Message() - grpcDetails = s.Proto().GetDetails() - } - httpCode := HTTPStatusFromCode(grpcCode) - return &StreamError{ - GrpcCode: int32(grpcCode), - HttpCode: int32(httpCode), - Message: grpcMessage, - HttpStatus: http.StatusText(httpCode), - Details: grpcDetails, - } -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go deleted file mode 100644 index ba66842c33..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go +++ /dev/null @@ -1,406 +0,0 @@ -package runtime - -import ( - "encoding/base64" - "fmt" - "net/url" - "reflect" - "regexp" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc/grpclog" -) - -var valuesKeyRegexp = regexp.MustCompile("^(.*)\\[(.*)\\]$") - -var currentQueryParser QueryParameterParser = &defaultQueryParser{} - -// QueryParameterParser defines interface for all query parameter parsers -type QueryParameterParser interface { - Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error -} - -// PopulateQueryParameters parses query parameters -// into "msg" using current query parser -func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { - return currentQueryParser.Parse(msg, values, filter) -} - -type defaultQueryParser struct{} - -// Parse populates "values" into "msg". -// A value is ignored if its key starts with one of the elements in "filter". -func (*defaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { - for key, values := range values { - match := valuesKeyRegexp.FindStringSubmatch(key) - if len(match) == 3 { - key = match[1] - values = append([]string{match[2]}, values...) - } - fieldPath := strings.Split(key, ".") - if filter.HasCommonPrefix(fieldPath) { - continue - } - if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil { - return err - } - } - return nil -} - -// PopulateFieldFromPath sets a value in a nested Protobuf structure. -// It instantiates missing protobuf fields as it goes. -func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { - fieldPath := strings.Split(fieldPathString, ".") - return populateFieldValueFromPath(msg, fieldPath, []string{value}) -} - -func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error { - m := reflect.ValueOf(msg) - if m.Kind() != reflect.Ptr { - return fmt.Errorf("unexpected type %T: %v", msg, msg) - } - var props *proto.Properties - m = m.Elem() - for i, fieldName := range fieldPath { - isLast := i == len(fieldPath)-1 - if !isLast && m.Kind() != reflect.Struct { - return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, ".")) - } - var f reflect.Value - var err error - f, props, err = fieldByProtoName(m, fieldName) - if err != nil { - return err - } else if !f.IsValid() { - grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, ".")) - return nil - } - - switch f.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: - if !isLast { - return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) - } - m = f - case reflect.Slice: - if !isLast { - return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, ".")) - } - // Handle []byte - if f.Type().Elem().Kind() == reflect.Uint8 { - m = f - break - } - return populateRepeatedField(f, values, props) - case reflect.Ptr: - if f.IsNil() { - m = reflect.New(f.Type().Elem()) - f.Set(m.Convert(f.Type())) - } - m = f.Elem() - continue - case reflect.Struct: - m = f - continue - case reflect.Map: - if !isLast { - return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) - } - return populateMapField(f, values, props) - default: - return fmt.Errorf("unexpected type %s in %T", f.Type(), msg) - } - } - switch len(values) { - case 0: - return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, ".")) - case 1: - default: - grpclog.Infof("too many field values: %s", strings.Join(fieldPath, ".")) - } - return populateField(m, values[0], props) -} - -// fieldByProtoName looks up a field whose corresponding protobuf field name is "name". -// "m" must be a struct value. It returns zero reflect.Value if no such field found. -func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) { - props := proto.GetProperties(m.Type()) - - // look up field name in oneof map - for _, op := range props.OneofTypes { - if name == op.Prop.OrigName || name == op.Prop.JSONName { - v := reflect.New(op.Type.Elem()) - field := m.Field(op.Field) - if !field.IsNil() { - return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName) - } - field.Set(v) - return v.Elem().Field(0), op.Prop, nil - } - } - - for _, p := range props.Prop { - if p.OrigName == name { - return m.FieldByName(p.Name), p, nil - } - if p.JSONName == name { - return m.FieldByName(p.Name), p, nil - } - } - return reflect.Value{}, nil, nil -} - -func populateMapField(f reflect.Value, values []string, props *proto.Properties) error { - if len(values) != 2 { - return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name) - } - - key, value := values[0], values[1] - keyType := f.Type().Key() - valueType := f.Type().Elem() - if f.IsNil() { - f.Set(reflect.MakeMap(f.Type())) - } - - keyConv, ok := convFromType[keyType.Kind()] - if !ok { - return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name) - } - valueConv, ok := convFromType[valueType.Kind()] - if !ok { - return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name) - } - - keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)}) - if err := keyV[1].Interface(); err != nil { - return err.(error) - } - valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)}) - if err := valueV[1].Interface(); err != nil { - return err.(error) - } - - f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType)) - - return nil -} - -func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error { - elemType := f.Type().Elem() - - // is the destination field a slice of an enumeration type? - if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { - return populateFieldEnumRepeated(f, values, enumValMap) - } - - conv, ok := convFromType[elemType.Kind()] - if !ok { - return fmt.Errorf("unsupported field type %s", elemType) - } - f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) - for i, v := range values { - result := conv.Call([]reflect.Value{reflect.ValueOf(v)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - f.Index(i).Set(result[0].Convert(f.Index(i).Type())) - } - return nil -} - -func populateField(f reflect.Value, value string, props *proto.Properties) error { - i := f.Addr().Interface() - - // Handle protobuf well known types - var name string - switch m := i.(type) { - case interface{ XXX_WellKnownType() string }: - name = m.XXX_WellKnownType() - case proto.Message: - const wktPrefix = "google.protobuf." - if fullName := proto.MessageName(m); strings.HasPrefix(fullName, wktPrefix) { - name = fullName[len(wktPrefix):] - } - } - switch name { - case "Timestamp": - if value == "null" { - f.FieldByName("Seconds").SetInt(0) - f.FieldByName("Nanos").SetInt(0) - return nil - } - - t, err := time.Parse(time.RFC3339Nano, value) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - f.FieldByName("Seconds").SetInt(int64(t.Unix())) - f.FieldByName("Nanos").SetInt(int64(t.Nanosecond())) - return nil - case "Duration": - if value == "null" { - f.FieldByName("Seconds").SetInt(0) - f.FieldByName("Nanos").SetInt(0) - return nil - } - d, err := time.ParseDuration(value) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - ns := d.Nanoseconds() - s := ns / 1e9 - ns %= 1e9 - f.FieldByName("Seconds").SetInt(s) - f.FieldByName("Nanos").SetInt(ns) - return nil - case "DoubleValue": - fallthrough - case "FloatValue": - float64Val, err := strconv.ParseFloat(value, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetFloat(float64Val) - return nil - case "Int64Value": - fallthrough - case "Int32Value": - int64Val, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetInt(int64Val) - return nil - case "UInt64Value": - fallthrough - case "UInt32Value": - uint64Val, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetUint(uint64Val) - return nil - case "BoolValue": - if value == "true" { - f.FieldByName("Value").SetBool(true) - } else if value == "false" { - f.FieldByName("Value").SetBool(false) - } else { - return fmt.Errorf("bad BoolValue: %s", value) - } - return nil - case "StringValue": - f.FieldByName("Value").SetString(value) - return nil - case "BytesValue": - bytesVal, err := base64.StdEncoding.DecodeString(value) - if err != nil { - return fmt.Errorf("bad BytesValue: %s", value) - } - f.FieldByName("Value").SetBytes(bytesVal) - return nil - case "FieldMask": - p := f.FieldByName("Paths") - for _, v := range strings.Split(value, ",") { - if v != "" { - p.Set(reflect.Append(p, reflect.ValueOf(v))) - } - } - return nil - } - - // Handle Time and Duration stdlib types - switch t := i.(type) { - case *time.Time: - pt, err := time.Parse(time.RFC3339Nano, value) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - *t = pt - return nil - case *time.Duration: - d, err := time.ParseDuration(value) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - *t = d - return nil - } - - // is the destination field an enumeration type? - if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { - return populateFieldEnum(f, value, enumValMap) - } - - conv, ok := convFromType[f.Kind()] - if !ok { - return fmt.Errorf("field type %T is not supported in query parameters", i) - } - result := conv.Call([]reflect.Value{reflect.ValueOf(value)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - f.Set(result[0].Convert(f.Type())) - return nil -} - -func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) { - // see if it's an enumeration string - if enumVal, ok := enumValMap[value]; ok { - return reflect.ValueOf(enumVal).Convert(t), nil - } - - // check for an integer that matches an enumeration value - eVal, err := strconv.Atoi(value) - if err != nil { - return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) - } - for _, v := range enumValMap { - if v == int32(eVal) { - return reflect.ValueOf(eVal).Convert(t), nil - } - } - return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) -} - -func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error { - cval, err := convertEnum(value, f.Type(), enumValMap) - if err != nil { - return err - } - f.Set(cval) - return nil -} - -func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error { - elemType := f.Type().Elem() - f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) - for i, v := range values { - result, err := convertEnum(v, elemType, enumValMap) - if err != nil { - return err - } - f.Index(i).Set(result) - } - return nil -} - -var ( - convFromType = map[reflect.Kind]reflect.Value{ - reflect.String: reflect.ValueOf(String), - reflect.Bool: reflect.ValueOf(Bool), - reflect.Float64: reflect.ValueOf(Float64), - reflect.Float32: reflect.ValueOf(Float32), - reflect.Int64: reflect.ValueOf(Int64), - reflect.Int32: reflect.ValueOf(Int32), - reflect.Uint64: reflect.ValueOf(Uint64), - reflect.Uint32: reflect.ValueOf(Uint32), - reflect.Slice: reflect.ValueOf(Bytes), - } -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel deleted file mode 100644 index 7109d79323..0000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -package(default_visibility = ["//visibility:public"]) - -go_library( - name = "go_default_library", - srcs = [ - "doc.go", - "pattern.go", - "readerfactory.go", - "trie.go", - ], - importpath = "github.com/grpc-ecosystem/grpc-gateway/utilities", -) - -go_test( - name = "go_default_test", - size = "small", - srcs = ["trie_test.go"], - embed = [":go_default_library"], -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE.txt similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE.txt diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel new file mode 100644 index 0000000000..f694f3c0d0 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "httprule", + srcs = [ + "compile.go", + "parse.go", + "types.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule", + deps = ["//utilities"], +) + +go_test( + name = "httprule_test", + size = "small", + srcs = [ + "compile_test.go", + "parse_test.go", + "types_test.go", + ], + embed = [":httprule"], + deps = [ + "//utilities", + "@com_github_golang_glog//:glog", + ], +) + +alias( + name = "go_default_library", + actual = ":httprule", + visibility = ["//:__subpackages__"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go new file mode 100644 index 0000000000..3cd9372959 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go @@ -0,0 +1,121 @@ +package httprule + +import ( + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" +) + +const ( + opcodeVersion = 1 +) + +// Template is a compiled representation of path templates. +type Template struct { + // Version is the version number of the format. + Version int + // OpCodes is a sequence of operations. + OpCodes []int + // Pool is a constant pool + Pool []string + // Verb is a VERB part in the template. + Verb string + // Fields is a list of field paths bound in this template. + Fields []string + // Original template (example: /v1/a_bit_of_everything) + Template string +} + +// Compiler compiles utilities representation of path templates into marshallable operations. +// They can be unmarshalled by runtime.NewPattern. +type Compiler interface { + Compile() Template +} + +type op struct { + // code is the opcode of the operation + code utilities.OpCode + + // str is a string operand of the code. + // num is ignored if str is not empty. + str string + + // num is a numeric operand of the code. + num int +} + +func (w wildcard) compile() []op { + return []op{ + {code: utilities.OpPush}, + } +} + +func (w deepWildcard) compile() []op { + return []op{ + {code: utilities.OpPushM}, + } +} + +func (l literal) compile() []op { + return []op{ + { + code: utilities.OpLitPush, + str: string(l), + }, + } +} + +func (v variable) compile() []op { + var ops []op + for _, s := range v.segments { + ops = append(ops, s.compile()...) + } + ops = append(ops, op{ + code: utilities.OpConcatN, + num: len(v.segments), + }, op{ + code: utilities.OpCapture, + str: v.path, + }) + + return ops +} + +func (t template) Compile() Template { + var rawOps []op + for _, s := range t.segments { + rawOps = append(rawOps, s.compile()...) + } + + var ( + ops []int + pool []string + fields []string + ) + consts := make(map[string]int) + for _, op := range rawOps { + ops = append(ops, int(op.code)) + if op.str == "" { + ops = append(ops, op.num) + } else { + // eof segment literal represents the "/" path pattern + if op.str == eof { + op.str = "" + } + if _, ok := consts[op.str]; !ok { + consts[op.str] = len(pool) + pool = append(pool, op.str) + } + ops = append(ops, consts[op.str]) + } + if op.code == utilities.OpCapture { + fields = append(fields, op.str) + } + } + return Template{ + Version: opcodeVersion, + OpCodes: ops, + Pool: pool, + Verb: t.verb, + Fields: fields, + Template: t.template, + } +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go new file mode 100644 index 0000000000..138f7c12f0 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go @@ -0,0 +1,11 @@ +// +build gofuzz + +package httprule + +func Fuzz(data []byte) int { + _, err := Parse(string(data)) + if err != nil { + return 0 + } + return 0 +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go new file mode 100644 index 0000000000..5edd784e62 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go @@ -0,0 +1,368 @@ +package httprule + +import ( + "fmt" + "strings" +) + +// InvalidTemplateError indicates that the path template is not valid. +type InvalidTemplateError struct { + tmpl string + msg string +} + +func (e InvalidTemplateError) Error() string { + return fmt.Sprintf("%s: %s", e.msg, e.tmpl) +} + +// Parse parses the string representation of path template +func Parse(tmpl string) (Compiler, error) { + if !strings.HasPrefix(tmpl, "/") { + return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"} + } + tokens, verb := tokenize(tmpl[1:]) + + p := parser{tokens: tokens} + segs, err := p.topLevelSegments() + if err != nil { + return template{}, InvalidTemplateError{tmpl: tmpl, msg: err.Error()} + } + + return template{ + segments: segs, + verb: verb, + template: tmpl, + }, nil +} + +func tokenize(path string) (tokens []string, verb string) { + if path == "" { + return []string{eof}, "" + } + + const ( + init = iota + field + nested + ) + st := init + for path != "" { + var idx int + switch st { + case init: + idx = strings.IndexAny(path, "/{") + case field: + idx = strings.IndexAny(path, ".=}") + case nested: + idx = strings.IndexAny(path, "/}") + } + if idx < 0 { + tokens = append(tokens, path) + break + } + switch r := path[idx]; r { + case '/', '.': + case '{': + st = field + case '=': + st = nested + case '}': + st = init + } + if idx == 0 { + tokens = append(tokens, path[idx:idx+1]) + } else { + tokens = append(tokens, path[:idx], path[idx:idx+1]) + } + path = path[idx+1:] + } + + l := len(tokens) + // See + // https://github.com/grpc-ecosystem/grpc-gateway/pull/1947#issuecomment-774523693 ; + // although normal and backwards-compat logic here is to use the last index + // of a colon, if the final segment is a variable followed by a colon, the + // part following the colon must be a verb. Hence if the previous token is + // an end var marker, we switch the index we're looking for to Index instead + // of LastIndex, so that we correctly grab the remaining part of the path as + // the verb. + var penultimateTokenIsEndVar bool + switch l { + case 0, 1: + // Not enough to be variable so skip this logic and don't result in an + // invalid index + default: + penultimateTokenIsEndVar = tokens[l-2] == "}" + } + t := tokens[l-1] + var idx int + if penultimateTokenIsEndVar { + idx = strings.Index(t, ":") + } else { + idx = strings.LastIndex(t, ":") + } + if idx == 0 { + tokens, verb = tokens[:l-1], t[1:] + } else if idx > 0 { + tokens[l-1], verb = t[:idx], t[idx+1:] + } + tokens = append(tokens, eof) + return tokens, verb +} + +// parser is a parser of the template syntax defined in github.com/googleapis/googleapis/google/api/http.proto. +type parser struct { + tokens []string + accepted []string +} + +// topLevelSegments is the target of this parser. +func (p *parser) topLevelSegments() ([]segment, error) { + if _, err := p.accept(typeEOF); err == nil { + p.tokens = p.tokens[:0] + return []segment{literal(eof)}, nil + } + segs, err := p.segments() + if err != nil { + return nil, err + } + if _, err := p.accept(typeEOF); err != nil { + return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, "")) + } + return segs, nil +} + +func (p *parser) segments() ([]segment, error) { + s, err := p.segment() + if err != nil { + return nil, err + } + + segs := []segment{s} + for { + if _, err := p.accept("/"); err != nil { + return segs, nil + } + s, err := p.segment() + if err != nil { + return segs, err + } + segs = append(segs, s) + } +} + +func (p *parser) segment() (segment, error) { + if _, err := p.accept("*"); err == nil { + return wildcard{}, nil + } + if _, err := p.accept("**"); err == nil { + return deepWildcard{}, nil + } + if l, err := p.literal(); err == nil { + return l, nil + } + + v, err := p.variable() + if err != nil { + return nil, fmt.Errorf("segment neither wildcards, literal or variable: %v", err) + } + return v, err +} + +func (p *parser) literal() (segment, error) { + lit, err := p.accept(typeLiteral) + if err != nil { + return nil, err + } + return literal(lit), nil +} + +func (p *parser) variable() (segment, error) { + if _, err := p.accept("{"); err != nil { + return nil, err + } + + path, err := p.fieldPath() + if err != nil { + return nil, err + } + + var segs []segment + if _, err := p.accept("="); err == nil { + segs, err = p.segments() + if err != nil { + return nil, fmt.Errorf("invalid segment in variable %q: %v", path, err) + } + } else { + segs = []segment{wildcard{}} + } + + if _, err := p.accept("}"); err != nil { + return nil, fmt.Errorf("unterminated variable segment: %s", path) + } + return variable{ + path: path, + segments: segs, + }, nil +} + +func (p *parser) fieldPath() (string, error) { + c, err := p.accept(typeIdent) + if err != nil { + return "", err + } + components := []string{c} + for { + if _, err = p.accept("."); err != nil { + return strings.Join(components, "."), nil + } + c, err := p.accept(typeIdent) + if err != nil { + return "", fmt.Errorf("invalid field path component: %v", err) + } + components = append(components, c) + } +} + +// A termType is a type of terminal symbols. +type termType string + +// These constants define some of valid values of termType. +// They improve readability of parse functions. +// +// You can also use "/", "*", "**", "." or "=" as valid values. +const ( + typeIdent = termType("ident") + typeLiteral = termType("literal") + typeEOF = termType("$") +) + +const ( + // eof is the terminal symbol which always appears at the end of token sequence. + eof = "\u0000" +) + +// accept tries to accept a token in "p". +// This function consumes a token and returns it if it matches to the specified "term". +// If it doesn't match, the function does not consume any tokens and return an error. +func (p *parser) accept(term termType) (string, error) { + t := p.tokens[0] + switch term { + case "/", "*", "**", ".", "=", "{", "}": + if t != string(term) && t != "/" { + return "", fmt.Errorf("expected %q but got %q", term, t) + } + case typeEOF: + if t != eof { + return "", fmt.Errorf("expected EOF but got %q", t) + } + case typeIdent: + if err := expectIdent(t); err != nil { + return "", err + } + case typeLiteral: + if err := expectPChars(t); err != nil { + return "", err + } + default: + return "", fmt.Errorf("unknown termType %q", term) + } + p.tokens = p.tokens[1:] + p.accepted = append(p.accepted, t) + return t, nil +} + +// expectPChars determines if "t" consists of only pchars defined in RFC3986. +// +// https://www.ietf.org/rfc/rfc3986.txt, P.49 +// pchar = unreserved / pct-encoded / sub-delims / ":" / "@" +// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" +// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" +// / "*" / "+" / "," / ";" / "=" +// pct-encoded = "%" HEXDIG HEXDIG +func expectPChars(t string) error { + const ( + init = iota + pct1 + pct2 + ) + st := init + for _, r := range t { + if st != init { + if !isHexDigit(r) { + return fmt.Errorf("invalid hexdigit: %c(%U)", r, r) + } + switch st { + case pct1: + st = pct2 + case pct2: + st = init + } + continue + } + + // unreserved + switch { + case 'A' <= r && r <= 'Z': + continue + case 'a' <= r && r <= 'z': + continue + case '0' <= r && r <= '9': + continue + } + switch r { + case '-', '.', '_', '~': + // unreserved + case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': + // sub-delims + case ':', '@': + // rest of pchar + case '%': + // pct-encoded + st = pct1 + default: + return fmt.Errorf("invalid character in path segment: %q(%U)", r, r) + } + } + if st != init { + return fmt.Errorf("invalid percent-encoding in %q", t) + } + return nil +} + +// expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*). +func expectIdent(ident string) error { + if ident == "" { + return fmt.Errorf("empty identifier") + } + for pos, r := range ident { + switch { + case '0' <= r && r <= '9': + if pos == 0 { + return fmt.Errorf("identifier starting with digit: %s", ident) + } + continue + case 'A' <= r && r <= 'Z': + continue + case 'a' <= r && r <= 'z': + continue + case r == '_': + continue + default: + return fmt.Errorf("invalid character %q(%U) in identifier: %s", r, r, ident) + } + } + return nil +} + +func isHexDigit(r rune) bool { + switch { + case '0' <= r && r <= '9': + return true + case 'A' <= r && r <= 'F': + return true + case 'a' <= r && r <= 'f': + return true + } + return false +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go new file mode 100644 index 0000000000..5a814a0004 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go @@ -0,0 +1,60 @@ +package httprule + +import ( + "fmt" + "strings" +) + +type template struct { + segments []segment + verb string + template string +} + +type segment interface { + fmt.Stringer + compile() (ops []op) +} + +type wildcard struct{} + +type deepWildcard struct{} + +type literal string + +type variable struct { + path string + segments []segment +} + +func (wildcard) String() string { + return "*" +} + +func (deepWildcard) String() string { + return "**" +} + +func (l literal) String() string { + return string(l) +} + +func (v variable) String() string { + var segs []string + for _, s := range v.segments { + segs = append(segs, s.String()) + } + return fmt.Sprintf("{%s=%s}", v.path, strings.Join(segs, "/")) +} + +func (t template) String() string { + var segs []string + for _, s := range t.segments { + segs = append(segs, s.String()) + } + str := strings.Join(segs, "/") + if t.verb != "" { + str = fmt.Sprintf("%s:%s", str, t.verb) + } + return "/" + str +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel new file mode 100644 index 0000000000..95f867a528 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel @@ -0,0 +1,91 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "runtime", + srcs = [ + "context.go", + "convert.go", + "doc.go", + "errors.go", + "fieldmask.go", + "handler.go", + "marshal_httpbodyproto.go", + "marshal_json.go", + "marshal_jsonpb.go", + "marshal_proto.go", + "marshaler.go", + "marshaler_registry.go", + "mux.go", + "pattern.go", + "proto2_convert.go", + "query.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime", + deps = [ + "//internal/httprule", + "//utilities", + "@go_googleapis//google/api:httpbody_go_proto", + "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//grpclog", + "@org_golang_google_grpc//metadata", + "@org_golang_google_grpc//status", + "@org_golang_google_protobuf//encoding/protojson", + "@org_golang_google_protobuf//proto", + "@org_golang_google_protobuf//reflect/protoreflect", + "@org_golang_google_protobuf//reflect/protoregistry", + "@org_golang_google_protobuf//types/known/durationpb", + "@org_golang_google_protobuf//types/known/timestamppb", + "@org_golang_google_protobuf//types/known/wrapperspb", + ], +) + +go_test( + name = "runtime_test", + size = "small", + srcs = [ + "context_test.go", + "convert_test.go", + "errors_test.go", + "fieldmask_test.go", + "handler_test.go", + "marshal_httpbodyproto_test.go", + "marshal_json_test.go", + "marshal_jsonpb_test.go", + "marshal_proto_test.go", + "marshaler_registry_test.go", + "mux_test.go", + "pattern_test.go", + "query_test.go", + ], + embed = [":runtime"], + deps = [ + "//runtime/internal/examplepb", + "//utilities", + "@com_github_google_go_cmp//cmp", + "@com_github_google_go_cmp//cmp/cmpopts", + "@go_googleapis//google/api:httpbody_go_proto", + "@go_googleapis//google/rpc:errdetails_go_proto", + "@go_googleapis//google/rpc:status_go_proto", + "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//metadata", + "@org_golang_google_grpc//status", + "@org_golang_google_protobuf//encoding/protojson", + "@org_golang_google_protobuf//proto", + "@org_golang_google_protobuf//testing/protocmp", + "@org_golang_google_protobuf//types/known/durationpb", + "@org_golang_google_protobuf//types/known/emptypb", + "@org_golang_google_protobuf//types/known/structpb", + "@org_golang_google_protobuf//types/known/timestamppb", + "@org_golang_google_protobuf//types/known/wrapperspb", + ], +) + +alias( + name = "go_default_library", + actual = ":runtime", + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go new file mode 100644 index 0000000000..fb57b9366e --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go @@ -0,0 +1,345 @@ +package runtime + +import ( + "context" + "encoding/base64" + "fmt" + "net" + "net/http" + "net/textproto" + "strconv" + "strings" + "sync" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// MetadataHeaderPrefix is the http prefix that represents custom metadata +// parameters to or from a gRPC call. +const MetadataHeaderPrefix = "Grpc-Metadata-" + +// MetadataPrefix is prepended to permanent HTTP header keys (as specified +// by the IANA) when added to the gRPC context. +const MetadataPrefix = "grpcgateway-" + +// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to +// HTTP headers in a response handled by grpc-gateway +const MetadataTrailerPrefix = "Grpc-Trailer-" + +const metadataGrpcTimeout = "Grpc-Timeout" +const metadataHeaderBinarySuffix = "-Bin" + +const xForwardedFor = "X-Forwarded-For" +const xForwardedHost = "X-Forwarded-Host" + +var ( + // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound + // header isn't present. If the value is 0 the sent `context` will not have a timeout. + DefaultContextTimeout = 0 * time.Second +) + +type ( + rpcMethodKey struct{} + httpPathPatternKey struct{} + + AnnotateContextOption func(ctx context.Context) context.Context +) + +func WithHTTPPathPattern(pattern string) AnnotateContextOption { + return func(ctx context.Context) context.Context { + return withHTTPPathPattern(ctx, pattern) + } +} + +func decodeBinHeader(v string) ([]byte, error) { + if len(v)%4 == 0 { + // Input was padded, or padding was not necessary. + return base64.StdEncoding.DecodeString(v) + } + return base64.RawStdEncoding.DecodeString(v) +} + +/* +AnnotateContext adds context information such as metadata from the request. + +At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", +except that the forwarded destination is not another HTTP service but rather +a gRPC service. +*/ +func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) { + ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...) + if err != nil { + return nil, err + } + if md == nil { + return ctx, nil + } + + return metadata.NewOutgoingContext(ctx, md), nil +} + +// AnnotateIncomingContext adds context information such as metadata from the request. +// Attach metadata as incoming context. +func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) { + ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...) + if err != nil { + return nil, err + } + if md == nil { + return ctx, nil + } + + return metadata.NewIncomingContext(ctx, md), nil +} + +func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) { + ctx = withRPCMethod(ctx, rpcMethodName) + for _, o := range options { + ctx = o(ctx) + } + var pairs []string + timeout := DefaultContextTimeout + if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { + var err error + timeout, err = timeoutDecode(tm) + if err != nil { + return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) + } + } + + for key, vals := range req.Header { + key = textproto.CanonicalMIMEHeaderKey(key) + for _, val := range vals { + // For backwards-compatibility, pass through 'authorization' header with no prefix. + if key == "Authorization" { + pairs = append(pairs, "authorization", val) + } + if h, ok := mux.incomingHeaderMatcher(key); ok { + // Handles "-bin" metadata in grpc, since grpc will do another base64 + // encode before sending to server, we need to decode it first. + if strings.HasSuffix(key, metadataHeaderBinarySuffix) { + b, err := decodeBinHeader(val) + if err != nil { + return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err) + } + + val = string(b) + } + pairs = append(pairs, h, val) + } + } + } + if host := req.Header.Get(xForwardedHost); host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), host) + } else if req.Host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) + } + + if addr := req.RemoteAddr; addr != "" { + if remoteIP, _, err := net.SplitHostPort(addr); err == nil { + if fwd := req.Header.Get(xForwardedFor); fwd == "" { + pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) + } else { + pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) + } + } + } + + if timeout != 0 { + //nolint:govet // The context outlives this function + ctx, _ = context.WithTimeout(ctx, timeout) + } + if len(pairs) == 0 { + return ctx, nil, nil + } + md := metadata.Pairs(pairs...) + for _, mda := range mux.metadataAnnotators { + md = metadata.Join(md, mda(ctx, req)) + } + return ctx, md, nil +} + +// ServerMetadata consists of metadata sent from gRPC server. +type ServerMetadata struct { + HeaderMD metadata.MD + TrailerMD metadata.MD +} + +type serverMetadataKey struct{} + +// NewServerMetadataContext creates a new context with ServerMetadata +func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { + return context.WithValue(ctx, serverMetadataKey{}, md) +} + +// ServerMetadataFromContext returns the ServerMetadata in ctx +func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { + md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) + return +} + +// ServerTransportStream implements grpc.ServerTransportStream. +// It should only be used by the generated files to support grpc.SendHeader +// outside of gRPC server use. +type ServerTransportStream struct { + mu sync.Mutex + header metadata.MD + trailer metadata.MD +} + +// Method returns the method for the stream. +func (s *ServerTransportStream) Method() string { + return "" +} + +// Header returns the header metadata of the stream. +func (s *ServerTransportStream) Header() metadata.MD { + s.mu.Lock() + defer s.mu.Unlock() + return s.header.Copy() +} + +// SetHeader sets the header metadata. +func (s *ServerTransportStream) SetHeader(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + + s.mu.Lock() + s.header = metadata.Join(s.header, md) + s.mu.Unlock() + return nil +} + +// SendHeader sets the header metadata. +func (s *ServerTransportStream) SendHeader(md metadata.MD) error { + return s.SetHeader(md) +} + +// Trailer returns the cached trailer metadata. +func (s *ServerTransportStream) Trailer() metadata.MD { + s.mu.Lock() + defer s.mu.Unlock() + return s.trailer.Copy() +} + +// SetTrailer sets the trailer metadata. +func (s *ServerTransportStream) SetTrailer(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + + s.mu.Lock() + s.trailer = metadata.Join(s.trailer, md) + s.mu.Unlock() + return nil +} + +func timeoutDecode(s string) (time.Duration, error) { + size := len(s) + if size < 2 { + return 0, fmt.Errorf("timeout string is too short: %q", s) + } + d, ok := timeoutUnitToDuration(s[size-1]) + if !ok { + return 0, fmt.Errorf("timeout unit is not recognized: %q", s) + } + t, err := strconv.ParseInt(s[:size-1], 10, 64) + if err != nil { + return 0, err + } + return d * time.Duration(t), nil +} + +func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { + switch u { + case 'H': + return time.Hour, true + case 'M': + return time.Minute, true + case 'S': + return time.Second, true + case 'm': + return time.Millisecond, true + case 'u': + return time.Microsecond, true + case 'n': + return time.Nanosecond, true + default: + } + return +} + +// isPermanentHTTPHeader checks whether hdr belongs to the list of +// permanent request headers maintained by IANA. +// http://www.iana.org/assignments/message-headers/message-headers.xml +func isPermanentHTTPHeader(hdr string) bool { + switch hdr { + case + "Accept", + "Accept-Charset", + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Cache-Control", + "Content-Type", + "Cookie", + "Date", + "Expect", + "From", + "Host", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Schedule-Tag-Match", + "If-Unmodified-Since", + "Max-Forwards", + "Origin", + "Pragma", + "Referer", + "User-Agent", + "Via", + "Warning": + return true + } + return false +} + +// RPCMethod returns the method string for the server context. The returned +// string is in the format of "/package.service/method". +func RPCMethod(ctx context.Context) (string, bool) { + m := ctx.Value(rpcMethodKey{}) + if m == nil { + return "", false + } + ms, ok := m.(string) + if !ok { + return "", false + } + return ms, true +} + +func withRPCMethod(ctx context.Context, rpcMethodName string) context.Context { + return context.WithValue(ctx, rpcMethodKey{}, rpcMethodName) +} + +// HTTPPathPattern returns the HTTP path pattern string relating to the HTTP handler, if one exists. +// The format of the returned string is defined by the google.api.http path template type. +func HTTPPathPattern(ctx context.Context) (string, bool) { + m := ctx.Value(httpPathPatternKey{}) + if m == nil { + return "", false + } + ms, ok := m.(string) + if !ok { + return "", false + } + return ms, true +} + +func withHTTPPathPattern(ctx context.Context, httpPathPattern string) context.Context { + return context.WithValue(ctx, httpPathPatternKey{}, httpPathPattern) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go similarity index 80% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go index 2c279344dc..e6bc4e6cee 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go @@ -6,10 +6,10 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/ptypes/duration" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" ) // String just returns the given string. @@ -205,9 +205,11 @@ func BytesSlice(val, sep string) ([][]byte, error) { } // Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp. -func Timestamp(val string) (*timestamp.Timestamp, error) { - var r timestamp.Timestamp - err := jsonpb.UnmarshalString(val, &r) +func Timestamp(val string) (*timestamppb.Timestamp, error) { + var r timestamppb.Timestamp + val = strconv.Quote(strings.Trim(val, `"`)) + unmarshaler := &protojson.UnmarshalOptions{} + err := unmarshaler.Unmarshal([]byte(val), &r) if err != nil { return nil, err } @@ -215,9 +217,11 @@ func Timestamp(val string) (*timestamp.Timestamp, error) { } // Duration converts the given string into a timestamp.Duration. -func Duration(val string) (*duration.Duration, error) { - var r duration.Duration - err := jsonpb.UnmarshalString(val, &r) +func Duration(val string) (*durationpb.Duration, error) { + var r durationpb.Duration + val = strconv.Quote(strings.Trim(val, `"`)) + unmarshaler := &protojson.UnmarshalOptions{} + err := unmarshaler.Unmarshal([]byte(val), &r) if err != nil { return nil, err } @@ -265,54 +269,54 @@ func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) { */ // StringValue well-known type support as wrapper around string type -func StringValue(val string) (*wrappers.StringValue, error) { - return &wrappers.StringValue{Value: val}, nil +func StringValue(val string) (*wrapperspb.StringValue, error) { + return &wrapperspb.StringValue{Value: val}, nil } // FloatValue well-known type support as wrapper around float32 type -func FloatValue(val string) (*wrappers.FloatValue, error) { +func FloatValue(val string) (*wrapperspb.FloatValue, error) { parsedVal, err := Float32(val) - return &wrappers.FloatValue{Value: parsedVal}, err + return &wrapperspb.FloatValue{Value: parsedVal}, err } // DoubleValue well-known type support as wrapper around float64 type -func DoubleValue(val string) (*wrappers.DoubleValue, error) { +func DoubleValue(val string) (*wrapperspb.DoubleValue, error) { parsedVal, err := Float64(val) - return &wrappers.DoubleValue{Value: parsedVal}, err + return &wrapperspb.DoubleValue{Value: parsedVal}, err } // BoolValue well-known type support as wrapper around bool type -func BoolValue(val string) (*wrappers.BoolValue, error) { +func BoolValue(val string) (*wrapperspb.BoolValue, error) { parsedVal, err := Bool(val) - return &wrappers.BoolValue{Value: parsedVal}, err + return &wrapperspb.BoolValue{Value: parsedVal}, err } // Int32Value well-known type support as wrapper around int32 type -func Int32Value(val string) (*wrappers.Int32Value, error) { +func Int32Value(val string) (*wrapperspb.Int32Value, error) { parsedVal, err := Int32(val) - return &wrappers.Int32Value{Value: parsedVal}, err + return &wrapperspb.Int32Value{Value: parsedVal}, err } // UInt32Value well-known type support as wrapper around uint32 type -func UInt32Value(val string) (*wrappers.UInt32Value, error) { +func UInt32Value(val string) (*wrapperspb.UInt32Value, error) { parsedVal, err := Uint32(val) - return &wrappers.UInt32Value{Value: parsedVal}, err + return &wrapperspb.UInt32Value{Value: parsedVal}, err } // Int64Value well-known type support as wrapper around int64 type -func Int64Value(val string) (*wrappers.Int64Value, error) { +func Int64Value(val string) (*wrapperspb.Int64Value, error) { parsedVal, err := Int64(val) - return &wrappers.Int64Value{Value: parsedVal}, err + return &wrapperspb.Int64Value{Value: parsedVal}, err } // UInt64Value well-known type support as wrapper around uint64 type -func UInt64Value(val string) (*wrappers.UInt64Value, error) { +func UInt64Value(val string) (*wrapperspb.UInt64Value, error) { parsedVal, err := Uint64(val) - return &wrappers.UInt64Value{Value: parsedVal}, err + return &wrapperspb.UInt64Value{Value: parsedVal}, err } // BytesValue well-known type support as wrapper around bytes[] type -func BytesValue(val string) (*wrappers.BytesValue, error) { +func BytesValue(val string) (*wrapperspb.BytesValue, error) { parsedVal, err := Bytes(val) - return &wrappers.BytesValue{Value: parsedVal}, err + return &wrapperspb.BytesValue{Value: parsedVal}, err } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go new file mode 100644 index 0000000000..d9e0013c43 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go @@ -0,0 +1,180 @@ +package runtime + +import ( + "context" + "errors" + "io" + "net/http" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// ErrorHandlerFunc is the signature used to configure error handling. +type ErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) + +// StreamErrorHandlerFunc is the signature used to configure stream error handling. +type StreamErrorHandlerFunc func(context.Context, error) *status.Status + +// RoutingErrorHandlerFunc is the signature used to configure error handling for routing errors. +type RoutingErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, int) + +// HTTPStatusError is the error to use when needing to provide a different HTTP status code for an error +// passed to the DefaultRoutingErrorHandler. +type HTTPStatusError struct { + HTTPStatus int + Err error +} + +func (e *HTTPStatusError) Error() string { + return e.Err.Error() +} + +// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. +// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +func HTTPStatusFromCode(code codes.Code) int { + switch code { + case codes.OK: + return http.StatusOK + case codes.Canceled: + return http.StatusRequestTimeout + case codes.Unknown: + return http.StatusInternalServerError + case codes.InvalidArgument: + return http.StatusBadRequest + case codes.DeadlineExceeded: + return http.StatusGatewayTimeout + case codes.NotFound: + return http.StatusNotFound + case codes.AlreadyExists: + return http.StatusConflict + case codes.PermissionDenied: + return http.StatusForbidden + case codes.Unauthenticated: + return http.StatusUnauthorized + case codes.ResourceExhausted: + return http.StatusTooManyRequests + case codes.FailedPrecondition: + // Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status. + return http.StatusBadRequest + case codes.Aborted: + return http.StatusConflict + case codes.OutOfRange: + return http.StatusBadRequest + case codes.Unimplemented: + return http.StatusNotImplemented + case codes.Internal: + return http.StatusInternalServerError + case codes.Unavailable: + return http.StatusServiceUnavailable + case codes.DataLoss: + return http.StatusInternalServerError + } + + grpclog.Infof("Unknown gRPC error code: %v", code) + return http.StatusInternalServerError +} + +// HTTPError uses the mux-configured error handler. +func HTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { + mux.errorHandler(ctx, mux, marshaler, w, r, err) +} + +// DefaultHTTPErrorHandler is the default error handler. +// If "err" is a gRPC Status, the function replies with the status code mapped by HTTPStatusFromCode. +// If "err" is a HTTPStatusError, the function replies with the status code provide by that struct. This is +// intended to allow passing through of specific statuses via the function set via WithRoutingErrorHandler +// for the ServeMux constructor to handle edge cases which the standard mappings in HTTPStatusFromCode +// are insufficient for. +// If otherwise, it replies with http.StatusInternalServerError. +// +// The response body written by this function is a Status message marshaled by the Marshaler. +func DefaultHTTPErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { + // return Internal when Marshal failed + const fallback = `{"code": 13, "message": "failed to marshal error message"}` + + var customStatus *HTTPStatusError + if errors.As(err, &customStatus) { + err = customStatus.Err + } + + s := status.Convert(err) + pb := s.Proto() + + w.Header().Del("Trailer") + w.Header().Del("Transfer-Encoding") + + contentType := marshaler.ContentType(pb) + w.Header().Set("Content-Type", contentType) + + if s.Code() == codes.Unauthenticated { + w.Header().Set("WWW-Authenticate", s.Message()) + } + + buf, merr := marshaler.Marshal(pb) + if merr != nil { + grpclog.Infof("Failed to marshal error message %q: %v", s, merr) + w.WriteHeader(http.StatusInternalServerError) + if _, err := io.WriteString(w, fallback); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + + // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 + // Unless the request includes a TE header field indicating "trailers" + // is acceptable, as described in Section 4.3, a server SHOULD NOT + // generate trailer fields that it believes are necessary for the user + // agent to receive. + doForwardTrailers := requestAcceptsTrailers(r) + + if doForwardTrailers { + handleForwardResponseTrailerHeader(w, md) + w.Header().Set("Transfer-Encoding", "chunked") + } + + st := HTTPStatusFromCode(s.Code()) + if customStatus != nil { + st = customStatus.HTTPStatus + } + + w.WriteHeader(st) + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + if doForwardTrailers { + handleForwardResponseTrailer(w, md) + } +} + +func DefaultStreamErrorHandler(_ context.Context, err error) *status.Status { + return status.Convert(err) +} + +// DefaultRoutingErrorHandler is our default handler for routing errors. +// By default http error codes mapped on the following error codes: +// NotFound -> grpc.NotFound +// StatusBadRequest -> grpc.InvalidArgument +// MethodNotAllowed -> grpc.Unimplemented +// Other -> grpc.Internal, method is not expecting to be called for anything else +func DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) { + sterr := status.Error(codes.Internal, "Unexpected routing error") + switch httpStatus { + case http.StatusBadRequest: + sterr = status.Error(codes.InvalidArgument, http.StatusText(httpStatus)) + case http.StatusMethodNotAllowed: + sterr = status.Error(codes.Unimplemented, http.StatusText(httpStatus)) + case http.StatusNotFound: + sterr = status.Error(codes.NotFound, http.StatusText(httpStatus)) + } + mux.errorHandler(ctx, mux, marshaler, w, r, sterr) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go new file mode 100644 index 0000000000..0138ed2f76 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go @@ -0,0 +1,165 @@ +package runtime + +import ( + "encoding/json" + "fmt" + "io" + "sort" + + "google.golang.org/genproto/protobuf/field_mask" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" +) + +func getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { + fd := fields.ByName(protoreflect.Name(name)) + if fd != nil { + return fd + } + + return fields.ByJSONName(name) +} + +// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body. +func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.FieldMask, error) { + fm := &field_mask.FieldMask{} + var root interface{} + + if err := json.NewDecoder(r).Decode(&root); err != nil { + if err == io.EOF { + return fm, nil + } + return nil, err + } + + queue := []fieldMaskPathItem{{node: root, msg: msg.ProtoReflect()}} + for len(queue) > 0 { + // dequeue an item + item := queue[0] + queue = queue[1:] + + m, ok := item.node.(map[string]interface{}) + switch { + case ok: + // if the item is an object, then enqueue all of its children + for k, v := range m { + if item.msg == nil { + return nil, fmt.Errorf("JSON structure did not match request type") + } + + fd := getFieldByName(item.msg.Descriptor().Fields(), k) + if fd == nil { + return nil, fmt.Errorf("could not find field %q in %q", k, item.msg.Descriptor().FullName()) + } + + if isDynamicProtoMessage(fd.Message()) { + for _, p := range buildPathsBlindly(k, v) { + newPath := p + if item.path != "" { + newPath = item.path + "." + newPath + } + queue = append(queue, fieldMaskPathItem{path: newPath}) + } + continue + } + + if isProtobufAnyMessage(fd.Message()) { + _, hasTypeField := v.(map[string]interface{})["@type"] + if hasTypeField { + queue = append(queue, fieldMaskPathItem{path: k}) + continue + } else { + return nil, fmt.Errorf("could not find field @type in %q in message %q", k, item.msg.Descriptor().FullName()) + } + + } + + child := fieldMaskPathItem{ + node: v, + } + if item.path == "" { + child.path = string(fd.FullName().Name()) + } else { + child.path = item.path + "." + string(fd.FullName().Name()) + } + + switch { + case fd.IsList(), fd.IsMap(): + // As per: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/field_mask.proto#L85-L86 + // Do not recurse into repeated fields. The repeated field goes on the end of the path and we stop. + fm.Paths = append(fm.Paths, child.path) + case fd.Message() != nil: + child.msg = item.msg.Get(fd).Message() + fallthrough + default: + queue = append(queue, child) + } + } + case len(item.path) > 0: + // otherwise, it's a leaf node so print its path + fm.Paths = append(fm.Paths, item.path) + } + } + + // Sort for deterministic output in the presence + // of repeated fields. + sort.Strings(fm.Paths) + + return fm, nil +} + +func isProtobufAnyMessage(md protoreflect.MessageDescriptor) bool { + return md != nil && (md.FullName() == "google.protobuf.Any") +} + +func isDynamicProtoMessage(md protoreflect.MessageDescriptor) bool { + return md != nil && (md.FullName() == "google.protobuf.Struct" || md.FullName() == "google.protobuf.Value") +} + +// buildPathsBlindly does not attempt to match proto field names to the +// json value keys. Instead it relies completely on the structure of +// the unmarshalled json contained within in. +// Returns a slice containing all subpaths with the root at the +// passed in name and json value. +func buildPathsBlindly(name string, in interface{}) []string { + m, ok := in.(map[string]interface{}) + if !ok { + return []string{name} + } + + var paths []string + queue := []fieldMaskPathItem{{path: name, node: m}} + for len(queue) > 0 { + cur := queue[0] + queue = queue[1:] + + m, ok := cur.node.(map[string]interface{}) + if !ok { + // This should never happen since we should always check that we only add + // nodes of type map[string]interface{} to the queue. + continue + } + for k, v := range m { + if mi, ok := v.(map[string]interface{}); ok { + queue = append(queue, fieldMaskPathItem{path: cur.path + "." + k, node: mi}) + } else { + // This is not a struct, so there are no more levels to descend. + curPath := cur.path + "." + k + paths = append(paths, curPath) + } + } + } + return paths +} + +// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask +type fieldMaskPathItem struct { + // the list of prior fields leading up to node connected by dots + path string + + // a generic decoded json object the current item to inspect for further path extraction + node interface{} + + // parent message + msg protoreflect.Message +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go new file mode 100644 index 0000000000..d1e21df481 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go @@ -0,0 +1,223 @@ +package runtime + +import ( + "context" + "fmt" + "io" + "net/http" + "net/textproto" + "strings" + + "google.golang.org/genproto/googleapis/api/httpbody" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// ForwardResponseStream forwards the stream from gRPC server to REST client. +func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + f, ok := w.(http.Flusher) + if !ok { + grpclog.Infof("Flush not supported in %T", w) + http.Error(w, "unexpected type of web server", http.StatusInternalServerError) + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + http.Error(w, "unexpected error", http.StatusInternalServerError) + return + } + handleForwardResponseServerMetadata(w, mux, md) + + w.Header().Set("Transfer-Encoding", "chunked") + if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + var delimiter []byte + if d, ok := marshaler.(Delimited); ok { + delimiter = d.Delimiter() + } else { + delimiter = []byte("\n") + } + + var wroteHeader bool + for { + resp, err := recv() + if err == io.EOF { + return + } + if err != nil { + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) + return + } + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) + return + } + + if !wroteHeader { + w.Header().Set("Content-Type", marshaler.ContentType(resp)) + } + + var buf []byte + httpBody, isHTTPBody := resp.(*httpbody.HttpBody) + switch { + case resp == nil: + buf, err = marshaler.Marshal(errorChunk(status.New(codes.Internal, "empty response"))) + case isHTTPBody: + buf = httpBody.GetData() + default: + result := map[string]interface{}{"result": resp} + if rb, ok := resp.(responseBody); ok { + result["result"] = rb.XXX_ResponseBody() + } + + buf, err = marshaler.Marshal(result) + } + + if err != nil { + grpclog.Infof("Failed to marshal response chunk: %v", err) + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) + return + } + if _, err = w.Write(buf); err != nil { + grpclog.Infof("Failed to send response chunk: %v", err) + return + } + wroteHeader = true + if _, err = w.Write(delimiter); err != nil { + grpclog.Infof("Failed to send delimiter chunk: %v", err) + return + } + f.Flush() + } +} + +func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) { + for k, vs := range md.HeaderMD { + if h, ok := mux.outgoingHeaderMatcher(k); ok { + for _, v := range vs { + w.Header().Add(h, v) + } + } + } +} + +func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { + for k := range md.TrailerMD { + tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) + w.Header().Add("Trailer", tKey) + } +} + +func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { + for k, vs := range md.TrailerMD { + tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) + for _, v := range vs { + w.Header().Add(tKey, v) + } + } +} + +// responseBody interface contains method for getting field for marshaling to the response body +// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule` +type responseBody interface { + XXX_ResponseBody() interface{} +} + +// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. +func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + + // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 + // Unless the request includes a TE header field indicating "trailers" + // is acceptable, as described in Section 4.3, a server SHOULD NOT + // generate trailer fields that it believes are necessary for the user + // agent to receive. + doForwardTrailers := requestAcceptsTrailers(req) + + if doForwardTrailers { + handleForwardResponseTrailerHeader(w, md) + w.Header().Set("Transfer-Encoding", "chunked") + } + + handleForwardResponseTrailerHeader(w, md) + + contentType := marshaler.ContentType(resp) + w.Header().Set("Content-Type", contentType) + + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + var buf []byte + var err error + if rb, ok := resp.(responseBody); ok { + buf, err = marshaler.Marshal(rb.XXX_ResponseBody()) + } else { + buf, err = marshaler.Marshal(resp) + } + if err != nil { + grpclog.Infof("Marshal error: %v", err) + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + if _, err = w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + if doForwardTrailers { + handleForwardResponseTrailer(w, md) + } +} + +func requestAcceptsTrailers(req *http.Request) bool { + te := req.Header.Get("TE") + return strings.Contains(strings.ToLower(te), "trailers") +} + +func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { + if len(opts) == 0 { + return nil + } + for _, opt := range opts { + if err := opt(ctx, w, resp); err != nil { + grpclog.Infof("Error handling ForwardResponseOptions: %v", err) + return err + } + } + return nil +} + +func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) { + st := mux.streamErrorHandler(ctx, err) + msg := errorChunk(st) + if !wroteHeader { + w.Header().Set("Content-Type", marshaler.ContentType(msg)) + w.WriteHeader(HTTPStatusFromCode(st.Code())) + } + buf, merr := marshaler.Marshal(msg) + if merr != nil { + grpclog.Infof("Failed to marshal an error: %v", merr) + return + } + if _, werr := w.Write(buf); werr != nil { + grpclog.Infof("Failed to notify error to client: %v", werr) + return + } +} + +func errorChunk(st *status.Status) map[string]proto.Message { + return map[string]proto.Message{"error": st.Proto()} +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go new file mode 100644 index 0000000000..b86135c889 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go @@ -0,0 +1,32 @@ +package runtime + +import ( + "google.golang.org/genproto/googleapis/api/httpbody" +) + +// HTTPBodyMarshaler is a Marshaler which supports marshaling of a +// google.api.HttpBody message as the full response body if it is +// the actual message used as the response. If not, then this will +// simply fallback to the Marshaler specified as its default Marshaler. +type HTTPBodyMarshaler struct { + Marshaler +} + +// ContentType returns its specified content type in case v is a +// google.api.HttpBody message, otherwise it will fall back to the default Marshalers +// content type. +func (h *HTTPBodyMarshaler) ContentType(v interface{}) string { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.GetContentType() + } + return h.Marshaler.ContentType(v) +} + +// Marshal marshals "v" by returning the body bytes if v is a +// google.api.HttpBody message, otherwise it falls back to the default Marshaler. +func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.Data, nil + } + return h.Marshaler.Marshal(v) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go similarity index 95% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go index f9d3a585a4..d6aa825783 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go @@ -15,7 +15,7 @@ import ( type JSONBuiltin struct{} // ContentType always Returns "application/json". -func (*JSONBuiltin) ContentType() string { +func (*JSONBuiltin) ContentType(_ interface{}) string { return "application/json" } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go new file mode 100644 index 0000000000..7387c8e397 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go @@ -0,0 +1,344 @@ +package runtime + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "reflect" + "strconv" + + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" +) + +// JSONPb is a Marshaler which marshals/unmarshals into/from JSON +// with the "google.golang.org/protobuf/encoding/protojson" marshaler. +// It supports the full functionality of protobuf unlike JSONBuiltin. +// +// The NewDecoder method returns a DecoderWrapper, so the underlying +// *json.Decoder methods can be used. +type JSONPb struct { + protojson.MarshalOptions + protojson.UnmarshalOptions +} + +// ContentType always returns "application/json". +func (*JSONPb) ContentType(_ interface{}) string { + return "application/json" +} + +// Marshal marshals "v" into JSON. +func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { + if _, ok := v.(proto.Message); !ok { + return j.marshalNonProtoField(v) + } + + var buf bytes.Buffer + if err := j.marshalTo(&buf, v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + buf, err := j.marshalNonProtoField(v) + if err != nil { + return err + } + _, err = w.Write(buf) + return err + } + b, err := j.MarshalOptions.Marshal(p) + if err != nil { + return err + } + + _, err = w.Write(b) + return err +} + +var ( + // protoMessageType is stored to prevent constant lookup of the same type at runtime. + protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() +) + +// marshalNonProto marshals a non-message field of a protobuf message. +// This function does not correctly marshal arbitrary data structures into JSON, +// it is only capable of marshaling non-message field values of protobuf, +// i.e. primitive types, enums; pointers to primitives or enums; maps from +// integer/string types to primitives/enums/pointers to messages. +func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { + if v == nil { + return []byte("null"), nil + } + rv := reflect.ValueOf(v) + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return []byte("null"), nil + } + rv = rv.Elem() + } + + if rv.Kind() == reflect.Slice { + if rv.IsNil() { + if j.EmitUnpopulated { + return []byte("[]"), nil + } + return []byte("null"), nil + } + + if rv.Type().Elem().Implements(protoMessageType) { + var buf bytes.Buffer + err := buf.WriteByte('[') + if err != nil { + return nil, err + } + for i := 0; i < rv.Len(); i++ { + if i != 0 { + err = buf.WriteByte(',') + if err != nil { + return nil, err + } + } + if err = j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { + return nil, err + } + } + err = buf.WriteByte(']') + if err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + + if rv.Type().Elem().Implements(typeProtoEnum) { + var buf bytes.Buffer + err := buf.WriteByte('[') + if err != nil { + return nil, err + } + for i := 0; i < rv.Len(); i++ { + if i != 0 { + err = buf.WriteByte(',') + if err != nil { + return nil, err + } + } + if j.UseEnumNumbers { + _, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10)) + } else { + _, err = buf.WriteString("\"" + rv.Index(i).Interface().(protoEnum).String() + "\"") + } + if err != nil { + return nil, err + } + } + err = buf.WriteByte(']') + if err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + } + + if rv.Kind() == reflect.Map { + m := make(map[string]*json.RawMessage) + for _, k := range rv.MapKeys() { + buf, err := j.Marshal(rv.MapIndex(k).Interface()) + if err != nil { + return nil, err + } + m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) + } + if j.Indent != "" { + return json.MarshalIndent(m, "", j.Indent) + } + return json.Marshal(m) + } + if enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers { + return json.Marshal(enum.String()) + } + return json.Marshal(rv.Interface()) +} + +// Unmarshal unmarshals JSON "data" into "v" +func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { + return unmarshalJSONPb(data, j.UnmarshalOptions, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONPb) NewDecoder(r io.Reader) Decoder { + d := json.NewDecoder(r) + return DecoderWrapper{ + Decoder: d, + UnmarshalOptions: j.UnmarshalOptions, + } +} + +// DecoderWrapper is a wrapper around a *json.Decoder that adds +// support for protos to the Decode method. +type DecoderWrapper struct { + *json.Decoder + protojson.UnmarshalOptions +} + +// Decode wraps the embedded decoder's Decode method to support +// protos using a jsonpb.Unmarshaler. +func (d DecoderWrapper) Decode(v interface{}) error { + return decodeJSONPb(d.Decoder, d.UnmarshalOptions, v) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONPb) NewEncoder(w io.Writer) Encoder { + return EncoderFunc(func(v interface{}) error { + if err := j.marshalTo(w, v); err != nil { + return err + } + // mimic json.Encoder by adding a newline (makes output + // easier to read when it contains multiple encoded items) + _, err := w.Write(j.Delimiter()) + return err + }) +} + +func unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + d := json.NewDecoder(bytes.NewReader(data)) + return decodeJSONPb(d, unmarshaler, v) +} + +func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + return decodeNonProtoField(d, unmarshaler, v) + } + + // Decode into bytes for marshalling + var b json.RawMessage + err := d.Decode(&b) + if err != nil { + return err + } + + return unmarshaler.Unmarshal([]byte(b), p) +} + +func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("%T is not a pointer", v) + } + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + rv.Set(reflect.New(rv.Type().Elem())) + } + if rv.Type().ConvertibleTo(typeProtoMessage) { + // Decode into bytes for marshalling + var b json.RawMessage + err := d.Decode(&b) + if err != nil { + return err + } + + return unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message)) + } + rv = rv.Elem() + } + if rv.Kind() == reflect.Map { + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + conv, ok := convFromType[rv.Type().Key().Kind()] + if !ok { + return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) + } + + m := make(map[string]*json.RawMessage) + if err := d.Decode(&m); err != nil { + return err + } + for k, v := range m { + result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + bk := result[0] + bv := reflect.New(rv.Type().Elem()) + if v == nil { + null := json.RawMessage("null") + v = &null + } + if err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil { + return err + } + rv.SetMapIndex(bk, bv.Elem()) + } + return nil + } + if rv.Kind() == reflect.Slice { + var sl []json.RawMessage + if err := d.Decode(&sl); err != nil { + return err + } + if sl != nil { + rv.Set(reflect.MakeSlice(rv.Type(), 0, 0)) + } + for _, item := range sl { + bv := reflect.New(rv.Type().Elem()) + if err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil { + return err + } + rv.Set(reflect.Append(rv, bv.Elem())) + } + return nil + } + if _, ok := rv.Interface().(protoEnum); ok { + var repr interface{} + if err := d.Decode(&repr); err != nil { + return err + } + switch v := repr.(type) { + case string: + // TODO(yugui) Should use proto.StructProperties? + return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) + case float64: + rv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type())) + return nil + default: + return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) + } + } + return d.Decode(v) +} + +type protoEnum interface { + fmt.Stringer + EnumDescriptor() ([]byte, []int) +} + +var typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem() + +var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() + +// Delimiter for newline encoded JSON streams. +func (j *JSONPb) Delimiter() []byte { + return []byte("\n") +} + +var ( + convFromType = map[reflect.Kind]reflect.Value{ + reflect.String: reflect.ValueOf(String), + reflect.Bool: reflect.ValueOf(Bool), + reflect.Float64: reflect.ValueOf(Float64), + reflect.Float32: reflect.ValueOf(Float32), + reflect.Int64: reflect.ValueOf(Int64), + reflect.Int32: reflect.ValueOf(Int32), + reflect.Uint64: reflect.ValueOf(Uint64), + reflect.Uint32: reflect.ValueOf(Uint32), + reflect.Slice: reflect.ValueOf(Bytes), + } +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go similarity index 93% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go index f65d1a2676..007f8f1a2c 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go @@ -4,15 +4,16 @@ import ( "io" "errors" - "github.com/golang/protobuf/proto" "io/ioutil" + + "google.golang.org/protobuf/proto" ) // ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes type ProtoMarshaller struct{} // ContentType always returns "application/octet-stream". -func (*ProtoMarshaller) ContentType() string { +func (*ProtoMarshaller) ContentType(_ interface{}) string { return "application/octet-stream" } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go similarity index 80% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go index 4615329421..2c0d25ff49 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go @@ -16,14 +16,9 @@ type Marshaler interface { // NewEncoder returns an Encoder which writes bytes sequence into "w". NewEncoder(w io.Writer) Encoder // ContentType returns the Content-Type which this marshaler is responsible for. - ContentType() string -} - -// Marshalers that implement contentTypeMarshaler will have their ContentTypeFromMessage method called -// to set the Content-Type header on the response -type contentTypeMarshaler interface { - // ContentTypeFromMessage returns the Content-Type this marshaler produces from the provided message - ContentTypeFromMessage(v interface{}) string + // The parameter describes the type which is being marshalled, which can sometimes + // affect the content type returned. + ContentType(v interface{}) string } // Decoder decodes a byte sequence diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go similarity index 91% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go index 8dd5c24db4..a714de0240 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go @@ -6,6 +6,7 @@ import ( "net/http" "google.golang.org/grpc/grpclog" + "google.golang.org/protobuf/encoding/protojson" ) // MIMEWildcard is the fallback MIME type used for requests which do not match @@ -16,7 +17,16 @@ var ( acceptHeader = http.CanonicalHeaderKey("Accept") contentTypeHeader = http.CanonicalHeaderKey("Content-Type") - defaultMarshaler = &JSONPb{OrigName: true} + defaultMarshaler = &HTTPBodyMarshaler{ + Marshaler: &JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + EmitUnpopulated: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: true, + }, + }, + } ) // MarshalerForRequest returns the inbound/outbound marshalers for this request. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go new file mode 100644 index 0000000000..46a4aabaf9 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go @@ -0,0 +1,356 @@ +package runtime + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/textproto" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// UnescapingMode defines the behavior of ServeMux when unescaping path parameters. +type UnescapingMode int + +const ( + // UnescapingModeLegacy is the default V2 behavior, which escapes the entire + // path string before doing any routing. + UnescapingModeLegacy UnescapingMode = iota + + // EscapingTypeExceptReserved unescapes all path parameters except RFC 6570 + // reserved characters. + UnescapingModeAllExceptReserved + + // EscapingTypeExceptSlash unescapes URL path parameters except path + // seperators, which will be left as "%2F". + UnescapingModeAllExceptSlash + + // URL path parameters will be fully decoded. + UnescapingModeAllCharacters + + // UnescapingModeDefault is the default escaping type. + // TODO(v3): default this to UnescapingModeAllExceptReserved per grpc-httpjson-transcoding's + // reference implementation + UnescapingModeDefault = UnescapingModeLegacy +) + +// A HandlerFunc handles a specific pair of path pattern and HTTP method. +type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) + +// ServeMux is a request multiplexer for grpc-gateway. +// It matches http requests to patterns and invokes the corresponding handler. +type ServeMux struct { + // handlers maps HTTP method to a list of handlers. + handlers map[string][]handler + forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error + marshalers marshalerRegistry + incomingHeaderMatcher HeaderMatcherFunc + outgoingHeaderMatcher HeaderMatcherFunc + metadataAnnotators []func(context.Context, *http.Request) metadata.MD + errorHandler ErrorHandlerFunc + streamErrorHandler StreamErrorHandlerFunc + routingErrorHandler RoutingErrorHandlerFunc + disablePathLengthFallback bool + unescapingMode UnescapingMode +} + +// ServeMuxOption is an option that can be given to a ServeMux on construction. +type ServeMuxOption func(*ServeMux) + +// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. +// +// forwardResponseOption is an option that will be called on the relevant context.Context, +// http.ResponseWriter, and proto.Message before every forwarded response. +// +// The message may be nil in the case where just a header is being sent. +func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) + } +} + +// WithEscapingType sets the escaping type. See the definitions of UnescapingMode +// for more information. +func WithUnescapingMode(mode UnescapingMode) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.unescapingMode = mode + } +} + +// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters. +// Configuring this will mean the generated OpenAPI output is no longer correct, and it should be +// done with careful consideration. +func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption { + return func(serveMux *ServeMux) { + currentQueryParser = queryParameterParser + } +} + +// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context. +type HeaderMatcherFunc func(string) (string, bool) + +// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header +// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with +// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. +func DefaultHeaderMatcher(key string) (string, bool) { + key = textproto.CanonicalMIMEHeaderKey(key) + if isPermanentHTTPHeader(key) { + return MetadataPrefix + key, true + } else if strings.HasPrefix(key, MetadataHeaderPrefix) { + return key[len(MetadataHeaderPrefix):], true + } + return "", false +} + +// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway. +// +// This matcher will be called with each header in http.Request. If matcher returns true, that header will be +// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. +func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + return func(mux *ServeMux) { + mux.incomingHeaderMatcher = fn + } +} + +// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. +// +// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be +// passed to http response returned from gateway. To transform the header before passing to response, +// matcher should return modified header. +func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + return func(mux *ServeMux) { + mux.outgoingHeaderMatcher = fn + } +} + +// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context. +// +// This can be used by services that need to read from http.Request and modify gRPC context. A common use case +// is reading token from cookie and adding it in gRPC context. +func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator) + } +} + +// WithErrorHandler returns a ServeMuxOption for configuring a custom error handler. +// +// This can be used to configure a custom error response. +func WithErrorHandler(fn ErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.errorHandler = fn + } +} + +// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream +// error handler, which allows for customizing the error trailer for server-streaming +// calls. +// +// For stream errors that occur before any response has been written, the mux's +// ErrorHandler will be invoked. However, once data has been written, the errors must +// be handled differently: they must be included in the response body. The response body's +// final message will include the error details returned by the stream error handler. +func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.streamErrorHandler = fn + } +} + +// WithRoutingErrorHandler returns a ServeMuxOption for configuring a custom error handler to handle http routing errors. +// +// Method called for errors which can happen before gRPC route selected or executed. +// The following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest +func WithRoutingErrorHandler(fn RoutingErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.routingErrorHandler = fn + } +} + +// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback. +func WithDisablePathLengthFallback() ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.disablePathLengthFallback = true + } +} + +// NewServeMux returns a new ServeMux whose internal mapping is empty. +func NewServeMux(opts ...ServeMuxOption) *ServeMux { + serveMux := &ServeMux{ + handlers: make(map[string][]handler), + forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), + marshalers: makeMarshalerMIMERegistry(), + errorHandler: DefaultHTTPErrorHandler, + streamErrorHandler: DefaultStreamErrorHandler, + routingErrorHandler: DefaultRoutingErrorHandler, + unescapingMode: UnescapingModeDefault, + } + + for _, opt := range opts { + opt(serveMux) + } + + if serveMux.incomingHeaderMatcher == nil { + serveMux.incomingHeaderMatcher = DefaultHeaderMatcher + } + + if serveMux.outgoingHeaderMatcher == nil { + serveMux.outgoingHeaderMatcher = func(key string) (string, bool) { + return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true + } + } + + return serveMux +} + +// Handle associates "h" to the pair of HTTP method and path pattern. +func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { + s.handlers[meth] = append([]handler{{pat: pat, h: h}}, s.handlers[meth]...) +} + +// HandlePath allows users to configure custom path handlers. +// refer: https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/inject_router/ +func (s *ServeMux) HandlePath(meth string, pathPattern string, h HandlerFunc) error { + compiler, err := httprule.Parse(pathPattern) + if err != nil { + return fmt.Errorf("parsing path pattern: %w", err) + } + tp := compiler.Compile() + pattern, err := NewPattern(tp.Version, tp.OpCodes, tp.Pool, tp.Verb) + if err != nil { + return fmt.Errorf("creating new pattern: %w", err) + } + s.Handle(meth, pattern, h) + return nil +} + +// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. +func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + path := r.URL.Path + if !strings.HasPrefix(path, "/") { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusBadRequest) + return + } + + // TODO(v3): remove UnescapingModeLegacy + if s.unescapingMode != UnescapingModeLegacy && r.URL.RawPath != "" { + path = r.URL.RawPath + } + + components := strings.Split(path[1:], "/") + + if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { + r.Method = strings.ToUpper(override) + if err := r.ParseForm(); err != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr) + return + } + } + + // Verb out here is to memoize for the fallback case below + var verb string + + for _, h := range s.handlers[r.Method] { + // If the pattern has a verb, explicitly look for a suffix in the last + // component that matches a colon plus the verb. This allows us to + // handle some cases that otherwise can't be correctly handled by the + // former LastIndex case, such as when the verb literal itself contains + // a colon. This should work for all cases that have run through the + // parser because we know what verb we're looking for, however, there + // are still some cases that the parser itself cannot disambiguate. See + // the comment there if interested. + patVerb := h.pat.Verb() + l := len(components) + lastComponent := components[l-1] + var idx int = -1 + if patVerb != "" && strings.HasSuffix(lastComponent, ":"+patVerb) { + idx = len(lastComponent) - len(patVerb) - 1 + } + if idx == 0 { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) + return + } + if idx > 0 { + components[l-1], verb = lastComponent[:idx], lastComponent[idx+1:] + } + + pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) + if err != nil { + var mse MalformedSequenceError + if ok := errors.As(err, &mse); ok { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{ + HTTPStatus: http.StatusBadRequest, + Err: mse, + }) + } + continue + } + h.h(w, r, pathParams) + return + } + + // lookup other methods to handle fallback from GET to POST and + // to determine if it is NotImplemented or NotFound. + for m, handlers := range s.handlers { + if m == r.Method { + continue + } + for _, h := range handlers { + pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) + if err != nil { + var mse MalformedSequenceError + if ok := errors.As(err, &mse); ok { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{ + HTTPStatus: http.StatusBadRequest, + Err: mse, + }) + } + continue + } + // X-HTTP-Method-Override is optional. Always allow fallback to POST. + if s.isPathLengthFallback(r) { + if err := r.ParseForm(); err != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr) + return + } + h.h(w, r, pathParams) + return + } + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusMethodNotAllowed) + return + } + } + + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) +} + +// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. +func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { + return s.forwardResponseOptions +} + +func (s *ServeMux) isPathLengthFallback(r *http.Request) bool { + return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" +} + +type handler struct { + pat Pattern + h HandlerFunc +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go new file mode 100644 index 0000000000..df7cb81426 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go @@ -0,0 +1,383 @@ +package runtime + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc/grpclog" +) + +var ( + // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. + ErrNotMatch = errors.New("not match to the path pattern") + // ErrInvalidPattern indicates that the given definition of Pattern is not valid. + ErrInvalidPattern = errors.New("invalid pattern") + // ErrMalformedSequence indicates that an escape sequence was malformed. + ErrMalformedSequence = errors.New("malformed escape sequence") +) + +type MalformedSequenceError string + +func (e MalformedSequenceError) Error() string { + return "malformed path escape " + strconv.Quote(string(e)) +} + +type op struct { + code utilities.OpCode + operand int +} + +// Pattern is a template pattern of http request paths defined in +// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto +type Pattern struct { + // ops is a list of operations + ops []op + // pool is a constant pool indexed by the operands or vars. + pool []string + // vars is a list of variables names to be bound by this pattern + vars []string + // stacksize is the max depth of the stack + stacksize int + // tailLen is the length of the fixed-size segments after a deep wildcard + tailLen int + // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. + verb string +} + +// NewPattern returns a new Pattern from the given definition values. +// "ops" is a sequence of op codes. "pool" is a constant pool. +// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. +// "version" must be 1 for now. +// It returns an error if the given definition is invalid. +func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) { + if version != 1 { + grpclog.Infof("unsupported version: %d", version) + return Pattern{}, ErrInvalidPattern + } + + l := len(ops) + if l%2 != 0 { + grpclog.Infof("odd number of ops codes: %d", l) + return Pattern{}, ErrInvalidPattern + } + + var ( + typedOps []op + stack, maxstack int + tailLen int + pushMSeen bool + vars []string + ) + for i := 0; i < l; i += 2 { + op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpPushM: + if pushMSeen { + grpclog.Infof("pushM appears twice") + return Pattern{}, ErrInvalidPattern + } + pushMSeen = true + stack++ + case utilities.OpLitPush: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("negative literal index: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpConcatN: + if op.operand <= 0 { + grpclog.Infof("negative concat size: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + stack -= op.operand + if stack < 0 { + grpclog.Info("stack underflow") + return Pattern{}, ErrInvalidPattern + } + stack++ + case utilities.OpCapture: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("variable name index out of bound: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + v := pool[op.operand] + op.operand = len(vars) + vars = append(vars, v) + stack-- + if stack < 0 { + grpclog.Infof("stack underflow") + return Pattern{}, ErrInvalidPattern + } + default: + grpclog.Infof("invalid opcode: %d", op.code) + return Pattern{}, ErrInvalidPattern + } + + if maxstack < stack { + maxstack = stack + } + typedOps = append(typedOps, op) + } + return Pattern{ + ops: typedOps, + pool: pool, + vars: vars, + stacksize: maxstack, + tailLen: tailLen, + verb: verb, + }, nil +} + +// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. +func MustPattern(p Pattern, err error) Pattern { + if err != nil { + grpclog.Fatalf("Pattern initialization failed: %v", err) + } + return p +} + +// MatchAndEscape examines components to determine if they match to a Pattern. +// MatchAndEscape will return an error if no Patterns matched or if a pattern +// matched but contained malformed escape sequences. If successful, the function +// returns a mapping from field paths to their captured values. +func (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) { + if p.verb != verb { + if p.verb != "" { + return nil, ErrNotMatch + } + if len(components) == 0 { + components = []string{":" + verb} + } else { + components = append([]string{}, components...) + components[len(components)-1] += ":" + verb + } + } + + var pos int + stack := make([]string, 0, p.stacksize) + captured := make([]string, len(p.vars)) + l := len(components) + for _, op := range p.ops { + var err error + + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush, utilities.OpLitPush: + if pos >= l { + return nil, ErrNotMatch + } + c := components[pos] + if op.code == utilities.OpLitPush { + if lit := p.pool[op.operand]; c != lit { + return nil, ErrNotMatch + } + } else if op.code == utilities.OpPush { + if c, err = unescape(c, unescapingMode, false); err != nil { + return nil, err + } + } + stack = append(stack, c) + pos++ + case utilities.OpPushM: + end := len(components) + if end < pos+p.tailLen { + return nil, ErrNotMatch + } + end -= p.tailLen + c := strings.Join(components[pos:end], "/") + if c, err = unescape(c, unescapingMode, true); err != nil { + return nil, err + } + stack = append(stack, c) + pos = end + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + captured[op.operand] = stack[n] + stack = stack[:n] + } + } + if pos < l { + return nil, ErrNotMatch + } + bindings := make(map[string]string) + for i, val := range captured { + bindings[p.vars[i]] = val + } + return bindings, nil +} + +// MatchAndEscape examines components to determine if they match to a Pattern. +// It will never perform per-component unescaping (see: UnescapingModeLegacy). +// MatchAndEscape will return an error if no Patterns matched. If successful, +// the function returns a mapping from field paths to their captured values. +// +// Deprecated: Use MatchAndEscape. +func (p Pattern) Match(components []string, verb string) (map[string]string, error) { + return p.MatchAndEscape(components, verb, UnescapingModeDefault) +} + +// Verb returns the verb part of the Pattern. +func (p Pattern) Verb() string { return p.verb } + +func (p Pattern) String() string { + var stack []string + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + stack = append(stack, "*") + case utilities.OpLitPush: + stack = append(stack, p.pool[op.operand]) + case utilities.OpPushM: + stack = append(stack, "**") + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) + } + } + segs := strings.Join(stack, "/") + if p.verb != "" { + return fmt.Sprintf("/%s:%s", segs, p.verb) + } + return "/" + segs +} + +/* + * The following code is adopted and modified from Go's standard library + * and carries the attached license. + * + * 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. + */ + +// ishex returns whether or not the given byte is a valid hex character +func ishex(c byte) bool { + switch { + case '0' <= c && c <= '9': + return true + case 'a' <= c && c <= 'f': + return true + case 'A' <= c && c <= 'F': + return true + } + return false +} + +func isRFC6570Reserved(c byte) bool { + switch c { + case '!', '#', '$', '&', '\'', '(', ')', '*', + '+', ',', '/', ':', ';', '=', '?', '@', '[', ']': + return true + default: + return false + } +} + +// unhex converts a hex point to the bit representation +func unhex(c byte) byte { + switch { + case '0' <= c && c <= '9': + return c - '0' + case 'a' <= c && c <= 'f': + return c - 'a' + 10 + case 'A' <= c && c <= 'F': + return c - 'A' + 10 + } + return 0 +} + +// shouldUnescapeWithMode returns true if the character is escapable with the +// given mode +func shouldUnescapeWithMode(c byte, mode UnescapingMode) bool { + switch mode { + case UnescapingModeAllExceptReserved: + if isRFC6570Reserved(c) { + return false + } + case UnescapingModeAllExceptSlash: + if c == '/' { + return false + } + case UnescapingModeAllCharacters: + return true + } + return true +} + +// unescape unescapes a path string using the provided mode +func unescape(s string, mode UnescapingMode, multisegment bool) (string, error) { + // TODO(v3): remove UnescapingModeLegacy + if mode == UnescapingModeLegacy { + return s, nil + } + + if !multisegment { + mode = UnescapingModeAllCharacters + } + + // Count %, check that they're well-formed. + n := 0 + for i := 0; i < len(s); { + if s[i] == '%' { + n++ + if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) { + s = s[i:] + if len(s) > 3 { + s = s[:3] + } + + return "", MalformedSequenceError(s) + } + i += 3 + } else { + i++ + } + } + + if n == 0 { + return s, nil + } + + var t strings.Builder + t.Grow(len(s)) + for i := 0; i < len(s); i++ { + switch s[i] { + case '%': + c := unhex(s[i+1])<<4 | unhex(s[i+2]) + if shouldUnescapeWithMode(c, mode) { + t.WriteByte(c) + i += 2 + continue + } + fallthrough + default: + t.WriteByte(s[i]) + } + } + + return t.String(), nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go similarity index 98% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go index a3151e2a55..d549407f20 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go @@ -1,7 +1,7 @@ package runtime import ( - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // StringP returns a pointer to a string whose pointee is same as the given string value. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go new file mode 100644 index 0000000000..fb0c84ef0c --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go @@ -0,0 +1,329 @@ +package runtime + +import ( + "encoding/base64" + "errors" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + "time" + + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/genproto/protobuf/field_mask" + "google.golang.org/grpc/grpclog" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`) + +var currentQueryParser QueryParameterParser = &defaultQueryParser{} + +// QueryParameterParser defines interface for all query parameter parsers +type QueryParameterParser interface { + Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error +} + +// PopulateQueryParameters parses query parameters +// into "msg" using current query parser +func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + return currentQueryParser.Parse(msg, values, filter) +} + +type defaultQueryParser struct{} + +// Parse populates "values" into "msg". +// A value is ignored if its key starts with one of the elements in "filter". +func (*defaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + for key, values := range values { + match := valuesKeyRegexp.FindStringSubmatch(key) + if len(match) == 3 { + key = match[1] + values = append([]string{match[2]}, values...) + } + fieldPath := strings.Split(key, ".") + if filter.HasCommonPrefix(fieldPath) { + continue + } + if err := populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, values); err != nil { + return err + } + } + return nil +} + +// PopulateFieldFromPath sets a value in a nested Protobuf structure. +func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { + fieldPath := strings.Split(fieldPathString, ".") + return populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, []string{value}) +} + +func populateFieldValueFromPath(msgValue protoreflect.Message, fieldPath []string, values []string) error { + if len(fieldPath) < 1 { + return errors.New("no field path") + } + if len(values) < 1 { + return errors.New("no value provided") + } + + var fieldDescriptor protoreflect.FieldDescriptor + for i, fieldName := range fieldPath { + fields := msgValue.Descriptor().Fields() + + // Get field by name + fieldDescriptor = fields.ByName(protoreflect.Name(fieldName)) + if fieldDescriptor == nil { + fieldDescriptor = fields.ByJSONName(fieldName) + if fieldDescriptor == nil { + // We're not returning an error here because this could just be + // an extra query parameter that isn't part of the request. + grpclog.Infof("field not found in %q: %q", msgValue.Descriptor().FullName(), strings.Join(fieldPath, ".")) + return nil + } + } + + // If this is the last element, we're done + if i == len(fieldPath)-1 { + break + } + + // Only singular message fields are allowed + if fieldDescriptor.Message() == nil || fieldDescriptor.Cardinality() == protoreflect.Repeated { + return fmt.Errorf("invalid path: %q is not a message", fieldName) + } + + // Get the nested message + msgValue = msgValue.Mutable(fieldDescriptor).Message() + } + + // Check if oneof already set + if of := fieldDescriptor.ContainingOneof(); of != nil { + if f := msgValue.WhichOneof(of); f != nil { + return fmt.Errorf("field already set for oneof %q", of.FullName().Name()) + } + } + + switch { + case fieldDescriptor.IsList(): + return populateRepeatedField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).List(), values) + case fieldDescriptor.IsMap(): + return populateMapField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).Map(), values) + } + + if len(values) > 1 { + return fmt.Errorf("too many values for field %q: %s", fieldDescriptor.FullName().Name(), strings.Join(values, ", ")) + } + + return populateField(fieldDescriptor, msgValue, values[0]) +} + +func populateField(fieldDescriptor protoreflect.FieldDescriptor, msgValue protoreflect.Message, value string) error { + v, err := parseField(fieldDescriptor, value) + if err != nil { + return fmt.Errorf("parsing field %q: %w", fieldDescriptor.FullName().Name(), err) + } + + msgValue.Set(fieldDescriptor, v) + return nil +} + +func populateRepeatedField(fieldDescriptor protoreflect.FieldDescriptor, list protoreflect.List, values []string) error { + for _, value := range values { + v, err := parseField(fieldDescriptor, value) + if err != nil { + return fmt.Errorf("parsing list %q: %w", fieldDescriptor.FullName().Name(), err) + } + list.Append(v) + } + + return nil +} + +func populateMapField(fieldDescriptor protoreflect.FieldDescriptor, mp protoreflect.Map, values []string) error { + if len(values) != 2 { + return fmt.Errorf("more than one value provided for key %q in map %q", values[0], fieldDescriptor.FullName()) + } + + key, err := parseField(fieldDescriptor.MapKey(), values[0]) + if err != nil { + return fmt.Errorf("parsing map key %q: %w", fieldDescriptor.FullName().Name(), err) + } + + value, err := parseField(fieldDescriptor.MapValue(), values[1]) + if err != nil { + return fmt.Errorf("parsing map value %q: %w", fieldDescriptor.FullName().Name(), err) + } + + mp.Set(key.MapKey(), value) + + return nil +} + +func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (protoreflect.Value, error) { + switch fieldDescriptor.Kind() { + case protoreflect.BoolKind: + v, err := strconv.ParseBool(value) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfBool(v), nil + case protoreflect.EnumKind: + enum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName()) + switch { + case errors.Is(err, protoregistry.NotFound): + return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fieldDescriptor.Enum().FullName()) + case err != nil: + return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err) + } + // Look for enum by name + v := enum.Descriptor().Values().ByName(protoreflect.Name(value)) + if v == nil { + i, err := strconv.Atoi(value) + if err != nil { + return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) + } + // Look for enum by number + v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i)) + if v == nil { + return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) + } + } + return protoreflect.ValueOfEnum(v.Number()), nil + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfInt32(int32(v)), nil + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfInt64(v), nil + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfUint32(uint32(v)), nil + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfUint64(v), nil + case protoreflect.FloatKind: + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfFloat32(float32(v)), nil + case protoreflect.DoubleKind: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfFloat64(v), nil + case protoreflect.StringKind: + return protoreflect.ValueOfString(value), nil + case protoreflect.BytesKind: + v, err := base64.URLEncoding.DecodeString(value) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfBytes(v), nil + case protoreflect.MessageKind, protoreflect.GroupKind: + return parseMessage(fieldDescriptor.Message(), value) + default: + panic(fmt.Sprintf("unknown field kind: %v", fieldDescriptor.Kind())) + } +} + +func parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (protoreflect.Value, error) { + var msg proto.Message + switch msgDescriptor.FullName() { + case "google.protobuf.Timestamp": + if value == "null" { + break + } + t, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return protoreflect.Value{}, err + } + msg = timestamppb.New(t) + case "google.protobuf.Duration": + if value == "null" { + break + } + d, err := time.ParseDuration(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = durationpb.New(d) + case "google.protobuf.DoubleValue": + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.DoubleValue{Value: v} + case "google.protobuf.FloatValue": + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.FloatValue{Value: float32(v)} + case "google.protobuf.Int64Value": + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.Int64Value{Value: v} + case "google.protobuf.Int32Value": + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.Int32Value{Value: int32(v)} + case "google.protobuf.UInt64Value": + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.UInt64Value{Value: v} + case "google.protobuf.UInt32Value": + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.UInt32Value{Value: uint32(v)} + case "google.protobuf.BoolValue": + v, err := strconv.ParseBool(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.BoolValue{Value: v} + case "google.protobuf.StringValue": + msg = &wrapperspb.StringValue{Value: value} + case "google.protobuf.BytesValue": + v, err := base64.URLEncoding.DecodeString(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = &wrapperspb.BytesValue{Value: v} + case "google.protobuf.FieldMask": + fm := &field_mask.FieldMask{} + fm.Paths = append(fm.Paths, strings.Split(value, ",")...) + msg = fm + default: + return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName())) + } + + return protoreflect.ValueOfMessage(msg.ProtoReflect()), nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel new file mode 100644 index 0000000000..5d8d12bc42 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "utilities", + srcs = [ + "doc.go", + "pattern.go", + "readerfactory.go", + "trie.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", +) + +go_test( + name = "utilities_test", + size = "small", + srcs = ["trie_test.go"], + deps = [":utilities"], +) + +alias( + name = "go_default_library", + actual = ":utilities", + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go similarity index 98% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go index c2b7b30dd9..af3b703d50 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go @@ -145,10 +145,7 @@ func (l byLex) Less(i, j int) bool { return false } } - if k < len(sj) { - return true - } - return false + return k < len(sj) } // HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence. diff --git a/vendor/github.com/huandu/xstrings/.travis.yml b/vendor/github.com/huandu/xstrings/.travis.yml deleted file mode 100644 index d6460be411..0000000000 --- a/vendor/github.com/huandu/xstrings/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -install: - - go get golang.org/x/tools/cmd/cover - - go get github.com/mattn/goveralls -script: - - go test -v -covermode=count -coverprofile=coverage.out - - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ ! -z "$COVERALLS_TOKEN" ]; then $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN; fi' diff --git a/vendor/github.com/huandu/xstrings/README.md b/vendor/github.com/huandu/xstrings/README.md index 292bf2f39e..750c3c7eb6 100644 --- a/vendor/github.com/huandu/xstrings/README.md +++ b/vendor/github.com/huandu/xstrings/README.md @@ -1,7 +1,7 @@ -# xstrings # +# xstrings -[![Build Status](https://travis-ci.org/huandu/xstrings.svg?branch=master)](https://travis-ci.org/huandu/xstrings) -[![GoDoc](https://godoc.org/github.com/huandu/xstrings?status.svg)](https://godoc.org/github.com/huandu/xstrings) +[![Build Status](https://github.com/huandu/xstrings/workflows/Go/badge.svg)](https://github.com/huandu/xstrings/actions) +[![Go Doc](https://godoc.org/github.com/huandu/xstrings?status.svg)](https://pkg.go.dev/github.com/huandu/xstrings) [![Go Report](https://goreportcard.com/badge/github.com/huandu/xstrings)](https://goreportcard.com/report/github.com/huandu/xstrings) [![Coverage Status](https://coveralls.io/repos/github/huandu/xstrings/badge.svg?branch=master)](https://coveralls.io/github/huandu/xstrings?branch=master) @@ -9,109 +9,109 @@ Go package [xstrings](https://godoc.org/github.com/huandu/xstrings) is a collect All functions are well tested and carefully tuned for performance. -## Propose a new function ## +## Propose a new function Please review [contributing guideline](CONTRIBUTING.md) and [create new issue](https://github.com/huandu/xstrings/issues) to state why it should be included. -## Install ## +## Install Use `go get` to install this library. go get github.com/huandu/xstrings -## API document ## +## API document See [GoDoc](https://godoc.org/github.com/huandu/xstrings) for full document. -## Function list ## +## Function list Go functions have a unique naming style. One, who has experience in other language but new in Go, may have difficulties to find out right string function to use. Here is a list of functions in [strings](http://golang.org/pkg/strings) and [xstrings](https://godoc.org/github.com/huandu/xstrings) with enough extra information about how to map these functions to their friends in other languages. Hope this list could be helpful for fresh gophers. -### Package `xstrings` functions ### - -*Keep this table sorted by Function in ascending order.* - -| Function | Friends | # | -| -------- | ------- | --- | -| [Center](https://godoc.org/github.com/huandu/xstrings#Center) | `str.center` in Python; `String#center` in Ruby | [#30](https://github.com/huandu/xstrings/issues/30) | -| [Count](https://godoc.org/github.com/huandu/xstrings#Count) | `String#count` in Ruby | [#16](https://github.com/huandu/xstrings/issues/16) | -| [Delete](https://godoc.org/github.com/huandu/xstrings#Delete) | `String#delete` in Ruby | [#17](https://github.com/huandu/xstrings/issues/17) | -| [ExpandTabs](https://godoc.org/github.com/huandu/xstrings#ExpandTabs) | `str.expandtabs` in Python | [#27](https://github.com/huandu/xstrings/issues/27) | -| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | -| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | -| [Insert](https://godoc.org/github.com/huandu/xstrings#Insert) | `String#insert` in Ruby | [#18](https://github.com/huandu/xstrings/issues/18) | -| [LastPartition](https://godoc.org/github.com/huandu/xstrings#LastPartition) | `str.rpartition` in Python; `String#rpartition` in Ruby | [#19](https://github.com/huandu/xstrings/issues/19) | -| [LeftJustify](https://godoc.org/github.com/huandu/xstrings#LeftJustify) | `str.ljust` in Python; `String#ljust` in Ruby | [#28](https://github.com/huandu/xstrings/issues/28) | -| [Len](https://godoc.org/github.com/huandu/xstrings#Len) | `mb_strlen` in PHP | [#23](https://github.com/huandu/xstrings/issues/23) | -| [Partition](https://godoc.org/github.com/huandu/xstrings#Partition) | `str.partition` in Python; `String#partition` in Ruby | [#10](https://github.com/huandu/xstrings/issues/10) | -| [Reverse](https://godoc.org/github.com/huandu/xstrings#Reverse) | `String#reverse` in Ruby; `strrev` in PHP; `reverse` in Perl | [#7](https://github.com/huandu/xstrings/issues/7) | -| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) | -| [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) | -| [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) | -| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | -| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | -| [Slice](https://godoc.org/github.com/huandu/xstrings#Slice) | `mb_substr` in PHP | [#9](https://github.com/huandu/xstrings/issues/9) | -| [Squeeze](https://godoc.org/github.com/huandu/xstrings#Squeeze) | `String#squeeze` in Ruby | [#11](https://github.com/huandu/xstrings/issues/11) | -| [Successor](https://godoc.org/github.com/huandu/xstrings#Successor) | `String#succ` or `String#next` in Ruby | [#22](https://github.com/huandu/xstrings/issues/22) | -| [SwapCase](https://godoc.org/github.com/huandu/xstrings#SwapCase) | `str.swapcase` in Python; `String#swapcase` in Ruby | [#12](https://github.com/huandu/xstrings/issues/12) | -| [ToCamelCase](https://godoc.org/github.com/huandu/xstrings#ToCamelCase) | `String#camelize` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | -| [ToKebab](https://godoc.org/github.com/huandu/xstrings#ToKebabCase) | - | [#41](https://github.com/huandu/xstrings/issues/41) | -| [ToSnakeCase](https://godoc.org/github.com/huandu/xstrings#ToSnakeCase) | `String#underscore` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | -| [Translate](https://godoc.org/github.com/huandu/xstrings#Translate) | `str.translate` in Python; `String#tr` in Ruby; `strtr` in PHP; `tr///` in Perl | [#21](https://github.com/huandu/xstrings/issues/21) | -| [Width](https://godoc.org/github.com/huandu/xstrings#Width) | `mb_strwidth` in PHP | [#26](https://github.com/huandu/xstrings/issues/26) | -| [WordCount](https://godoc.org/github.com/huandu/xstrings#WordCount) | `str_word_count` in PHP | [#14](https://github.com/huandu/xstrings/issues/14) | -| [WordSplit](https://godoc.org/github.com/huandu/xstrings#WordSplit) | - | [#14](https://github.com/huandu/xstrings/issues/14) | - -### Package `strings` functions ### - -*Keep this table sorted by Function in ascending order.* - -| Function | Friends | -| -------- | ------- | -| [Contains](http://golang.org/pkg/strings/#Contains) | `String#include?` in Ruby | -| [ContainsAny](http://golang.org/pkg/strings/#ContainsAny) | - | -| [ContainsRune](http://golang.org/pkg/strings/#ContainsRune) | - | -| [Count](http://golang.org/pkg/strings/#Count) | `str.count` in Python; `substr_count` in PHP | -| [EqualFold](http://golang.org/pkg/strings/#EqualFold) | `stricmp` in PHP; `String#casecmp` in Ruby | -| [Fields](http://golang.org/pkg/strings/#Fields) | `str.split` in Python; `split` in Perl; `String#split` in Ruby | -| [FieldsFunc](http://golang.org/pkg/strings/#FieldsFunc) | - | -| [HasPrefix](http://golang.org/pkg/strings/#HasPrefix) | `str.startswith` in Python; `String#start_with?` in Ruby | -| [HasSuffix](http://golang.org/pkg/strings/#HasSuffix) | `str.endswith` in Python; `String#end_with?` in Ruby | -| [Index](http://golang.org/pkg/strings/#Index) | `str.index` in Python; `String#index` in Ruby; `strpos` in PHP; `index` in Perl | -| [IndexAny](http://golang.org/pkg/strings/#IndexAny) | - | -| [IndexByte](http://golang.org/pkg/strings/#IndexByte) | - | -| [IndexFunc](http://golang.org/pkg/strings/#IndexFunc) | - | -| [IndexRune](http://golang.org/pkg/strings/#IndexRune) | - | -| [Join](http://golang.org/pkg/strings/#Join) | `str.join` in Python; `Array#join` in Ruby; `implode` in PHP; `join` in Perl | -| [LastIndex](http://golang.org/pkg/strings/#LastIndex) | `str.rindex` in Python; `String#rindex`; `strrpos` in PHP; `rindex` in Perl | -| [LastIndexAny](http://golang.org/pkg/strings/#LastIndexAny) | - | -| [LastIndexFunc](http://golang.org/pkg/strings/#LastIndexFunc) | - | -| [Map](http://golang.org/pkg/strings/#Map) | `String#each_codepoint` in Ruby | -| [Repeat](http://golang.org/pkg/strings/#Repeat) | operator `*` in Python and Ruby; `str_repeat` in PHP | -| [Replace](http://golang.org/pkg/strings/#Replace) | `str.replace` in Python; `String#sub` in Ruby; `str_replace` in PHP | -| [Split](http://golang.org/pkg/strings/#Split) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | -| [SplitAfter](http://golang.org/pkg/strings/#SplitAfter) | - | -| [SplitAfterN](http://golang.org/pkg/strings/#SplitAfterN) | - | -| [SplitN](http://golang.org/pkg/strings/#SplitN) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | -| [Title](http://golang.org/pkg/strings/#Title) | `str.title` in Python | -| [ToLower](http://golang.org/pkg/strings/#ToLower) | `str.lower` in Python; `String#downcase` in Ruby; `strtolower` in PHP; `lc` in Perl | -| [ToLowerSpecial](http://golang.org/pkg/strings/#ToLowerSpecial) | - | -| [ToTitle](http://golang.org/pkg/strings/#ToTitle) | - | -| [ToTitleSpecial](http://golang.org/pkg/strings/#ToTitleSpecial) | - | -| [ToUpper](http://golang.org/pkg/strings/#ToUpper) | `str.upper` in Python; `String#upcase` in Ruby; `strtoupper` in PHP; `uc` in Perl | -| [ToUpperSpecial](http://golang.org/pkg/strings/#ToUpperSpecial) | - | -| [Trim](http://golang.org/pkg/strings/#Trim) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | -| [TrimFunc](http://golang.org/pkg/strings/#TrimFunc) | - | -| [TrimLeft](http://golang.org/pkg/strings/#TrimLeft) | `str.lstrip` in Python; `String#lstrip` in Ruby; `ltrim` in PHP | -| [TrimLeftFunc](http://golang.org/pkg/strings/#TrimLeftFunc) | - | -| [TrimPrefix](http://golang.org/pkg/strings/#TrimPrefix) | - | -| [TrimRight](http://golang.org/pkg/strings/#TrimRight) | `str.rstrip` in Python; `String#rstrip` in Ruby; `rtrim` in PHP | -| [TrimRightFunc](http://golang.org/pkg/strings/#TrimRightFunc) | - | -| [TrimSpace](http://golang.org/pkg/strings/#TrimSpace) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | -| [TrimSuffix](http://golang.org/pkg/strings/#TrimSuffix) | `String#chomp` in Ruby; `chomp` in Perl | - -## License ## +### Package `xstrings` functions + +_Keep this table sorted by Function in ascending order._ + +| Function | Friends | # | +| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------- | +| [Center](https://godoc.org/github.com/huandu/xstrings#Center) | `str.center` in Python; `String#center` in Ruby | [#30](https://github.com/huandu/xstrings/issues/30) | +| [Count](https://godoc.org/github.com/huandu/xstrings#Count) | `String#count` in Ruby | [#16](https://github.com/huandu/xstrings/issues/16) | +| [Delete](https://godoc.org/github.com/huandu/xstrings#Delete) | `String#delete` in Ruby | [#17](https://github.com/huandu/xstrings/issues/17) | +| [ExpandTabs](https://godoc.org/github.com/huandu/xstrings#ExpandTabs) | `str.expandtabs` in Python | [#27](https://github.com/huandu/xstrings/issues/27) | +| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | +| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) | +| [Insert](https://godoc.org/github.com/huandu/xstrings#Insert) | `String#insert` in Ruby | [#18](https://github.com/huandu/xstrings/issues/18) | +| [LastPartition](https://godoc.org/github.com/huandu/xstrings#LastPartition) | `str.rpartition` in Python; `String#rpartition` in Ruby | [#19](https://github.com/huandu/xstrings/issues/19) | +| [LeftJustify](https://godoc.org/github.com/huandu/xstrings#LeftJustify) | `str.ljust` in Python; `String#ljust` in Ruby | [#28](https://github.com/huandu/xstrings/issues/28) | +| [Len](https://godoc.org/github.com/huandu/xstrings#Len) | `mb_strlen` in PHP | [#23](https://github.com/huandu/xstrings/issues/23) | +| [Partition](https://godoc.org/github.com/huandu/xstrings#Partition) | `str.partition` in Python; `String#partition` in Ruby | [#10](https://github.com/huandu/xstrings/issues/10) | +| [Reverse](https://godoc.org/github.com/huandu/xstrings#Reverse) | `String#reverse` in Ruby; `strrev` in PHP; `reverse` in Perl | [#7](https://github.com/huandu/xstrings/issues/7) | +| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) | +| [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) | +| [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) | +| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | +| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | +| [Slice](https://godoc.org/github.com/huandu/xstrings#Slice) | `mb_substr` in PHP | [#9](https://github.com/huandu/xstrings/issues/9) | +| [Squeeze](https://godoc.org/github.com/huandu/xstrings#Squeeze) | `String#squeeze` in Ruby | [#11](https://github.com/huandu/xstrings/issues/11) | +| [Successor](https://godoc.org/github.com/huandu/xstrings#Successor) | `String#succ` or `String#next` in Ruby | [#22](https://github.com/huandu/xstrings/issues/22) | +| [SwapCase](https://godoc.org/github.com/huandu/xstrings#SwapCase) | `str.swapcase` in Python; `String#swapcase` in Ruby | [#12](https://github.com/huandu/xstrings/issues/12) | +| [ToCamelCase](https://godoc.org/github.com/huandu/xstrings#ToCamelCase) | `String#camelize` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | +| [ToKebab](https://godoc.org/github.com/huandu/xstrings#ToKebabCase) | - | [#41](https://github.com/huandu/xstrings/issues/41) | +| [ToSnakeCase](https://godoc.org/github.com/huandu/xstrings#ToSnakeCase) | `String#underscore` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) | +| [Translate](https://godoc.org/github.com/huandu/xstrings#Translate) | `str.translate` in Python; `String#tr` in Ruby; `strtr` in PHP; `tr///` in Perl | [#21](https://github.com/huandu/xstrings/issues/21) | +| [Width](https://godoc.org/github.com/huandu/xstrings#Width) | `mb_strwidth` in PHP | [#26](https://github.com/huandu/xstrings/issues/26) | +| [WordCount](https://godoc.org/github.com/huandu/xstrings#WordCount) | `str_word_count` in PHP | [#14](https://github.com/huandu/xstrings/issues/14) | +| [WordSplit](https://godoc.org/github.com/huandu/xstrings#WordSplit) | - | [#14](https://github.com/huandu/xstrings/issues/14) | + +### Package `strings` functions + +_Keep this table sorted by Function in ascending order._ + +| Function | Friends | +| --------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| [Contains](http://golang.org/pkg/strings/#Contains) | `String#include?` in Ruby | +| [ContainsAny](http://golang.org/pkg/strings/#ContainsAny) | - | +| [ContainsRune](http://golang.org/pkg/strings/#ContainsRune) | - | +| [Count](http://golang.org/pkg/strings/#Count) | `str.count` in Python; `substr_count` in PHP | +| [EqualFold](http://golang.org/pkg/strings/#EqualFold) | `stricmp` in PHP; `String#casecmp` in Ruby | +| [Fields](http://golang.org/pkg/strings/#Fields) | `str.split` in Python; `split` in Perl; `String#split` in Ruby | +| [FieldsFunc](http://golang.org/pkg/strings/#FieldsFunc) | - | +| [HasPrefix](http://golang.org/pkg/strings/#HasPrefix) | `str.startswith` in Python; `String#start_with?` in Ruby | +| [HasSuffix](http://golang.org/pkg/strings/#HasSuffix) | `str.endswith` in Python; `String#end_with?` in Ruby | +| [Index](http://golang.org/pkg/strings/#Index) | `str.index` in Python; `String#index` in Ruby; `strpos` in PHP; `index` in Perl | +| [IndexAny](http://golang.org/pkg/strings/#IndexAny) | - | +| [IndexByte](http://golang.org/pkg/strings/#IndexByte) | - | +| [IndexFunc](http://golang.org/pkg/strings/#IndexFunc) | - | +| [IndexRune](http://golang.org/pkg/strings/#IndexRune) | - | +| [Join](http://golang.org/pkg/strings/#Join) | `str.join` in Python; `Array#join` in Ruby; `implode` in PHP; `join` in Perl | +| [LastIndex](http://golang.org/pkg/strings/#LastIndex) | `str.rindex` in Python; `String#rindex`; `strrpos` in PHP; `rindex` in Perl | +| [LastIndexAny](http://golang.org/pkg/strings/#LastIndexAny) | - | +| [LastIndexFunc](http://golang.org/pkg/strings/#LastIndexFunc) | - | +| [Map](http://golang.org/pkg/strings/#Map) | `String#each_codepoint` in Ruby | +| [Repeat](http://golang.org/pkg/strings/#Repeat) | operator `*` in Python and Ruby; `str_repeat` in PHP | +| [Replace](http://golang.org/pkg/strings/#Replace) | `str.replace` in Python; `String#sub` in Ruby; `str_replace` in PHP | +| [Split](http://golang.org/pkg/strings/#Split) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | +| [SplitAfter](http://golang.org/pkg/strings/#SplitAfter) | - | +| [SplitAfterN](http://golang.org/pkg/strings/#SplitAfterN) | - | +| [SplitN](http://golang.org/pkg/strings/#SplitN) | `str.split` in Python; `String#split` in Ruby; `explode` in PHP; `split` in Perl | +| [Title](http://golang.org/pkg/strings/#Title) | `str.title` in Python | +| [ToLower](http://golang.org/pkg/strings/#ToLower) | `str.lower` in Python; `String#downcase` in Ruby; `strtolower` in PHP; `lc` in Perl | +| [ToLowerSpecial](http://golang.org/pkg/strings/#ToLowerSpecial) | - | +| [ToTitle](http://golang.org/pkg/strings/#ToTitle) | - | +| [ToTitleSpecial](http://golang.org/pkg/strings/#ToTitleSpecial) | - | +| [ToUpper](http://golang.org/pkg/strings/#ToUpper) | `str.upper` in Python; `String#upcase` in Ruby; `strtoupper` in PHP; `uc` in Perl | +| [ToUpperSpecial](http://golang.org/pkg/strings/#ToUpperSpecial) | - | +| [Trim](http://golang.org/pkg/strings/#Trim) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | +| [TrimFunc](http://golang.org/pkg/strings/#TrimFunc) | - | +| [TrimLeft](http://golang.org/pkg/strings/#TrimLeft) | `str.lstrip` in Python; `String#lstrip` in Ruby; `ltrim` in PHP | +| [TrimLeftFunc](http://golang.org/pkg/strings/#TrimLeftFunc) | - | +| [TrimPrefix](http://golang.org/pkg/strings/#TrimPrefix) | - | +| [TrimRight](http://golang.org/pkg/strings/#TrimRight) | `str.rstrip` in Python; `String#rstrip` in Ruby; `rtrim` in PHP | +| [TrimRightFunc](http://golang.org/pkg/strings/#TrimRightFunc) | - | +| [TrimSpace](http://golang.org/pkg/strings/#TrimSpace) | `str.strip` in Python; `String#strip` in Ruby; `trim` in PHP | +| [TrimSuffix](http://golang.org/pkg/strings/#TrimSuffix) | `String#chomp` in Ruby; `chomp` in Perl | + +## License This library is licensed under MIT license. See LICENSE for details. diff --git a/vendor/github.com/huandu/xstrings/convert.go b/vendor/github.com/huandu/xstrings/convert.go index 3d5a34950b..151c3151d9 100644 --- a/vendor/github.com/huandu/xstrings/convert.go +++ b/vendor/github.com/huandu/xstrings/convert.go @@ -130,7 +130,7 @@ func camelCaseToLowerCase(str string, connector rune) string { wt, word, remaining = nextWord(remaining) } - if wt != invalidWord && wt != punctWord { + if wt != invalidWord && wt != punctWord && wt != connectorWord { buf.WriteRune(connector) } diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md index aa8cbd7ce6..7e6f7aeee8 100644 --- a/vendor/github.com/imdario/mergo/README.md +++ b/vendor/github.com/imdario/mergo/README.md @@ -8,8 +8,7 @@ [![Coverage Status][9]][10] [![Sourcegraph][11]][12] [![FOSSA Status][13]][14] - -[![GoCenter Kudos][15]][16] +[![Become my sponsor][15]][16] [1]: https://travis-ci.org/imdario/mergo.png [2]: https://travis-ci.org/imdario/mergo @@ -25,8 +24,8 @@ [12]: https://sourcegraph.com/github.com/imdario/mergo?badge [13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield [14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield -[15]: https://search.gocenter.io/api/ui/badge/github.com%2Fimdario%2Fmergo -[16]: https://search.gocenter.io/github.com/imdario/mergo +[15]: https://img.shields.io/github/sponsors/imdario +[16]: https://github.com/sponsors/imdario A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements. @@ -36,11 +35,11 @@ Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the ## Status -It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc](https://github.com/imdario/mergo#mergo-in-the-wild). +It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild). ### Important note -Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds suppot for go modules. +Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules. Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code. @@ -51,12 +50,12 @@ If you were using Mergo before April 6th, 2015, please check your project works If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes: Buy Me a Coffee at ko-fi.com -[![Beerpay](https://beerpay.io/imdario/mergo/badge.svg)](https://beerpay.io/imdario/mergo) -[![Beerpay](https://beerpay.io/imdario/mergo/make-wish.svg)](https://beerpay.io/imdario/mergo) Donate using Liberapay +Become my sponsor ### Mergo in the wild +- [cli/cli](https://github.com/cli/cli) - [moby/moby](https://github.com/moby/moby) - [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) - [vmware/dispatch](https://github.com/vmware/dispatch) @@ -98,6 +97,8 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont - [jnuthong/item_search](https://github.com/jnuthong/item_search) - [bukalapak/snowboard](https://github.com/bukalapak/snowboard) - [containerssh/containerssh](https://github.com/containerssh/containerssh) +- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser) +- [tjpnz/structbot](https://github.com/tjpnz/structbot) ## Install @@ -168,7 +169,7 @@ func main() { Note: if test are failing due missing package, please execute: - go get gopkg.in/yaml.v2 + go get gopkg.in/yaml.v3 ### Transformers @@ -218,7 +219,6 @@ func main() { } ``` - ## Contact me If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario) @@ -227,18 +227,6 @@ If I can help you, you have an idea or you are using Mergo in your projects, don Written by [Dario Castañé](http://dario.im). -## Top Contributors - -[![0](https://sourcerer.io/fame/imdario/imdario/mergo/images/0)](https://sourcerer.io/fame/imdario/imdario/mergo/links/0) -[![1](https://sourcerer.io/fame/imdario/imdario/mergo/images/1)](https://sourcerer.io/fame/imdario/imdario/mergo/links/1) -[![2](https://sourcerer.io/fame/imdario/imdario/mergo/images/2)](https://sourcerer.io/fame/imdario/imdario/mergo/links/2) -[![3](https://sourcerer.io/fame/imdario/imdario/mergo/images/3)](https://sourcerer.io/fame/imdario/imdario/mergo/links/3) -[![4](https://sourcerer.io/fame/imdario/imdario/mergo/images/4)](https://sourcerer.io/fame/imdario/imdario/mergo/links/4) -[![5](https://sourcerer.io/fame/imdario/imdario/mergo/images/5)](https://sourcerer.io/fame/imdario/imdario/mergo/links/5) -[![6](https://sourcerer.io/fame/imdario/imdario/mergo/images/6)](https://sourcerer.io/fame/imdario/imdario/mergo/links/6) -[![7](https://sourcerer.io/fame/imdario/imdario/mergo/images/7)](https://sourcerer.io/fame/imdario/imdario/mergo/links/7) - - ## License [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE). diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go index 8c2a8fcd90..8b4e2f47a0 100644 --- a/vendor/github.com/imdario/mergo/merge.go +++ b/vendor/github.com/imdario/mergo/merge.go @@ -79,7 +79,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co visited[h] = &visit{addr, typ, seen} } - if config.Transformers != nil && !isEmptyValue(dst) { + if config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() { if fn := config.Transformers.Transformer(dst.Type()); fn != nil { err = fn(dst, src) return diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/github.com/imdario/mergo/mergo.go index 3cc926c7f6..9fe362d476 100644 --- a/vendor/github.com/imdario/mergo/mergo.go +++ b/vendor/github.com/imdario/mergo/mergo.go @@ -17,7 +17,7 @@ import ( var ( ErrNilArguments = errors.New("src and dst must not be nil") ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type") - ErrNotSupported = errors.New("only structs and maps are supported") + ErrNotSupported = errors.New("only structs, maps, and slices are supported") ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") ErrNonPointerAgument = errors.New("dst must be a pointer") @@ -65,7 +65,7 @@ func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) { return } vDst = reflect.ValueOf(dst).Elem() - if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map { + if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map && vDst.Kind() != reflect.Slice { err = ErrNotSupported return } diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE index 5f0d1fb6a7..5f920e9732 100644 --- a/vendor/github.com/inconshreveable/mousetrap/LICENSE +++ b/vendor/github.com/inconshreveable/mousetrap/LICENSE @@ -1,13 +1,201 @@ -Copyright 2014 Alan Shreve + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -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 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - http://www.apache.org/licenses/LICENSE-2.0 + 1. Definitions. -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. + "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 2022 Alan Shreve (@inconshreveable) + + 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/jmoiron/sqlx/sqlx.go b/vendor/github.com/jmoiron/sqlx/sqlx.go index 112ef70e9c..f7b2876834 100644 --- a/vendor/github.com/jmoiron/sqlx/sqlx.go +++ b/vendor/github.com/jmoiron/sqlx/sqlx.go @@ -878,9 +878,10 @@ func structOnlyError(t reflect.Type) error { } // scanAll scans all rows into a destination, which must be a slice of any -// type. If the destination slice type is a Struct, then StructScan will be -// used on each row. If the destination is some other kind of base type, then -// each row must only have one column which can scan into that type. This +// type. It resets the slice length to zero before appending each element to +// the slice. If the destination slice type is a Struct, then StructScan will +// be used on each row. If the destination is some other kind of base type, +// then each row must only have one column which can scan into that type. This // allows you to do something like: // // rows, _ := db.Query("select id from people;") @@ -910,6 +911,7 @@ func scanAll(rows rowsi, dest interface{}, structOnly bool) error { if err != nil { return err } + direct.SetLen(0) isPtr := slice.Elem().Kind() == reflect.Ptr base := reflectx.Deref(slice.Elem()) diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go index e050d53586..e70b386ff0 100644 --- a/vendor/github.com/lib/pq/conn.go +++ b/vendor/github.com/lib/pq/conn.go @@ -31,8 +31,10 @@ var ( ErrNotSupported = errors.New("pq: Unsupported command") ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction") ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server") - ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less") - ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly") + ErrSSLKeyUnknownOwnership = errors.New("pq: Could not get owner information for private key, may not be properly protected") + ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key has world access. Permissions should be u=rw,g=r (0640) if owned by root, or u=rw (0600), or less") + + ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly") errUnexpectedReady = errors.New("unexpected ReadyForQuery") errNoRowsAffected = errors.New("no RowsAffected available after the empty statement") @@ -322,7 +324,7 @@ func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error) { if err != nil { return nil, err } - c.dialer = d + c.Dialer(d) return c.open(context.Background()) } @@ -1125,7 +1127,7 @@ func isDriverSetting(key string) bool { return true case "password": return true - case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline": + case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline", "sslsni": return true case "fallback_application_name": return true @@ -2018,6 +2020,8 @@ func parseEnviron(env []string) (out map[string]string) { accrue("sslkey") case "PGSSLROOTCERT": accrue("sslrootcert") + case "PGSSLSNI": + accrue("sslsni") case "PGREQUIRESSL", "PGSSLCRL": unsupported() case "PGREQUIREPEER": diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go index d7d4726156..1145e12257 100644 --- a/vendor/github.com/lib/pq/connector.go +++ b/vendor/github.com/lib/pq/connector.go @@ -27,6 +27,11 @@ func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) { return c.open(ctx) } +// Dialer allows change the dialer used to open connections. +func (c *Connector) Dialer(dialer Dialer) { + c.dialer = dialer +} + // Driver returns the underlying driver of this Connector. func (c *Connector) Driver() driver.Driver { return &Driver{} diff --git a/vendor/github.com/lib/pq/copy.go b/vendor/github.com/lib/pq/copy.go index c072bc3bc4..2f5c1ec8a6 100644 --- a/vendor/github.com/lib/pq/copy.go +++ b/vendor/github.com/lib/pq/copy.go @@ -1,6 +1,7 @@ package pq import ( + "context" "database/sql/driver" "encoding/binary" "errors" @@ -273,6 +274,43 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) { return driver.RowsAffected(0), nil } +// CopyData inserts a raw string into the COPY stream. The insert is +// asynchronous and CopyData can return errors from previous CopyData calls to +// the same COPY stmt. +// +// You need to call Exec(nil) to sync the COPY stream and to get any +// errors from pending data, since Stmt.Close() doesn't return errors +// to the user. +func (ci *copyin) CopyData(ctx context.Context, line string) (r driver.Result, err error) { + if ci.closed { + return nil, errCopyInClosed + } + + if finish := ci.cn.watchCancel(ctx); finish != nil { + defer finish() + } + + if err := ci.getBad(); err != nil { + return nil, err + } + defer ci.cn.errRecover(&err) + + if err := ci.err(); err != nil { + return nil, err + } + + ci.buffer = append(ci.buffer, []byte(line)...) + ci.buffer = append(ci.buffer, '\n') + + if len(ci.buffer) > ciBufferFlushSize { + ci.flush(ci.buffer) + // reset buffer, keep bytes for message identifier and length + ci.buffer = ci.buffer[:5] + } + + return driver.RowsAffected(0), nil +} + func (ci *copyin) Close() (err error) { if ci.closed { // Don't do anything, we're already closed return nil diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go index 210b1ec347..bffe6096af 100644 --- a/vendor/github.com/lib/pq/encode.go +++ b/vendor/github.com/lib/pq/encode.go @@ -422,7 +422,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro if remainderIdx < len(str) && str[remainderIdx] == '.' { fracStart := remainderIdx + 1 - fracOff := strings.IndexAny(str[fracStart:], "-+ ") + fracOff := strings.IndexAny(str[fracStart:], "-+Z ") if fracOff < 0 { fracOff = len(str) - fracStart } @@ -432,7 +432,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro remainderIdx += fracOff + 1 } if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') { - // time zone separator is always '-' or '+' (UTC is +00) + // time zone separator is always '-' or '+' or 'Z' (UTC is +00) var tzSign int switch c := str[tzStart]; c { case '-': @@ -454,7 +454,11 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro remainderIdx += 3 } tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec) + } else if tzStart < len(str) && str[tzStart] == 'Z' { + // time zone Z separator indicates UTC is +00 + remainderIdx += 1 } + var isoYear int if isBC { diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go index 5cfe9c6e9f..f67c5a5fa6 100644 --- a/vendor/github.com/lib/pq/error.go +++ b/vendor/github.com/lib/pq/error.go @@ -402,6 +402,11 @@ func (err *Error) Fatal() bool { return err.Severity == Efatal } +// SQLState returns the SQLState of the error. +func (err *Error) SQLState() string { + return string(err.Code) +} + // Get implements the legacy PGError interface. New code should use the fields // of the Error struct directly. func (err *Error) Get(k byte) (v string) { @@ -444,7 +449,7 @@ func (err *Error) Get(k byte) (v string) { return "" } -func (err Error) Error() string { +func (err *Error) Error() string { return "pq: " + err.Message } diff --git a/vendor/github.com/lib/pq/ssl.go b/vendor/github.com/lib/pq/ssl.go index e5eb928954..36b61ba45b 100644 --- a/vendor/github.com/lib/pq/ssl.go +++ b/vendor/github.com/lib/pq/ssl.go @@ -8,6 +8,7 @@ import ( "os" "os/user" "path/filepath" + "strings" ) // ssl generates a function to upgrade a net.Conn based on the "sslmode" and @@ -50,6 +51,16 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) { return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode) } + // Set Server Name Indication (SNI), if enabled by connection parameters. + // By default SNI is on, any value which is not starting with "1" disables + // SNI -- that is the same check vanilla libpq uses. + if sslsni := o["sslsni"]; sslsni == "" || strings.HasPrefix(sslsni, "1") { + // RFC 6066 asks to not set SNI if the host is a literal IP address (IPv4 + // or IPv6). This check is coded already crypto.tls.hostnameInSNI, so + // just always set ServerName here and let crypto/tls do the filtering. + tlsConf.ServerName = o["host"] + } + err := sslClientCertificates(&tlsConf, o) if err != nil { return nil, err diff --git a/vendor/github.com/lib/pq/ssl_permissions.go b/vendor/github.com/lib/pq/ssl_permissions.go index 014af6a169..d587f102ed 100644 --- a/vendor/github.com/lib/pq/ssl_permissions.go +++ b/vendor/github.com/lib/pq/ssl_permissions.go @@ -3,7 +3,28 @@ package pq -import "os" +import ( + "errors" + "os" + "syscall" +) + +const ( + rootUserID = uint32(0) + + // The maximum permissions that a private key file owned by a regular user + // is allowed to have. This translates to u=rw. + maxUserOwnedKeyPermissions os.FileMode = 0600 + + // The maximum permissions that a private key file owned by root is allowed + // to have. This translates to u=rw,g=r. + maxRootOwnedKeyPermissions os.FileMode = 0640 +) + +var ( + errSSLKeyHasUnacceptableUserPermissions = errors.New("permissions for files not owned by root should be u=rw (0600) or less") + errSSLKeyHasUnacceptableRootPermissions = errors.New("permissions for root owned files should be u=rw,g=r (0640) or less") +) // sslKeyPermissions checks the permissions on user-supplied ssl key files. // The key file should have very little access. @@ -14,8 +35,59 @@ func sslKeyPermissions(sslkey string) error { if err != nil { return err } - if info.Mode().Perm()&0077 != 0 { - return ErrSSLKeyHasWorldPermissions + + err = hasCorrectPermissions(info) + + // return ErrSSLKeyHasWorldPermissions for backwards compatability with + // existing code. + if err == errSSLKeyHasUnacceptableUserPermissions || err == errSSLKeyHasUnacceptableRootPermissions { + err = ErrSSLKeyHasWorldPermissions } - return nil + return err +} + +// hasCorrectPermissions checks the file info (and the unix-specific stat_t +// output) to verify that the permissions on the file are correct. +// +// If the file is owned by the same user the process is running as, +// the file should only have 0600 (u=rw). If the file is owned by root, +// and the group matches the group that the process is running in, the +// permissions cannot be more than 0640 (u=rw,g=r). The file should +// never have world permissions. +// +// Returns an error when the permission check fails. +func hasCorrectPermissions(info os.FileInfo) error { + // if file's permission matches 0600, allow access. + userPermissionMask := (os.FileMode(0777) ^ maxUserOwnedKeyPermissions) + + // regardless of if we're running as root or not, 0600 is acceptable, + // so we return if we match the regular user permission mask. + if info.Mode().Perm()&userPermissionMask == 0 { + return nil + } + + // We need to pull the Unix file information to get the file's owner. + // If we can't access it, there's some sort of operating system level error + // and we should fail rather than attempting to use faulty information. + sysInfo := info.Sys() + if sysInfo == nil { + return ErrSSLKeyUnknownOwnership + } + + unixStat, ok := sysInfo.(*syscall.Stat_t) + if !ok { + return ErrSSLKeyUnknownOwnership + } + + // if the file is owned by root, we allow 0640 (u=rw,g=r) to match what + // Postgres does. + if unixStat.Uid == rootUserID { + rootPermissionMask := (os.FileMode(0777) ^ maxRootOwnedKeyPermissions) + if info.Mode().Perm()&rootPermissionMask != 0 { + return errSSLKeyHasUnacceptableRootPermissions + } + return nil + } + + return errSSLKeyHasUnacceptableUserPermissions } diff --git a/vendor/github.com/mailru/easyjson/jlexer/lexer.go b/vendor/github.com/mailru/easyjson/jlexer/lexer.go index a42e9d65ad..b5f5e26132 100644 --- a/vendor/github.com/mailru/easyjson/jlexer/lexer.go +++ b/vendor/github.com/mailru/easyjson/jlexer/lexer.go @@ -401,6 +401,7 @@ func (r *Lexer) scanToken() { // consume resets the current token to allow scanning the next one. func (r *Lexer) consume() { r.token.kind = tokenUndef + r.token.byteValueCloned = false r.token.delimValue = 0 } @@ -528,6 +529,7 @@ func (r *Lexer) Skip() { func (r *Lexer) SkipRecursive() { r.scanToken() var start, end byte + startPos := r.start switch r.token.delimValue { case '{': @@ -553,6 +555,14 @@ func (r *Lexer) SkipRecursive() { level-- if level == 0 { r.pos += i + 1 + if !json.Valid(r.Data[startPos:r.pos]) { + r.pos = len(r.Data) + r.fatalError = &LexerError{ + Reason: "skipped array/object json value is invalid", + Offset: r.pos, + Data: string(r.Data[r.pos:]), + } + } return } case c == '\\' && inQuotes: @@ -702,6 +712,10 @@ func (r *Lexer) Bytes() []byte { r.errInvalidToken("string") return nil } + if err := r.unescapeStringToken(); err != nil { + r.errInvalidToken("string") + return nil + } ret := make([]byte, base64.StdEncoding.DecodedLen(len(r.token.byteValue))) n, err := base64.StdEncoding.Decode(ret, r.token.byteValue) if err != nil { diff --git a/vendor/github.com/mattn/go-sqlite3/callback.go b/vendor/github.com/mattn/go-sqlite3/callback.go index b020fe37c0..d305691004 100644 --- a/vendor/github.com/mattn/go-sqlite3/callback.go +++ b/vendor/github.com/mattn/go-sqlite3/callback.go @@ -353,6 +353,20 @@ func callbackRetNil(ctx *C.sqlite3_context, v reflect.Value) error { return nil } +func callbackRetGeneric(ctx *C.sqlite3_context, v reflect.Value) error { + if v.IsNil() { + C.sqlite3_result_null(ctx) + return nil + } + + cb, err := callbackRet(v.Elem().Type()) + if err != nil { + return err + } + + return cb(ctx, v.Elem()) +} + func callbackRet(typ reflect.Type) (callbackRetConverter, error) { switch typ.Kind() { case reflect.Interface: @@ -360,6 +374,11 @@ func callbackRet(typ reflect.Type) (callbackRetConverter, error) { if typ.Implements(errorInterface) { return callbackRetNil, nil } + + if typ.NumMethod() == 0 { + return callbackRetGeneric, nil + } + fallthrough case reflect.Slice: if typ.Elem().Kind() != reflect.Uint8 { diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c index bb9dc50ec7..102821bbe5 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c @@ -1,7 +1,7 @@ #ifndef USE_LIBSQLITE3 /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.37.0. By combining all the individual C code files into this +** version 3.38.5. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -453,9 +453,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.37.0" -#define SQLITE_VERSION_NUMBER 3037000 -#define SQLITE_SOURCE_ID "2021-11-27 14:13:22 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a" +#define SQLITE_VERSION "3.38.5" +#define SQLITE_VERSION_NUMBER 3038005 +#define SQLITE_SOURCE_ID "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -873,7 +873,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ /* ** CAPI3REF: Flags For File Open Operations @@ -4131,13 +4131,14 @@ SQLITE_API void sqlite3_free_filename(char*); ** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving -** interfaces are: +** interfaces include the following: ** **
    **
  • sqlite3_errcode() **
  • sqlite3_extended_errcode() **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() +**
  • sqlite3_error_offset() **
** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -4152,6 +4153,13 @@ SQLITE_API void sqlite3_free_filename(char*); ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -4171,6 +4179,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Prepared Statement Object @@ -4582,6 +4591,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a ** read-only no-op if the table already exists, but ** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -4650,6 +4663,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used as arguments @@ -5271,6 +5286,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** ** Warning: ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. In a multithreaded environment, ** an unprotected sqlite3_value object may only be used safely with @@ -5284,7 +5303,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** -** The these routines may attempt to convert the datatype of the result. +** These routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions @@ -5309,7 +5328,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** TEXT BLOB No change ** BLOB INTEGER [CAST] to INTEGER ** BLOB FLOAT [CAST] to REAL -** BLOB TEXT Add a zero terminator if needed +** BLOB TEXT [CAST] to TEXT, ensure zero terminator ** ** )^ ** @@ -7429,24 +7448,56 @@ struct sqlite3_index_info { ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of +** an operator that is part of a constraint term in the WHERE clause of ** a query that uses a [virtual table]. -*/ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -#define SQLITE_INDEX_CONSTRAINT_NE 68 -#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -#define SQLITE_INDEX_CONSTRAINT_IS 72 -#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is no commonly needed. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -7475,7 +7526,7 @@ struct sqlite3_index_info { ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is -** NULL then no new module is create and any existing modules with the +** NULL then no new module is created and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] @@ -8251,7 +8302,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 -#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -8774,6 +8826,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
SQLITE_STMTSTATUS_FILTER_HIT
+** SQLITE_STMTSTATUS_FILTER_MISS
+**
^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal. +** ** [[SQLITE_STMTSTATUS_MEMUSED]]
SQLITE_STMTSTATUS_MEMUSED
**
^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually @@ -8788,6 +8850,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 /* @@ -9756,19 +9820,269 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info ** ** This function may only be called from within a call to the [xBestIndex] -** method of a [virtual table]. +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. +** +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. ** -** The first argument must be the sqlite3_index_info object that is the -** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the sqlite3_index_info -** structure passed to xBestIndex. This function returns a pointer to a buffer -** containing the name of the collation sequence for the corresponding -** constraint. +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: +** +**
    +**
  1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

  2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

  3. Otherwise, "BINARY" is returned. +**

*/ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
  1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

  2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

  3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all "aOrderBy" columns +** are adjacent.)^ ^(Furthermore, only a single row for each particular +** combination of values in the columns identified by the "aOrderBy" field +** needs to be returned.)^ ^It is always ok for two or more rows with the same +** values in all "aOrderBy" columns to be returned, as long as all such rows +** are adjacent. ^The virtual table may, if it chooses, omit extra rows +** that have the same value for all columns identified by "aOrderBy". +** ^However omitting the extra rows is optional. +** This mode is used for a DISTINCT query. +**

+** +** ^For the purposes of comparing virtual table output values to see if the +** values are same value for sorting purposes, two NULL values are considered +** to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** the "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**
    +**
  1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

  2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

+** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
    +**
  1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. +** +**

  2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

)^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing use the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
+**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
+**        rc==SQLITE_OK && pVal
+**        rc=sqlite3_vtab_in_next(pList, &pVal)
+**    ){
+**      // do something with pVal
+**    }
+**    if( rc!=SQLITE_OK ){
+**      // an error has occurred
+**    }
+** 
)^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); + /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} @@ -13622,78 +13936,79 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_SLASH 109 #define TK_REM 110 #define TK_CONCAT 111 -#define TK_COLLATE 112 -#define TK_BITNOT 113 -#define TK_ON 114 -#define TK_INDEXED 115 -#define TK_STRING 116 -#define TK_JOIN_KW 117 -#define TK_CONSTRAINT 118 -#define TK_DEFAULT 119 -#define TK_NULL 120 -#define TK_PRIMARY 121 -#define TK_UNIQUE 122 -#define TK_CHECK 123 -#define TK_REFERENCES 124 -#define TK_AUTOINCR 125 -#define TK_INSERT 126 -#define TK_DELETE 127 -#define TK_UPDATE 128 -#define TK_SET 129 -#define TK_DEFERRABLE 130 -#define TK_FOREIGN 131 -#define TK_DROP 132 -#define TK_UNION 133 -#define TK_ALL 134 -#define TK_EXCEPT 135 -#define TK_INTERSECT 136 -#define TK_SELECT 137 -#define TK_VALUES 138 -#define TK_DISTINCT 139 -#define TK_DOT 140 -#define TK_FROM 141 -#define TK_JOIN 142 -#define TK_USING 143 -#define TK_ORDER 144 -#define TK_GROUP 145 -#define TK_HAVING 146 -#define TK_LIMIT 147 -#define TK_WHERE 148 -#define TK_RETURNING 149 -#define TK_INTO 150 -#define TK_NOTHING 151 -#define TK_FLOAT 152 -#define TK_BLOB 153 -#define TK_INTEGER 154 -#define TK_VARIABLE 155 -#define TK_CASE 156 -#define TK_WHEN 157 -#define TK_THEN 158 -#define TK_ELSE 159 -#define TK_INDEX 160 -#define TK_ALTER 161 -#define TK_ADD 162 -#define TK_WINDOW 163 -#define TK_OVER 164 -#define TK_FILTER 165 -#define TK_COLUMN 166 -#define TK_AGG_FUNCTION 167 -#define TK_AGG_COLUMN 168 -#define TK_TRUEFALSE 169 -#define TK_ISNOT 170 -#define TK_FUNCTION 171 -#define TK_UMINUS 172 -#define TK_UPLUS 173 -#define TK_TRUTH 174 -#define TK_REGISTER 175 -#define TK_VECTOR 176 -#define TK_SELECT_COLUMN 177 -#define TK_IF_NULL_ROW 178 -#define TK_ASTERISK 179 -#define TK_SPAN 180 -#define TK_ERROR 181 -#define TK_SPACE 182 -#define TK_ILLEGAL 183 +#define TK_PTR 112 +#define TK_COLLATE 113 +#define TK_BITNOT 114 +#define TK_ON 115 +#define TK_INDEXED 116 +#define TK_STRING 117 +#define TK_JOIN_KW 118 +#define TK_CONSTRAINT 119 +#define TK_DEFAULT 120 +#define TK_NULL 121 +#define TK_PRIMARY 122 +#define TK_UNIQUE 123 +#define TK_CHECK 124 +#define TK_REFERENCES 125 +#define TK_AUTOINCR 126 +#define TK_INSERT 127 +#define TK_DELETE 128 +#define TK_UPDATE 129 +#define TK_SET 130 +#define TK_DEFERRABLE 131 +#define TK_FOREIGN 132 +#define TK_DROP 133 +#define TK_UNION 134 +#define TK_ALL 135 +#define TK_EXCEPT 136 +#define TK_INTERSECT 137 +#define TK_SELECT 138 +#define TK_VALUES 139 +#define TK_DISTINCT 140 +#define TK_DOT 141 +#define TK_FROM 142 +#define TK_JOIN 143 +#define TK_USING 144 +#define TK_ORDER 145 +#define TK_GROUP 146 +#define TK_HAVING 147 +#define TK_LIMIT 148 +#define TK_WHERE 149 +#define TK_RETURNING 150 +#define TK_INTO 151 +#define TK_NOTHING 152 +#define TK_FLOAT 153 +#define TK_BLOB 154 +#define TK_INTEGER 155 +#define TK_VARIABLE 156 +#define TK_CASE 157 +#define TK_WHEN 158 +#define TK_THEN 159 +#define TK_ELSE 160 +#define TK_INDEX 161 +#define TK_ALTER 162 +#define TK_ADD 163 +#define TK_WINDOW 164 +#define TK_OVER 165 +#define TK_FILTER 166 +#define TK_COLUMN 167 +#define TK_AGG_FUNCTION 168 +#define TK_AGG_COLUMN 169 +#define TK_TRUEFALSE 170 +#define TK_ISNOT 171 +#define TK_FUNCTION 172 +#define TK_UMINUS 173 +#define TK_UPLUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_SPACE 183 +#define TK_ILLEGAL 184 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14335,10 +14650,11 @@ typedef struct With With; /* ** A bit in a Bitmask */ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT64(n) (((u64)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT64(n) (((u64)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) +#define ALLBITS ((Bitmask)-1) /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer @@ -15254,45 +15570,45 @@ typedef struct VdbeOpList VdbeOpList; #define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 61 /* jump */ #define OP_VNext 62 /* jump */ -#define OP_Init 63 /* jump, synopsis: Start at P2 */ -#define OP_PureFunc 64 /* synopsis: r[P3]=func(r[P2@NP]) */ -#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@NP]) */ -#define OP_Return 66 -#define OP_EndCoroutine 67 -#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */ -#define OP_Halt 69 -#define OP_Integer 70 /* synopsis: r[P2]=P1 */ -#define OP_Int64 71 /* synopsis: r[P2]=P4 */ -#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */ -#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */ -#define OP_ChngCntRow 81 /* synopsis: output=r[P1] */ -#define OP_ResultRow 82 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 83 -#define OP_AddImm 84 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 85 -#define OP_Cast 86 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 87 -#define OP_Compare 88 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_IsTrue 89 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_ZeroOrNull 90 /* synopsis: r[P2] = 0 OR NULL */ -#define OP_Offset 91 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 92 /* synopsis: r[P3]=PX */ -#define OP_TypeCheck 93 /* synopsis: typecheck(r[P1@P2]) */ -#define OP_Affinity 94 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 95 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 96 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 97 -#define OP_SetCookie 98 -#define OP_ReopenIdx 99 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 100 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 101 /* synopsis: root=P2 iDb=P3 */ +#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_Init 64 /* jump, synopsis: Start at P2 */ +#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Return 67 +#define OP_EndCoroutine 68 +#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 70 +#define OP_Integer 71 /* synopsis: r[P2]=P1 */ +#define OP_Int64 72 /* synopsis: r[P2]=P4 */ +#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */ +#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */ +#define OP_FkCheck 82 +#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 84 +#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 86 +#define OP_Cast 87 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 88 +#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */ +#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 93 /* synopsis: r[P3]=PX */ +#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */ +#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 97 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 98 +#define OP_SetCookie 99 +#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */ #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 159 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 160 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 162 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 163 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 164 -#define OP_CursorLock 165 -#define OP_CursorUnlock 166 -#define OP_TableLock 167 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 168 -#define OP_VCreate 169 -#define OP_VDestroy 170 -#define OP_VOpen 171 -#define OP_VColumn 172 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 173 -#define OP_Pagecount 174 -#define OP_MaxPgcnt 175 -#define OP_Trace 176 -#define OP_CursorHint 177 -#define OP_ReleaseReg 178 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 179 -#define OP_Explain 180 -#define OP_Abortable 181 +#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 113 +#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */ +#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_SorterOpen 118 +#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 121 +#define OP_ColumnsUsed 122 +#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */ +#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 128 +#define OP_Delete 129 +#define OP_ResetCount 130 +#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 132 /* synopsis: r[P2]=data */ +#define OP_RowData 133 /* synopsis: r[P2]=data */ +#define OP_Rowid 134 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 135 +#define OP_SeekEnd 136 +#define OP_IdxInsert 137 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 138 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 142 +#define OP_Destroy 143 +#define OP_Clear 144 +#define OP_ResetSorter 145 +#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 147 +#define OP_ParseSchema 148 +#define OP_LoadAnalysis 149 +#define OP_DropTable 150 +#define OP_DropIndex 151 +#define OP_DropTrigger 152 +#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_IntegrityCk 154 +#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 156 +#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 165 +#define OP_CursorLock 166 +#define OP_CursorUnlock 167 +#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 169 +#define OP_VCreate 170 +#define OP_VDestroy 171 +#define OP_VOpen 172 +#define OP_VInitIn 173 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VColumn 174 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 175 +#define OP_Pagecount 176 +#define OP_MaxPgcnt 177 +#define OP_FilterAdd 178 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 179 +#define OP_CursorHint 180 +#define OP_ReleaseReg 181 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 182 +#define OP_Explain 183 +#define OP_Abortable 184 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -15393,21 +15712,22 @@ typedef struct VdbeOpList VdbeOpList; /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ -/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\ -/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\ -/* 80 */ 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\ -/* 88 */ 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00,\ -/* 96 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\ +/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ +/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\ +/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\ +/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\ +/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\ -/* 136 */ 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,\ -/* 144 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00,\ +/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ +/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\ +/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ -/* 176 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 176 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 184 */ 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -15415,7 +15735,7 @@ typedef struct VdbeOpList VdbeOpList; ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ -#define SQLITE_MX_JUMP_OPCODE 63 /* Maximum JUMP opcode */ +#define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */ /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -16476,6 +16796,7 @@ struct sqlite3 { u32 nSchemaLock; /* Do not reset the schema when non-zero */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ + int errByteOffset; /* Byte offset of error in SQL statement */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ u32 dbOptFlags; /* Flags to enable/disable optimizations */ @@ -16710,6 +17031,9 @@ struct sqlite3 { #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */ #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */ +#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ +#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ +#define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -16883,7 +17207,7 @@ struct FuncDestructor { ** are interpreted in the same way as the first 4 parameters to ** FUNCTION(). ** -** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) +** WAGGREGATE(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) ** Used to create an aggregate function definition implemented by ** the C functions xStep and xFinal. The first four parameters ** are interpreted in the same way as the first 4 parameters to @@ -16910,6 +17234,10 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } +#define JFUNCTION(zName, nArg, iArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -17764,7 +18092,10 @@ struct Expr { ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ - int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + union { + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + int iOfst; /* else: start of token from start of statement */ + } w; AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18504,6 +18835,8 @@ struct Parse { AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ union { int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ @@ -18524,6 +18857,7 @@ struct Parse { **************************************************************************/ int aTempReg[8]; /* Holding area for temporary registers */ + Parse *pOuterParse; /* Outer Parse object when nested */ Token sNameToken; /* Token with unqualified schema object name */ /************************************************************************ @@ -18558,9 +18892,7 @@ struct Parse { Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ #endif - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -18576,7 +18908,8 @@ struct Parse { /* ** Sizes and pointers of various parts of the Parse object. */ -#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/ +#define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg)) +#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ @@ -18871,6 +19204,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ @@ -19351,7 +19685,7 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); SQLITE_PRIVATE void sqlite3DequoteToken(Token*); SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); -SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); +SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); @@ -19512,10 +19846,12 @@ SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*); SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, Upsert*); -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*, + ExprList*,Select*,u16,int); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); @@ -19594,6 +19930,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif @@ -19630,9 +19967,14 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*); +#endif SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); @@ -19722,14 +20064,8 @@ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); -#ifndef SQLITE_OMIT_VIRTUALTABLE SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); -#endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); -#endif SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int); SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); @@ -19916,17 +20252,20 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, FuncDestructor *pDestructor ); SQLITE_PRIVATE void sqlite3NoopDestructor(void*); -SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*); SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*); +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*); SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); @@ -20031,11 +20370,17 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); + SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*); +#endif SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); -SQLITE_PRIVATE void sqlite3ParserReset(Parse*); +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*); +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*); SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); @@ -20094,6 +20439,7 @@ SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3*,int); #else #define sqlite3FkActions(a,b,c,d,e,f) #define sqlite3FkCheck(a,b,c,d,e,f) @@ -20101,6 +20447,7 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); #define sqlite3FkOldmask(a,b) 0 #define sqlite3FkRequired(a,b,c,d) 0 #define sqlite3FkReferences(a) 0 + #define sqlite3FkClearTriggerCache(a,b) #endif #ifndef SQLITE_OMIT_FOREIGN_KEY SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); @@ -20466,6 +20813,14 @@ SQLITE_API extern int sqlite3_open_file_count; /************** End of os_common.h *******************************************/ /************** Begin file ctime.c *******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script in the canonical +** SQLite source tree at tool/mkctimec.tcl. +** +** To modify this header, edit any of the various lists in that script +** which specify categories of generated conditionals in this file. +*/ + /* ** 2010 February 23 ** @@ -20514,9 +20869,6 @@ SQLITE_API extern int sqlite3_open_file_count; */ static const char * const sqlite3azCompileOpt[] = { -/* -** BEGIN CODE GENERATED BY tool/mkctime.tcl -*/ #ifdef SQLITE_32BIT_ROWID "32BIT_ROWID", #endif @@ -20725,9 +21077,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_IOTRACE "ENABLE_IOTRACE", #endif -#ifdef SQLITE_ENABLE_JSON1 - "ENABLE_JSON1", -#endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION "ENABLE_LOAD_EXTENSION", #endif @@ -21051,6 +21400,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS "OMIT_INTROSPECTION_PRAGMAS", #endif +#ifdef SQLITE_OMIT_JSON + "OMIT_JSON", +#endif #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION "OMIT_LIKE_OPTIMIZATION", #endif @@ -21239,10 +21591,8 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ZERO_MALLOC "ZERO_MALLOC", #endif -/* -** END CODE GENERATED BY tool/mkctime.tcl -*/ -}; + +} ; SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]); @@ -21541,6 +21891,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ @@ -21754,7 +22105,7 @@ typedef struct AuxData AuxData; typedef struct VdbeCursor VdbeCursor; struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ - i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ + i8 iDb; /* Index of cursor database in db->aDb[] */ u8 nullRow; /* True if pointing to a row with no data */ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ u8 isTable; /* True for rowid tables. False for indexes */ @@ -21767,9 +22118,11 @@ struct VdbeCursor { Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ - Btree *pBtx; /* Separate file holding temporary table */ + union { /* pBtx for isEphermeral. pAltMap otherwise */ + Btree *pBtx; /* Separate file holding temporary table */ + u32 *aAltMap; /* Mapping from table to index column numbers */ + } ub; i64 seqCount; /* Sequence counter */ - u32 *aAltMap; /* Mapping from table to index column numbers */ /* Cached OP_Column parse information is only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of @@ -22109,7 +22462,7 @@ struct Vdbe { bft bIsReader:1; /* True for statements that read */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */ + u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_ENABLE_NORMALIZE char *zNormSql; /* Normalization of the associated SQL statement */ @@ -22159,6 +22512,24 @@ struct PreUpdate { Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; +/* +** An instance of this object is used to pass an vector of values into +** OP_VFilter, the xFilter method of a virtual table. The vector is the +** set of values on the right-hand side of an IN constraint. +** +** The value as passed into xFilter is an sqlite3_value with a "pointer" +** type, such as is generated by sqlite3_result_pointer() and read by +** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null +** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces +** know how to use this object to step through all the values in the +** right operand of the IN constraint. +*/ +typedef struct ValueList ValueList; +struct ValueList { + BtCursor *pCsr; /* An ephemeral table holding all values */ + sqlite3_value *pOut; /* Register to hold each decoded output value */ +}; + /* ** Function prototypes */ @@ -22171,7 +22542,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); @@ -22217,7 +22588,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*); SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); @@ -23195,8 +23566,10 @@ static void clearYMD_HMS_TZ(DateTime *p){ ** is available. This routine returns 0 on success and ** non-zero on any kind of error. ** -** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this -** routine will always fail. +** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this +** routine will always fail. If bLocaltimeFault is nonzero and +** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is +** invoked in place of the OS-defined localtime() function. ** ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C ** library function localtime_r() is used to assist in the calculation of @@ -23212,14 +23585,30 @@ static int osLocaltime(time_t *t, struct tm *pTm){ sqlite3_mutex_enter(mutex); pX = localtime(t); #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 + && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm) + ){ + pX = pTm; + }else{ + pX = 0; + } + } #endif if( pX ) *pTm = *pX; +#if SQLITE_THREADSAFE>0 sqlite3_mutex_leave(mutex); +#endif rc = pX==0; #else #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 ){ + return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm); + }else{ + return 1; + } + } #endif #if HAVE_LOCALTIME_R rc = localtime_r(t, pTm)==0; @@ -23234,67 +23623,56 @@ static int osLocaltime(time_t *t, struct tm *pTm){ #ifndef SQLITE_OMIT_LOCALTIME /* -** Compute the difference (in milliseconds) between localtime and UTC -** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, -** return this value and set *pRc to SQLITE_OK. -** -** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value -** is undefined in this case. +** Assuming the input DateTime is UTC, move it to its localtime equivalent. */ -static sqlite3_int64 localtimeOffset( - DateTime *p, /* Date at which to calculate offset */ - sqlite3_context *pCtx, /* Write error here if one occurs */ - int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +static int toLocaltime( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx /* Write error here if one occurs */ ){ - DateTime x, y; time_t t; struct tm sLocal; + int iYearDiff; /* Initialize the contents of sLocal to avoid a compiler warning. */ memset(&sLocal, 0, sizeof(sLocal)); - x = *p; - computeYMD_HMS(&x); - if( x.Y<1971 || x.Y>=2038 ){ + computeJD(p); + if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */ + || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */ + ){ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only ** works for years between 1970 and 2037. For dates outside this range, ** SQLite attempts to map the year into an equivalent year within this ** range, do the calculation, then map the year back. */ - x.Y = 2000; - x.M = 1; - x.D = 1; - x.h = 0; - x.m = 0; - x.s = 0.0; - } else { - int s = (int)(x.s + 0.5); - x.s = s; + DateTime x = *p; + computeYMD_HMS(&x); + iYearDiff = (2000 + x.Y%4) - x.Y; + x.Y += iYearDiff; + x.validJD = 0; + computeJD(&x); + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); + }else{ + iYearDiff = 0; + t = (time_t)(p->iJD/1000 - 21086676*(i64)10000); } - x.tz = 0; - x.validJD = 0; - computeJD(&x); - t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); if( osLocaltime(&t, &sLocal) ){ sqlite3_result_error(pCtx, "local time unavailable", -1); - *pRc = SQLITE_ERROR; - return 0; + return SQLITE_ERROR; } - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - y.validYMD = 1; - y.validHMS = 1; - y.validJD = 0; - y.rawS = 0; - y.validTZ = 0; - y.isError = 0; - computeJD(&y); - *pRc = SQLITE_OK; - return y.iJD - x.iJD; + p->Y = sLocal.tm_year + 1900 - iYearDiff; + p->M = sLocal.tm_mon + 1; + p->D = sLocal.tm_mday; + p->h = sLocal.tm_hour; + p->m = sLocal.tm_min; + p->s = sLocal.tm_sec + (p->iJD%1000)*0.001; + p->validYMD = 1; + p->validHMS = 1; + p->validJD = 0; + p->rawS = 0; + p->validTZ = 0; + p->isError = 0; + return SQLITE_OK; } #endif /* SQLITE_OMIT_LOCALTIME */ @@ -23307,18 +23685,17 @@ static sqlite3_int64 localtimeOffset( ** of several units of time. */ static const struct { - u8 eType; /* Transformation type code */ - u8 nName; /* Length of th name */ - char *zName; /* Name of the transformation */ - double rLimit; /* Maximum NNN value for this transform */ - double rXform; /* Constant used for this transform */ + u8 nName; /* Length of the name */ + char zName[7]; /* Name of the transformation */ + float rLimit; /* Maximum NNN value for this transform */ + float rXform; /* Constant used for this transform */ } aXformType[] = { - { 0, 6, "second", 464269060800.0, 1000.0 }, - { 0, 6, "minute", 7737817680.0, 60000.0 }, - { 0, 4, "hour", 128963628.0, 3600000.0 }, - { 0, 3, "day", 5373485.0, 86400000.0 }, - { 1, 5, "month", 176546.0, 2592000000.0 }, - { 2, 4, "year", 14713.0, 31536000000.0 }, + { 6, "second", 4.6427e+14, 1.0 }, + { 6, "minute", 7.7379e+12, 60.0 }, + { 4, "hour", 1.2897e+11, 3600.0 }, + { 3, "day", 5373485.0, 86400.0 }, + { 5, "month", 176546.0, 2592000.0 }, + { 4, "year", 14713.0, 31536000.0 }, }; /* @@ -23349,11 +23726,55 @@ static int parseModifier( sqlite3_context *pCtx, /* Function context */ const char *z, /* The text of the modifier */ int n, /* Length of zMod in bytes */ - DateTime *p /* The date/time value to be modified */ + DateTime *p, /* The date/time value to be modified */ + int idx /* Parameter index of the modifier */ ){ int rc = 1; double r; switch(sqlite3UpperToLower[(u8)z[0]] ){ + case 'a': { + /* + ** auto + ** + ** If rawS is available, then interpret as a julian day number, or + ** a unix timestamp, depending on its magnitude. + */ + if( sqlite3_stricmp(z, "auto")==0 ){ + if( idx>1 ) return 1; /* IMP: R-33611-57934 */ + if( !p->rawS || p->validJD ){ + rc = 0; + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + rc = 0; + } + } + break; + } + case 'j': { + /* + ** julianday + ** + ** Always interpret the prior number as a julian-day value. If this + ** is not the first modifier, or if the prior argument is not a numeric + ** value in the allowed range of julian day numbers understood by + ** SQLite (0..5373484.5) then the result will be NULL. + */ + if( sqlite3_stricmp(z, "julianday")==0 ){ + if( idx>1 ) return 1; /* IMP: R-31176-64601 */ + if( p->validJD && p->rawS ){ + rc = 0; + p->rawS = 0; + } + } + break; + } #ifndef SQLITE_OMIT_LOCALTIME case 'l': { /* localtime @@ -23362,9 +23783,7 @@ static int parseModifier( ** show local time. */ if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ - computeJD(p); - p->iJD += localtimeOffset(p, pCtx, &rc); - clearYMD_HMS_TZ(p); + rc = toLocaltime(p, pCtx); } break; } @@ -23377,6 +23796,7 @@ static int parseModifier( ** seconds since 1970. Convert to a real julian day number. */ if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ + if( idx>1 ) return 1; /* IMP: R-49255-55373 */ r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); @@ -23389,18 +23809,31 @@ static int parseModifier( #ifndef SQLITE_OMIT_LOCALTIME else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ if( p->tzSet==0 ){ - sqlite3_int64 c1; + i64 iOrigJD; /* Original localtime */ + i64 iGuess; /* Guess at the corresponding utc time */ + int cnt = 0; /* Safety to prevent infinite loop */ + int iErr; /* Guess is off by this much */ + computeJD(p); - c1 = localtimeOffset(p, pCtx, &rc); - if( rc==SQLITE_OK ){ - p->iJD -= c1; - clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p, pCtx, &rc); - } + iGuess = iOrigJD = p->iJD; + iErr = 0; + do{ + DateTime new; + memset(&new, 0, sizeof(new)); + iGuess -= iErr; + new.iJD = iGuess; + new.validJD = 1; + rc = toLocaltime(&new, pCtx); + if( rc ) return rc; + computeJD(&new); + iErr = new.iJD - iOrigJD; + }while( iErr && cnt++<3 ); + memset(p, 0, sizeof(*p)); + p->iJD = iGuess; + p->validJD = 1; p->tzSet = 1; - }else{ - rc = SQLITE_OK; } + rc = SQLITE_OK; } #endif break; @@ -23516,9 +23949,10 @@ static int parseModifier( && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 && r>-aXformType[i].rLimit && rM += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; @@ -23528,8 +23962,9 @@ static int parseModifier( r -= (int)r; break; } - case 2: { /* Special processing to add years */ + case 5: { /* Special processing to add years */ int y = (int)r; + assert( strcmp(aXformType[i].zName,"year")==0 ); computeYMD_HMS(p); p->Y += y; p->validJD = 0; @@ -23538,7 +23973,7 @@ static int parseModifier( } } computeJD(p); - p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder); + p->iJD += (sqlite3_int64)(r*1000.0*aXformType[i].rXform + rRounder); rc = 0; break; } @@ -23588,7 +24023,7 @@ static int isDate( for(i=1; iisError || !validJulianDay(p->iJD) ) return 1; @@ -23618,6 +24053,24 @@ static void juliandayFunc( } } +/* +** unixepoch( TIMESTRING, MOD, MOD, ...) +** +** Return the number of seconds (including fractional seconds) since +** the unix epoch of 1970-01-01 00:00:00 GMT. +*/ +static void unixepochFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + computeJD(&x); + sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); + } +} + /* ** datetime( TIMESTRING, MOD, MOD, ...) ** @@ -23630,11 +24083,38 @@ static void datetimeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int Y, s; + char zBuf[24]; computeYMD_HMS(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d", - x.Y, x.M, x.D, x.h, x.m, (int)(x.s)); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = ' '; + zBuf[12] = '0' + (x.h/10)%10; + zBuf[13] = '0' + (x.h)%10; + zBuf[14] = ':'; + zBuf[15] = '0' + (x.m/10)%10; + zBuf[16] = '0' + (x.m)%10; + zBuf[17] = ':'; + s = (int)x.s; + zBuf[18] = '0' + (s/10)%10; + zBuf[19] = '0' + (s)%10; + zBuf[20] = 0; + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT); + } } } @@ -23650,10 +24130,20 @@ static void timeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int s; + char zBuf[16]; computeHMS(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + zBuf[0] = '0' + (x.h/10)%10; + zBuf[1] = '0' + (x.h)%10; + zBuf[2] = ':'; + zBuf[3] = '0' + (x.m/10)%10; + zBuf[4] = '0' + (x.m)%10; + zBuf[5] = ':'; + s = (int)x.s; + zBuf[6] = '0' + (s/10)%10; + zBuf[7] = '0' + (s)%10; + zBuf[8] = 0; + sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT); } } @@ -23669,10 +24159,28 @@ static void dateFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int Y; + char zBuf[16]; computeYMD(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = 0; + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT); + } } } @@ -23894,6 +24402,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ static FuncDef aDateTimeFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS PURE_DATE(julianday, -1, 0, 0, juliandayFunc ), + PURE_DATE(unixepoch, -1, 0, 0, unixepochFunc ), PURE_DATE(date, -1, 0, 0, dateFunc ), PURE_DATE(time, -1, 0, 0, timeFunc ), PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), @@ -28830,8 +29339,9 @@ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const cha ** Free any prior content in *pz and replace it with a copy of zNew. */ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ + char *z = sqlite3DbStrDup(db, zNew); sqlite3DbFree(db, *pz); - *pz = sqlite3DbStrDup(db, zNew); + *pz = z; } /* @@ -28839,8 +29349,15 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ ** has happened. This routine will set db->mallocFailed, and also ** temporarily disable the lookaside memory allocator and interrupt ** any running VDBEs. +** +** Always return a NULL pointer so that this routine can be invoked using +** +** return sqlite3OomFault(db); +** +** and thereby avoid unnecessary stack frame allocations for the overwhelmingly +** common case where no OOM occurs. */ -SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ @@ -28848,9 +29365,11 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ } DisableLookaside; if( db->pParse ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); db->pParse->rc = SQLITE_NOMEM_BKPT; } } + return 0; } /* @@ -29759,12 +30278,22 @@ SQLITE_API void sqlite3_str_vappendf( goto adjust_width_for_utf8; } case etTOKEN: { - Token *pToken; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; - pToken = va_arg(ap, Token*); - assert( bArgList==0 ); - if( pToken && pToken->n ){ - sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + if( flag_alternateform ){ + /* %#T means an Expr pointer that uses Expr.u.zToken */ + Expr *pExpr = va_arg(ap,Expr*); + if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){ + sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken); + sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr); + } + }else{ + /* %T means a Token pointer */ + Token *pToken = va_arg(ap, Token*); + assert( bArgList==0 ); + if( pToken && pToken->n ){ + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + sqlite3RecordErrorByteOffset(pAccum->db, pToken->z); + } } length = width = 0; break; @@ -29819,6 +30348,42 @@ SQLITE_API void sqlite3_str_vappendf( }/* End for loop over the format string */ } /* End of function */ + +/* +** The z string points to the first character of a token that is +** associated with an error. If db does not already have an error +** byte offset recorded, try to compute the error byte offset for +** z and set the error byte offset in db. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){ + const Parse *pParse; + const char *zText; + const char *zEnd; + assert( z!=0 ); + if( NEVER(db==0) ) return; + if( db->errByteOffset!=(-2) ) return; + pParse = db->pParse; + if( NEVER(pParse==0) ) return; + zText =pParse->zTail; + if( NEVER(zText==0) ) return; + zEnd = &zText[strlen(zText)]; + if( SQLITE_WITHIN(z,zText,zEnd) ){ + db->errByteOffset = (int)(z-zText); + } +} + +/* +** If pExpr has a byte offset for the start of a token, record that as +** as the error offset. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ + while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){ + pExpr = pExpr->pLeft; + } + if( pExpr==0 ) return; + db->errByteOffset = pExpr->w.iOfst; +} + /* ** Enlarge the memory allocation on a StrAccum object so that it is ** able to accept at least N more bytes of text. @@ -29826,7 +30391,7 @@ SQLITE_API void sqlite3_str_vappendf( ** Return the number of bytes of text that StrAccum is able to accept ** after the attempted enlargement. The value returned might be zero. */ -static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ @@ -30660,7 +31225,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable); } if( ExprHasProperty(pExpr, EP_FromDDL) ){ sqlite3_str_appendf(&x, " DDL"); @@ -32142,7 +32707,11 @@ static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ assert( db!=0 ); db->errCode = err_code; - if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); + if( err_code || db->pErr ){ + sqlite3ErrorFinish(db, err_code); + }else{ + db->errByteOffset = -1; + } } /* @@ -32152,6 +32721,7 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ assert( db!=0 ); db->errCode = SQLITE_OK; + db->errByteOffset = -1; if( db->pErr ) sqlite3ValueSetNull(db->pErr); } @@ -32172,17 +32742,8 @@ SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ ** handle "db". The error code is set to "err_code". ** ** If it is not NULL, string zFormat specifies the format of the -** error string in the style of the printf functions: The following -** format characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** zFormat and any string tokens that follow it are assumed to be -** encoded in UTF-8. +** error string. zFormat and any string tokens that follow it are +** assumed to be encoded in UTF-8. ** ** To clear the most recent error for sqlite handle "db", sqlite3Error ** should be called with err_code set to SQLITE_OK and zFormat set @@ -32206,13 +32767,6 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *z /* ** Add an error message to pParse->zErrMsg and increment pParse->nErr. -** The following formatting characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList ** ** This function should be used to report any error that occurs while ** compiling an SQL statement (i.e. within sqlite3_prepare()). The @@ -32225,11 +32779,19 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ char *zMsg; va_list ap; sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + db->errByteOffset = -2; va_start(ap, zFormat); zMsg = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); + if( db->errByteOffset<-1 ) db->errByteOffset = -1; if( db->suppressErr ){ sqlite3DbFree(db, zMsg); + if( db->mallocFailed ){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } }else{ pParse->nErr++; sqlite3DbFree(db, pParse->zErrMsg); @@ -33611,7 +34173,6 @@ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ return a[x&7] + y - 10; } -#ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Convert a double into a LogEst ** In other words, compute an approximation for 10*log2(x). @@ -33626,16 +34187,9 @@ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ e = (a>>52) - 1022; return e*10; } -#endif /* SQLITE_OMIT_VIRTUALTABLE */ -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) /* ** Convert a LogEst into an integer. -** -** Note that this routine is only used when one or more of various -** non-standard compile-time options is enabled. */ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ u64 n; @@ -33643,17 +34197,9 @@ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ x /= 10; if( n>=5 ) n -= 2; else if( n>=1 ) n -= 1; -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) if( x>60 ) return (u64)LARGEST_INT64; -#else - /* If only SQLITE_ENABLE_STAT4 is on, then the largest input - ** possible to this routine is 310, resulting in a maximum x of 31 */ - assert( x<=60 ); -#endif return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); } -#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ /* ** Add a new name/number pair to a VList. This might require that the @@ -34107,45 +34653,45 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 61 */ "IncrVacuum" OpHelp(""), /* 62 */ "VNext" OpHelp(""), - /* 63 */ "Init" OpHelp("Start at P2"), - /* 64 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), - /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), - /* 66 */ "Return" OpHelp(""), - /* 67 */ "EndCoroutine" OpHelp(""), - /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), - /* 69 */ "Halt" OpHelp(""), - /* 70 */ "Integer" OpHelp("r[P2]=P1"), - /* 71 */ "Int64" OpHelp("r[P2]=P4"), - /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 81 */ "ChngCntRow" OpHelp("output=r[P1]"), - /* 82 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 83 */ "CollSeq" OpHelp(""), - /* 84 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 85 */ "RealAffinity" OpHelp(""), - /* 86 */ "Cast" OpHelp("affinity(r[P1])"), - /* 87 */ "Permutation" OpHelp(""), - /* 88 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 89 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 90 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), - /* 91 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 92 */ "Column" OpHelp("r[P3]=PX"), - /* 93 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), - /* 94 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 95 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 96 */ "Count" OpHelp("r[P2]=count()"), - /* 97 */ "ReadCookie" OpHelp(""), - /* 98 */ "SetCookie" OpHelp(""), - /* 99 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 100 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 101 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 64 */ "Init" OpHelp("Start at P2"), + /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), + /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), + /* 67 */ "Return" OpHelp(""), + /* 68 */ "EndCoroutine" OpHelp(""), + /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 70 */ "Halt" OpHelp(""), + /* 71 */ "Integer" OpHelp("r[P2]=P1"), + /* 72 */ "Int64" OpHelp("r[P2]=P4"), + /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 82 */ "FkCheck" OpHelp(""), + /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 84 */ "CollSeq" OpHelp(""), + /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 86 */ "RealAffinity" OpHelp(""), + /* 87 */ "Cast" OpHelp("affinity(r[P1])"), + /* 88 */ "Permutation" OpHelp(""), + /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), + /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 93 */ "Column" OpHelp("r[P3]=PX"), + /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), + /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 97 */ "Count" OpHelp("r[P2]=count()"), + /* 98 */ "ReadCookie" OpHelp(""), + /* 99 */ "SetCookie" OpHelp(""), + /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 159 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 160 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 161 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 162 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 163 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 164 */ "Expire" OpHelp(""), - /* 165 */ "CursorLock" OpHelp(""), - /* 166 */ "CursorUnlock" OpHelp(""), - /* 167 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 168 */ "VBegin" OpHelp(""), - /* 169 */ "VCreate" OpHelp(""), - /* 170 */ "VDestroy" OpHelp(""), - /* 171 */ "VOpen" OpHelp(""), - /* 172 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 173 */ "VRename" OpHelp(""), - /* 174 */ "Pagecount" OpHelp(""), - /* 175 */ "MaxPgcnt" OpHelp(""), - /* 176 */ "Trace" OpHelp(""), - /* 177 */ "CursorHint" OpHelp(""), - /* 178 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 179 */ "Noop" OpHelp(""), - /* 180 */ "Explain" OpHelp(""), - /* 181 */ "Abortable" OpHelp(""), + /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 113 */ "OpenDup" OpHelp(""), + /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "String8" OpHelp("r[P2]='P4'"), + /* 118 */ "SorterOpen" OpHelp(""), + /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 121 */ "Close" OpHelp(""), + /* 122 */ "ColumnsUsed" OpHelp(""), + /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 128 */ "RowCell" OpHelp(""), + /* 129 */ "Delete" OpHelp(""), + /* 130 */ "ResetCount" OpHelp(""), + /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 132 */ "SorterData" OpHelp("r[P2]=data"), + /* 133 */ "RowData" OpHelp("r[P2]=data"), + /* 134 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 135 */ "NullRow" OpHelp(""), + /* 136 */ "SeekEnd" OpHelp(""), + /* 137 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 138 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 142 */ "FinishSeek" OpHelp(""), + /* 143 */ "Destroy" OpHelp(""), + /* 144 */ "Clear" OpHelp(""), + /* 145 */ "ResetSorter" OpHelp(""), + /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 147 */ "SqlExec" OpHelp(""), + /* 148 */ "ParseSchema" OpHelp(""), + /* 149 */ "LoadAnalysis" OpHelp(""), + /* 150 */ "DropTable" OpHelp(""), + /* 151 */ "DropIndex" OpHelp(""), + /* 152 */ "DropTrigger" OpHelp(""), + /* 153 */ "Real" OpHelp("r[P2]=P4"), + /* 154 */ "IntegrityCk" OpHelp(""), + /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 156 */ "Param" OpHelp(""), + /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 165 */ "Expire" OpHelp(""), + /* 166 */ "CursorLock" OpHelp(""), + /* 167 */ "CursorUnlock" OpHelp(""), + /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 169 */ "VBegin" OpHelp(""), + /* 170 */ "VCreate" OpHelp(""), + /* 171 */ "VDestroy" OpHelp(""), + /* 172 */ "VOpen" OpHelp(""), + /* 173 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 174 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 175 */ "VRename" OpHelp(""), + /* 176 */ "Pagecount" OpHelp(""), + /* 177 */ "MaxPgcnt" OpHelp(""), + /* 178 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 179 */ "Trace" OpHelp(""), + /* 180 */ "CursorHint" OpHelp(""), + /* 181 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 182 */ "Noop" OpHelp(""), + /* 183 */ "Explain" OpHelp(""), + /* 184 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -39145,11 +39694,17 @@ static int unixShmLock( int flags /* What to do with the lock */ ){ unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ - unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + unixShm *p; /* The shared memory being locked */ + unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ - int *aLock = pShmNode->aLock; + int *aLock; + + p = pDbFd->pShm; + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + aLock = pShmNode->aLock; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); @@ -46437,10 +46992,14 @@ static int winShmLock( winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ winShm *p = pDbFd->pShm; /* The shared memory being locked */ winShm *pX; /* For looping over all siblings */ - winShmNode *pShmNode = p->pShmNode; + winShmNode *pShmNode; int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); assert( n>=1 ); assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) @@ -50370,7 +50929,8 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ ** make it so. */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ - assert( p->nRef>0 ); + assert( p->nRef>0 || p->pCache->bPurgeable==0 ); + testcase( p->nRef==0 ); assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; @@ -55502,6 +56062,9 @@ static int pager_playback(Pager *pPager, int isHot){ goto end_playback; } pPager->dbSize = mxPg; + if( pPager->mxPgnomxPgno = mxPg; + } } /* Copy original pages out of the journal and back into the @@ -56558,8 +57121,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ ** current database image, in pages, OR ** ** b) if the page content were written at this time, it would not -** be necessary to write the current content out to the sub-journal -** (as determined by function subjRequiresPage()). +** be necessary to write the current content out to the sub-journal. ** ** If the condition asserted by this function were not true, and the ** dirty page were to be discarded from the cache via the pagerStress() @@ -56574,8 +57136,16 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ */ #if defined(SQLITE_DEBUG) static void assertTruncateConstraintCb(PgHdr *pPg){ + Pager *pPager = pPg->pPager; assert( pPg->flags&PGHDR_DIRTY ); - assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); + if( pPg->pgno>pPager->dbSize ){ /* if (a) is false */ + Pgno pgno = pPg->pgno; + int i; + for(i=0; ipPager->nSavepoint; i++){ + PagerSavepoint *p = &pPager->aSavepoint[i]; + assert( p->nOrigpInSavepoint,pgno) ); + } + } } static void assertTruncateConstraint(Pager *pPager){ sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); @@ -56597,7 +57167,6 @@ static void assertTruncateConstraint(Pager *pPager){ */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ assert( pPager->dbSize>=nPage || CORRUPT_DB ); - testcase( pPager->dbSizeeState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; @@ -57916,7 +58485,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ ** may mean that the pager was in the error-state when this ** function was called and the journal file does not exist. */ - if( !isOpen(pPager->jfd) ){ + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ sqlite3_vfs * const pVfs = pPager->pVfs; int bExists; /* True if journal file exists */ rc = sqlite3OsAccess( @@ -58318,6 +58887,7 @@ SQLITE_PRIVATE int sqlite3PagerGet( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ + /* printf("PAGE %u\n", pgno); fflush(stdout); */ return pPager->xGet(pPager, pgno, ppPage, flags); } @@ -59923,12 +60493,12 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ u8 eOld = pPager->journalMode; /* Prior journalmode */ /* The eMode parameter is always valid */ - assert( eMode==PAGER_JOURNALMODE_DELETE - || eMode==PAGER_JOURNALMODE_TRUNCATE - || eMode==PAGER_JOURNALMODE_PERSIST - || eMode==PAGER_JOURNALMODE_OFF - || eMode==PAGER_JOURNALMODE_WAL - || eMode==PAGER_JOURNALMODE_MEMORY ); + assert( eMode==PAGER_JOURNALMODE_DELETE /* 0 */ + || eMode==PAGER_JOURNALMODE_PERSIST /* 1 */ + || eMode==PAGER_JOURNALMODE_OFF /* 2 */ + || eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */ + || eMode==PAGER_JOURNALMODE_MEMORY /* 4 */ + || eMode==PAGER_JOURNALMODE_WAL /* 5 */ ); /* This routine is only called from the OP_JournalMode opcode, and ** the logic there will never allow a temporary file to be changed @@ -59965,7 +60535,6 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ assert( isOpen(pPager->fd) || pPager->exclusiveMode ); if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ - /* In this case we would like to delete the journal file. If it is ** not possible, then that is not a problem. Deleting the journal file ** here is an optimization only. @@ -60077,6 +60646,18 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint( int *pnCkpt /* OUT: Final number of checkpointed frames */ ){ int rc = SQLITE_OK; + if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + /* This only happens when a database file is zero bytes in size opened and + ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint() + ** is invoked without any intervening transactions. We need to start + ** a transaction to initialize pWal. The PRAGMA table_list statement is + ** used for this since it starts transactions on every database file, + ** including all ATTACHed databases. This seems expensive for a single + ** sqlite3_wal_checkpoint() call, but it happens very rarely. + ** https://sqlite.org/forum/forumpost/fd0f19d229156939 + */ + sqlite3_exec(db, "PRAGMA table_list",0,0,0); + } if( pPager->pWal ){ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), @@ -62976,7 +63557,9 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ } /* Allocate a buffer to read frames into */ - szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; + assert( (pWal->szPage & (pWal->szPage-1))==0 ); + assert( pWal->szPage>=512 && pWal->szPage<=65536 ); + szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; aFrame = (u8 *)sqlite3_malloc64(szFrame); if( aFrame==0 ){ rc = SQLITE_NOMEM_BKPT; @@ -62990,7 +63573,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** the caller. */ aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; - for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); iOffset+szFrame<=szWal; iOffset+=szFrame ){ @@ -64841,7 +65424,9 @@ struct MemPage { u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ - u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aDataEnd; /* One byte past the end of the entire page - not just + ** the usable space, the entire page. Used to prevent + ** corruption-induced of buffer overflow. */ u8 *aCellIdx; /* The cell index area */ u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ DbPage *pDbPage; /* Pager page handle */ @@ -66798,18 +67383,32 @@ static void btreeParseCellPtr( ** ** pIter += getVarint(pIter, (u64*)&pInfo->nKey); ** - ** The code is inlined to avoid a function call. + ** The code is inlined and the loop is unrolled for performance. + ** This routine is a high-runner. */ iKey = *pIter; if( iKey>=0x80 ){ - u8 *pEnd = &pIter[7]; - iKey &= 0x7f; - while(1){ - iKey = (iKey<<7) | (*++pIter & 0x7f); - if( (*pIter)<0x80 ) break; - if( pIter>=pEnd ){ - iKey = (iKey<<8) | *++pIter; - break; + u8 x; + iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<8) | (*++pIter); + } + } + } + } + } } } } @@ -66819,7 +67418,7 @@ static void btreeParseCellPtr( pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. @@ -66856,7 +67455,7 @@ static void btreeParseCellPtrIndex( pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. @@ -66919,7 +67518,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ while( (*pIter++)&0x80 && pItermaxLocal ); - testcase( nSize==pPage->maxLocal+1 ); + testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ nSize += (u32)(pIter - pCell); if( nSize<4 ) nSize = 4; @@ -66927,7 +67526,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ int minLocal = pPage->minLocal; nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); testcase( nSize==pPage->maxLocal ); - testcase( nSize==pPage->maxLocal+1 ); + testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize>pPage->maxLocal ){ nSize = minLocal; } @@ -67168,6 +67767,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); + return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); @@ -67341,7 +67942,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ return SQLITE_CORRUPT_PAGE(pPage); } - assert( iFreeBlk>iPtr || iFreeBlk==0 ); + assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); /* At this point: ** iFreeBlk: First freeblock after iStart, or zero if none @@ -67612,7 +68213,7 @@ static int btreeInitPage(MemPage *pPage){ pPage->nOverflow = 0; pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; pPage->aCellIdx = data + pPage->childPtrSize + 8; - pPage->aDataEnd = pPage->aData + pBt->usableSize; + pPage->aDataEnd = pPage->aData + pBt->pageSize; pPage->aDataOfst = pPage->aData + pPage->childPtrSize; /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ @@ -67647,7 +68248,7 @@ static void zeroPage(MemPage *pPage, int flags){ u8 hdr = pPage->hdrOffset; u16 first; - assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); @@ -67663,7 +68264,7 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); pPage->cellOffset = first; - pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aDataEnd = &data[pBt->pageSize]; pPage->aCellIdx = &data[first]; pPage->aDataOfst = &data[pPage->childPtrSize]; pPage->nOverflow = 0; @@ -67789,7 +68390,7 @@ static int getAndInitPage( goto getAndInitPage_error2; } } - assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); /* If obtaining a child page for a cursor, we must verify that the page is @@ -68266,30 +68867,38 @@ static int removeFromSharingList(BtShared *pBt){ ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child ** pointer. */ -static void allocateTempSpace(BtShared *pBt){ - if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); - - /* One of the uses of pBt->pTmpSpace is to format cells before - ** inserting them into a leaf page (function fillInCell()). If - ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes - ** by the various routines that manipulate binary cells. Which - ** can mean that fillInCell() only initializes the first 2 or 3 - ** bytes of pTmpSpace, but that the first 4 bytes are copied from - ** it into a database page. This is not actually a problem, but it - ** does cause a valgrind error when the 1 or 2 bytes of unitialized - ** data is passed to system call write(). So to avoid this error, - ** zero the first 4 bytes of temp space here. - ** - ** Also: Provide four bytes of initialized space before the - ** beginning of pTmpSpace as an area available to prepend the - ** left-child pointer to the beginning of a cell. - */ - if( pBt->pTmpSpace ){ - memset(pBt->pTmpSpace, 0, 8); - pBt->pTmpSpace += 4; - } +static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ + assert( pBt!=0 ); + assert( pBt->pTmpSpace==0 ); + /* This routine is called only by btreeCursor() when allocating the + ** first write cursor for the BtShared object */ + assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + if( pBt->pTmpSpace==0 ){ + BtCursor *pCur = pBt->pCursor; + pBt->pCursor = pCur->pNext; /* Unlink the cursor */ + memset(pCur, 0, sizeof(*pCur)); + return SQLITE_NOMEM_BKPT; } + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of unitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + return SQLITE_OK; } /* @@ -68786,9 +69395,13 @@ static int lockBtree(BtShared *pBt){ pageSize-usableSize); return rc; } - if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ - rc = SQLITE_CORRUPT_BKPT; - goto page1_init_failed; + if( nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + }else{ + nPage = nPageFile; + } } /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to ** be less than 480. In other words, if the page size is 512, then the @@ -69818,7 +70431,7 @@ static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ int nPage = get4byte(&pPage1->aData[28]); testcase( nPage==0 ); if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); - testcase( pBt->nPage!=nPage ); + testcase( pBt->nPage!=(u32)nPage ); pBt->nPage = nPage; } @@ -70030,10 +70643,6 @@ static int btreeCursor( assert( pBt->pPage1 && pBt->pPage1->aData ); assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); - if( wrFlag ){ - allocateTempSpace(pBt); - if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT; - } if( iTable<=1 ){ if( iTable<1 ){ return SQLITE_CORRUPT_BKPT; @@ -70050,19 +70659,25 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; - pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY; + pCur->curFlags = 0; /* If there are two or more cursors on the same btree, then all such ** cursors *must* have the BTCF_Multiple flag set. */ for(pX=pBt->pCursor; pX; pX=pX->pNext){ if( pX->pgnoRoot==iTable ){ pX->curFlags |= BTCF_Multiple; - pCur->curFlags |= BTCF_Multiple; + pCur->curFlags = BTCF_Multiple; } } + pCur->eState = CURSOR_INVALID; pCur->pNext = pBt->pCursor; pBt->pCursor = pCur; - pCur->eState = CURSOR_INVALID; + if( wrFlag ){ + pCur->curFlags |= BTCF_WriteFlag; + pCur->curPagerFlags = 0; + if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt); + }else{ + pCur->curPagerFlags = PAGER_GET_READONLY; + } return SQLITE_OK; } static int btreeCursorWithLock( @@ -70837,7 +71452,7 @@ static int moveToRoot(BtCursor *pCur){ while( --pCur->iPage ){ releasePageNotNull(pCur->apPage[pCur->iPage]); } - pCur->pPage = pCur->apPage[0]; + pRoot = pCur->pPage = pCur->apPage[0]; goto skip_init; } }else if( pCur->pgnoRoot==0 ){ @@ -70862,7 +71477,7 @@ static int moveToRoot(BtCursor *pCur){ pCur->curIntKey = pCur->pPage->intKey; } pRoot = pCur->pPage; - assert( pRoot->pgno==pCur->pgnoRoot ); + assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB ); /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is @@ -70884,7 +71499,6 @@ static int moveToRoot(BtCursor *pCur){ pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - pRoot = pCur->pPage; if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; }else if( !pRoot->leaf ){ @@ -71125,7 +71739,6 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( upr = pPage->nCell-1; assert( biasRight==0 || biasRight==1 ); idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ - pCur->ix = (u16)idx; for(;;){ i64 nCellKey; pCell = findCellPastPtr(pPage, idx); @@ -71267,7 +71880,6 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( lwr = 0; upr = pPage->nCell-1; idx = upr>>1; /* idx = (lwr+upr)/2; */ - pCur->ix = (u16)idx; for(;;){ int nCell; /* Size of the pCell cell in bytes */ pCell = findCellPastPtr(pPage, idx); @@ -71356,7 +71968,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixpPage->nCell ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; @@ -71959,7 +72571,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ assert( CORRUPT_DB || iPage>1 ); assert( !pMemPage || pMemPage->pgno==iPage ); - if( NEVER(iPage<2) || iPage>pBt->nPage ){ + if( iPage<2 || iPage>pBt->nPage ){ return SQLITE_CORRUPT_BKPT; } if( pMemPage ){ @@ -72383,16 +72995,24 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ if( *pRC ) return; - assert( idx>=0 && idxnCell ); + assert( idx>=0 ); + assert( idxnCell ); assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->nFree>=0 ); data = pPage->aData; ptr = &pPage->aCellIdx[2*idx]; + assert( pPage->pBt->usableSize > (u32)(ptr-data) ); pc = get2byte(ptr); hdr = pPage->hdrOffset; - testcase( pc==get2byte(&data[hdr+5]) ); +#if 0 /* Not required. Omit for efficiency */ + if( pcnCell*2 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } +#endif + testcase( pc==(u32)get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; @@ -72684,7 +73304,7 @@ static int rebuildPage( assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kpPg->aDataEnd) ) goto editpage_fail; + if( pData>pPg->aDataEnd ) goto editpage_fail; /* Add cells to the start of the page */ if( iNewmaxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=i && ALWAYS(kpKeyInfo==0 ); - if( pCur->eState==CURSOR_FAULT ){ - assert( pCur->skipNext!=SQLITE_OK ); - return pCur->skipNext; - } - - assert( cursorOwnsBtShared(pCur) ); - assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && pBt->inTransaction==TRANS_WRITE - && (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - - /* Assert that the caller has been consistent. If this cursor was opened - ** expecting an index b-tree, then the caller should be inserting blob - ** keys with no associated data. If the cursor was opened expecting an - ** intkey table, the caller should be inserting integer keys with a - ** blob of associated data. */ - assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); - /* Save the positions of any other cursors open on this table. ** ** In some cases, the call to btreeMoveto() below is a no-op. For @@ -74430,6 +75032,24 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } } + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = moveToRoot(pCur); + if( rc && rc!=SQLITE_EMPTY ) return rc; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); + if( pCur->pKeyInfo==0 ){ assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob @@ -74518,14 +75138,13 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } } assert( pCur->eState==CURSOR_VALID - || (pCur->eState==CURSOR_INVALID && loc) - || CORRUPT_DB ); + || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ - if( NEVER(pCur->eState>CURSOR_INVALID) ){ + if( pCur->eState>CURSOR_INVALID ){ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); @@ -74791,14 +75410,13 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; - int rc; /* Return code */ - MemPage *pPage; /* Page to delete cell from */ - unsigned char *pCell; /* Pointer to cell to delete */ - int iCellIdx; /* Index of cell to delete */ - int iCellDepth; /* Depth of node containing pCell */ - CellInfo info; /* Size of the cell being deleted */ - int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ - u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + CellInfo info; /* Size of the cell being deleted */ + u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ assert( cursorOwnsBtShared(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -74807,28 +75425,45 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); - if( pCur->eState==CURSOR_REQUIRESEEK ){ - rc = btreeRestoreCursorPosition(pCur); - assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); - if( rc || pCur->eState!=CURSOR_VALID ) return rc; + if( pCur->eState!=CURSOR_VALID ){ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = btreeRestoreCursorPosition(pCur); + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; + }else{ + return SQLITE_CORRUPT_BKPT; + } } - assert( CORRUPT_DB || pCur->eState==CURSOR_VALID ); + assert( pCur->eState==CURSOR_VALID ); iCellDepth = pCur->iPage; iCellIdx = pCur->ix; pPage = pCur->pPage; + if( pPage->nCell<=iCellIdx ){ + return SQLITE_CORRUPT_BKPT; + } pCell = findCell(pPage, iCellIdx); - if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT; + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ + return SQLITE_CORRUPT_BKPT; + } - /* If the bPreserve flag is set to true, then the cursor position must + /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must ** be preserved following this delete operation. If the current delete ** will cause a b-tree rebalance, then this is done by saving the cursor ** key and leaving the cursor in CURSOR_REQUIRESEEK state before ** returning. ** - ** Or, if the current delete will not cause a rebalance, then the cursor + ** If the current delete will not cause a rebalance, then the cursor ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately - ** before or after the deleted entry. In this case set bSkipnext to true. */ + ** before or after the deleted entry. + ** + ** The bPreserve value records which path is required: + ** + ** bPreserve==0 Not necessary to save the cursor position + ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position + ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. + */ + bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) @@ -74839,7 +75474,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ - bSkipnext = 1; + bPreserve = 2; } } @@ -74939,8 +75574,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ } if( rc==SQLITE_OK ){ - if( bSkipnext ){ - assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); + if( bPreserve>1 ){ + assert( (pCur->iPage==iCellDepth || CORRUPT_DB) ); assert( pPage==pCur->pPage || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; @@ -75150,7 +75785,7 @@ static int clearDatabasePage( rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); if( rc ) return rc; if( (pBt->openFlags & BTREE_SINGLE)==0 - && sqlite3PagerPageRefcount(pPage->pDbPage)!=1 + && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) ){ rc = SQLITE_CORRUPT_BKPT; goto cleardatabasepage_out; @@ -76530,14 +77165,13 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ if( i==1 ){ Parse sParse; int rc = 0; - memset(&sParse, 0, sizeof(sParse)); - sParse.db = pDb; + sqlite3ParseObjectInit(&sParse,pDb); if( sqlite3OpenTempDatabase(&sParse) ){ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); rc = SQLITE_ERROR; } sqlite3DbFree(pErrorDb, sParse.zErrMsg); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); if( rc ){ return 0; } @@ -77423,7 +78057,11 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; + return SQLITE_OK; + } + if( pMem->enc==desiredEnc ){ return SQLITE_OK; } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -77815,12 +78453,12 @@ static SQLITE_NOINLINE i64 doubleToInt64(double r){ ** ** If pMem represents a string value, its encoding might be changed. */ -static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){ +static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){ i64 value = 0; sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; } -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ int flags; assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -78135,6 +78773,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( void (*xDestructor)(void*) ){ assert( pMem->flags==MEM_Null ); + vdbeMemClear(pMem); pMem->u.zPType = zPType ? zPType : ""; pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; @@ -78749,11 +79388,7 @@ static int valueFromExpr( assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; -#if defined(SQLITE_ENABLE_STAT4) if( op==TK_REGISTER ) op = pExpr->op2; -#else - if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; -#endif /* Compressed expressions only appear when parsing the DEFAULT clause ** on a table column definition, and hence only when pCtx==0. This @@ -78868,7 +79503,7 @@ static int valueFromExpr( no_mem: #ifdef SQLITE_ENABLE_STAT4 - if( pCtx==0 || pCtx->pParse->nErr==0 ) + if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) ) #endif sqlite3OomFault(db); sqlite3DbFree(db, zVal); @@ -80546,8 +81181,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ */ static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ assert( p->nOp>0 || p->aOp==0 ); - assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed - || p->pParse->nErr>0 ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 ); if( p->nOp ){ assert( p->aOp ); sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); @@ -81638,8 +82272,6 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } - assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); - assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); @@ -82420,6 +83052,7 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ sqlite3ValueSetNull(db->pErr); } db->errCode = rc; + db->errByteOffset = -1; return rc; } @@ -82741,7 +83374,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ if( p->deferredMoveto ){ u32 iMap; assert( !p->isEphemeral ); - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ + if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; return SQLITE_OK; @@ -83019,14 +83652,14 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ /* ** Deserialize the data blob pointed to by buf as serial type serial_type -** and store the result in pMem. Return the number of bytes read. +** and store the result in pMem. ** ** This function is implemented as two separate routines for performance. ** The few cases that require local variables are broken out into a separate ** routine so that in most cases the overhead of moving the stack pointer ** is avoided. */ -static u32 serialGet( +static void serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -83060,9 +83693,8 @@ static u32 serialGet( memcpy(&pMem->u.r, &x, sizeof(x)); pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; } - return 8; } -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( +SQLITE_PRIVATE void sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -83073,13 +83705,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->flags = MEM_Null|MEM_Zero; pMem->n = 0; pMem->u.nZero = 0; - break; + return; } case 11: /* Reserved for future use */ case 0: { /* Null */ /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ pMem->flags = MEM_Null; - break; + return; } case 1: { /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement @@ -83087,7 +83719,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = ONE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 1; + return; } case 2: { /* 2-byte signed integer */ /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit @@ -83095,7 +83727,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 2; + return; } case 3: { /* 3-byte signed integer */ /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit @@ -83103,7 +83735,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = THREE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 3; + return; } case 4: { /* 4-byte signed integer */ /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit @@ -83115,7 +83747,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( #endif pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 4; + return; } case 5: { /* 6-byte signed integer */ /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit @@ -83123,13 +83755,14 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 6; + return; } case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ /* These use local variables, so do them in a separate routine ** to avoid having to move the frame pointer in the common case */ - return serialGet(buf,serial_type,pMem); + serialGet(buf,serial_type,pMem); + return; } case 8: /* Integer 0 */ case 9: { /* Integer 1 */ @@ -83137,7 +83770,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ pMem->u.i = serial_type-8; pMem->flags = MEM_Int; - return 0; + return; } default: { /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in @@ -83148,10 +83781,10 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->z = (char *)buf; pMem->n = (serial_type-12)/2; pMem->flags = aFlag[serial_type&1]; - return pMem->n; + return; } } - return 0; + return; } /* ** This routine is used to allocate sufficient space for an UnpackedRecord @@ -83214,7 +83847,8 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->szMalloc = 0; pMem->z = 0; - d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + d += sqlite3VdbeSerialTypeLen(serial_type); pMem++; if( (++u)>=p->nField ) break; } @@ -83298,7 +83932,8 @@ static int vdbeRecordCompareDebug( /* Extract the values to be compared. */ - d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + d1 += sqlite3VdbeSerialTypeLen(serial_type1); /* Do the comparison */ @@ -84102,7 +84737,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* The index entry must begin with a header size */ getVarint32NR((u8*)m.z, szHdr); testcase( szHdr==3 ); - testcase( szHdr==m.n ); + testcase( szHdr==(u32)m.n ); testcase( szHdr>0x7fffffff ); assert( m.n>=0 ); if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ @@ -85276,6 +85911,70 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ return sqlite3_value_nochange(p->pOut); } +/* +** Implementation of sqlite3_vtab_in_first() (if bNext==0) and +** sqlite3_vtab_in_next() (if bNext!=0). +*/ +static int valueFromValueList( + sqlite3_value *pVal, /* Pointer to the ValueList object */ + sqlite3_value **ppOut, /* Store the next value from the list here */ + int bNext /* 1 for _next(). 0 for _first() */ +){ + int rc; + ValueList *pRhs; + + *ppOut = 0; + if( pVal==0 ) return SQLITE_MISUSE; + pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); + if( pRhs==0 ) return SQLITE_MISUSE; + if( bNext ){ + rc = sqlite3BtreeNext(pRhs->pCsr, 0); + }else{ + int dummy = 0; + rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); + assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) ); + if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE; + } + if( rc==SQLITE_OK ){ + u32 sz; /* Size of current row in bytes */ + Mem sMem; /* Raw content of current row */ + memset(&sMem, 0, sizeof(sMem)); + sz = sqlite3BtreePayloadSize(pRhs->pCsr); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); + if( rc==SQLITE_OK ){ + u8 *zBuf = (u8*)sMem.z; + u32 iSerial; + sqlite3_value *pOut = pRhs->pOut; + int iOff = 1 + getVarint32(&zBuf[1], iSerial); + sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut); + pOut->enc = ENC(pOut->db); + if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){ + rc = SQLITE_NOMEM; + }else{ + *ppOut = pOut; + } + } + sqlite3VdbeMemRelease(&sMem); + } + return rc; +} + +/* +** Set the iterator value pVal to point to the first value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 0); +} + +/* +** Set the iterator value pVal to point to the next value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 1); +} + /* ** Return the current time for a statement. If the current time ** is requested more than once within the same run of a single prepared @@ -85960,7 +86659,10 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu break; } case SQLITE_FLOAT: { - rc = sqlite3_bind_double(pStmt, i, pValue->u.r); + assert( pValue->flags & (MEM_Real|MEM_IntReal) ); + rc = sqlite3_bind_double(pStmt, i, + (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i + ); break; } case SQLITE_BLOB: { @@ -86940,7 +87642,6 @@ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ - int iDb, /* Database the cursor belongs to, or -1 */ u8 eCurType /* Type of the new cursor */ ){ /* Find the memory cell that will be used to store the blob of memory @@ -86997,7 +87698,6 @@ static VdbeCursor *allocateCursor( p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; - pCx->iDb = iDb; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ @@ -87370,6 +88070,29 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ } } +/* +** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning +** with pOp->p3. Return the hash. +*/ +static u64 filterHash(const Mem *aMem, const Op *pOp){ + int i, mx; + u64 h = 0; + + assert( pOp->p4type==P4_INT32 ); + for(i=pOp->p3, mx=i+pOp->p4.i; iflags & (MEM_Int|MEM_IntReal) ){ + h += p->u.i; + }else if( p->flags & MEM_Real ){ + h += sqlite3VdbeIntValue(p); + }else if( p->flags & (MEM_Str|MEM_Blob) ){ + h += p->n; + if( p->flags & MEM_Zero ) h += p->u.nZero; + } + } + return h; +} + /* ** Return the symbolic name for the data type of a pMem */ @@ -87665,6 +88388,8 @@ case OP_Gosub: { /* jump */ /* Most jump operations do a goto to this spot in order to update ** the pOp pointer. */ jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ pOp = &aOp[pOp->p2 - 1]; break; } @@ -88024,12 +88749,18 @@ case OP_SoftNull: { ** Synopsis: r[P2]=P4 (len=P1) ** ** P4 points to a blob of data P1 bytes long. Store this -** blob in register P2. +** blob in register P2. If P4 is a NULL pointer, then construct +** a zero-filled blob that is P1 bytes long in P2. */ case OP_Blob: { /* out2 */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); pOut = out2Prerelease(p, pOp); - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + if( pOp->p4.z==0 ){ + sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1); + if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem; + }else{ + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + } pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; @@ -88178,24 +88909,22 @@ case OP_IntCopy: { /* out2 */ break; } -/* Opcode: ChngCntRow P1 P2 * * * -** Synopsis: output=r[P1] +/* Opcode: FkCheck * * * * * ** -** Output value in register P1 as the chance count for a DML statement, -** due to the "PRAGMA count_changes=ON" setting. Or, if there was a -** foreign key error in the statement, trigger the error now. +** Halt with an SQLITE_CONSTRAINT error if there are any unresolved +** foreign key constraint violations. If there are no foreign key +** constraint violations, this is a no-op. ** -** This opcode is a variant of OP_ResultRow that checks the foreign key -** immediate constraint count and throws an error if the count is -** non-zero. The P2 opcode must be 1. +** FK constraint violations are also checked when the prepared statement +** exits. This opcode is used to raise foreign key constraint errors prior +** to returning results such as a row change count or the result of a +** RETURNING clause. */ -case OP_ChngCntRow: { - assert( pOp->p2==1 ); +case OP_FkCheck: { if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ goto abort_due_to_error; } - /* Fall through to the next case, OP_ResultRow */ - /* no break */ deliberate_fall_through + break; } /* Opcode: ResultRow P1 P2 * * * @@ -88833,7 +89562,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; } if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); @@ -89301,10 +90030,18 @@ case OP_Offset: { /* out3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; pOut = &p->aMem[pOp->p3]; - if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){ + if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){ sqlite3VdbeMemSetNull(pOut); }else{ - sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + if( sqlite3BtreeEof(pC->uc.pCursor) ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + } } break; } @@ -89363,6 +90100,7 @@ case OP_Column: { assert( pC!=0 ); assert( p2<(u32)pC->nField ); aOffset = pC->aOffset; + assert( aOffset==pC->aType+pC->nField ); assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); @@ -89658,6 +90396,8 @@ case OP_TypeCheck: { break; } case COLTYPE_REAL: { + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal ); if( pIn1->flags & MEM_Int ){ /* When applying REAL affinity, if the result is still an MEM_Int ** that will fit in 6 bytes, then change the type to MEM_IntReal @@ -89675,7 +90415,7 @@ case OP_TypeCheck: { pIn1->flags |= MEM_Real; pIn1->flags &= ~MEM_Int; } - }else if( (pIn1->flags & MEM_Real)==0 ){ + }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){ goto vdbe_type_error; } break; @@ -89914,7 +90654,7 @@ case OP_MakeRecord: { testcase( uu==127 ); testcase( uu==128 ); testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); - testcase( uu==2147483647 ); testcase( uu==2147483648 ); + testcase( uu==2147483647 ); testcase( uu==2147483648LL ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ if( (i&1)==i && file_format>=4 ){ @@ -90042,7 +90782,7 @@ case OP_MakeRecord: { break; } -/* Opcode: Count P1 P2 p3 * * +/* Opcode: Count P1 P2 P3 * * ** Synopsis: r[P2]=count() ** ** Store the number of entries (an integer value) in the table or index @@ -90512,6 +91252,7 @@ case OP_SetCookie: { /* When the schema cookie changes, record the new cookie internally */ pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5; db->mDbFlags |= DBFLAG_SchemaChange; + sqlite3FkClearTriggerCache(db, pOp->p1); }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; @@ -90689,8 +91430,9 @@ case OP_OpenWrite: assert( pOp->p1>=0 ); assert( nField>=0 ); testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ - pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); + pCur = allocateCursor(p, pOp->p1, nField, CURTYPE_BTREE); if( pCur==0 ) goto no_mem; + pCur->iDb = iDb; pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; @@ -90732,7 +91474,7 @@ case OP_OpenDup: { assert( pOrig ); assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ - pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); + pCx = allocateCursor(p, pOp->p1, pOrig->nField, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->isEphemeral = 1; @@ -90740,10 +91482,10 @@ case OP_OpenDup: { pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; - pCx->pBtx = pOrig->pBtx; + pCx->ub.pBtx = pOrig->ub.pBtx; pCx->hasBeenDuped = 1; pOrig->hasBeenDuped = 1; - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this @@ -90816,16 +91558,16 @@ case OP_OpenEphemeral: { assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + rc = sqlite3BtreeClearTable(pCx->ub.pBtx, pCx->pgnoRoot, 0); }else{ - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); + rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0); if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before @@ -90834,26 +91576,26 @@ case OP_OpenEphemeral: { */ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot, + rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ pCx->pgnoRoot = SCHEMA_ROOT; - rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); pCx->isTable = 1; } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); if( rc ){ - sqlite3BtreeClose(pCx->pBtx); + sqlite3BtreeClose(pCx->ub.pBtx); } } } @@ -90877,7 +91619,7 @@ case OP_SorterOpen: { assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER); if( pCx==0 ) goto no_mem; pCx->pKeyInfo = pOp->p4.pKeyInfo; assert( pCx->pKeyInfo->db==db ); @@ -90926,7 +91668,7 @@ case OP_OpenPseudo: { assert( pOp->p1>=0 ); assert( pOp->p3>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); + pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->seekResult = pOp->p2; @@ -92378,6 +93120,10 @@ case OP_Rowid: { /* out2 */ ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. +** +** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo) +** just reset the cache for that cursor. This causes the row of +** content held by the pseudo-cursor to be reparsed. */ case OP_NullRow: { VdbeCursor *pC; @@ -92866,9 +93612,9 @@ case OP_IdxRowid: { /* out2 */ pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); - pTabCur->aAltMap = pOp->p4.ai; - assert( !pC->isEphemeral ); assert( !pTabCur->isEphemeral ); + pTabCur->ub.aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -94390,7 +95136,7 @@ case OP_VOpen: { pVCur->pVtab = pVtab; /* Initialize vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB); + pCur = allocateCursor(p, pOp->p1, 0, CURTYPE_VTAB); if( pCur ){ pCur->uc.pVCur = pVCur; pVtab->nRef++; @@ -94403,6 +95149,34 @@ case OP_VOpen: { } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VInitIn P1 P2 P3 * * +** Synopsis: r[P2]=ValueList(P1,P3) +** +** Set register P2 to be a pointer to a ValueList object for cursor P1 +** with cache register P3 and output register P3+1. This ValueList object +** can be used as the first argument to sqlite3_vtab_in_first() and +** sqlite3_vtab_in_next() to extract all of the values stored in the P1 +** cursor. Register P3 is used to hold the values returned by +** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). +*/ +case OP_VInitIn: { /* out2 */ + VdbeCursor *pC; /* The cursor containing the RHS values */ + ValueList *pRhs; /* New ValueList object to put in reg[P2] */ + + pC = p->apCsr[pOp->p1]; + pRhs = sqlite3_malloc64( sizeof(*pRhs) ); + if( pRhs==0 ) goto no_mem; + pRhs->pCsr = pC->uc.pCursor; + pRhs->pOut = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 P4 * ** Synopsis: iplan=r[P3] zplan='P4' @@ -94828,6 +95602,77 @@ case OP_Function: { /* group */ break; } +/* Opcode: FilterAdd P1 * P3 P4 * +** Synopsis: filter(P1) += key(P3@P4) +** +** Compute a hash on the P4 registers starting with r[P3] and +** add that hash to the bloom filter contained in r[P1]. +*/ +case OP_FilterAdd: { + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags & MEM_Blob ); + assert( pIn1->n>0 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= pIn1->n; + pIn1->z[h/8] |= 1<<(h&7); + break; +} + +/* Opcode: Filter P1 P2 P3 P4 * +** Synopsis: if key(P3@P4) not in filter(P1) goto P2 +** +** Compute a hash on the key contained in the P4 registers starting +** with r[P3]. Check to see if that hash is found in the +** bloom filter hosted by register P1. If it is not present then +** maybe jump to P2. Otherwise fall through. +** +** False negatives are harmless. It is always safe to fall through, +** even if the value is in the bloom filter. A false negative causes +** more CPU cycles to be used, but it should still yield the correct +** answer. However, an incorrect answer may well arise from a +** false positive - if the jump is taken when it should fall through. +*/ +case OP_Filter: { /* jump */ + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)!=0 ); + assert( pIn1->n >= 1 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= pIn1->n; + if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ + VdbeBranchTaken(1, 2); + p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; + goto jump_to_p2; + }else{ + p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++; + VdbeBranchTaken(0, 2); + } + break; +} + /* Opcode: Trace P1 P2 * P4 * ** ** Write P4 on the statement trace output if statement tracing is @@ -95318,10 +96163,9 @@ SQLITE_API int sqlite3_blob_open( sqlite3_mutex_enter(db->mutex); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); - do { - memset(&sParse, 0, sizeof(Parse)); + while(1){ + sqlite3ParseObjectInit(&sParse,db); if( !pBlob ) goto blob_open_out; - sParse.db = db; sqlite3DbFree(db, zErr); zErr = 0; @@ -95498,7 +96342,9 @@ SQLITE_API int sqlite3_blob_open( goto blob_open_out; } rc = blobSeekToRow(pBlob, iRow, &zErr); - } while( (++nAttempt)=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break; + sqlite3ParseObjectReset(&sParse); + } blob_open_out: if( rc==SQLITE_OK && db->mallocFailed==0 ){ @@ -95509,7 +96355,7 @@ SQLITE_API int sqlite3_blob_open( } sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -96644,7 +97490,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( } #endif - assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); + assert( pCsr->pKeyInfo ); + assert( !pCsr->isEphemeral ); assert( pCsr->eCurType==CURTYPE_SORTER ); szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); @@ -99057,6 +99904,9 @@ static int memjrnlCreateFile(MemJournal *p){ } +/* Forward reference */ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size); + /* ** Write data to the file. */ @@ -99087,22 +99937,20 @@ static int memjrnlWrite( ** the in-memory journal is being used by a connection using the ** atomic-write optimization. In this case the first 28 bytes of the ** journal file may be written as part of committing the transaction. */ - assert( iOfst==p->endpoint.iOffset || iOfst==0 ); -#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ - || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + assert( iOfst<=p->endpoint.iOffset ); + if( iOfst>0 && iOfst!=p->endpoint.iOffset ){ + memjrnlTruncate(pJfd, iOfst); + } if( iOfst==0 && p->pFirst ){ assert( p->nChunkSize>iAmt ); memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); - }else -#else - assert( iOfst>0 || p->pFirst==0 ); -#endif - { + }else{ while( nWrite>0 ){ FileChunk *pChunk = p->endpoint.pChunk; int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize); int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset); + assert( pChunk!=0 || iChunkOffset==0 ); if( iChunkOffset==0 ){ /* New chunk is required to extend the file. */ FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); @@ -99117,10 +99965,11 @@ static int memjrnlWrite( assert( !p->pFirst ); p->pFirst = pNew; } - p->endpoint.pChunk = pNew; + pChunk = p->endpoint.pChunk = pNew; } - memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace); + assert( pChunk!=0 ); + memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace); zWrite += iSpace; nWrite -= iSpace; p->endpoint.iOffset += iSpace; @@ -99144,7 +99993,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ p->pFirst = 0; }else{ i64 iOff = p->nChunkSize; - for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + for(pIter=p->pFirst; ALWAYS(pIter) && iOffpNext){ iOff += p->nChunkSize; } if( ALWAYS(pIter) ){ @@ -99898,8 +100747,9 @@ static int lookupName( } if( hit || zTab==0 ) continue; } - if( zDb && pTab->pSchema!=pSchema ){ - continue; + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; } if( zTab ){ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; @@ -100030,6 +100880,7 @@ static int lookupName( pExpr->y.pTab = pTab; if( pParse->bReturning ){ eNewExprOp = TK_REGISTER; + pExpr->op2 = TK_COLUMN; pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + sqlite3TableColumnToStorage(pTab, iCol) + 1; }else{ @@ -100196,6 +101047,7 @@ static int lookupName( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; } @@ -100304,7 +101156,8 @@ static void notValidImpl( Parse *pParse, /* Leave error message here */ NameContext *pNC, /* The name context */ const char *zMsg, /* Type of error */ - Expr *pExpr /* Invalidate this expression on error */ + Expr *pExpr, /* Invalidate this expression on error */ + Expr *pError /* Associate error with this expression */ ){ const char *zIn = "partial index WHERE clauses"; if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; @@ -100316,10 +101169,11 @@ static void notValidImpl( #endif sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); if( pExpr ) pExpr->op = TK_NULL; + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); } -#define sqlite3ResolveNotValid(P,N,M,X,E) \ +#define sqlite3ResolveNotValid(P,N,M,X,E,R) \ assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ - if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E); + if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R); /* ** Expression p should encode a floating point value between 1.0 and 0.0. @@ -100454,7 +101308,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", - NC_IdxExpr|NC_GenCol, 0); + NC_IdxExpr|NC_GenCol, 0, pExpr); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; @@ -100485,7 +101339,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ - int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ @@ -100495,7 +101348,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); zId = pExpr->u.zToken; - nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); @@ -100512,8 +101364,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->iTable = exprProbability(pList->a[1].pExpr); if( pExpr->iTable<0 ){ sqlite3ErrorMsg(pParse, - "second argument to likelihood() must be a " - "constant between 0.0 and 1.0"); + "second argument to %#T() must be a " + "constant between 0.0 and 1.0", pExpr); pNC->nNcErr++; } }else{ @@ -100534,8 +101386,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); if( auth!=SQLITE_OK ){ if( auth==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized to use function: %s", - pDef->zName); + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", + pExpr); pNC->nNcErr++; } pExpr->op = TK_NULL; @@ -100558,7 +101410,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all ** all this. */ sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx|NC_GenCol, 0); + NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); }else{ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ pExpr->op2 = pNC->ncFlags & NC_SelfRef; @@ -100571,7 +101423,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be - ** used to activate internal functionsn for testing purposes */ + ** used to activate internal functions for testing purposes */ no_such_func = 1; pDef = 0; }else @@ -100590,7 +101442,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ); if( pDef && pDef->xValue==0 && pWin ){ sqlite3ErrorMsg(pParse, - "%.*s() may not be used as a window function", nId, zId + "%#T() may not be used as a window function", pExpr ); pNC->nNcErr++; }else if( @@ -100604,13 +101456,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ }else{ zType = "aggregate"; } - sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); + sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr); pNC->nNcErr++; is_agg = 0; } #else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ - sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); + sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); pNC->nNcErr++; is_agg = 0; } @@ -100620,18 +101472,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && pParse->explain==0 #endif ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); pNC->nNcErr++; }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()", + pExpr); pNC->nNcErr++; } #ifndef SQLITE_OMIT_WINDOWFUNC else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ErrorMsg(pParse, - "FILTER may not be used with non-aggregate %.*s()", - nId, zId + "FILTER may not be used with non-aggregate %#T()", + pExpr ); pNC->nNcErr++; } @@ -100716,7 +101568,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); if( pNC->ncFlags & NC_SelfRef ){ - notValidImpl(pParse, pNC, "subqueries", pExpr); + notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); }else{ sqlite3WalkSelect(pWalker, pExpr->x.pSelect); } @@ -100734,7 +101586,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); sqlite3ResolveNotValid(pParse, pNC, "parameters", - NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr); break; } case TK_IS: @@ -100786,11 +101638,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_BETWEEN ); sqlite3ErrorMsg(pParse, "row value misused"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); } break; } } - return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + return pParse->nErr ? WRC_Abort : WRC_Continue; } /* @@ -100898,11 +101752,13 @@ static void resolveOutOfRangeError( Parse *pParse, /* The error context into which to write the error */ const char *zType, /* "ORDER" or "GROUP" */ int i, /* The index (1-based) of the term out of range */ - int mx /* Largest permissible value of i */ + int mx, /* Largest permissible value of i */ + Expr *pError /* Associate the error with the expression */ ){ sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i, zType, mx); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); } /* @@ -100958,7 +101814,7 @@ static int resolveCompoundOrderBy( if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; } }else{ @@ -101054,7 +101910,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ if( pItem->u.x.iOrderByCol ){ if( pItem->u.x.iOrderByCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0); return 1; } resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); @@ -101146,7 +102002,7 @@ static int resolveOrderGroupBy( ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ if( iCol<1 || iCol>0xffff ){ - resolveOutOfRangeError(pParse, zType, i+1, nResult); + resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2); return 1; } pItem->u.x.iOrderByCol = (u16)iCol; @@ -101204,7 +102060,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ */ if( (p->selFlags & SF_Expanded)==0 ){ sqlite3SelectPrep(pParse, p, pOuterNC); - return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; + return pParse->nErr ? WRC_Abort : WRC_Prune; } isCompound = p->pPrior!=0; @@ -101252,7 +102108,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; - if( pParse->nErr || db->mallocFailed ) return WRC_Abort; + if( pParse->nErr ) return WRC_Abort; + assert( db->mallocFailed==0 ); /* If the number of references to the outer context changed when ** expressions in the sub-select were resolved, the sub-select @@ -102398,9 +103255,8 @@ static void heightOfSelect(const Select *pSelect, int *pnHeight){ ** if appropriate. */ static void exprSetHeight(Expr *p){ - int nHeight = 0; - heightOfExpr(p->pLeft, &nHeight); - heightOfExpr(p->pRight, &nHeight); + int nHeight = p->pLeft ? p->pLeft->nHeight : 0; + if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight; if( ExprUseXSelect(p) ){ heightOfSelect(p->x.pSelect, &nHeight); }else if( p->x.pList ){ @@ -102699,6 +103555,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction( sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } + pNew->w.iOfst = (int)(pToken->z - pParse->zTail); if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] && !pParse->nested @@ -102742,7 +103599,7 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable( ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning ** that the schema is possibly tainted). */ - sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName); + sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr); } } } @@ -102798,6 +103655,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); return; } x = (ynVar)i; @@ -102825,6 +103683,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n pExpr->iColumn = x; if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); } } @@ -103911,6 +104770,38 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } +/* +** Check pExpr to see if it is an invariant constraint on data source pSrc. +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** double, return 0. +** +** To be an invariant constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (*) ** Not applicable to this branch ** +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. +** (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +*/ +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). @@ -104086,7 +104977,7 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ return ExprHasProperty(p, EP_CanBeNull) || p->y.pTab==0 || /* Reference to column of index on expression */ (p->iColumn>=0 - && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */ + && p->y.pTab->aCol!=0 /* Possible due to prior error */ && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; @@ -104432,8 +105323,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; - assert( pReq!=0 || pRhs->iColumn==XN_ROWID - || pParse->nErr || db->mallocFailed ); + assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); @@ -104909,10 +105799,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } pSel->iLimit = 0; if( sqlite3Select(pParse, pSel, &dest) ){ - if( pParse->nErr ){ - pExpr->op2 = pExpr->op; - pExpr->op = TK_ERROR; - } + pExpr->op2 = pExpr->op; + pExpr->op = TK_ERROR; return 0; } pExpr->iTable = rReg = dest.iSDParm; @@ -105129,10 +106017,9 @@ static void sqlite3ExprCodeIN( }else{ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } - if( pParse->nErr ) goto sqlite3ExprCodeIN_finished; for(i=0; ipLeft, i); - if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); VdbeCoverage(v); @@ -105270,11 +106157,12 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ c = sqlite3DecOrHexToI64(z, &value); if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ #ifdef SQLITE_OMIT_FLOATING_POINT - sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); + sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr); #else #ifndef SQLITE_OMIT_HEX_INTEGER if( sqlite3_strnicmp(z,"0x",2)==0 ){ - sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z); + sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T", + negFlag?"-":"",pExpr); }else #endif { @@ -105950,7 +106838,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) || NEVER(pExpr->iAgg>=pInfo->nFunc) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); }else{ return pInfo->aFunc[pExpr->iAgg].iMem; } @@ -105991,7 +106879,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } #endif if( pDef==0 || pDef->xFinalize!=0 ){ - sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); + sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ @@ -108307,7 +109195,9 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ int r1; /* Temporary registers */ db = pParse->db; - if( pParse->nErr || db->mallocFailed ) return; + assert( db->pParse==pParse ); + if( pParse->nErr ) return; + assert( db->mallocFailed==0 ); pNew = pParse->pNewTable; assert( pNew ); @@ -108433,7 +109323,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ " THEN raise(ABORT,'CHECK constraint failed')" " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" - " FROM pragma_quick_check(\"%w\",\"%w\")" + " FROM pragma_quick_check(%Q,%Q)" " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", zTab, zDb ); @@ -108612,7 +109502,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; } if( iCol==pTab->nCol ){ - sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); goto exit_rename_column; } @@ -108718,7 +109608,9 @@ struct RenameCtx { ** following a valid object, it may not be used in comparison operations. */ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ - if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){ + assert( pParse==pParse->db->pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr==0 ){ const RenameToken *p; u8 i = 0; for(p=pParse->pRename; p; p=p->pNext){ @@ -109040,12 +109932,12 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s%s: %s", + zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); + sqlite3DbFree(pParse->db, zErr); } /* @@ -109109,24 +110001,22 @@ static int renameParseSql( int bTemp /* True if SQL is from temp schema */ ){ int rc; - char *zErr = 0; + sqlite3ParseObjectInit(p, db); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ + return SQLITE_CORRUPT_BKPT; + } db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); - - /* Parse the SQL statement passed as the first argument. If no error - ** occurs and the parse does not result in a new table, index or - ** trigger object, the database must be corrupt. */ - memset(p, 0, sizeof(Parse)); p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; - assert( p->zErrMsg==0 ); - assert( rc!=SQLITE_OK || zErr==0 ); - p->zErrMsg = zErr; + rc = sqlite3RunParser(p, zSql); if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK - && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 + && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) ){ rc = SQLITE_CORRUPT_BKPT; } @@ -109404,13 +110294,13 @@ static void renameParseCleanup(Parse *pParse){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->zErrMsg); renameTokenFree(db, pParse->pRename); - sqlite3ParserReset(pParse); + sqlite3ParseObjectReset(pParse); } /* ** SQL function: ** -** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld) +** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP) ** ** 0. zSql: SQL statement to rewrite ** 1. type: Type of object ("table", "view" etc.) @@ -109428,7 +110318,8 @@ static void renameParseCleanup(Parse *pParse){ ** ** This function is used internally by the ALTER TABLE RENAME COLUMN command. ** It is only accessible to SQL created using sqlite3NestedParse(). It is -** not reachable from ordinary SQL passed into sqlite3_prepare(). +** not reachable from ordinary SQL passed into sqlite3_prepare() unless the +** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled. */ static void renameColumnFunc( sqlite3_context *context, @@ -109577,7 +110468,9 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[0]); + }else if( sParse.zErrMsg ){ renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); @@ -109776,7 +110669,9 @@ static void renameTableFunc( rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); } if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[3]); + }else if( sParse.zErrMsg ){ renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); @@ -109801,10 +110696,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } -/* -** The implementation of an SQL scalar function that rewrites DDL statements -** so that any string literals that use double-quotes are modified so that -** they use single quotes. +/* SQL function: sqlite_rename_quotefix(DB,SQL) +** +** Rewrite the DDL statement "SQL" so that any string literals that use +** double-quotes use single quotes instead. ** ** Two arguments must be passed: ** @@ -109823,6 +110718,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ ** returns the string: ** ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1 +** +** If there is a error in the input SQL, then raise an error, except +** if PRAGMA writable_schema=ON, then just return the input string +** unmodified following an error. */ static void renameQuotefixFunc( sqlite3_context *context, @@ -109897,7 +110796,11 @@ static void renameQuotefixFunc( renameTokenFree(db, sCtx.pList); } if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(context, rc); + if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){ + sqlite3_result_value(context, argv[1]); + }else{ + sqlite3_result_error_code(context, rc); + } } renameParseCleanup(&sParse); } @@ -109909,7 +110812,8 @@ static void renameQuotefixFunc( sqlite3BtreeLeaveAll(db); } -/* +/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS) +** ** An SQL user function that checks that there are no parse or symbol ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. ** After an ALTER TABLE .. RENAME operation is performed and the schema @@ -109924,11 +110828,13 @@ static void renameQuotefixFunc( ** 5: "when" part of error message. ** 6: True to disable the DQS quirk when parsing SQL. ** -** Unless it finds an error, this function normally returns NULL. However, it -** returns integer value 1 if: +** The return value is computed as follows: ** -** * the SQL argument creates a trigger, and -** * the table that the trigger is attached to is in database zDb. +** A. If an error is seen and not in PRAGMA writable_schema=ON mode, +** then raise the error. +** B. Else if a trigger is created and the the table that the trigger is +** attached to is in database zDb, then return 1. +** C. Otherwise return NULL. */ static void renameTableTest( sqlite3_context *context, @@ -109973,12 +110879,16 @@ static void renameTableTest( if( rc==SQLITE_OK ){ int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); int i2 = sqlite3FindDbName(db, zDb); - if( i1==i2 ) sqlite3_result_int(context, 1); + if( i1==i2 ){ + /* Handle output case B */ + sqlite3_result_int(context, 1); + } } } } - if( rc!=SQLITE_OK && zWhen ){ + if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){ + /* Output case A */ renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); @@ -110094,7 +111004,7 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T } iCol = sqlite3ColumnIndex(pTab, zCol); if( iCol<0 ){ - sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol); + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); goto exit_drop_column; } @@ -110118,6 +111028,12 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); zDb = db->aDb[iDb].zDbSName; +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + goto exit_drop_column; + } +#endif renameTestSchema(pParse, zDb, iDb==1, "", 0); renameFixQuotes(pParse, zDb, iDb==1); sqlite3NestedParse(pParse, @@ -112505,7 +113421,7 @@ static void codeAttach( } #ifndef SQLITE_OMIT_AUTHORIZATION - if( pAuthArg ){ + if( ALWAYS(pAuthArg) ){ char *zAuthArg; if( pAuthArg->op==TK_STRING ){ assert( !ExprHasProperty(pAuthArg, EP_IntValue) ); @@ -113166,11 +114082,13 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ assert( pParse->pToplevel==0 ); db = pParse->db; + assert( db->pParse==pParse ); if( pParse->nested ) return; - if( db->mallocFailed || pParse->nErr ){ - if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; + if( pParse->nErr ){ + if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM; return; } + assert( db->mallocFailed==0 ); /* Begin by generating some termination code at the end of the ** vdbe program @@ -113193,9 +114111,10 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ int i; int reg; - if( pReturning->nRetCol==0 ){ + if( NEVER(pReturning->nRetCol==0) ){ assert( CORRUPT_DB ); }else{ + sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); VdbeCoverage(v); @@ -113288,7 +114207,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ if( pParse->bReturning ){ Returning *pRet = pParse->u1.pReturning; - if( pRet->nRetCol==0 ){ + if( NEVER(pRet->nRetCol==0) ){ assert( CORRUPT_DB ); }else{ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); @@ -113302,7 +114221,9 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Get the VDBE program ready for execution */ - if( v && pParse->nErr==0 && !db->mallocFailed ){ + assert( v!=0 || pParse->nErr ); + assert( db->mallocFailed==0 || pParse->nErr ); + if( pParse->nErr==0 ){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ assert( pParse->pAinc==0 || pParse->nTab>0 ); @@ -113329,7 +114250,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; - char *zErrMsg = 0; sqlite3 *db = pParse->db; u32 savedDbFlags = db->mDbFlags; char saveBuf[PARSE_TAIL_SZ]; @@ -113351,9 +114271,10 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); db->mDbFlags |= DBFLAG_PreferBuiltin; - sqlite3RunParser(pParse, zSql, &zErrMsg); + sqlite3RunParser(pParse, zSql); + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = 0; db->mDbFlags = savedDbFlags; - sqlite3DbFree(db, zErrMsg); sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; @@ -114313,7 +115234,8 @@ SQLITE_PRIVATE void sqlite3StartTable( pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ - sqlite3ErrorMsg(pParse, "table %T already exists", pName); + sqlite3ErrorMsg(pParse, "%s %T already exists", + (IsView(pTable)? "view" : "table"), pName); }else{ assert( !db->init.busy || CORRUPT_DB ); sqlite3CodeVerifySchema(pParse, iDb); @@ -115408,10 +116330,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); - if( db->mallocFailed || pParse->nErr ){ + if( pParse->nErr ){ pTab->tabFlags &= ~TF_WithoutRowid; return; } + assert( db->mallocFailed==0 ); pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk->nKeyCol==1 ); }else{ @@ -115842,6 +116765,11 @@ SQLITE_PRIVATE void sqlite3EndTable( int addrInsLoop; /* Top of the loop for inserting rows */ Table *pSelTab; /* A table that describes the SELECT results */ + if( IN_SPECIAL_PARSE ){ + pParse->rc = SQLITE_ERROR; + pParse->nErr++; + return; + } regYield = ++pParse->nMem; regRec = ++pParse->nMem; regRowid = ++pParse->nMem; @@ -116152,10 +117080,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ */ sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); - if( db->mallocFailed==0 - && pParse->nErr==0 + if( pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ + assert( db->mallocFailed==0 ); sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, SQLITE_AFF_NONE); } @@ -116774,7 +117702,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ tnum = pIndex->tnum; } pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); - assert( pKey!=0 || db->mallocFailed || pParse->nErr ); + assert( pKey!=0 || pParse->nErr ); /* Open the sorter cursor if we are to use one. */ iSorter = pParse->nTab++; @@ -116938,9 +117866,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex( char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ - if( db->mallocFailed || pParse->nErr>0 ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto exit_create_index; } + assert( db->mallocFailed==0 ); if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } @@ -117004,7 +117934,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( pDb = &db->aDb[iDb]; assert( pTab!=0 ); - assert( pParse->nErr==0 ); if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 @@ -117428,13 +118357,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex( /* Add an entry in sqlite_schema for this index */ sqlite3NestedParse(pParse, - "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, - pIndex->zName, - pTab->zName, - iMem, - zStmt - ); + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); sqlite3DbFree(db, zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire @@ -117568,10 +118497,10 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists sqlite3 *db = pParse->db; int iDb; - assert( pParse->nErr==0 ); /* Never called with prior errors */ if( db->mallocFailed ){ goto exit_drop_index; } + assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; @@ -117982,7 +118911,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( pItem->pUsing = pUsing; return p; - append_from_error: +append_from_error: assert( p==0 ); sqlite3ExprDelete(db, pOn); sqlite3IdListDelete(db, pUsing); @@ -119012,7 +119941,6 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( const char *zName = aDef[i].zName; int nName = sqlite3Strlen30(zName); int h = SQLITE_FUNC_HASH(zName[0], nName); - assert( zName[0]>='a' && zName[0]<='z' ); assert( aDef[i].funcFlags & SQLITE_FUNC_BUILTIN ); pOther = sqlite3FunctionSearch(h, zName); if( pOther ){ @@ -119239,6 +120167,16 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ return pTab; } +/* Generate byte-code that will report the number of rows modified +** by a DELETE, INSERT, or UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC); +} + /* Return true if table pTab is read-only. ** ** A table is read-only if any of the following are true: @@ -119478,9 +120416,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( memset(&sContext, 0, sizeof(sContext)); db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto delete_from_cleanup; } + assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); @@ -119661,7 +120601,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); @@ -119814,9 +120754,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); } delete_from_cleanup: @@ -120267,6 +121205,18 @@ static void typeofFunc( sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC); } +/* subtype(X) +** +** Return the subtype of X +*/ +static void subtypeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + sqlite3_result_int(context, sqlite3_value_subtype(argv[0])); +} /* ** Implementation of the length() function @@ -120428,7 +121378,7 @@ static void instrFunc( } /* -** Implementation of the printf() function. +** Implementation of the printf() (a.k.a. format()) SQL function. */ static void printfFunc( sqlite3_context *context, @@ -121197,39 +122147,42 @@ static const char hexdigits[] = { }; /* -** Implementation of the QUOTE() function. This function takes a single -** argument. If the argument is numeric, the return value is the same as -** the argument. If the argument is NULL, the return value is the string -** "NULL". Otherwise, the argument is enclosed in single quotes with -** single-quote escapes. +** Append to pStr text that is the SQL literal representation of the +** value contained in pValue. */ -static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ + /* As currently implemented, the string must be initially empty. + ** we might relax this requirement in the future, but that will + ** require enhancements to the implementation. */ + assert( pStr!=0 && pStr->nChar==0 ); + + switch( sqlite3_value_type(pValue) ){ case SQLITE_FLOAT: { double r1, r2; - char zBuf[50]; - r1 = sqlite3_value_double(argv[0]); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); - sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); - if( r1!=r2 ){ - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); + const char *zVal; + r1 = sqlite3_value_double(pValue); + sqlite3_str_appendf(pStr, "%!.15g", r1); + zVal = sqlite3_str_value(pStr); + if( zVal ){ + sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); + if( r1!=r2 ){ + sqlite3_str_reset(pStr); + sqlite3_str_appendf(pStr, "%!.20e", r1); + } } - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); break; } case SQLITE_INTEGER: { - sqlite3_result_value(context, argv[0]); + sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); break; } case SQLITE_BLOB: { - char *zText = 0; - char const *zBlob = sqlite3_value_blob(argv[0]); - int nBlob = sqlite3_value_bytes(argv[0]); - assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); - if( zText ){ + char const *zBlob = sqlite3_value_blob(pValue); + int nBlob = sqlite3_value_bytes(pValue); + assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ + sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); + if( pStr->accError==0 ){ + char *zText = pStr->zText; int i; for(i=0; i>4)&0x0F]; @@ -121239,42 +122192,48 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ zText[(nBlob*2)+3] = '\0'; zText[0] = 'X'; zText[1] = '\''; - sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); - sqlite3_free(zText); + pStr->nChar = nBlob*2 + 3; } break; } case SQLITE_TEXT: { - int i,j; - u64 n; - const unsigned char *zArg = sqlite3_value_text(argv[0]); - char *z; - - if( zArg==0 ) return; - for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } - z = contextMalloc(context, ((i64)i)+((i64)n)+3); - if( z ){ - z[0] = '\''; - for(i=0, j=1; zArg[i]; i++){ - z[j++] = zArg[i]; - if( zArg[i]=='\'' ){ - z[j++] = '\''; - } - } - z[j++] = '\''; - z[j] = 0; - sqlite3_result_text(context, z, j, sqlite3_free); - } + const unsigned char *zArg = sqlite3_value_text(pValue); + sqlite3_str_appendf(pStr, "%Q", zArg); break; } default: { - assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); - sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); + assert( sqlite3_value_type(pValue)==SQLITE_NULL ); + sqlite3_str_append(pStr, "NULL", 4); break; } } } +/* +** Implementation of the QUOTE() function. +** +** The quote(X) function returns the text of an SQL literal which is the +** value of its argument suitable for inclusion into an SQL statement. +** Strings are surrounded by single-quotes with escapes on interior quotes +** as needed. BLOBs are encoded as hexadecimal literals. Strings with +** embedded NUL characters cannot be represented as string literals in SQL +** and hence the returned string literal is truncated prior to the first NUL. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + sqlite3_str str; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3QuoteValue(&str,argv[0]); + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, + SQLITE_DYNAMIC); + if( str.accError!=SQLITE_OK ){ + sqlite3_result_null(context); + sqlite3_result_error_code(context, str.accError); + } +} + /* ** The unicode() function. Return the integer unicode code-point value ** for the first character of the input string. @@ -122390,8 +123349,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET| - SQLITE_FUNC_TYPEOF), + {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF, + 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} }, #endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), @@ -122408,9 +123367,11 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION(instr, 2, 0, 0, instrFunc ), FUNCTION(printf, -1, 0, 0, printfFunc ), + FUNCTION(format, -1, 0, 0, printfFunc ), FUNCTION(unicode, 1, 0, 0, unicodeFunc ), FUNCTION(char, -1, 0, 0, charFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), @@ -122509,6 +123470,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif sqlite3WindowFunctions(); sqlite3RegisterDateTimeFunctions(); + sqlite3RegisterJsonFunctions(); sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); #if 0 /* Enable to print out how the built-in functions are hashed */ @@ -123184,7 +124146,7 @@ static void fkScanChildren( ** clause. For each row found, increment either the deferred or immediate ** foreign key constraint counter. */ if( pParse->nErr==0 ){ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0); sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); if( pWInfo ){ sqlite3WhereEnd(pWInfo); @@ -123235,6 +124197,25 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ } } +/* +** Clear the apTrigger[] cache of CASCADE triggers for all foreign keys +** in a particular database. This needs to happen when the schema +** changes. +*/ +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ + HashElem *k; + Hash *pHash = &db->aDb[iDb].pSchema->tblHash; + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k)){ + Table *pTab = sqliteHashData(k); + FKey *pFKey; + if( !IsOrdinaryTable(pTab) ) continue; + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + fkTriggerDelete(db, pFKey->apTrigger[0]); pFKey->apTrigger[0] = 0; + fkTriggerDelete(db, pFKey->apTrigger[1]); pFKey->apTrigger[1] = 0; + } + } +} + /* ** This function is called to generate code that runs when table pTab is ** being dropped from the database. The SrcList passed as the second argument @@ -124035,7 +125016,7 @@ SQLITE_PRIVATE void sqlite3OpenTable( }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); - assert( pPk->tnum==pTab->tnum ); + assert( pPk->tnum==pTab->tnum || CORRUPT_DB ); sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pPk); VdbeComment((v, "%s", pTab->zName)); @@ -124173,7 +125154,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ } for(i=j=0; inCol; i++){ - assert( pTab->aCol[i].affinity!=0 ); + assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ zColAff[j++] = pTab->aCol[i].affinity; } @@ -124707,9 +125688,11 @@ SQLITE_PRIVATE void sqlite3Insert( #endif db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto insert_cleanup; } + assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ /* If the Select object is really just a simple VALUES() list with a @@ -124785,7 +125768,11 @@ SQLITE_PRIVATE void sqlite3Insert( ** ** This is the 2nd template. */ - if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + if( pColumn==0 + && pSelect!=0 + && pTrigger==0 + && xferOptimization(pParse, pTab, pSelect, onError, iDb) + ){ assert( !pTrigger ); assert( pList==0 ); goto insert_end; @@ -124885,7 +125872,9 @@ SQLITE_PRIVATE void sqlite3Insert( dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; - if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); @@ -125374,9 +126363,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); } insert_cleanup: @@ -126001,6 +126988,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( onError==OE_Replace /* IPK rule is REPLACE */ && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ + && !upsertIpkDelay /* IPK check already deferred by UPSERT */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; VdbeComment((v, "defer IPK REPLACE until last")); @@ -126409,6 +127397,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( ipkTop ){ sqlite3VdbeGoto(v, ipkTop); VdbeComment((v, "Do IPK REPLACE")); + assert( ipkBottom>0 ); sqlite3VdbeJumpHere(v, ipkBottom); } @@ -126539,7 +127528,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( } pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); if( update_flags==0 ){ @@ -126755,18 +127743,13 @@ static int xferOptimization( int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ int regData, regRowid; /* Registers holding data and rowid */ - if( pSelect==0 ){ - return 0; /* Must be of the form INSERT INTO ... SELECT ... */ - } + assert( pSelect!=0 ); if( pParse->pWith || pSelect->pWith ){ /* Do not attempt to process this query if there are an WITH clauses ** attached to it. Proceeding may generate a false "no such table: xxx" ** error if pSelect reads from a CTE named "xxx". */ return 0; } - if( sqlite3TriggerList(pParse, pDest) ){ - return 0; /* tab1 must not have triggers */ - } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pDest) ){ return 0; /* tab1 must not be a virtual table */ @@ -127629,6 +128612,13 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); + /* Version 3.38.0 and later */ + int (*error_offset)(sqlite3*); + int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); + int (*vtab_distinct)(sqlite3_index_info*); + int (*vtab_in)(sqlite3_index_info*,int,int); + int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); + int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); }; /* @@ -127940,6 +128930,13 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_total_changes64 sqlite3_api->total_changes64 /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +/* Version 3.38.0 and later */ +#define sqlite3_error_offset sqlite3_api->error_offset +#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value +#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct +#define sqlite3_vtab_in sqlite3_api->vtab_in +#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first +#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -128429,6 +129426,13 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_total_changes64, /* Version 3.37.0 and later */ sqlite3_autovacuum_pages, + /* Version 3.38.0 and later */ + sqlite3_error_offset, + sqlite3_vtab_rhs_value, + sqlite3_vtab_distinct, + sqlite3_vtab_in, + sqlite3_vtab_in_first, + sqlite3_vtab_in_next }; /* True if x is the directory separator character @@ -130730,6 +131734,10 @@ SQLITE_PRIVATE void sqlite3Pragma( (void)sqlite3_finalize(pDummy); sqlite3DbFree(db, zSql); } + if( db->mallocFailed ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + } pHash = &db->aDb[ii].pSchema->tblHash; break; } @@ -132587,7 +133595,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl sqlite3ResetAllSchemasOfConnection(db); pDb = &db->aDb[iDb]; }else - if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ + if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){ /* Hack: If the SQLITE_NoSchemaError flag is set, then consider ** the schema loaded, even if errors (other than OOM) occurred. In ** this situation the current sqlite3_prepare() operation will fail, @@ -132766,8 +133774,14 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ /* ** Free all memory allocations in the pParse object */ -SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + assert( pParse->nested==0 ); +#ifndef SQLITE_OMIT_SHARED_CACHE + sqlite3DbFree(db, pParse->aTableLock); +#endif while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; pParse->pCleanup = pCleanup->pNext; @@ -132778,11 +133792,12 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ if( pParse->pConstExpr ){ sqlite3ExprListDelete(db, pParse->pConstExpr); } - if( db ){ - assert( db->lookaside.bDisable >= pParse->disableLookaside ); - db->lookaside.bDisable -= pParse->disableLookaside; - db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; - } + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; + assert( pParse->db->pParse==pParse ); + db->pParse = pParse->pOuterParse; + pParse->db = 0; pParse->disableLookaside = 0; } @@ -132795,7 +133810,7 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ ** cost for this mechansim (an extra malloc), so it should not be used ** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in -** sqlite3ParserReset(), which reduces the total CPU cycle count. +** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. ** ** If a memory allocation error occurs, then the cleanup happens immediately. ** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the @@ -132835,6 +133850,33 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup( return pPtr; } +/* +** Turn bulk memory into a valid Parse object and link that Parse object +** into database connection db. +** +** Call sqlite3ParseObjectReset() to undo this operation. +** +** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which +** is generated by Lemon. +*/ +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ + memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + assert( db->pParse!=pParse ); + pParse->pOuterParse = db->pParse; + db->pParse = pParse; + pParse->db = db; + if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory"); +} + +/* +** Maximum number of times that we will try again to prepare a statement +** that returns SQLITE_ERROR_RETRY. +*/ +#ifndef SQLITE_MAX_PREPARE_RETRY +# define SQLITE_MAX_PREPARE_RETRY 25 +#endif + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -132847,16 +133889,19 @@ static int sqlite3Prepare( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ - char *zErrMsg = 0; /* Error message */ int rc = SQLITE_OK; /* Result code */ int i; /* Loop counter */ Parse sParse; /* Parsing context */ - memset(&sParse, 0, PARSE_HDR_SZ); + /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */ + memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ); memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); + sParse.pOuterParse = db->pParse; + db->pParse = &sParse; + sParse.db = db; sParse.pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); - /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ + if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory"); assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of @@ -132909,7 +133954,6 @@ static int sqlite3Prepare( sqlite3VtabUnlockList(db); - sParse.db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; @@ -132922,14 +133966,14 @@ static int sqlite3Prepare( } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ - sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); + sqlite3RunParser(&sParse, zSqlCopy); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ sParse.zTail = &zSql[nBytes]; } }else{ - sqlite3RunParser(&sParse, zSql, &zErrMsg); + sqlite3RunParser(&sParse, zSql); } assert( 0==sParse.nQueryLoop ); @@ -132945,7 +133989,7 @@ static int sqlite3Prepare( sParse.checkSchema = 0; } if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ - if( sParse.checkSchema ){ + if( sParse.checkSchema && db->init.busy==0 ){ schemaIsValid(&sParse); } if( sParse.pVdbe ){ @@ -132953,14 +133997,14 @@ static int sqlite3Prepare( } assert( 0==(*ppStmt) ); rc = sParse.rc; - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); + if( sParse.zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); }else{ sqlite3Error(db, rc); } }else{ - assert( zErrMsg==0 ); + assert( sParse.zErrMsg==0 ); *ppStmt = (sqlite3_stmt*)sParse.pVdbe; rc = SQLITE_OK; sqlite3ErrorClear(db); @@ -132976,7 +134020,7 @@ static int sqlite3Prepare( end_prepare: - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); return rc; } static int sqlite3LockAndPrepare( @@ -133006,7 +134050,8 @@ static int sqlite3LockAndPrepare( ** reset is considered a permanent error. */ rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); assert( rc==SQLITE_OK || *ppStmt==0 ); - }while( rc==SQLITE_ERROR_RETRY + if( rc==SQLITE_OK || db->mallocFailed ) break; + }while( (rc==SQLITE_ERROR_RETRY && (cnt++)iRightJoinTable = pE2->iTable; + pEq->w.iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* ** Set the EP_FromJoin property on all terms of the given expression. -** And set the Expr.iRightJoinTable to iTable for every term in the +** And set the Expr.w.iRightJoinTable to iTable for every term in the ** expression. ** ** The EP_FromJoin property is used on terms of an expression to tell @@ -133597,8 +134642,8 @@ static void addWhereTerm( ** WHERE clause during join processing but we need to remember that they ** originated in the ON or USING clause. ** -** The Expr.iRightJoinTable tells the WHERE clause processing that the -** expression depends on table iRightJoinTable even if that table is not +** The Expr.w.iRightJoinTable tells the WHERE clause processing that the +** expression depends on table w.iRightJoinTable even if that table is not ** explicitly mentioned in the expression. That information is needed ** for cases like this: ** @@ -133616,7 +134661,7 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->iRightJoinTable = iTable; + p->w.iRightJoinTable = iTable; if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); if( p->x.pList ){ @@ -133632,7 +134677,7 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ } /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every -** term that is marked with EP_FromJoin and iRightJoinTable==iTable into +** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** ** This happens when a LEFT JOIN is simplified into an ordinary JOIN. @@ -133640,7 +134685,7 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ static void unsetJoinExpr(Expr *p, int iTable){ while( p ){ if( ExprHasProperty(p, EP_FromJoin) - && (iTable<0 || p->iRightJoinTable==iTable) ){ + && (iTable<0 || p->w.iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } if( p->op==TK_COLUMN && p->iTable==iTable ){ @@ -134630,7 +135675,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->nRef = 1; memset(&p[1], 0, nExtra); }else{ - sqlite3OomFault(db); + return (KeyInfo*)sqlite3OomFault(db); } return p; } @@ -134801,6 +135846,9 @@ static void generateSortTail( iTab = pSort->iECursor; if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ + if( eDest==SRT_Mem && p->iOffset ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst); + } regRowid = 0; regRow = pDest->iSdst; }else{ @@ -136522,6 +137570,8 @@ static int multiSelectOrderBy( ){ int i, j; /* Loop counters */ Select *pPrior; /* Another SELECT immediately to our left */ + Select *pSplit; /* Left-most SELECT in the right-hand group */ + int nSelect; /* Number of SELECT statements in the compound */ Vdbe *v; /* Generate code to this VDBE */ SelectDest destA; /* Destination for coroutine A */ SelectDest destB; /* Destination for coroutine B */ @@ -136567,8 +137617,7 @@ static int multiSelectOrderBy( /* Patch up the ORDER BY clause */ op = p->op; - pPrior = p->pPrior; - assert( pPrior->pOrderBy==0 ); + assert( p->pPrior->pOrderBy==0 ); pOrderBy = p->pOrderBy; assert( pOrderBy ); nOrderBy = pOrderBy->nExpr; @@ -136618,11 +137667,6 @@ static int multiSelectOrderBy( pKeyMerge = 0; } - /* Reattach the ORDER BY clause to the query. - */ - p->pOrderBy = pOrderBy; - pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); - /* Allocate a range of temporary registers and the KeyInfo needed ** for the logic that removes duplicate result rows when the ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). @@ -136647,12 +137691,30 @@ static int multiSelectOrderBy( /* Separate the left and the right query from one another */ - p->pPrior = 0; + nSelect = 1; + if( (op==TK_ALL || op==TK_UNION) + && OptimizationEnabled(db, SQLITE_BalancedMerge) + ){ + for(pSplit=p; pSplit->pPrior!=0 && pSplit->op==op; pSplit=pSplit->pPrior){ + nSelect++; + assert( pSplit->pPrior->pNext==pSplit ); + } + } + if( nSelect<=3 ){ + pSplit = p; + }else{ + pSplit = p; + for(i=2; ipPrior; } + } + pPrior = pSplit->pPrior; + assert( pPrior!=0 ); + pSplit->pPrior = 0; pPrior->pNext = 0; + assert( p->pOrderBy == pOrderBy ); + assert( pOrderBy!=0 || db->mallocFailed ); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); - if( pPrior->pPrior==0 ){ - sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); - } + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); /* Compute the limit registers */ computeLimitRegisters(pParse, p, labelEnd); @@ -136803,12 +137865,11 @@ static int multiSelectOrderBy( /* Reassembly the compound query so that it will be freed correctly ** by the calling function */ - if( p->pPrior ){ - sqlite3SelectDelete(db, p->pPrior); + if( pSplit->pPrior ){ + sqlite3SelectDelete(db, pSplit->pPrior); } - p->pPrior = pPrior; - pPrior->pNext = p; - + pSplit->pPrior = pPrior; + pPrior->pNext = pSplit; sqlite3ExprListDelete(db, pPrior->pOrderBy); pPrior->pOrderBy = 0; @@ -136858,9 +137919,9 @@ static Expr *substExpr( ){ if( pExpr==0 ) return 0; if( ExprHasProperty(pExpr, EP_FromJoin) - && pExpr->iRightJoinTable==pSubst->iTable + && pExpr->w.iRightJoinTable==pSubst->iTable ){ - pExpr->iRightJoinTable = pSubst->iNewTable; + pExpr->w.iRightJoinTable = pSubst->iNewTable; } if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable @@ -136899,7 +137960,7 @@ static Expr *substExpr( ExprSetProperty(pNew, EP_CanBeNull); } if( ExprHasProperty(pExpr,EP_FromJoin) ){ - sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable); + sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; @@ -137064,7 +138125,7 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ renumberCursorDoMapping(pWalker, &pExpr->iTable); } if( ExprHasProperty(pExpr, EP_FromJoin) ){ - renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable); + renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable); } return WRC_Continue; } @@ -138032,8 +139093,7 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor, /* Cursor number of the subquery */ - int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ + SrcItem *pSrc /* The subquery term of the outer FROM clause */ ){ Expr *pNew; int nChng = 0; @@ -138068,20 +139128,25 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, - iCursor, isLeftJoin); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); pWhere = pWhere->pLeft; } + +#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_FromJoin)==0 - || pWhere->iRightJoinTable!=iCursor) + || pWhere->w.iRightJoinTable!=iCursor) ){ return 0; /* restriction (4) */ } - if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ + if( ExprHasProperty(pWhere,EP_FromJoin) + && pWhere->w.iRightJoinTable!=iCursor + ){ return 0; /* restriction (5) */ } - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ +#endif + + if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -138089,8 +139154,8 @@ static int pushDownWhereTerms( pNew = sqlite3ExprDup(pParse->db, pWhere, 0); unsetJoinExpr(pNew, -1); x.pParse = pParse; - x.iTable = iCursor; - x.iNewTable = iCursor; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); @@ -138798,7 +139863,8 @@ static int selectExpander(Walker *pWalker, Select *p){ /* Process NATURAL keywords, and ON and USING clauses of joins. */ - if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr || sqliteProcessJoin(pParse, p) ){ return WRC_Abort; } @@ -139095,12 +140161,13 @@ SQLITE_PRIVATE void sqlite3SelectPrep( NameContext *pOuterNC /* Name context for container */ ){ assert( p!=0 || pParse->db->mallocFailed ); + assert( pParse->db->pParse==pParse ); if( pParse->db->mallocFailed ) return; if( p->selFlags & SF_HasTypeInfo ) return; sqlite3SelectExpand(pParse, p); - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; sqlite3ResolveSelectNames(pParse, p, pOuterNC); - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; sqlite3SelectAddTypeInfo(pParse, p); } @@ -139117,8 +140184,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ int i; struct AggInfo_func *pFunc; int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + assert( pParse->db->pParse==pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( nReg==0 ) return; - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; #ifdef SQLITE_DEBUG /* Verify that all AggInfo registers are within the range specified by ** AggInfo.mnReg..AggInfo.mxReg */ @@ -139541,10 +140610,12 @@ SQLITE_PRIVATE int sqlite3Select( u8 minMaxFlag; /* Flag for min/max queries */ db = pParse->db; + assert( pParse==db->pParse ); v = sqlite3GetVdbe(pParse); - if( p==0 || db->mallocFailed || pParse->nErr ){ + if( p==0 || pParse->nErr ){ return 1; } + assert( db->mallocFailed==0 ); if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); @@ -139579,9 +140650,10 @@ SQLITE_PRIVATE int sqlite3Select( p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); - if( pParse->nErr || db->mallocFailed ){ + if( pParse->nErr ){ goto select_end; } + assert( db->mallocFailed==0 ); assert( p->pEList!=0 ); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x104 ){ @@ -139625,7 +140697,7 @@ SQLITE_PRIVATE int sqlite3Select( #ifndef SQLITE_OMIT_WINDOWFUNC if( sqlite3WindowRewrite(pParse, p) ){ - assert( db->mallocFailed || pParse->nErr>0 ); + assert( pParse->nErr ); goto select_end; } #if SELECTTRACE_ENABLED @@ -139865,8 +140937,7 @@ SQLITE_PRIVATE int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, - (pItem->fg.jointype & JT_OUTER)!=0) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ @@ -140101,7 +141172,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Begin the database scan. */ SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, - p->pEList, wctrlFlags, p->nSelectRow); + p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); @@ -140365,7 +141436,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 + 0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0 ); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDistinct); @@ -140663,7 +141734,7 @@ SQLITE_PRIVATE int sqlite3Select( SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, - pDistinct, minMaxFlag|distFlag, 0); + pDistinct, 0, minMaxFlag|distFlag, 0); if( pWInfo==0 ){ goto select_end; } @@ -140720,7 +141791,7 @@ SQLITE_PRIVATE int sqlite3Select( */ select_end: assert( db->mallocFailed==0 || db->mallocFailed==1 ); - pParse->nErr += db->mallocFailed; + assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ @@ -141400,6 +142471,7 @@ static TriggerStep *triggerStepAllocate( sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; + if( pParse->nErr ) return 0; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; @@ -141872,6 +142944,7 @@ static void codeReturningTrigger( assert( v!=0 ); assert( pParse->bReturning ); + assert( db->pParse==pParse ); pReturning = pParse->u1.pReturning; assert( pTrigger == &(pReturning->retTrig) ); memset(&sSelect, 0, sizeof(sSelect)); @@ -141882,12 +142955,13 @@ static void codeReturningTrigger( sFrom.a[0].pTab = pTab; sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); - if( db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); sqlite3GenerateColumnNames(pParse, &sSelect); } sqlite3ExprListDelete(db, sSelect.pEList); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); - if( pNew ){ + if( !db->mallocFailed ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); if( pReturning->nRetCol==0 ){ @@ -141899,7 +142973,9 @@ static void codeReturningTrigger( sNC.ncFlags = NC_UBaseReg; pParse->eTriggerOp = pTrigger->op; pParse->pTriggerTab = pTab; - if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){ + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK + && ALWAYS(!db->mallocFailed) + ){ int i; int nCol = pNew->nExpr; int reg = pParse->nMem+1; @@ -141907,16 +142983,20 @@ static void codeReturningTrigger( pReturning->iRetReg = reg; for(i=0; ia[i].pExpr; + assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ sqlite3ExprCodeFactorable(pParse, pCol, reg+i); + if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); + } } sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); } - sqlite3ExprListDelete(db, pNew); - pParse->eTriggerOp = 0; - pParse->pTriggerTab = 0; } + sqlite3ExprListDelete(db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; } @@ -142058,8 +143138,8 @@ static TriggerPrg *codeRowTrigger( Vdbe *v; /* Temporary VM */ NameContext sNC; /* Name context for sub-vdbe */ SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ - Parse *pSubParse; /* Parse context for sub-vdbe */ int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + Parse sSubParse; /* Parse context for sub-vdbe */ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); assert( pTop->pVdbe ); @@ -142081,19 +143161,17 @@ static TriggerPrg *codeRowTrigger( /* Allocate and populate a new Parse context to use for coding the ** trigger sub-program. */ - pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); - if( !pSubParse ) return 0; + sqlite3ParseObjectInit(&sSubParse, db); memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pSubParse; - pSubParse->db = db; - pSubParse->pTriggerTab = pTab; - pSubParse->pToplevel = pTop; - pSubParse->zAuthContext = pTrigger->zName; - pSubParse->eTriggerOp = pTrigger->op; - pSubParse->nQueryLoop = pParse->nQueryLoop; - pSubParse->disableVtab = pParse->disableVtab; - - v = sqlite3GetVdbe(pSubParse); + sNC.pParse = &sSubParse; + sSubParse.pTriggerTab = pTab; + sSubParse.pToplevel = pTop; + sSubParse.zAuthContext = pTrigger->zName; + sSubParse.eTriggerOp = pTrigger->op; + sSubParse.nQueryLoop = pParse->nQueryLoop; + sSubParse.disableVtab = pParse->disableVtab; + + v = sqlite3GetVdbe(&sSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -142119,14 +143197,14 @@ static TriggerPrg *codeRowTrigger( if( db->mallocFailed==0 && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) ){ - iEndTrigger = sqlite3VdbeMakeLabel(pSubParse); - sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse); + sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); } sqlite3ExprDelete(db, pWhen); } /* Code the trigger program into the sub-vdbe. */ - codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); + codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf); /* Insert an OP_Halt at the end of the sub-program. */ if( iEndTrigger ){ @@ -142134,23 +143212,24 @@ static TriggerPrg *codeRowTrigger( } sqlite3VdbeAddOp0(v, OP_Halt); VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + transferParseError(pParse, &sSubParse); - transferParseError(pParse, pSubParse); - if( db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } - pProgram->nMem = pSubParse->nMem; - pProgram->nCsr = pSubParse->nTab; + pProgram->nMem = sSubParse.nMem; + pProgram->nCsr = sSubParse.nTab; pProgram->token = (void *)pTrigger; - pPrg->aColmask[0] = pSubParse->oldmask; - pPrg->aColmask[1] = pSubParse->newmask; + pPrg->aColmask[0] = sSubParse.oldmask; + pPrg->aColmask[1] = sSubParse.newmask; sqlite3VdbeDelete(v); + }else{ + transferParseError(pParse, &sSubParse); } - assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); - sqlite3ParserReset(pSubParse); - sqlite3StackFree(db, pSubParse); - + assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); + sqlite3ParseObjectReset(&sSubParse); return pPrg; } @@ -142183,6 +143262,7 @@ static TriggerPrg *getRowTrigger( /* If an existing TriggerPrg could not be located, create a new one. */ if( !pPrg ){ pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + pParse->db->errByteOffset = -1; } return pPrg; @@ -142205,7 +143285,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ TriggerPrg *pPrg; pPrg = getRowTrigger(pParse, p, pTab, orconf); - assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); + assert( pPrg || pParse->nErr ); /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program ** is a pointer to the sub-vdbe containing the trigger program. */ @@ -142723,9 +143803,11 @@ SQLITE_PRIVATE void sqlite3Update( memset(&sContext, 0, sizeof(sContext)); db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto update_cleanup; } + assert( db->mallocFailed==0 ); /* Locate the table which we want to update. */ @@ -143097,7 +144179,7 @@ SQLITE_PRIVATE void sqlite3Update( if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); if( pWInfo==0 ) goto update_cleanup; /* A one-pass strategy that might update more than one row may not @@ -143497,9 +144579,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); } update_cleanup: @@ -143621,7 +144701,9 @@ static void updateVirtualTable( regRowid = ++pParse->nMem; /* Start scanning the virtual table */ - pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0); + pWInfo = sqlite3WhereBegin( + pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0 + ); if( pWInfo==0 ) return; /* Populate the argument registers. */ @@ -145248,7 +146330,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ VtabCtx *pCtx; int rc = SQLITE_OK; Table *pTab; - char *zErr = 0; Parse sParse; int initBusy; @@ -145267,9 +146348,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pTab = pCtx->pTab; assert( IsVirtual(pTab) ); - memset(&sParse, 0, sizeof(sParse)); + sqlite3ParseObjectInit(&sParse, db); sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; - sParse.db = db; + sParse.disableTriggers = 1; /* We should never be able to reach this point while loading the ** schema. Nevertheless, defend against that (turn off db->init.busy) ** in case a bug arises. */ @@ -145277,11 +146358,12 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ initBusy = db->init.busy; db->init.busy = 0; sParse.nQueryLoop = 1; - if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) - && sParse.pNewTable - && !db->mallocFailed + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) + && ALWAYS(sParse.pNewTable!=0) + && ALWAYS(!db->mallocFailed) && IsOrdinaryTable(sParse.pNewTable) ){ + assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; @@ -145311,8 +146393,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ } pCtx->bDeclared = 1; }else{ - sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); + sqlite3ErrorWithMsg(db, SQLITE_ERROR, + (sParse.zErrMsg ? "%s" : 0), sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); rc = SQLITE_ERROR; } sParse.eParseMode = PARSE_MODE_NORMAL; @@ -145321,7 +146404,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3VdbeFinalize(sParse.pVdbe); } sqlite3DeleteTable(db, sParse.pNewTable); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); db->init.busy = initBusy; assert( (rc&0xff)==rc ); @@ -145873,6 +146956,7 @@ struct WhereLevel { u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif + int regFilter; /* Bloom filter */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ @@ -145931,10 +147015,12 @@ struct WhereLoop { } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ - u8 needFree; /* True if sqlite3_free(idxStr) is needed */ + u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ + u32 bOmitOffset : 1; /* True to let virtual table handle offset */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ + u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ } vtab; } u; u32 wsFlags; /* WHERE_* flags describing the plan */ @@ -146078,7 +147164,7 @@ struct WhereTerm { #define TERM_COPIED 0x0008 /* Has a child */ #define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ -#define TERM_OR_OK 0x0040 /* Used during OR-clause processing */ +#define TERM_OK 0x0040 /* Used during OR-clause processing */ #define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ #define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ @@ -146091,6 +147177,7 @@ struct WhereTerm { #else # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */ #endif +#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -146101,11 +147188,11 @@ struct WhereScan { WhereClause *pWC; /* WhereClause currently being scanned */ const char *zCollName; /* Required collating sequence, if not NULL */ Expr *pIdxExpr; /* Search for this index expression */ + int k; /* Resume scanning at this->pWC->a[this->k] */ + u32 opMask; /* Acceptable operators */ char idxaff; /* Must match this affinity, if zCollName!=NULL */ + unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */ unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */ - unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */ - u32 opMask; /* Acceptable operators */ - int k; /* Resume scanning at this->pWC->a[this->k] */ int aiCur[11]; /* Cursors in the equivalence class */ i16 aiColumn[11]; /* Corresponding column number in the eq-class */ }; @@ -146129,6 +147216,7 @@ struct WhereClause { u8 hasOr; /* True if any a[].eOperator is WO_OR */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ + int nBase; /* Number of terms through the last non-Virtual */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ #if defined(SQLITE_SMALL_STACK) WhereTerm aStatic[1]; /* Initial static space for a[] */ @@ -146186,11 +147274,6 @@ struct WhereMaskSet { int ix[BMS]; /* Cursor assigned to each bit */ }; -/* -** Initialize a WhereMaskSet object -*/ -#define initMaskSet(P) (P)->n=0 - /* ** This object is a convenience wrapper holding all information needed ** to construct WhereLoop objects for a particular query. @@ -146198,7 +147281,6 @@ struct WhereMaskSet { struct WhereLoopBuilder { WhereInfo *pWInfo; /* Information about this WHERE */ WhereClause *pWC; /* WHERE clause terms */ - ExprList *pOrderBy; /* ORDER BY clause */ WhereLoop *pNew; /* Template WhereLoop */ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ #ifdef SQLITE_ENABLE_STAT4 @@ -146266,6 +147348,9 @@ struct WhereInfo { ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ Expr *pWhere; /* The complete WHERE clause */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */ +#endif int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ @@ -146319,8 +147404,14 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ); +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 +# define sqlite3WhereExplainBloomFilter(u,v,w) 0 #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3WhereAddScanStatus( @@ -146345,6 +147436,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); @@ -146413,6 +147505,9 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ +#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ +#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ +#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -146575,19 +147670,27 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ - const char *zRangeOp; + char cRangeOp; +#if 0 /* Better output, but breaks many tests */ + const Table *pTab = pItem->pTab; + const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName: + "rowid"; +#else + const char *zRowid = "rowid"; +#endif + sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid); if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ - zRangeOp = "="; + cRangeOp = '='; }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ - zRangeOp = ">? AND rowid<"; + sqlite3_str_appendf(&str, ">? AND %s", zRowid); + cRangeOp = '<'; }else if( flags&WHERE_BTM_LIMIT ){ - zRangeOp = ">"; + cRangeOp = '>'; }else{ assert( flags&WHERE_TOP_LIMIT); - zRangeOp = "<"; + cRangeOp = '<'; } - sqlite3_str_appendf(&str, - " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); + sqlite3_str_appendf(&str, "%c?)", cRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ @@ -146610,6 +147713,56 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } return ret; } + +/* +** Add a single OP_Explain opcode that describes a Bloom filter. +** +** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or +** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not +** required and this routine is a no-op. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +){ + int ret = 0; + SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zMsg; /* Text to add to EQP output */ + int i; /* Loop counter */ + WhereLoop *pLoop; /* The where loop */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); + pLoop = pLevel->pWLoop; + if( pLoop->wsFlags & WHERE_IPK ){ + const Table *pTab = pItem->pTab; + if( pTab->iPKey>=0 ){ + sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); + }else{ + sqlite3_str_appendf(&str, "rowid=?"); + } + }else{ + for(i=pLoop->nSkip; iu.btree.nEq; i++){ + const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i); + if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5); + sqlite3_str_appendf(&str, "%s=?", z); + } + } + sqlite3_str_append(&str, ")", 1); + zMsg = sqlite3StrAccumFinish(&str); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + return ret; +} #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -147133,6 +148286,7 @@ static int codeAllEqualityTerms( VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); + assert( pLevel->addrSkip==0 ); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); VdbeCoverageIf(v, bRev==0); @@ -147165,6 +148319,9 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); } } + } + for(j=nSkip; jaLTerm[j]; if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ /* No affinity ever needs to be (or should be) applied to a value @@ -147179,7 +148336,8 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } - if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed==0 ); if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ zAff[j] = SQLITE_AFF_BLOB; } @@ -147369,7 +148527,7 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; - for(i=0; inTerm; i++){ + for(i=0; inBase; i++){ pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; @@ -147399,7 +148557,7 @@ static void codeCursorHint( if( pTabItem->fg.jointype & JT_LEFT ){ Expr *pExpr = pTerm->pExpr; if( !ExprHasProperty(pExpr, EP_FromJoin) - || pExpr->iRightJoinTable!=pTabItem->iCursor + || pExpr->w.iRightJoinTable!=pTabItem->iCursor ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintIsOrFunction; @@ -147571,6 +148729,7 @@ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr = sqlite3ExprSkipCollate(pExpr); preserveExpr(pX, pExpr); pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; @@ -147700,6 +148859,68 @@ static void whereApplyPartialIndexConstraints( } } +/* +** This routine is called right after An OP_Filter has been generated and +** before the corresponding index search has been performed. This routine +** checks to see if there are additional Bloom filters in inner loops that +** can be checked prior to doing the index lookup. If there are available +** inner-loop Bloom filters, then evaluate those filters now, before the +** index lookup. The idea is that a Bloom filter check is way faster than +** an index lookup, and the Bloom filter might return false, meaning that +** the index lookup can be skipped. +** +** We know that an inner loop uses a Bloom filter because it has the +** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked, +** then clear the WhereLevel.regFilter value to prevent the Bloom filter +** from being checked a second time when the inner loop is evaluated. +*/ +static SQLITE_NOINLINE void filterPullDown( + Parse *pParse, /* Parsing context */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + int addrNxt, /* Jump here to bypass inner loops */ + Bitmask notReady /* Loops that are not ready */ +){ + while( ++iLevel < pWInfo->nLevel ){ + WhereLevel *pLevel = &pWInfo->a[iLevel]; + WhereLoop *pLoop = pLevel->pWLoop; + if( pLevel->regFilter==0 ) continue; + if( pLevel->pWLoop->nSkip ) continue; + /* ,--- Because sqlite3ConstructBloomFilter() has will not have set + ** vvvvv--' pLevel->regFilter if this were true. */ + if( NEVER(pLoop->prereq & notReady) ) continue; + assert( pLevel->addrBrk==0 ); + pLevel->addrBrk = addrNxt; + if( pLoop->wsFlags & WHERE_IPK ){ + WhereTerm *pTerm = pLoop->aLTerm[0]; + int regRowid; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + regRowid = sqlite3GetTempReg(pParse); + regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, regRowid, 1); + VdbeCoverage(pParse->pVdbe); + }else{ + u16 nEq = pLoop->u.btree.nEq; + int r1; + char *zStartAff; + + assert( pLoop->wsFlags & WHERE_INDEXED ); + assert( (pLoop->wsFlags & WHERE_COLUMN_IN)==0 ); + r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff); + codeApplyAffinity(pParse, r1, nEq, zStartAff); + sqlite3DbFree(pParse->db, zStartAff); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, r1, nEq); + VdbeCoverage(pParse->pVdbe); + } + pLevel->regFilter = 0; + pLevel->addrBrk = 0; + } +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -147802,7 +149023,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int iReg; /* P3 Value for OP_VFilter */ int addrNotFound; int nConstraint = pLoop->nLTerm; - int iIn; /* Counter for IN constraints */ iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; @@ -147811,11 +149031,27 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pTerm = pLoop->aLTerm[j]; if( NEVER(pTerm==0) ) continue; if( pTerm->eOperator & WO_IN ){ - codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); - addrNotFound = pLevel->addrNxt; + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + } }else{ Expr *pRight = pTerm->pExpr->pRight; codeExprOrVector(pParse, pRight, iTarget, 1); + if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET + && pLoop->u.vtab.bOmitOffset + ){ + assert( pTerm->eOperator==WO_AUX ); + assert( pWInfo->pLimit!=0 ); + assert( pWInfo->pLimit->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset); + VdbeComment((v,"Zero OFFSET counter")); + } } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); @@ -147832,44 +149068,54 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); - if( pLoop->wsFlags & WHERE_IN_ABLE ){ - iIn = pLevel->u.in.nIn; - }else{ - iIn = 0; - } - for(j=nConstraint-1; j>=0; j--){ + + for(j=0; jaLTerm[j]; - if( (pTerm->eOperator & WO_IN)!=0 ) iIn--; if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); - }else if( (pTerm->eOperator & WO_IN)!=0 - && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 + continue; + } + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + && !db->mallocFailed ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ + int iIn; /* IN loop corresponding to the j-th constraint */ /* Reload the constraint value into reg[iReg+j+2]. The same value ** was loaded into the same register prior to the OP_VFilter, but ** the xFilter implementation might have changed the datatype or - ** encoding of the value in the register, so it *must* be reloaded. */ - assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed ); - if( !db->mallocFailed ){ - assert( iIn>=0 && iInu.in.nIn ); + ** encoding of the value in the register, so it *must* be reloaded. + */ + for(iIn=0; ALWAYS(iInu.in.nIn); iIn++){ pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); - assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid ); - assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 ); - assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 ); - testcase( pOp->opcode==OP_Rowid ); - sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2) + || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2) + ){ + testcase( pOp->opcode==OP_Rowid ); + sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + break; + } } /* Generate code that will continue to the next row if - ** the IN constraint is not satisfied */ + ** the IN constraint is not satisfied + */ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); - assert( pCompare!=0 || db->mallocFailed ); - if( pCompare ){ - pCompare->pLeft = pTerm->pExpr->pLeft; + if( !db->mallocFailed ){ + int iFld = pTerm->u.x.iField; + Expr *pLeft = pTerm->pExpr->pLeft; + assert( pLeft!=0 ); + if( iFld>0 ){ + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + assert( iFld<=pLeft->x.pList->nExpr ); + pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr; + }else{ + pCompare->pLeft = pLeft; + } pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); if( pRight ){ pRight->iTable = iReg+j+2; @@ -147878,11 +149124,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ); } pCompare->pLeft = 0; - sqlite3ExprDelete(db, pCompare); } + sqlite3ExprDelete(db, pCompare); } } - assert( iIn==0 || db->mallocFailed ); + /* These registers need to be preserved in case there is an IN operator ** loop. So we could deallocate the registers here (and potentially ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems @@ -147910,6 +149156,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + iRowidReg, 1); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); pLevel->op = OP_Noop; @@ -148235,6 +149487,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); VdbeComment((v, "NULL-scan pass ctr")); } + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + regBase, nEq); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); @@ -148562,7 +149820,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y - ** Then for every term xN, evaluate as the subexpression: xN AND z + ** Then for every term xN, evaluate as the subexpression: xN AND y ** That way, terms in y that are factored into the disjunction will ** be picked up by the recursive calls to sqlite3WhereBegin() below. ** @@ -148574,6 +149832,20 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** This optimization also only applies if the (x1 OR x2 OR ...) term ** is not contained in the ON clause of a LEFT JOIN. ** See ticket http://www.sqlite.org/src/info/f2369304e4 + ** + ** 2022-02-04: Do not push down slices of a row-value comparison. + ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, + ** the initialization of the right-hand operand of the vector comparison + ** might not occur, or might occur only in an OR branch that is not + ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. + ** + ** 2022-03-03: Do not push down expressions that involve subqueries. + ** The subquery might get coded as a subroutine. Any table-references + ** in the subquery might be resolved to index-references for the index on + ** the OR branch in which the subroutine is coded. But if the subroutine + ** is invoked from a different OR branch that uses a different index, such + ** index-references will not work. tag-20220303a + ** https://sqlite.org/forum/forumpost/36937b197273d403 */ if( pWC->nTerm>1 ){ int iTerm; @@ -148582,9 +149854,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( &pWC->a[iTerm] == pTerm ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); - if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); + if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ + continue; + } if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; - testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); + if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } @@ -148625,9 +149900,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Loop through table entries that match term pOrTerm. */ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); - pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, WHERE_OR_SUBCLAUSE, iCovCur); - assert( pSubWInfo || pParse->nErr || db->mallocFailed ); + assert( pSubWInfo || pParse->nErr ); if( pSubWInfo ){ WhereLoop *pSubLoop; int addrExplain = sqlite3WhereExplainOneScan( @@ -148866,7 +150141,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** then we cannot use the "t1.a=t2.b" constraint, but we can code ** the implied "t1.a=123" constraint. */ - for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){ Expr *pE, sEAlt; WhereTerm *pAlt; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -148911,7 +150186,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -149022,6 +150297,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); } pTerm = &pWC->a[idx = pWC->nTerm++]; + if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; if( p && ExprHasProperty(p, EP_Unlikely) ){ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; }else{ @@ -149364,7 +150640,7 @@ static int isAuxiliaryVtabOperator( assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pMod = (sqlite3_module *)pVtab->pModule; + pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction!=0 ){ i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ @@ -149408,7 +150684,7 @@ static int isAuxiliaryVtabOperator( static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ if( pDerived ){ pDerived->flags |= pBase->flags & EP_FromJoin; - pDerived->iRightJoinTable = pBase->iRightJoinTable; + pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable; } } @@ -149738,7 +151014,7 @@ static void exprAnalyzeOrTerm( pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); - pOrTerm->wtFlags &= ~TERM_OR_OK; + pOrTerm->wtFlags &= ~TERM_OK; if( pOrTerm->leftCursor==iCursor ){ /* This is the 2-bit case and we are on the second iteration and ** current term is from the first iteration. So skip this term. */ @@ -149779,7 +151055,7 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->eOperator & WO_EQ ); assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pOrTerm->leftCursor!=iCursor ){ - pOrTerm->wtFlags &= ~TERM_OR_OK; + pOrTerm->wtFlags &= ~TERM_OK; }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ @@ -149795,7 +151071,7 @@ static void exprAnalyzeOrTerm( if( affRight!=0 && affRight!=affLeft ){ okToChngToIN = 0; }else{ - pOrTerm->wtFlags |= TERM_OR_OK; + pOrTerm->wtFlags |= TERM_OK; } } } @@ -149812,7 +151088,7 @@ static void exprAnalyzeOrTerm( Expr *pNew; /* The complete IN operator */ for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ - if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; + if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; assert( pOrTerm->eOperator & WO_EQ ); assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pOrTerm->leftCursor==iCursor ); @@ -150013,10 +151289,13 @@ static void exprAnalyze( if( db->mallocFailed ){ return; } + assert( pWC->nTerm > idxTerm ); pTerm = &pWC->a[idxTerm]; pMaskSet = &pWInfo->sMaskSet; pExpr = pTerm->pExpr; + assert( pExpr!=0 ); /* Because malloc() has not failed */ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); + pMaskSet->bVarSelect = 0; prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; if( op==TK_IN ){ @@ -150027,16 +151306,30 @@ static void exprAnalyze( }else{ pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); } - }else if( op==TK_ISNULL ){ - pTerm->prereqRight = 0; + prereqAll = prereqLeft | pTerm->prereqRight; }else{ pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); + if( pExpr->pLeft==0 + || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow) + || pExpr->x.pList!=0 + ){ + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); + }else{ + prereqAll = prereqLeft | pTerm->prereqRight; + } } - pMaskSet->bVarSelect = 0; - prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; + +#ifdef SQLITE_DEBUG + if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){ + printf("\n*** Incorrect prereqAll computed for:\n"); + sqlite3TreeViewExpr(0,pExpr,0); + abort(); + } +#endif + if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable); prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ @@ -150304,7 +151597,10 @@ static void exprAnalyze( ** no longer used. ** ** This is only required if at least one side of the comparison operation - ** is not a sub-select. */ + ** is not a sub-select. + ** + ** tag-20220128a + */ if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft @@ -150321,7 +151617,7 @@ static void exprAnalyze( pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); transferJoinMarkings(pNew, pExpr); - idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE); exprAnalyze(pSrc, pWC, idxNew); } pTerm = &pWC->a[idxTerm]; @@ -150351,7 +151647,7 @@ static void exprAnalyze( int i; for(i=0; ipLeft); i++){ int idxNew; - idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); pWC->a[idxNew].u.x.iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); @@ -150384,7 +151680,7 @@ static void exprAnalyze( 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_FromJoin); - pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; + pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable; } idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -150447,6 +151743,113 @@ SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ } } +/* +** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or +** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the +** where-clause passed as the first argument. The value for the term +** is found in register iReg. +** +** In the common case where the value is a simple integer +** (example: "LIMIT 5 OFFSET 10") then the expression codes as a +** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value(). +** If not, then it codes as a TK_REGISTER expression. +*/ +static void whereAddLimitExpr( + WhereClause *pWC, /* Add the constraint to this WHERE clause */ + int iReg, /* Register that will hold value of the limit/offset */ + Expr *pExpr, /* Expression that defines the limit/offset */ + int iCsr, /* Cursor to which the constraint applies */ + int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ +){ + Parse *pParse = pWC->pWInfo->pParse; + sqlite3 *db = pParse->db; + Expr *pNew; + int iVal = 0; + + if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); + if( pVal==0 ) return; + ExprSetProperty(pVal, EP_IntValue); + pVal->u.iValue = iVal; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + }else{ + Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0); + if( pVal==0 ) return; + pVal->iTable = iReg; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + } + if( pNew ){ + WhereTerm *pTerm; + int idx; + idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL); + pTerm = &pWC->a[idx]; + pTerm->leftCursor = iCsr; + pTerm->eOperator = WO_AUX; + pTerm->eMatchOp = eMatchOp; + } +} + +/* +** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the +** SELECT statement passed as the second argument. These terms are only +** added if: +** +** 1. The SELECT statement has a LIMIT clause, and +** 2. The SELECT statement is not an aggregate or DISTINCT query, and +** 3. The SELECT statement has exactly one object in its from clause, and +** that object is a virtual table, and +** 4. There are no terms in the WHERE clause that will not be passed +** to the virtual table xBestIndex method. +** 5. The ORDER BY clause, if any, will be made available to the xBestIndex +** method. +** +** LIMIT and OFFSET terms are ignored by most of the planner code. They +** exist only so that they may be passed to the xBestIndex method of the +** single virtual table in the FROM clause of the SELECT. +*/ +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) ); + if( (p && p->pLimit) /* 1 */ + && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + ){ + ExprList *pOrderBy = p->pOrderBy; + int iCsr = p->pSrc->a[0].iCursor; + int ii; + + /* Check condition (4). Return early if it is not met. */ + for(ii=0; iinTerm; ii++){ + if( pWC->a[ii].wtFlags & TERM_CODED ){ + /* This term is a vector operation that has been decomposed into + ** other, subsequent terms. It can be ignored. See tag-20220128a */ + assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); + assert( pWC->a[ii].eOperator==0 ); + continue; + } + if( pWC->a[ii].leftCursor!=iCsr ) return; + } + + /* Check condition (5). Return early if it is not met. */ + if( pOrderBy ){ + for(ii=0; iinExpr; ii++){ + Expr *pExpr = pOrderBy->a[ii].pExpr; + if( pExpr->op!=TK_COLUMN ) return; + if( pExpr->iTable!=iCsr ) return; + if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return; + } + } + + /* All conditions are met. Add the terms to the where-clause object. */ + assert( p->pLimit->op==TK_LIMIT ); + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + if( p->iOffset>0 ){ + whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, + iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); + } + } +} + /* ** Initialize a preallocated WhereClause structure. */ @@ -150458,6 +151861,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit( pWC->hasOr = 0; pWC->pOuter = 0; pWC->nTerm = 0; + pWC->nBase = 0; pWC->nSlot = ArraySize(pWC->aStatic); pWC->a = pWC->aStatic; } @@ -150468,17 +151872,34 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit( ** sqlite3WhereClauseInit(). */ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ - int i; - WhereTerm *a; sqlite3 *db = pWC->pWInfo->pParse->db; - for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ - if( a->wtFlags & TERM_DYNAMIC ){ - sqlite3ExprDelete(db, a->pExpr); + assert( pWC->nTerm>=pWC->nBase ); + if( pWC->nTerm>0 ){ + WhereTerm *a = pWC->a; + WhereTerm *aLast = &pWC->a[pWC->nTerm-1]; +#ifdef SQLITE_DEBUG + int i; + /* Verify that every term past pWC->nBase is virtual */ + for(i=pWC->nBase; inTerm; i++){ + assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 ); } - if( a->wtFlags & TERM_ORINFO ){ - whereOrInfoDelete(db, a->u.pOrInfo); - }else if( a->wtFlags & TERM_ANDINFO ){ - whereAndInfoDelete(db, a->u.pAndInfo); +#endif + while(1){ + assert( a->eMatchOp==0 || a->eOperator==WO_AUX ); + if( a->wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, a->pExpr); + } + if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){ + if( a->wtFlags & TERM_ORINFO ){ + assert( (a->wtFlags & TERM_ANDINFO)==0 ); + whereOrInfoDelete(db, a->u.pOrInfo); + }else{ + assert( (a->wtFlags & TERM_ANDINFO)!=0 ); + whereAndInfoDelete(db, a->u.pAndInfo); + } + } + if( a==aLast ) break; + a++; } } if( pWC->a!=pWC->aStatic ){ @@ -150491,15 +151912,38 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ ** These routines walk (recursively) an expression tree and generate ** a bitmask indicating which tables are used in that expression ** tree. +** +** sqlite3WhereExprUsage(MaskSet, Expr) -> +** +** Return a Bitmask of all tables referenced by Expr. Expr can be +** be NULL, in which case 0 is returned. +** +** sqlite3WhereExprUsageNN(MaskSet, Expr) -> +** +** Same as sqlite3WhereExprUsage() except that Expr must not be +** NULL. The "NN" suffix on the name stands for "Not Null". +** +** sqlite3WhereExprListUsage(MaskSet, ExprList) -> +** +** Return a Bitmask of all tables referenced by every expression +** in the expression list ExprList. ExprList can be NULL, in which +** case 0 is returned. +** +** sqlite3WhereExprUsageFull(MaskSet, ExprList) -> +** +** Internal use only. Called only by sqlite3WhereExprUsageNN() for +** complex expressions that require pushing register values onto +** the stack. Many calls to sqlite3WhereExprUsageNN() do not need +** the more complex analysis done by this routine. Hence, the +** computations done by this routine are broken out into a separate +** "no-inline" function to avoid the stack push overhead in the +** common case where it is not needed. */ -SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ +static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull( + WhereMaskSet *pMaskSet, + Expr *p +){ Bitmask mask; - if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ - return sqlite3WhereGetMask(pMaskSet, p->iTable); - }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - assert( p->op!=TK_IF_NULL_ROW ); - return 0; - } mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); if( p->pRight ){ @@ -150521,6 +151965,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ #endif return mask; } +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; + } + return sqlite3WhereExprUsageFull(pMaskSet, p); +} SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; } @@ -150590,6 +152043,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( pColRef->iColumn = k++; assert( ExprUseYTab(pColRef) ); pColRef->y.pTab = pTab; + pItem->colUsed |= sqlite3ExprColUsed(pColRef); pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); @@ -150634,8 +152088,14 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( */ typedef struct HiddenIndexInfo HiddenIndexInfo; struct HiddenIndexInfo { - WhereClause *pWC; /* The Where clause being analyzed */ - Parse *pParse; /* The parsing context */ + WhereClause *pWC; /* The Where clause being analyzed */ + Parse *pParse; /* The parsing context */ + int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ + u32 mIn; /* Mask of terms that are IN (...) */ + u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ + sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST + ** because extra space is allocated to hold up + ** to nTerm such values */ }; /* Forward declaration of methods */ @@ -150838,7 +152298,12 @@ static int whereOrInsert( SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ int i; assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); - for(i=0; in; i++){ + assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 ); + assert( iCursor>=-1 ); + if( pMaskSet->ix[0]==iCursor ){ + return 1; + } + for(i=1; in; i++){ if( pMaskSet->ix[i]==iCursor ){ return MASKBIT(i); } @@ -151023,16 +152488,16 @@ static WhereTerm *whereScanInit( if( pIdx ){ int j = iColumn; iColumn = pIdx->aiColumn[j]; - if( iColumn==XN_EXPR ){ - pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - pScan->zCollName = pIdx->azColl[j]; - pScan->aiColumn[0] = XN_EXPR; - return whereScanInitIndexExpr(pScan); - }else if( iColumn==pIdx->pTable->iPKey ){ + if( iColumn==pIdx->pTable->iPKey ){ iColumn = XN_ROWID; }else if( iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; pScan->zCollName = pIdx->azColl[j]; + }else if( iColumn==XN_EXPR ){ + pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + pScan->zCollName = pIdx->azColl[j]; + pScan->aiColumn[0] = XN_EXPR; + return whereScanInitIndexExpr(pScan); } }else if( iColumn==XN_EXPR ){ return 0; @@ -151275,12 +152740,14 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ - sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", + sqlite3DebugPrintf( + " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", i, p->aConstraint[i].iColumn, p->aConstraint[i].iTermOffset, p->aConstraint[i].op, - p->aConstraint[i].usable); + p->aConstraint[i].usable, + sqlite3_vtab_collation(p,i)); } for(i=0; inOrderBy; i++){ sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", @@ -151316,9 +152783,9 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ ** index existed. */ static int termCanDriveIndex( - WhereTerm *pTerm, /* WHERE clause term to check */ - SrcItem *pSrc, /* Table we are trying to access */ - Bitmask notReady /* Tables in outer loops of the join */ + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc, /* Table we are trying to access */ + const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; @@ -151349,11 +152816,11 @@ static int termCanDriveIndex( ** and to set up the WhereLevel object pLevel so that the code generator ** makes use of the automatic index. */ -static void constructAutomaticIndex( +static SQLITE_NOINLINE void constructAutomaticIndex( Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - SrcItem *pSrc, /* The FROM clause term to get the next index */ - Bitmask notReady, /* Mask of cursors that are not available */ + const WhereClause *pWC, /* The WHERE clause */ + const SrcItem *pSrc, /* The FROM clause term to get the next index */ + const Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ int nKeyCol; /* Number of columns in the constructed index */ @@ -151395,13 +152862,12 @@ static void constructAutomaticIndex( idxCols = 0; for(pTerm=pWC->a; pTermpExpr; - assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ - || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ - || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ - if( pLoop->prereq==0 - && (pTerm->wtFlags & TERM_VIRTUAL)==0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ + /* Make the automatic index a partial index if there are terms in the + ** WHERE clause (or the ON clause of a LEFT join) that constrain which + ** rows of the target table (pSrc) that can be used. */ + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsTableConstraint(pExpr, pSrc) + ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); } @@ -151508,6 +152974,10 @@ static void constructAutomaticIndex( sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + pLevel->regFilter = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); + } /* Fill the automatic index with content */ pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; @@ -151530,6 +153000,10 @@ static void constructAutomaticIndex( regBase = sqlite3GenerateIndexKey( pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 ); + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, + regBase, pLoop->u.btree.nEq); + } sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); @@ -151556,22 +153030,149 @@ static void constructAutomaticIndex( } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ +/* +** Generate bytecode that will initialize a Bloom filter that is appropriate +** for pLevel. +** +** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER +** flag set, initialize a Bloomfilter for them as well. Except don't do +** this recursive initialization if the SQLITE_BloomPulldown optimization has +** been turned off. +** +** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared +** from the loop, but the regFilter value is set to a register that implements +** the Bloom filter. When regFilter is positive, the +** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter +** and skip the subsequence B-Tree seek if the Bloom filter indicates that +** no matching rows exist. +** +** This routine may only be called if it has previously been determined that +** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit +** is set. +*/ +static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( + WhereInfo *pWInfo, /* The WHERE clause */ + int iLevel, /* Index in pWInfo->a[] that is pLevel */ + WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */ + Bitmask notReady /* Loops that are not ready */ +){ + int addrOnce; /* Address of opening OP_Once */ + int addrTop; /* Address of OP_Rewind */ + int addrCont; /* Jump here to skip a row */ + const WhereTerm *pTerm; /* For looping over WHERE clause terms */ + const WhereTerm *pWCEnd; /* Last WHERE clause term */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ + int iCur; /* Cursor for table getting the filter */ + + assert( pLoop!=0 ); + assert( v!=0 ); + assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + do{ + const SrcItem *pItem; + const Table *pTab; + u64 sz; + sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); + addrCont = sqlite3VdbeMakeLabel(pParse); + iCur = pLevel->iTabCur; + pLevel->regFilter = ++pParse->nMem; + + /* The Bloom filter is a Blob held in a register. Initialize it + ** to zero-filled blob of at least 80K bits, but maybe more if the + ** estimated size of the table is larger. We could actually + ** measure the size of the table at run-time using OP_Count with + ** P3==1 and use that value to initialize the blob. But that makes + ** testing complicated. By basing the blob size on the value in the + ** sqlite_stat1 table, testing is much easier. + */ + pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + assert( pItem!=0 ); + pTab = pItem->pTab; + assert( pTab!=0 ); + sz = sqlite3LogEstToInt(pTab->nRowLogEst); + if( sz<10000 ){ + sz = 10000; + }else if( sz>10000000 ){ + sz = 10000000; + } + sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter); + + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm]; + for(pTerm=pWInfo->sWC.a; pTermpExpr; + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsTableConstraint(pExpr, pItem) + ){ + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + } + } + if( pLoop->wsFlags & WHERE_IPK ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1); + sqlite3ReleaseTempReg(pParse, r1); + }else{ + Index *pIdx = pLoop->u.btree.pIndex; + int n = pLoop->u.btree.nEq; + int r1 = sqlite3GetTempRange(pParse, n); + int jj; + for(jj=0; jjaiColumn[jj]; + assert( pIdx->pTable==pItem->pTab ); + sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj); + } + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); + sqlite3ReleaseTempRange(pParse, r1, n); + } + sqlite3VdbeResolveLabel(v, addrCont); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + pLoop->wsFlags &= ~WHERE_BLOOMFILTER; + if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; + while( ++iLevel < pWInfo->nLevel ){ + const SrcItem *pTabItem; + pLevel = &pWInfo->a[iLevel]; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + if( pTabItem->fg.jointype & JT_LEFT ) continue; + pLoop = pLevel->pWLoop; + if( NEVER(pLoop==0) ) continue; + if( pLoop->prereq & notReady ) continue; + if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) + ==WHERE_BLOOMFILTER + ){ + /* This is a candidate for bloom-filter pull-down (early evaluation). + ** The test that WHERE_COLUMN_IN is omitted is important, as we are + ** not able to do early evaluation of bloom filters that make use of + ** the IN operator */ + break; + } + } + }while( iLevel < pWInfo->nLevel ); + sqlite3VdbeJumpHere(v, addrOnce); +} + + #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure -** by passing the pointer returned by this function to sqlite3_free(). +** by passing the pointer returned by this function to freeIndexInfo(). */ static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, /* The parsing context */ + WhereInfo *pWInfo, /* The WHERE clause */ WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ SrcItem *pSrc, /* The FROM clause term that is the vtab */ - ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ int i, j; int nTerm; + Parse *pParse = pWInfo->pParse; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_orderby *pIdxOrderBy; struct sqlite3_index_constraint_usage *pUsage; @@ -151580,10 +153181,21 @@ static sqlite3_index_info *allocateIndexInfo( int nOrderBy; sqlite3_index_info *pIdxInfo; u16 mNoOmit = 0; + const Table *pTab; + int eDistinct = 0; + ExprList *pOrderBy = pWInfo->pOrderBy; + + assert( pSrc!=0 ); + pTab = pSrc->pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); - /* Count the number of possible WHERE clause constraints referring - ** to this virtual table */ + /* Find all WHERE clause constraints referring to this virtual table. + ** Mark each term with the TERM_OK flag. Set nTerm to the number of + ** terms found. + */ for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); @@ -151593,9 +153205,21 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - assert( pTerm->u.x.leftColumn>=(-1) ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + + /* tag-20191211-002: WHERE-clause constraints are not useful to the + ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the + ** equivalent restriction for ordinary tables. */ + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + ){ + continue; + } nTerm++; + pTerm->wtFlags |= TERM_OK; } /* If the ORDER BY clause contains only columns in the current @@ -151607,11 +153231,47 @@ static sqlite3_index_info *allocateIndexInfo( int n = pOrderBy->nExpr; for(i=0; ia[i].pExpr; - if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; + Expr *pE2; + + /* Skip over constant terms in the ORDER BY clause */ + if( sqlite3ExprIsConstant(pExpr) ){ + continue; + } + + /* Virtual tables are unable to deal with NULLS FIRST */ if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; + + /* First case - a direct column references without a COLLATE operator */ + if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ + assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumnnCol ); + continue; + } + + /* 2nd case - a column reference with a COLLATE operator. Only match + ** of the COLLATE operator matches the collation of the column. */ + if( pExpr->op==TK_COLLATE + && (pE2 = pExpr->pLeft)->op==TK_COLUMN + && pE2->iTable==pSrc->iCursor + ){ + const char *zColl; /* The collating sequence name */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pE2->iColumn>=XN_ROWID && pE2->iColumnnCol ); + pExpr->iColumn = pE2->iColumn; + if( pE2->iColumn<0 ) continue; /* Collseq does not matter for rowid */ + zColl = sqlite3ColumnColl(&pTab->aCol[pE2->iColumn]); + if( zColl==0 ) zColl = sqlite3StrBINARY; + if( sqlite3_stricmp(pExpr->u.zToken, zColl)==0 ) continue; + } + + /* No matches cause a break out of the loop */ + break; } - if( i==n){ + if( i==n ){ nOrderBy = n; + if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){ + eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0); + } } } @@ -151619,47 +153279,35 @@ static sqlite3_index_info *allocateIndexInfo( */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm - + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) ); + + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) + + sizeof(sqlite3_value*)*nTerm ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0; } pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; - pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; - pIdxInfo->nOrderBy = nOrderBy; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; pHidden->pWC = pWC; pHidden->pParse = pParse; + pHidden->eDistinct = eDistinct; + pHidden->mIn = 0; for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ u16 op; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; - - /* tag-20191211-002: WHERE-clause constraints are not useful to the - ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the - ** equivalent restriction for ordinary tables. */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - ){ - continue; - } - assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - assert( pTerm->u.x.leftColumn>=(-1) ); + if( (pTerm->wtFlags & TERM_OK)==0 ) continue; pIdxCons[j].iColumn = pTerm->u.x.leftColumn; pIdxCons[j].iTermOffset = i; op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ) op = WO_EQ; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } if( op==WO_AUX ){ pIdxCons[j].op = pTerm->eMatchOp; }else if( op & (WO_ISNULL|WO_IS) ){ @@ -151692,17 +153340,42 @@ static sqlite3_index_info *allocateIndexInfo( j++; } + assert( j==nTerm ); pIdxInfo->nConstraint = j; - for(i=0; ia[i].pExpr; - pIdxOrderBy[i].iColumn = pExpr->iColumn; - pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; + if( sqlite3ExprIsConstant(pExpr) ) continue; + assert( pExpr->op==TK_COLUMN + || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN + && pExpr->iColumn==pExpr->pLeft->iColumn) ); + pIdxOrderBy[j].iColumn = pExpr->iColumn; + pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; + j++; } + pIdxInfo->nOrderBy = j; *pmNoOmit = mNoOmit; return pIdxInfo; } +/* +** Free an sqlite3_index_info structure allocated by allocateIndexInfo() +** and possibly modified by xBestIndex methods. +*/ +static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden; + int i; + assert( pIdxInfo!=0 ); + pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->pParse!=0 ); + assert( pHidden->pParse->db==db ); + for(i=0; inConstraint; i++){ + sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ + pHidden->aRhs[i] = 0; + } + sqlite3DbFree(db, pIdxInfo); +} + /* ** The table object reference passed as the second argument to this function ** must represent a virtual table. This function invokes the xBestIndex() @@ -151724,7 +153397,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ int rc; whereTraceIndexInfoInputs(p); + pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); + pParse->db->nSchemaLock--; whereTraceIndexInfoOutputs(p); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ @@ -152498,9 +154173,9 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ sqlite3_free(z); } if( p->wsFlags & WHERE_SKIPSCAN ){ - sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); }else{ - sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); + sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); } sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ @@ -152960,11 +154635,11 @@ static void whereLoopOutputAdjust( LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); - for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ assert( pTerm!=0 ); - if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; - if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; if( (pTerm->prereqAll & notAllowed)!=0 ) continue; + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue; for(j=pLoop->nLTerm-1; j>=0; j--){ pX = pLoop->aLTerm[j]; if( pX==0 ) continue; @@ -152972,6 +154647,22 @@ static void whereLoopOutputAdjust( if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; } if( j<0 ){ + if( pLoop->maskSelf==pTerm->prereqAll ){ + /* If there are extra terms in the WHERE clause not used by an index + ** that depend only on the table being scanned, and that will tend to + ** cause many rows to be omitted, then mark that table as + ** "self-culling". + ** + ** 2022-03-24: Self-culling only applies if either the extra terms + ** are straight comparison operators that are non-true with NULL + ** operand, or if the loop is not a LEFT JOIN. + */ + if( (pTerm->eOperator & 0x3f)!=0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 + ){ + pLoop->wsFlags |= WHERE_SELFCULL; + } + } if( pTerm->truthProb<=0 ){ /* If a truth probability is specified using the likelihood() hints, ** then use the probability provided by the application. */ @@ -152999,7 +154690,9 @@ static void whereLoopOutputAdjust( } } } - if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; + if( pLoop->nOut > nRow-iReduce ){ + pLoop->nOut = nRow - iReduce; + } } /* @@ -153544,7 +155237,7 @@ static int whereUsablePartialIndex( for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; - if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab) && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) && (pTerm->wtFlags & TERM_VNULL)==0 @@ -153846,6 +155539,15 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if pTerm is a virtual table LIMIT or OFFSET term. +*/ +static int isLimitTerm(WhereTerm *pTerm){ + assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 ); + return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT + && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; +} + /* ** Argument pIdxInfo is already populated with all constraints that may ** be used by the virtual table identified by pBuilder->pNew->iTab. This @@ -153873,9 +155575,11 @@ static int whereLoopAddVirtualOne( u16 mExclude, /* Exclude terms using these operators */ sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ u16 mNoOmit, /* Do not omit these constraints */ - int *pbIn /* OUT: True if plan uses an IN(...) op */ + int *pbIn, /* OUT: True if plan uses an IN(...) op */ + int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */ ){ WhereClause *pWC = pBuilder->pWC; + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; int i; @@ -153898,6 +155602,7 @@ static int whereLoopAddVirtualOne( pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 + && (pbRetryLimit || !isLimitTerm(pTerm)) ){ pIdxCons->usable = 1; } @@ -153913,6 +155618,7 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); @@ -153930,8 +155636,8 @@ static int whereLoopAddVirtualOne( mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); - for(i=0; iaLTerm[i] = 0; - pNew->u.vtab.omitMask = 0; + memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint ); + memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab)); pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ieMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){ + pNew->u.vtab.bOmitOffset = 1; + } } - if( (pTerm->eOperator & WO_IN)!=0 ){ + if( SMASKBIT32(i) & pHidden->mHandleIn ){ + pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm); + }else if( (pTerm->eOperator & WO_IN)!=0 ){ /* A virtual table that is constrained by an IN clause may not ** consume the ORDER BY clause because (1) the order of IN terms ** is not necessarily related to the order of output terms and @@ -153976,6 +155687,21 @@ static int whereLoopAddVirtualOne( pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; *pbIn = 1; assert( (mExclude & WO_IN)==0 ); } + + if( isLimitTerm(pTerm) && *pbIn ){ + /* If there is an IN(...) term handled as an == (separate call to + ** xFilter for each value on the RHS of the IN) and a LIMIT or + ** OFFSET term handled as well, the plan is unusable. Set output + ** variable *pbRetryLimit to true to tell the caller to retry with + ** LIMIT and OFFSET disabled. */ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } + *pbRetryLimit = 1; + return SQLITE_OK; + } } } @@ -154020,11 +155746,19 @@ static int whereLoopAddVirtualOne( } /* -** If this function is invoked from within an xBestIndex() callback, it -** returns a pointer to a buffer containing the name of the collation -** sequence associated with element iCons of the sqlite3_index_info.aConstraint -** array. Or, if iCons is out of range or there is no active xBestIndex -** call, return NULL. +** Return the collating sequence for a constraint passed into xBestIndex. +** +** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex. +** This routine depends on there being a HiddenIndexInfo structure immediately +** following the sqlite3_index_info structure. +** +** Return a pointer to the collation name: +** +** 1. If there is an explicit COLLATE operator on the constaint, return it. +** +** 2. Else, if the column has an alternative collation, return that. +** +** 3. Otherwise, return "BINARY". */ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; @@ -154041,6 +155775,88 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int return zRet; } +/* +** Return true if constraint iCons is really an IN(...) constraint, or +** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0) +** or clear (if bHandle==0) the flag to handle it using an iterator. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + u32 m = SMASKBIT32(iCons); + if( m & pHidden->mIn ){ + if( bHandle==0 ){ + pHidden->mHandleIn &= ~m; + }else if( bHandle>0 ){ + pHidden->mHandleIn |= m; + } + return 1; + } + return 0; +} + +/* +** This interface is callable from within the xBestIndex callback only. +** +** If possible, set (*ppVal) to point to an object containing the value +** on the right-hand-side of constraint iCons. +*/ +SQLITE_API int sqlite3_vtab_rhs_value( + sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */ + int iCons, /* Constraint for which RHS is wanted */ + sqlite3_value **ppVal /* Write value extracted here */ +){ + HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; + sqlite3_value *pVal = 0; + int rc = SQLITE_OK; + if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ + rc = SQLITE_MISUSE; /* EV: R-30545-25046 */ + }else{ + if( pH->aRhs[iCons]==0 ){ + WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + rc = sqlite3ValueFromExpr( + pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), + SQLITE_AFF_BLOB, &pH->aRhs[iCons] + ); + testcase( rc!=SQLITE_OK ); + } + pVal = pH->aRhs[iCons]; + } + *ppVal = pVal; + + if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */ + rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */ + } + + return rc; +} + +/* +** Return true if ORDER BY clause may be handled as DISTINCT. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->eDistinct==0 + || pHidden->eDistinct==1 + || pHidden->eDistinct==2 ); + return pHidden->eDistinct; +} + +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** Cause the prepared statement that is associated with a call to +** xBestIndex to open write transactions on all attached schemas. +** This is used by the (built-in) sqlite_dbpage virtual table. +*/ +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + Parse *pParse = pHidden->pParse; + int nDb = pParse->db->nDb; + int i; + for(i=0; ipNew->iTab. That table is guaranteed to be a virtual table. @@ -154082,6 +155898,7 @@ static int whereLoopAddVirtual( WhereLoop *pNew; Bitmask mBest; /* Tables used by best possible plan */ u16 mNoOmit; + int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */ assert( (mPrereq & mUnusable)==0 ); pWInfo = pBuilder->pWInfo; @@ -154090,8 +155907,7 @@ static int whereLoopAddVirtual( pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; assert( IsVirtual(pSrc->pTab) ); - p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy, - &mNoOmit); + p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; pNew->wsFlags = WHERE_VIRTUALTABLE; @@ -154099,14 +155915,22 @@ static int whereLoopAddVirtual( pNew->u.vtab.needFree = 0; nConstraint = p->nConstraint; if( whereLoopResize(pParse->db, pNew, nConstraint) ){ - sqlite3DbFree(pParse->db, p); + freeIndexInfo(pParse->db, p); return SQLITE_NOMEM_BKPT; } /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); WHERETRACE(0x40, (" VirtualOne: all usable\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry + ); + if( bRetry ){ + assert( rc==SQLITE_OK ); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0 + ); + } /* If the call to xBestIndex() with all terms enabled produced a plan ** that does not require any source tables (IOW: a plan with mBest==0) @@ -154124,7 +155948,7 @@ static int whereLoopAddVirtual( if( bIn ){ WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn); + pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); assert( bIn==0 ); mBestNoIn = pNew->prereq & ~mPrereq; if( mBestNoIn==0 ){ @@ -154151,7 +155975,7 @@ static int whereLoopAddVirtual( WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn); + pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0); if( pNew->prereq==mPrereq ){ seenZero = 1; if( bIn==0 ) seenZeroNoIN = 1; @@ -154164,7 +155988,7 @@ static int whereLoopAddVirtual( if( rc==SQLITE_OK && seenZero==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn); + pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); if( bIn==0 ) seenZeroNoIN = 1; } @@ -154174,12 +155998,12 @@ static int whereLoopAddVirtual( if( rc==SQLITE_OK && seenZeroNoIN==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); + pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFreeNN(pParse->db, p); + freeIndexInfo(pParse->db, p); WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); return rc; } @@ -154223,7 +156047,6 @@ static int whereLoopAddOr( int i, j; sSubBuild = *pBuilder; - sSubBuild.pOrderBy = 0; sSubBuild.pOrSet = &sCur; WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); @@ -154235,6 +156058,7 @@ static int whereLoopAddOr( tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.nTerm = 1; + tempWC.nBase = 1; tempWC.a = pOrTerm; sSubBuild.pWC = &tempWC; }else{ @@ -155342,6 +157166,150 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ # define WHERETRACE_ALL_LOOPS(W,C) #endif +/* Attempt to omit tables from a join that do not affect the result. +** For a table to not affect the result, the following must be true: +** +** 1) The query must not be an aggregate. +** 2) The table must be the RHS of a LEFT JOIN. +** 3) Either the query must be DISTINCT, or else the ON or USING clause +** must contain a constraint that limits the scan of the table to +** at most a single row. +** 4) The table must not be referenced by any part of the query apart +** from its own USING or ON clause. +** +** For example, given: +** +** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); +** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); +** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); +** +** then table t2 can be omitted from the following: +** +** SELECT v1, v3 FROM t1 +** LEFT JOIN t2 ON (t1.ipk=t2.ipk) +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +** +** or from: +** +** SELECT DISTINCT v1, v3 FROM t1 +** LEFT JOIN t2 +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +*/ +static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( + WhereInfo *pWInfo, + Bitmask notReady +){ + int i; + Bitmask tabUsed; + + /* Preconditions checked by the caller */ + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) ); + + /* These two preconditions checked by the caller combine to guarantee + ** condition (1) of the header comment */ + assert( pWInfo->pResultSet!=0 ); + assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) ); + + tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet); + if( pWInfo->pOrderBy ){ + tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); + } + for(i=pWInfo->nLevel-1; i>=1; i--){ + WhereTerm *pTerm, *pEnd; + SrcItem *pItem; + WhereLoop *pLoop; + pLoop = pWInfo->a[i].pWLoop; + pItem = &pWInfo->pTabList->a[pLoop->iTab]; + if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 + && (pLoop->wsFlags & WHERE_ONEROW)==0 + ){ + continue; + } + if( (tabUsed & pLoop->maskSelf)!=0 ) continue; + pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor + ){ + break; + } + } + } + if( pTerm drop loop %c not used\n", pLoop->cId)); + notReady &= ~pLoop->maskSelf; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } + if( i!=pWInfo->nLevel-1 ){ + int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); + memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); + } + pWInfo->nLevel--; + assert( pWInfo->nLevel>0 ); + } + return notReady; +} + +/* +** Check to see if there are any SEARCH loops that might benefit from +** using a Bloom filter. Consider a Bloom filter if: +** +** (1) The SEARCH happens more than N times where N is the number +** of rows in the table that is being considered for the Bloom +** filter. +** (2) Some searches are expected to find zero rows. (This is determined +** by the WHERE_SELFCULL flag on the term.) +** (3) Bloom-filter processing is not disabled. (Checked by the +** caller.) +** (4) The size of the table being searched is known by ANALYZE. +** +** This block of code merely checks to see if a Bloom filter would be +** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the +** WhereLoop. The implementation of the Bloom filter comes further +** down where the code for each WhereLoop is generated. +*/ +static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( + const WhereInfo *pWInfo +){ + int i; + LogEst nSearch; + + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); + nSearch = pWInfo->a[0].pWLoop->nOut; + for(i=1; inLevel; i++){ + WhereLoop *pLoop = pWInfo->a[i].pWLoop; + const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); + if( (pLoop->wsFlags & reqFlags)==reqFlags + /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ + && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) + ){ + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pTab; + pTab->tabFlags |= TF_StatsUsed; + if( nSearch > pTab->nRowLogEst + && (pTab->tabFlags & TF_HasStat1)!=0 + ){ + testcase( pItem->fg.jointype & JT_LEFT ); + pLoop->wsFlags |= WHERE_BLOOMFILTER; + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + WHERETRACE(0xffff, ( + "-> use Bloom-filter on loop %c because there are ~%.1e " + "lookups into %s which has only ~%.1e rows\n", + pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, + (double)sqlite3LogEstToInt(pTab->nRowLogEst))); + } + } + nSearch += pLoop->nOut; + } +} + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains @@ -155436,6 +157404,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( Expr *pWhere, /* The WHERE clause */ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ + Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ @@ -155470,13 +157439,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; - sWLB.pOrderBy = pOrderBy; - - /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via - ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ - if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ - wctrlFlags &= ~WHERE_WANT_DISTINCT; - } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask @@ -155519,11 +157481,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; +#ifndef SQLITE_OMIT_VIRTUALTABLE + pWInfo->pLimit = pLimit; +#endif memset(&pWInfo->nOBSat, 0, offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; + pMaskSet->n = 0; + pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be + ** a valid cursor number, to avoid an initial + ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */ sWLB.pWInfo = pWInfo; sWLB.pWC = &pWInfo->sWC; sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); @@ -155536,7 +157505,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ - initMaskSet(pMaskSet); sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); @@ -155544,7 +157512,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( */ if( nTabList==0 ){ if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; - if( wctrlFlags & WHERE_WANT_DISTINCT ){ + if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && OptimizationEnabled(db, SQLITE_DistinctOpt) + ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); @@ -155582,6 +157552,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); + sqlite3WhereAddLimit(&pWInfo->sWC, pLimit); if( db->mallocFailed ) goto whereBeginError; /* Special case: WHERE terms that do not refer to any tables in the join @@ -155595,7 +157566,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** FROM ... WHERE random()>0; -- eval random() once per row ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall */ - for(ii=0; iinTerm; ii++){ + for(ii=0; iinBase; ii++){ WhereTerm *pT = &sWLB.pWC->a[ii]; if( pT->wtFlags & TERM_VIRTUAL ) continue; if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ @@ -155605,7 +157576,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } if( wctrlFlags & WHERE_WANT_DISTINCT ){ - if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + wctrlFlags &= ~WHERE_WANT_DISTINCT; + pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT; + }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ /* The DISTINCT marking is pointless. Ignore it. */ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; }else if( pOrderBy==0 ){ @@ -155676,9 +157652,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || db->mallocFailed ){ + if( pParse->nErr ){ goto whereBeginError; } + assert( db->mallocFailed==0 ); #ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); @@ -155706,34 +157683,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } #endif - /* Attempt to omit tables from the join that do not affect the result. - ** For a table to not affect the result, the following must be true: + /* Attempt to omit tables from a join that do not affect the result. + ** See the comment on whereOmitNoopJoin() for further information. ** - ** 1) The query must not be an aggregate. - ** 2) The table must be the RHS of a LEFT JOIN. - ** 3) Either the query must be DISTINCT, or else the ON or USING clause - ** must contain a constraint that limits the scan of the table to - ** at most a single row. - ** 4) The table must not be referenced by any part of the query apart - ** from its own USING or ON clause. - ** - ** For example, given: - ** - ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); - ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); - ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); - ** - ** then table t2 can be omitted from the following: - ** - ** SELECT v1, v3 FROM t1 - ** LEFT JOIN t2 ON (t1.ipk=t2.ipk) - ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) - ** - ** or from: - ** - ** SELECT DISTINCT v1, v3 FROM t1 - ** LEFT JOIN t2 - ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) + ** This query optimization is factored out into a separate "no-inline" + ** procedure to keep the sqlite3WhereBegin() procedure from becoming + ** too large. If sqlite3WhereBegin() becomes too large, that prevents + ** some C-compiler optimizers from in-lining the + ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to + ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; if( pWInfo->nLevel>=2 @@ -155741,49 +157699,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ - int i; - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); - if( sWLB.pOrderBy ){ - tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); - } - for(i=pWInfo->nLevel-1; i>=1; i--){ - WhereTerm *pTerm, *pEnd; - SrcItem *pItem; - pLoop = pWInfo->a[i].pWLoop; - pItem = &pWInfo->pTabList->a[pLoop->iTab]; - if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; - if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 - && (pLoop->wsFlags & WHERE_ONEROW)==0 - ){ - continue; - } - if( (tabUsed & pLoop->maskSelf)!=0 ) continue; - pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; - for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 ){ - if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - || pTerm->pExpr->iRightJoinTable!=pItem->iCursor - ){ - break; - } - } - } - if( pTerm drop loop %c not used\n", pLoop->cId)); - notReady &= ~pLoop->maskSelf; - for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 ){ - pTerm->wtFlags |= TERM_CODED; - } - } - if( i!=pWInfo->nLevel-1 ){ - int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); - memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); - } - pWInfo->nLevel--; - nTabList--; - } + notReady = whereOmitNoopJoin(pWInfo, notReady); + nTabList = pWInfo->nLevel; + assert( nTabList>0 ); + } + + /* Check to see if there are any SEARCH loops that might benefit from + ** using a Bloom filter. + */ + if( pWInfo->nLevel>=2 + && OptimizationEnabled(db, SQLITE_BloomFilter) + ){ + whereCheckIfBloomFilterIsUseful(pWInfo); } + #if defined(WHERETRACE_ENABLED) if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); @@ -155870,6 +157799,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 + && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0 ){ /* If we know that only a prefix of the record will be used, ** it is advantageous to reduce the "column count" field in @@ -155972,13 +157902,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pParse->nErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; + if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ + if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ - constructAutomaticIndex(pParse, &pWInfo->sWC, - &pTabList->a[pLevel->iFrom], notReady, pLevel); + constructAutomaticIndex(pParse, &pWInfo->sWC, + &pTabList->a[pLevel->iFrom], notReady, pLevel); +#endif + }else{ + sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); + } if( db->mallocFailed ) goto whereBeginError; } -#endif addrExplain = sqlite3WhereExplainOneScan( pParse, pTabList, pLevel, wctrlFlags ); @@ -156026,6 +157960,26 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } #endif +#ifdef SQLITE_DEBUG +/* +** Return true if cursor iCur is opened by instruction k of the +** bytecode. Used inside of assert() only. +*/ +static int cursorIsOpen(Vdbe *v, int iCur, int k){ + while( k>=0 ){ + VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); + if( pOp->p1!=iCur ) continue; + if( pOp->opcode==OP_Close ) return 0; + if( pOp->opcode==OP_OpenRead ) return 1; + if( pOp->opcode==OP_OpenWrite ) return 1; + if( pOp->opcode==OP_OpenDup ) return 1; + if( pOp->opcode==OP_OpenAutoindex ) return 1; + if( pOp->opcode==OP_OpenEphemeral ) return 1; + } + return 0; +} +#endif /* SQLITE_DEBUG */ + /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -156278,6 +158232,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ int x = pOp->p2; assert( pIdx->pTable==pTab ); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pOp->opcode==OP_Offset ){ + /* Do not need to translate the column number */ + }else +#endif if( !HasRowid(pTab) ){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; @@ -156291,9 +158250,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); + }else{ + /* Unable to translate the table reference into an index + ** reference. Verify that this is harmless - that the + ** table being referenced really is open. + */ +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + || pOp->opcode==OP_Offset + ); +#else + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + ); +#endif } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 - || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; @@ -157281,7 +159253,11 @@ static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ */ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; - if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){ + if( p->pWin + && p->pPrior==0 + && ALWAYS((p->selFlags & SF_WinRewrite)==0) + && ALWAYS(!IN_RENAME_OBJECT) + ){ Vdbe *v = sqlite3GetVdbe(pParse); sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ @@ -157356,6 +159332,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ ExprList *pArgs; assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->pFunc!=0 ); pArgs = pWin->pOwner->x.pList; if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); @@ -157430,12 +159407,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); } - if( rc ){ - if( pParse->nErr==0 ){ - assert( pParse->db->mallocFailed ); - sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); - } - } + assert( rc==SQLITE_OK || pParse->nErr!=0 ); return rc; } @@ -158053,7 +160025,7 @@ static void windowAggStep( for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pWin->iEphCsr ){ + if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ pOp->p1 = csr; } } @@ -159583,10 +161555,7 @@ static void updateDeleteLimitError( } - /* Construct a new Expr object from a single identifier. Use the - ** new Expr to populate pOut. Set the span of pOut to be the identifier - ** that created the expression. - */ + /* Construct a new Expr object from a single token */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ @@ -159606,6 +161575,7 @@ static void updateDeleteLimitError( p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; + p->w.iOfst = (int)(t.z - pParse->zTail); if( sqlite3Isquote(p->u.zToken[0]) ){ sqlite3DequoteExpr(p); } @@ -159772,78 +161742,79 @@ static void updateDeleteLimitError( #define TK_SLASH 109 #define TK_REM 110 #define TK_CONCAT 111 -#define TK_COLLATE 112 -#define TK_BITNOT 113 -#define TK_ON 114 -#define TK_INDEXED 115 -#define TK_STRING 116 -#define TK_JOIN_KW 117 -#define TK_CONSTRAINT 118 -#define TK_DEFAULT 119 -#define TK_NULL 120 -#define TK_PRIMARY 121 -#define TK_UNIQUE 122 -#define TK_CHECK 123 -#define TK_REFERENCES 124 -#define TK_AUTOINCR 125 -#define TK_INSERT 126 -#define TK_DELETE 127 -#define TK_UPDATE 128 -#define TK_SET 129 -#define TK_DEFERRABLE 130 -#define TK_FOREIGN 131 -#define TK_DROP 132 -#define TK_UNION 133 -#define TK_ALL 134 -#define TK_EXCEPT 135 -#define TK_INTERSECT 136 -#define TK_SELECT 137 -#define TK_VALUES 138 -#define TK_DISTINCT 139 -#define TK_DOT 140 -#define TK_FROM 141 -#define TK_JOIN 142 -#define TK_USING 143 -#define TK_ORDER 144 -#define TK_GROUP 145 -#define TK_HAVING 146 -#define TK_LIMIT 147 -#define TK_WHERE 148 -#define TK_RETURNING 149 -#define TK_INTO 150 -#define TK_NOTHING 151 -#define TK_FLOAT 152 -#define TK_BLOB 153 -#define TK_INTEGER 154 -#define TK_VARIABLE 155 -#define TK_CASE 156 -#define TK_WHEN 157 -#define TK_THEN 158 -#define TK_ELSE 159 -#define TK_INDEX 160 -#define TK_ALTER 161 -#define TK_ADD 162 -#define TK_WINDOW 163 -#define TK_OVER 164 -#define TK_FILTER 165 -#define TK_COLUMN 166 -#define TK_AGG_FUNCTION 167 -#define TK_AGG_COLUMN 168 -#define TK_TRUEFALSE 169 -#define TK_ISNOT 170 -#define TK_FUNCTION 171 -#define TK_UMINUS 172 -#define TK_UPLUS 173 -#define TK_TRUTH 174 -#define TK_REGISTER 175 -#define TK_VECTOR 176 -#define TK_SELECT_COLUMN 177 -#define TK_IF_NULL_ROW 178 -#define TK_ASTERISK 179 -#define TK_SPAN 180 -#define TK_ERROR 181 -#define TK_SPACE 182 -#define TK_ILLEGAL 183 +#define TK_PTR 112 +#define TK_COLLATE 113 +#define TK_BITNOT 114 +#define TK_ON 115 +#define TK_INDEXED 116 +#define TK_STRING 117 +#define TK_JOIN_KW 118 +#define TK_CONSTRAINT 119 +#define TK_DEFAULT 120 +#define TK_NULL 121 +#define TK_PRIMARY 122 +#define TK_UNIQUE 123 +#define TK_CHECK 124 +#define TK_REFERENCES 125 +#define TK_AUTOINCR 126 +#define TK_INSERT 127 +#define TK_DELETE 128 +#define TK_UPDATE 129 +#define TK_SET 130 +#define TK_DEFERRABLE 131 +#define TK_FOREIGN 132 +#define TK_DROP 133 +#define TK_UNION 134 +#define TK_ALL 135 +#define TK_EXCEPT 136 +#define TK_INTERSECT 137 +#define TK_SELECT 138 +#define TK_VALUES 139 +#define TK_DISTINCT 140 +#define TK_DOT 141 +#define TK_FROM 142 +#define TK_JOIN 143 +#define TK_USING 144 +#define TK_ORDER 145 +#define TK_GROUP 146 +#define TK_HAVING 147 +#define TK_LIMIT 148 +#define TK_WHERE 149 +#define TK_RETURNING 150 +#define TK_INTO 151 +#define TK_NOTHING 152 +#define TK_FLOAT 153 +#define TK_BLOB 154 +#define TK_INTEGER 155 +#define TK_VARIABLE 156 +#define TK_CASE 157 +#define TK_WHEN 158 +#define TK_THEN 159 +#define TK_ELSE 160 +#define TK_INDEX 161 +#define TK_ALTER 162 +#define TK_ADD 163 +#define TK_WINDOW 164 +#define TK_OVER 165 +#define TK_FILTER 166 +#define TK_COLUMN 167 +#define TK_AGG_FUNCTION 168 +#define TK_AGG_COLUMN 169 +#define TK_TRUEFALSE 170 +#define TK_ISNOT 171 +#define TK_FUNCTION 172 +#define TK_UMINUS 173 +#define TK_UPLUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_SPACE 183 +#define TK_ILLEGAL 184 #endif /**************** End token definitions ***************************************/ @@ -159903,30 +161874,30 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 318 +#define YYNOCODE 319 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 101 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - With* yy43; - u32 yy51; - int yy64; - struct FrameBound yy81; - struct {int value; int mask;} yy83; - TriggerStep* yy95; - Upsert* yy138; - IdList* yy240; - Cte* yy255; - Select* yy303; - Window* yy375; - u8 yy534; - ExprList* yy562; - struct TrigEvent yy570; - const char* yy600; - SrcList* yy607; - Expr* yy626; + TriggerStep* yy33; + Window* yy41; + Select* yy47; + SrcList* yy131; + struct TrigEvent yy180; + struct {int value; int mask;} yy231; + IdList* yy254; + u32 yy285; + ExprList* yy322; + Cte* yy385; + int yy394; + Upsert* yy444; + u8 yy516; + With* yy521; + const char* yy522; + Expr* yy528; + struct FrameBound yy595; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -159942,18 +161913,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 572 -#define YYNRULE 401 -#define YYNRULE_WITH_ACTION 339 -#define YYNTOKEN 184 -#define YY_MAX_SHIFT 571 -#define YY_MIN_SHIFTREDUCE 829 -#define YY_MAX_SHIFTREDUCE 1229 -#define YY_ERROR_ACTION 1230 -#define YY_ACCEPT_ACTION 1231 -#define YY_NO_ACTION 1232 -#define YY_MIN_REDUCE 1233 -#define YY_MAX_REDUCE 1633 +#define YYNSTATE 574 +#define YYNRULE 402 +#define YYNRULE_WITH_ACTION 340 +#define YYNTOKEN 185 +#define YY_MAX_SHIFT 573 +#define YY_MIN_SHIFTREDUCE 831 +#define YY_MAX_SHIFTREDUCE 1232 +#define YY_ERROR_ACTION 1233 +#define YY_ACCEPT_ACTION 1234 +#define YY_NO_ACTION 1235 +#define YY_MIN_REDUCE 1236 +#define YY_MAX_REDUCE 1637 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -160020,606 +161991,612 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2037) +#define YY_ACTTAB_COUNT (2070) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 564, 115, 112, 220, 169, 199, 115, 112, 220, 564, - /* 10 */ 375, 1266, 564, 376, 564, 270, 1309, 1309, 406, 407, - /* 20 */ 1084, 199, 1513, 41, 41, 515, 489, 521, 558, 558, - /* 30 */ 558, 965, 41, 41, 395, 41, 41, 51, 51, 966, - /* 40 */ 296, 1269, 296, 122, 123, 113, 1207, 1207, 1041, 1044, - /* 50 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 564, 407, - /* 60 */ 275, 275, 275, 275, 1268, 115, 112, 220, 115, 112, - /* 70 */ 220, 1512, 846, 561, 516, 561, 115, 112, 220, 250, - /* 80 */ 217, 71, 71, 122, 123, 113, 1207, 1207, 1041, 1044, - /* 90 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 440, 440, - /* 100 */ 440, 1149, 119, 119, 119, 119, 118, 118, 117, 117, - /* 110 */ 117, 116, 442, 1183, 1149, 116, 442, 1149, 546, 513, - /* 120 */ 1548, 1554, 374, 442, 6, 1183, 1154, 522, 1154, 407, - /* 130 */ 1556, 461, 373, 1554, 535, 99, 463, 332, 121, 121, - /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117, - /* 150 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, - /* 160 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 1257, 1183, - /* 170 */ 1184, 1185, 243, 1064, 564, 502, 499, 498, 567, 124, - /* 180 */ 567, 1183, 1184, 1185, 474, 497, 119, 119, 119, 119, - /* 190 */ 118, 118, 117, 117, 117, 116, 442, 70, 70, 407, - /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 442, - /* 210 */ 1409, 1469, 119, 119, 119, 119, 118, 118, 117, 117, - /* 220 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, - /* 230 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 407, 1031, - /* 240 */ 1031, 1042, 1045, 81, 382, 541, 378, 80, 119, 119, - /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 381, - /* 260 */ 463, 332, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, - /* 270 */ 1034, 120, 120, 121, 121, 121, 121, 262, 215, 512, - /* 280 */ 1424, 422, 119, 119, 119, 119, 118, 118, 117, 117, - /* 290 */ 117, 116, 442, 1231, 1, 1, 571, 2, 1235, 1573, - /* 300 */ 571, 2, 1235, 307, 1149, 141, 1600, 307, 407, 141, - /* 310 */ 1183, 361, 1317, 1035, 866, 531, 1317, 1149, 359, 1567, - /* 320 */ 1149, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 330 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, - /* 340 */ 1034, 120, 120, 121, 121, 121, 121, 275, 275, 1001, - /* 350 */ 426, 275, 275, 1128, 1627, 1021, 1627, 137, 542, 1541, - /* 360 */ 561, 272, 950, 950, 561, 1423, 1183, 1184, 1185, 1594, - /* 370 */ 866, 1012, 530, 315, 231, 1011, 468, 1276, 231, 119, - /* 380 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442, - /* 390 */ 1570, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 400 */ 116, 442, 330, 359, 1567, 564, 446, 1011, 1011, 1013, - /* 410 */ 446, 207, 564, 306, 555, 407, 363, 1021, 363, 346, - /* 420 */ 184, 118, 118, 117, 117, 117, 116, 442, 71, 71, - /* 430 */ 439, 438, 1126, 1012, 472, 71, 71, 1011, 205, 122, - /* 440 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, - /* 450 */ 121, 121, 121, 121, 219, 219, 472, 1183, 407, 570, - /* 460 */ 1183, 1235, 503, 1477, 149, 546, 307, 489, 141, 1011, - /* 470 */ 1011, 1013, 546, 140, 545, 1317, 1214, 191, 1214, 950, - /* 480 */ 950, 514, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, - /* 490 */ 1034, 120, 120, 121, 121, 121, 121, 563, 119, 119, - /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 283, - /* 510 */ 275, 275, 415, 1183, 1184, 1185, 1183, 1184, 1185, 372, - /* 520 */ 1183, 243, 344, 561, 502, 499, 498, 1539, 407, 1540, - /* 530 */ 1183, 288, 870, 143, 497, 1549, 185, 231, 9, 6, - /* 540 */ 253, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 550 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, - /* 560 */ 1034, 120, 120, 121, 121, 121, 121, 407, 137, 446, - /* 570 */ 447, 863, 169, 1183, 397, 1204, 1183, 1184, 1185, 931, - /* 580 */ 526, 1001, 98, 339, 564, 342, 1183, 1184, 1185, 306, - /* 590 */ 555, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, - /* 600 */ 120, 120, 121, 121, 121, 121, 452, 71, 71, 275, - /* 610 */ 275, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 620 */ 116, 442, 561, 417, 306, 555, 1183, 1307, 1307, 1183, - /* 630 */ 1184, 1185, 1204, 1149, 330, 458, 318, 407, 363, 470, - /* 640 */ 431, 1167, 32, 541, 527, 350, 1149, 1629, 393, 1149, - /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 660 */ 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, - /* 670 */ 120, 120, 121, 121, 121, 121, 407, 199, 472, 1183, - /* 680 */ 1022, 472, 1183, 1184, 1185, 386, 151, 539, 1548, 277, - /* 690 */ 400, 137, 6, 317, 5, 564, 562, 3, 920, 920, - /* 700 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, - /* 710 */ 120, 121, 121, 121, 121, 411, 505, 83, 71, 71, - /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 730 */ 442, 1183, 218, 428, 1183, 1183, 1184, 1185, 363, 261, - /* 740 */ 278, 358, 508, 353, 507, 248, 407, 306, 555, 1539, - /* 750 */ 1006, 349, 363, 291, 489, 302, 293, 1542, 281, 119, - /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442, - /* 770 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, - /* 780 */ 120, 121, 121, 121, 121, 407, 148, 1183, 1184, 1185, - /* 790 */ 1183, 1184, 1185, 275, 275, 1304, 1257, 1283, 483, 1476, - /* 800 */ 150, 489, 480, 564, 1187, 1304, 561, 1587, 1255, 122, - /* 810 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, - /* 820 */ 121, 121, 121, 121, 564, 886, 13, 13, 520, 119, - /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442, - /* 840 */ 1183, 420, 417, 564, 269, 269, 1316, 13, 13, 1539, - /* 850 */ 1546, 16, 16, 322, 6, 407, 506, 561, 1089, 1089, - /* 860 */ 486, 1187, 425, 1539, 887, 292, 71, 71, 119, 119, - /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 122, - /* 880 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, - /* 890 */ 121, 121, 121, 121, 564, 12, 1183, 1184, 1185, 407, - /* 900 */ 275, 275, 451, 303, 834, 835, 836, 417, 489, 276, - /* 910 */ 276, 1547, 284, 561, 319, 6, 321, 71, 71, 429, - /* 920 */ 451, 450, 561, 952, 101, 113, 1207, 1207, 1041, 1044, - /* 930 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 119, 119, - /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 1105, - /* 950 */ 1183, 489, 564, 1312, 437, 455, 478, 564, 246, 245, - /* 960 */ 244, 1409, 1545, 547, 1106, 405, 6, 1544, 196, 1258, - /* 970 */ 413, 6, 105, 462, 103, 71, 71, 286, 564, 1107, - /* 980 */ 13, 13, 119, 119, 119, 119, 118, 118, 117, 117, - /* 990 */ 117, 116, 442, 451, 104, 427, 337, 320, 275, 275, - /* 1000 */ 906, 13, 13, 564, 1482, 1105, 1183, 1184, 1185, 126, - /* 1010 */ 907, 561, 546, 564, 407, 478, 295, 1321, 253, 200, - /* 1020 */ 1106, 548, 1482, 1484, 280, 1409, 55, 55, 1287, 561, - /* 1030 */ 478, 380, 423, 951, 407, 1107, 71, 71, 122, 123, - /* 1040 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121, - /* 1050 */ 121, 121, 121, 1204, 407, 287, 552, 309, 122, 123, - /* 1060 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121, - /* 1070 */ 121, 121, 121, 441, 1128, 1628, 146, 1628, 122, 111, - /* 1080 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121, - /* 1090 */ 121, 121, 121, 404, 403, 1482, 424, 119, 119, 119, - /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 442, 1183, 564, - /* 1110 */ 1204, 544, 1086, 858, 329, 361, 1086, 119, 119, 119, - /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 442, 564, 294, - /* 1130 */ 144, 523, 56, 56, 224, 564, 510, 119, 119, 119, - /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 442, 484, 1409, - /* 1150 */ 537, 15, 15, 1126, 434, 439, 438, 407, 13, 13, - /* 1160 */ 1523, 12, 926, 1211, 1183, 1184, 1185, 925, 1213, 536, - /* 1170 */ 858, 557, 413, 193, 1525, 494, 1212, 448, 1160, 1222, - /* 1180 */ 1183, 564, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, - /* 1190 */ 120, 120, 121, 121, 121, 121, 1521, 1149, 564, 965, - /* 1200 */ 564, 1214, 247, 1214, 13, 13, 1409, 966, 538, 564, - /* 1210 */ 1149, 108, 556, 1149, 4, 310, 392, 1227, 17, 194, - /* 1220 */ 485, 43, 43, 57, 57, 306, 555, 524, 559, 1160, - /* 1230 */ 464, 564, 44, 44, 392, 1127, 1183, 1184, 1185, 479, - /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 1250 */ 442, 443, 564, 327, 13, 13, 564, 418, 1315, 414, - /* 1260 */ 171, 564, 311, 553, 213, 529, 1253, 564, 517, 543, - /* 1270 */ 412, 108, 556, 137, 4, 58, 58, 435, 314, 59, - /* 1280 */ 59, 274, 217, 549, 60, 60, 349, 476, 559, 1353, - /* 1290 */ 61, 61, 1021, 275, 275, 1228, 213, 564, 106, 106, - /* 1300 */ 8, 275, 275, 275, 275, 107, 561, 443, 566, 565, - /* 1310 */ 564, 443, 1011, 1228, 561, 564, 561, 564, 275, 275, - /* 1320 */ 62, 62, 1352, 553, 247, 456, 564, 98, 110, 306, - /* 1330 */ 555, 561, 564, 45, 45, 405, 1203, 533, 46, 46, - /* 1340 */ 47, 47, 532, 465, 1011, 1011, 1013, 1014, 27, 49, - /* 1350 */ 49, 564, 1021, 405, 469, 50, 50, 564, 106, 106, - /* 1360 */ 305, 564, 84, 204, 405, 107, 564, 443, 566, 565, - /* 1370 */ 405, 564, 1011, 564, 63, 63, 564, 1599, 564, 895, - /* 1380 */ 64, 64, 457, 477, 65, 65, 147, 96, 38, 14, - /* 1390 */ 14, 1528, 412, 564, 66, 66, 128, 128, 926, 67, - /* 1400 */ 67, 52, 52, 925, 1011, 1011, 1013, 1014, 27, 1572, - /* 1410 */ 1171, 445, 208, 1123, 279, 394, 68, 68, 228, 390, - /* 1420 */ 390, 389, 264, 387, 1171, 445, 843, 877, 279, 108, - /* 1430 */ 556, 453, 4, 390, 390, 389, 264, 387, 564, 225, - /* 1440 */ 843, 313, 328, 1003, 98, 252, 559, 544, 471, 312, - /* 1450 */ 252, 564, 208, 225, 564, 313, 473, 30, 252, 279, - /* 1460 */ 466, 69, 69, 312, 390, 390, 389, 264, 387, 443, - /* 1470 */ 333, 843, 98, 564, 53, 53, 323, 157, 157, 227, - /* 1480 */ 495, 553, 249, 289, 225, 564, 313, 162, 31, 1501, - /* 1490 */ 135, 564, 1500, 227, 312, 533, 158, 158, 885, 884, - /* 1500 */ 534, 162, 873, 301, 135, 564, 481, 226, 76, 76, - /* 1510 */ 1021, 347, 1071, 98, 54, 54, 106, 106, 1067, 564, - /* 1520 */ 249, 226, 519, 107, 227, 443, 566, 565, 72, 72, - /* 1530 */ 1011, 334, 162, 564, 230, 135, 108, 556, 959, 4, - /* 1540 */ 252, 408, 129, 129, 564, 1349, 306, 555, 564, 923, - /* 1550 */ 564, 110, 226, 559, 564, 408, 73, 73, 564, 873, - /* 1560 */ 306, 555, 1011, 1011, 1013, 1014, 27, 130, 130, 1071, - /* 1570 */ 449, 131, 131, 127, 127, 357, 443, 156, 156, 892, - /* 1580 */ 893, 155, 155, 338, 449, 356, 408, 564, 553, 968, - /* 1590 */ 969, 306, 555, 1015, 341, 564, 108, 556, 564, 4, - /* 1600 */ 1132, 1286, 533, 564, 856, 343, 145, 532, 345, 1300, - /* 1610 */ 136, 136, 1083, 559, 1083, 449, 564, 1021, 134, 134, - /* 1620 */ 1284, 132, 132, 106, 106, 1285, 133, 133, 564, 352, - /* 1630 */ 107, 564, 443, 566, 565, 1340, 443, 1011, 362, 75, - /* 1640 */ 75, 1082, 564, 1082, 564, 924, 1561, 110, 553, 551, - /* 1650 */ 1015, 77, 77, 1361, 74, 74, 1408, 1336, 1347, 550, - /* 1660 */ 1414, 1265, 1256, 1244, 1243, 42, 42, 48, 48, 1011, - /* 1670 */ 1011, 1013, 1014, 27, 1245, 1580, 490, 1021, 267, 202, - /* 1680 */ 1333, 365, 11, 106, 106, 930, 367, 210, 369, 391, - /* 1690 */ 107, 1395, 443, 566, 565, 223, 1390, 1011, 500, 454, - /* 1700 */ 282, 1400, 285, 108, 556, 214, 4, 325, 1383, 1283, - /* 1710 */ 475, 355, 1473, 1583, 1472, 1399, 371, 1222, 326, 398, - /* 1720 */ 559, 290, 331, 197, 100, 556, 209, 4, 198, 1011, - /* 1730 */ 1011, 1013, 1014, 27, 385, 256, 1520, 1518, 554, 1219, - /* 1740 */ 416, 559, 83, 443, 173, 206, 182, 221, 459, 167, - /* 1750 */ 177, 460, 175, 493, 233, 553, 79, 178, 1396, 179, - /* 1760 */ 35, 180, 96, 1402, 443, 396, 36, 467, 1478, 1401, - /* 1770 */ 482, 237, 1404, 399, 82, 186, 553, 1467, 89, 488, - /* 1780 */ 190, 268, 239, 491, 1021, 340, 240, 401, 1246, 1489, - /* 1790 */ 106, 106, 336, 509, 1294, 241, 1303, 107, 430, 443, - /* 1800 */ 566, 565, 1302, 91, 1011, 1021, 1598, 1301, 1273, 215, - /* 1810 */ 1597, 106, 106, 402, 877, 432, 354, 1272, 107, 1271, - /* 1820 */ 443, 566, 565, 1596, 1566, 1011, 1293, 433, 518, 299, - /* 1830 */ 300, 360, 95, 525, 1344, 364, 1011, 1011, 1013, 1014, - /* 1840 */ 27, 254, 255, 1552, 436, 1551, 125, 544, 10, 379, - /* 1850 */ 1326, 1453, 102, 97, 1345, 528, 304, 1011, 1011, 1013, - /* 1860 */ 1014, 27, 366, 377, 1343, 1342, 368, 370, 1325, 384, - /* 1870 */ 201, 383, 34, 1368, 1367, 568, 1177, 266, 263, 265, - /* 1880 */ 1505, 159, 569, 1241, 1236, 1506, 160, 142, 1504, 1503, - /* 1890 */ 297, 211, 830, 161, 212, 78, 444, 203, 308, 222, - /* 1900 */ 1081, 139, 1079, 316, 174, 163, 1203, 229, 176, 909, - /* 1910 */ 324, 232, 1095, 181, 409, 410, 172, 164, 165, 419, - /* 1920 */ 183, 85, 86, 421, 166, 87, 88, 1098, 1094, 234, - /* 1930 */ 235, 152, 18, 236, 335, 1087, 1216, 252, 187, 487, - /* 1940 */ 238, 188, 37, 845, 492, 356, 242, 496, 351, 501, - /* 1950 */ 189, 90, 19, 504, 348, 20, 875, 92, 298, 168, - /* 1960 */ 888, 153, 93, 511, 94, 1165, 154, 1047, 1134, 39, - /* 1970 */ 216, 1133, 271, 273, 958, 192, 953, 110, 1151, 1155, - /* 1980 */ 251, 7, 21, 1159, 1139, 22, 1153, 33, 23, 24, - /* 1990 */ 25, 540, 1158, 195, 98, 1062, 26, 1048, 1046, 1050, - /* 2000 */ 1104, 1051, 1103, 257, 258, 28, 40, 1173, 1016, 857, - /* 2010 */ 109, 29, 560, 388, 138, 1172, 259, 170, 260, 1232, - /* 2020 */ 1232, 919, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, - /* 2030 */ 1232, 1232, 1589, 1232, 1232, 1232, 1588, + /* 0 */ 566, 1307, 566, 1286, 201, 201, 566, 116, 112, 222, + /* 10 */ 566, 1307, 377, 566, 116, 112, 222, 397, 408, 409, + /* 20 */ 1260, 378, 1269, 41, 41, 41, 41, 1412, 1517, 71, + /* 30 */ 71, 967, 1258, 41, 41, 491, 71, 71, 272, 968, + /* 40 */ 298, 476, 298, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 50 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 543, 409, + /* 60 */ 1234, 1, 1, 573, 2, 1238, 548, 116, 112, 222, + /* 70 */ 309, 480, 142, 548, 1272, 524, 116, 112, 222, 1320, + /* 80 */ 417, 523, 547, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 90 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 424, 116, + /* 100 */ 112, 222, 120, 120, 120, 120, 119, 119, 118, 118, + /* 110 */ 118, 117, 113, 444, 277, 277, 277, 277, 560, 560, + /* 120 */ 560, 1558, 376, 1560, 1186, 375, 1157, 563, 1157, 563, + /* 130 */ 409, 1558, 537, 252, 219, 1553, 99, 141, 449, 6, + /* 140 */ 365, 233, 120, 120, 120, 120, 119, 119, 118, 118, + /* 150 */ 118, 117, 113, 444, 123, 124, 114, 1210, 1210, 1044, + /* 160 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 138, + /* 170 */ 289, 1186, 1546, 448, 118, 118, 118, 117, 113, 444, + /* 180 */ 125, 1186, 1187, 1188, 144, 465, 334, 566, 150, 127, + /* 190 */ 444, 122, 122, 122, 122, 115, 120, 120, 120, 120, + /* 200 */ 119, 119, 118, 118, 118, 117, 113, 444, 454, 419, + /* 210 */ 13, 13, 215, 120, 120, 120, 120, 119, 119, 118, + /* 220 */ 118, 118, 117, 113, 444, 422, 308, 557, 1186, 1187, + /* 230 */ 1188, 441, 440, 409, 1271, 122, 122, 122, 122, 120, + /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 250 */ 444, 1543, 98, 1033, 1033, 1045, 1048, 123, 124, 114, + /* 260 */ 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, + /* 270 */ 122, 122, 566, 406, 405, 1186, 566, 409, 1217, 319, + /* 280 */ 1217, 80, 81, 120, 120, 120, 120, 119, 119, 118, + /* 290 */ 118, 118, 117, 113, 444, 70, 70, 1186, 1604, 71, + /* 300 */ 71, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, + /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120, + /* 320 */ 119, 119, 118, 118, 118, 117, 113, 444, 1037, 210, + /* 330 */ 1186, 365, 1186, 1187, 1188, 245, 548, 399, 504, 501, + /* 340 */ 500, 108, 558, 138, 4, 516, 933, 433, 499, 217, + /* 350 */ 514, 522, 352, 879, 1186, 1187, 1188, 383, 561, 566, + /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117, + /* 370 */ 113, 444, 277, 277, 16, 16, 1598, 441, 440, 153, + /* 380 */ 409, 445, 13, 13, 1279, 563, 1214, 1186, 1187, 1188, + /* 390 */ 1003, 1216, 264, 555, 1574, 186, 566, 427, 138, 1215, + /* 400 */ 308, 557, 472, 138, 123, 124, 114, 1210, 1210, 1044, + /* 410 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 55, + /* 420 */ 55, 413, 1023, 507, 1217, 1186, 1217, 474, 106, 106, + /* 430 */ 1312, 1312, 1186, 171, 566, 384, 107, 380, 445, 568, + /* 440 */ 567, 430, 1543, 1013, 332, 549, 565, 263, 280, 360, + /* 450 */ 510, 355, 509, 250, 491, 308, 557, 71, 71, 351, + /* 460 */ 308, 557, 374, 120, 120, 120, 120, 119, 119, 118, + /* 470 */ 118, 118, 117, 113, 444, 1013, 1013, 1015, 1016, 27, + /* 480 */ 277, 277, 1186, 1187, 1188, 1152, 566, 528, 409, 1186, + /* 490 */ 1187, 1188, 348, 563, 548, 1260, 533, 517, 1152, 1516, + /* 500 */ 317, 1152, 285, 550, 485, 569, 566, 569, 482, 51, + /* 510 */ 51, 207, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, + /* 520 */ 1036, 121, 121, 122, 122, 122, 122, 171, 1412, 13, + /* 530 */ 13, 409, 277, 277, 1186, 505, 119, 119, 118, 118, + /* 540 */ 118, 117, 113, 444, 429, 563, 518, 220, 515, 1552, + /* 550 */ 365, 546, 1186, 6, 532, 123, 124, 114, 1210, 1210, + /* 560 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 570 */ 145, 120, 120, 120, 120, 119, 119, 118, 118, 118, + /* 580 */ 117, 113, 444, 245, 566, 474, 504, 501, 500, 566, + /* 590 */ 1481, 1186, 1187, 1188, 1310, 1310, 499, 1186, 149, 425, + /* 600 */ 1186, 480, 409, 274, 365, 952, 872, 56, 56, 1186, + /* 610 */ 1187, 1188, 71, 71, 120, 120, 120, 120, 119, 119, + /* 620 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 630 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 640 */ 122, 409, 541, 1552, 83, 865, 98, 6, 928, 529, + /* 650 */ 848, 543, 151, 927, 1186, 1187, 1188, 1186, 1187, 1188, + /* 660 */ 290, 1543, 187, 1633, 395, 123, 124, 114, 1210, 1210, + /* 670 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 680 */ 566, 954, 566, 453, 953, 120, 120, 120, 120, 119, + /* 690 */ 119, 118, 118, 118, 117, 113, 444, 1152, 221, 1186, + /* 700 */ 331, 453, 452, 13, 13, 13, 13, 1003, 365, 463, + /* 710 */ 1152, 193, 409, 1152, 382, 1543, 1170, 32, 297, 474, + /* 720 */ 195, 1527, 5, 952, 120, 120, 120, 120, 119, 119, + /* 730 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 740 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 750 */ 122, 409, 1067, 419, 1186, 1024, 1186, 1187, 1188, 1186, + /* 760 */ 419, 332, 460, 320, 544, 1545, 442, 442, 442, 566, + /* 770 */ 3, 117, 113, 444, 453, 123, 124, 114, 1210, 1210, + /* 780 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 790 */ 1473, 566, 15, 15, 293, 120, 120, 120, 120, 119, + /* 800 */ 119, 118, 118, 118, 117, 113, 444, 1186, 566, 1486, + /* 810 */ 1412, 1186, 1187, 1188, 13, 13, 1186, 1187, 1188, 1544, + /* 820 */ 271, 271, 409, 286, 308, 557, 1008, 1486, 1488, 196, + /* 830 */ 288, 71, 71, 563, 120, 120, 120, 120, 119, 119, + /* 840 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 850 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 860 */ 122, 409, 201, 1087, 1186, 1187, 1188, 1324, 304, 1529, + /* 870 */ 388, 278, 278, 450, 564, 402, 922, 922, 566, 563, + /* 880 */ 566, 426, 491, 480, 563, 123, 124, 114, 1210, 1210, + /* 890 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 900 */ 1486, 71, 71, 13, 13, 120, 120, 120, 120, 119, + /* 910 */ 119, 118, 118, 118, 117, 113, 444, 566, 545, 566, + /* 920 */ 1577, 573, 2, 1238, 1092, 1092, 488, 1480, 309, 1525, + /* 930 */ 142, 324, 409, 836, 837, 838, 312, 1320, 305, 363, + /* 940 */ 43, 43, 57, 57, 120, 120, 120, 120, 119, 119, + /* 950 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 960 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 970 */ 122, 12, 277, 277, 566, 1152, 409, 572, 428, 1238, + /* 980 */ 465, 334, 296, 474, 309, 563, 142, 249, 1152, 308, + /* 990 */ 557, 1152, 321, 1320, 323, 491, 455, 71, 71, 233, + /* 1000 */ 283, 101, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, + /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119, + /* 1020 */ 119, 118, 118, 118, 117, 113, 444, 1108, 277, 277, + /* 1030 */ 1412, 448, 394, 1230, 439, 277, 277, 248, 247, 246, + /* 1040 */ 1319, 563, 1109, 313, 198, 294, 491, 1318, 563, 464, + /* 1050 */ 566, 1427, 394, 1130, 1023, 233, 414, 1110, 295, 120, + /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 1070 */ 444, 1014, 104, 71, 71, 1013, 322, 496, 908, 566, + /* 1080 */ 277, 277, 277, 277, 1108, 1261, 415, 448, 909, 361, + /* 1090 */ 1571, 1315, 409, 563, 952, 563, 9, 202, 255, 1109, + /* 1100 */ 316, 487, 44, 44, 249, 559, 415, 1013, 1013, 1015, + /* 1110 */ 443, 1231, 409, 1603, 1110, 897, 123, 124, 114, 1210, + /* 1120 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1130 */ 122, 1231, 409, 1207, 215, 554, 123, 124, 114, 1210, + /* 1140 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1150 */ 122, 1131, 1631, 470, 1631, 255, 123, 111, 114, 1210, + /* 1160 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1170 */ 122, 1131, 1632, 414, 1632, 120, 120, 120, 120, 119, + /* 1180 */ 119, 118, 118, 118, 117, 113, 444, 221, 209, 351, + /* 1190 */ 1207, 1207, 147, 1426, 491, 120, 120, 120, 120, 119, + /* 1200 */ 119, 118, 118, 118, 117, 113, 444, 1256, 539, 519, + /* 1210 */ 888, 551, 952, 12, 566, 120, 120, 120, 120, 119, + /* 1220 */ 119, 118, 118, 118, 117, 113, 444, 538, 566, 860, + /* 1230 */ 1129, 361, 1571, 346, 1356, 409, 1163, 58, 58, 339, + /* 1240 */ 1355, 508, 277, 277, 277, 277, 277, 277, 1207, 889, + /* 1250 */ 1129, 59, 59, 459, 363, 563, 566, 563, 96, 563, + /* 1260 */ 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, + /* 1270 */ 122, 122, 122, 122, 566, 1412, 566, 281, 1186, 60, + /* 1280 */ 60, 110, 392, 392, 391, 266, 389, 860, 1163, 845, + /* 1290 */ 566, 481, 566, 436, 341, 1152, 344, 61, 61, 62, + /* 1300 */ 62, 967, 227, 1550, 315, 431, 540, 6, 1152, 968, + /* 1310 */ 566, 1152, 314, 45, 45, 46, 46, 512, 120, 120, + /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 444, + /* 1330 */ 416, 173, 1532, 47, 47, 1186, 1187, 1188, 108, 558, + /* 1340 */ 325, 4, 229, 1551, 928, 566, 437, 6, 566, 927, + /* 1350 */ 164, 566, 1290, 137, 1190, 561, 566, 1549, 566, 1089, + /* 1360 */ 566, 6, 566, 1089, 531, 566, 868, 8, 49, 49, + /* 1370 */ 228, 50, 50, 566, 63, 63, 566, 457, 445, 64, + /* 1380 */ 64, 65, 65, 14, 14, 66, 66, 407, 129, 129, + /* 1390 */ 555, 566, 458, 566, 1505, 486, 67, 67, 566, 52, + /* 1400 */ 52, 546, 407, 467, 535, 410, 226, 1023, 566, 534, + /* 1410 */ 308, 557, 1190, 407, 68, 68, 69, 69, 566, 1023, + /* 1420 */ 566, 53, 53, 868, 1014, 106, 106, 525, 1013, 566, + /* 1430 */ 1504, 159, 159, 107, 451, 445, 568, 567, 471, 307, + /* 1440 */ 1013, 160, 160, 76, 76, 566, 1548, 466, 407, 407, + /* 1450 */ 6, 1225, 54, 54, 478, 276, 219, 566, 887, 886, + /* 1460 */ 1013, 1013, 1015, 84, 206, 1206, 230, 282, 72, 72, + /* 1470 */ 329, 483, 1013, 1013, 1015, 1016, 27, 1576, 1174, 447, + /* 1480 */ 130, 130, 281, 148, 105, 38, 103, 392, 392, 391, + /* 1490 */ 266, 389, 566, 1126, 845, 396, 566, 108, 558, 566, + /* 1500 */ 4, 311, 566, 30, 17, 566, 279, 227, 566, 315, + /* 1510 */ 108, 558, 468, 4, 561, 73, 73, 314, 566, 157, + /* 1520 */ 157, 566, 131, 131, 526, 132, 132, 561, 128, 128, + /* 1530 */ 566, 158, 158, 566, 31, 291, 566, 445, 330, 521, + /* 1540 */ 98, 152, 152, 420, 136, 136, 1005, 229, 254, 555, + /* 1550 */ 445, 479, 336, 135, 135, 164, 133, 133, 137, 134, + /* 1560 */ 134, 875, 555, 535, 566, 473, 566, 254, 536, 475, + /* 1570 */ 335, 254, 98, 894, 895, 228, 535, 566, 1023, 566, + /* 1580 */ 1074, 534, 210, 232, 106, 106, 1352, 75, 75, 77, + /* 1590 */ 77, 1023, 107, 340, 445, 568, 567, 106, 106, 1013, + /* 1600 */ 74, 74, 42, 42, 566, 107, 343, 445, 568, 567, + /* 1610 */ 410, 497, 1013, 251, 359, 308, 557, 1135, 349, 875, + /* 1620 */ 98, 1070, 345, 251, 358, 1591, 347, 48, 48, 1017, + /* 1630 */ 1303, 1013, 1013, 1015, 1016, 27, 1289, 1287, 1074, 451, + /* 1640 */ 961, 925, 254, 110, 1013, 1013, 1015, 1016, 27, 1174, + /* 1650 */ 447, 970, 971, 281, 108, 558, 1288, 4, 392, 392, + /* 1660 */ 391, 266, 389, 1343, 1086, 845, 1086, 1085, 858, 1085, + /* 1670 */ 146, 561, 926, 354, 110, 303, 364, 553, 227, 1364, + /* 1680 */ 315, 108, 558, 1411, 4, 1339, 492, 1017, 314, 1350, + /* 1690 */ 1565, 552, 1417, 1268, 445, 204, 1259, 1247, 561, 1246, + /* 1700 */ 1248, 1584, 269, 1336, 367, 369, 555, 371, 11, 212, + /* 1710 */ 393, 225, 1393, 284, 1398, 456, 287, 327, 229, 328, + /* 1720 */ 292, 445, 1386, 216, 333, 1403, 164, 477, 373, 137, + /* 1730 */ 1402, 400, 502, 555, 1286, 1023, 357, 1477, 199, 1587, + /* 1740 */ 211, 106, 106, 932, 1476, 1225, 228, 556, 175, 107, + /* 1750 */ 200, 445, 568, 567, 258, 387, 1013, 1524, 1522, 223, + /* 1760 */ 1222, 418, 1023, 83, 208, 79, 82, 184, 106, 106, + /* 1770 */ 1482, 169, 177, 461, 179, 462, 107, 1399, 445, 568, + /* 1780 */ 567, 410, 180, 1013, 495, 181, 308, 557, 1013, 1013, + /* 1790 */ 1015, 1016, 27, 182, 35, 235, 100, 558, 398, 4, + /* 1800 */ 96, 1405, 1404, 36, 484, 469, 1407, 188, 401, 1471, + /* 1810 */ 451, 89, 1493, 561, 239, 1013, 1013, 1015, 1016, 27, + /* 1820 */ 490, 338, 270, 241, 192, 342, 493, 242, 403, 1249, + /* 1830 */ 243, 511, 432, 1297, 1306, 91, 445, 1305, 1304, 879, + /* 1840 */ 217, 434, 435, 1570, 1276, 1602, 520, 1601, 555, 301, + /* 1850 */ 527, 404, 1275, 302, 356, 1274, 1600, 95, 1347, 366, + /* 1860 */ 1296, 362, 1348, 368, 256, 257, 1556, 1555, 438, 1346, + /* 1870 */ 370, 126, 1345, 10, 1371, 546, 381, 1023, 102, 1457, + /* 1880 */ 97, 530, 34, 106, 106, 570, 1180, 372, 265, 1329, + /* 1890 */ 379, 107, 203, 445, 568, 567, 1328, 385, 1013, 1370, + /* 1900 */ 386, 267, 268, 571, 1244, 161, 1239, 162, 1509, 1510, + /* 1910 */ 1508, 143, 1507, 299, 832, 213, 214, 78, 446, 205, + /* 1920 */ 310, 306, 163, 224, 1084, 140, 1082, 318, 165, 176, + /* 1930 */ 1013, 1013, 1015, 1016, 27, 178, 1206, 231, 911, 234, + /* 1940 */ 326, 1098, 183, 421, 166, 167, 411, 185, 85, 423, + /* 1950 */ 412, 86, 174, 87, 168, 88, 1101, 236, 1097, 237, + /* 1960 */ 154, 18, 238, 254, 337, 1219, 489, 1090, 240, 190, + /* 1970 */ 37, 847, 189, 494, 358, 244, 350, 506, 191, 877, + /* 1980 */ 90, 498, 19, 20, 503, 92, 353, 890, 300, 170, + /* 1990 */ 155, 93, 513, 94, 1168, 156, 1050, 1137, 39, 218, + /* 2000 */ 273, 275, 1136, 960, 194, 955, 110, 1154, 1158, 253, + /* 2010 */ 7, 1162, 1156, 21, 22, 1161, 1142, 23, 24, 25, + /* 2020 */ 33, 542, 26, 260, 197, 98, 1065, 1051, 1049, 1053, + /* 2030 */ 1107, 1054, 1106, 259, 28, 40, 562, 1018, 859, 109, + /* 2040 */ 29, 921, 390, 1176, 172, 139, 1175, 1235, 261, 1235, + /* 2050 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 262, 1235, 1235, + /* 2060 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 192, 273, 274, 275, 192, 192, 273, 274, 275, 192, - /* 10 */ 218, 215, 192, 218, 192, 212, 234, 235, 205, 19, - /* 20 */ 11, 192, 294, 215, 216, 203, 192, 203, 209, 210, - /* 30 */ 211, 31, 215, 216, 205, 215, 216, 215, 216, 39, - /* 40 */ 227, 215, 229, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 19, - /* 60 */ 238, 239, 238, 239, 215, 273, 274, 275, 273, 274, - /* 70 */ 275, 237, 21, 251, 252, 251, 273, 274, 275, 255, - /* 80 */ 256, 215, 216, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 209, 210, - /* 100 */ 211, 76, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 59, 89, 111, 112, 92, 252, 307, - /* 120 */ 308, 313, 314, 112, 312, 59, 86, 261, 88, 19, - /* 130 */ 313, 80, 315, 313, 314, 25, 127, 128, 54, 55, - /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, - /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 115, - /* 170 */ 116, 117, 118, 122, 192, 121, 122, 123, 202, 69, - /* 180 */ 204, 115, 116, 117, 192, 131, 102, 103, 104, 105, - /* 190 */ 106, 107, 108, 109, 110, 111, 112, 215, 216, 19, - /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112, - /* 210 */ 192, 160, 102, 103, 104, 105, 106, 107, 108, 109, - /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, - /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 46, - /* 240 */ 47, 48, 49, 24, 248, 192, 250, 67, 102, 103, - /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 277, - /* 260 */ 127, 128, 43, 44, 45, 46, 47, 48, 49, 50, - /* 270 */ 51, 52, 53, 54, 55, 56, 57, 26, 164, 165, - /* 280 */ 272, 263, 102, 103, 104, 105, 106, 107, 108, 109, - /* 290 */ 110, 111, 112, 184, 185, 186, 187, 188, 189, 186, - /* 300 */ 187, 188, 189, 194, 76, 196, 229, 194, 19, 196, - /* 310 */ 59, 192, 203, 120, 59, 87, 203, 89, 310, 311, - /* 320 */ 92, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, - /* 340 */ 51, 52, 53, 54, 55, 56, 57, 238, 239, 73, - /* 350 */ 231, 238, 239, 22, 23, 100, 25, 81, 305, 306, - /* 360 */ 251, 23, 25, 25, 251, 272, 115, 116, 117, 214, - /* 370 */ 115, 116, 144, 192, 265, 120, 114, 222, 265, 102, - /* 380 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 390 */ 192, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 400 */ 111, 112, 126, 310, 311, 192, 297, 152, 153, 154, - /* 410 */ 297, 149, 192, 137, 138, 19, 192, 100, 192, 23, - /* 420 */ 22, 106, 107, 108, 109, 110, 111, 112, 215, 216, - /* 430 */ 106, 107, 101, 116, 192, 215, 216, 120, 149, 43, - /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 450 */ 54, 55, 56, 57, 117, 117, 192, 59, 19, 187, - /* 460 */ 59, 189, 23, 282, 240, 252, 194, 192, 196, 152, - /* 470 */ 153, 154, 252, 72, 261, 203, 152, 25, 154, 142, - /* 480 */ 142, 261, 43, 44, 45, 46, 47, 48, 49, 50, - /* 490 */ 51, 52, 53, 54, 55, 56, 57, 192, 102, 103, - /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 267, - /* 510 */ 238, 239, 237, 115, 116, 117, 115, 116, 117, 192, - /* 520 */ 59, 118, 16, 251, 121, 122, 123, 303, 19, 303, - /* 530 */ 59, 267, 23, 72, 131, 308, 22, 265, 22, 312, - /* 540 */ 24, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, - /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 81, 297, - /* 570 */ 295, 23, 192, 59, 203, 59, 115, 116, 117, 108, - /* 580 */ 192, 73, 25, 77, 192, 79, 115, 116, 117, 137, - /* 590 */ 138, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 600 */ 52, 53, 54, 55, 56, 57, 119, 215, 216, 238, - /* 610 */ 239, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 620 */ 111, 112, 251, 192, 137, 138, 59, 234, 235, 115, - /* 630 */ 116, 117, 116, 76, 126, 127, 128, 19, 192, 268, - /* 640 */ 19, 23, 22, 192, 252, 24, 89, 300, 301, 92, - /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 670 */ 52, 53, 54, 55, 56, 57, 19, 192, 192, 59, - /* 680 */ 23, 192, 115, 116, 117, 200, 240, 307, 308, 22, - /* 690 */ 205, 81, 312, 262, 22, 192, 133, 22, 135, 136, - /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 710 */ 53, 54, 55, 56, 57, 197, 95, 150, 215, 216, - /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 730 */ 112, 59, 192, 112, 59, 115, 116, 117, 192, 118, - /* 740 */ 119, 120, 121, 122, 123, 124, 19, 137, 138, 303, - /* 750 */ 23, 130, 192, 267, 192, 252, 267, 306, 203, 102, - /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 780 */ 53, 54, 55, 56, 57, 19, 240, 115, 116, 117, - /* 790 */ 115, 116, 117, 238, 239, 222, 192, 224, 280, 237, - /* 800 */ 240, 192, 284, 192, 59, 232, 251, 140, 204, 43, - /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 820 */ 54, 55, 56, 57, 192, 35, 215, 216, 192, 102, - /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 840 */ 59, 230, 192, 192, 238, 239, 237, 215, 216, 303, - /* 850 */ 308, 215, 216, 16, 312, 19, 66, 251, 126, 127, - /* 860 */ 128, 116, 230, 303, 74, 203, 215, 216, 102, 103, - /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43, - /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 890 */ 54, 55, 56, 57, 192, 212, 115, 116, 117, 19, - /* 900 */ 238, 239, 192, 252, 7, 8, 9, 192, 192, 238, - /* 910 */ 239, 308, 262, 251, 77, 312, 79, 215, 216, 129, - /* 920 */ 210, 211, 251, 142, 158, 45, 46, 47, 48, 49, - /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103, - /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 12, - /* 950 */ 59, 192, 192, 237, 252, 243, 192, 192, 126, 127, - /* 960 */ 128, 192, 308, 203, 27, 253, 312, 308, 285, 207, - /* 970 */ 208, 312, 157, 290, 159, 215, 216, 262, 192, 42, - /* 980 */ 215, 216, 102, 103, 104, 105, 106, 107, 108, 109, - /* 990 */ 110, 111, 112, 283, 158, 230, 237, 160, 238, 239, - /* 1000 */ 63, 215, 216, 192, 192, 12, 115, 116, 117, 22, - /* 1010 */ 73, 251, 252, 192, 19, 192, 230, 239, 24, 24, - /* 1020 */ 27, 261, 210, 211, 99, 192, 215, 216, 225, 251, - /* 1030 */ 192, 192, 263, 142, 19, 42, 215, 216, 43, 44, - /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1050 */ 55, 56, 57, 59, 19, 291, 63, 132, 43, 44, - /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1070 */ 55, 56, 57, 252, 22, 23, 22, 25, 43, 44, - /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1090 */ 55, 56, 57, 106, 107, 283, 263, 102, 103, 104, - /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 192, - /* 1110 */ 116, 144, 29, 59, 291, 192, 33, 102, 103, 104, - /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 192, 291, - /* 1130 */ 163, 19, 215, 216, 15, 192, 108, 102, 103, 104, - /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 65, 192, - /* 1150 */ 66, 215, 216, 101, 231, 106, 107, 19, 215, 216, - /* 1160 */ 192, 212, 134, 114, 115, 116, 117, 139, 119, 85, - /* 1170 */ 116, 207, 208, 230, 192, 19, 127, 192, 94, 60, - /* 1180 */ 59, 192, 44, 45, 46, 47, 48, 49, 50, 51, - /* 1190 */ 52, 53, 54, 55, 56, 57, 192, 76, 192, 31, - /* 1200 */ 192, 152, 46, 154, 215, 216, 192, 39, 87, 192, - /* 1210 */ 89, 19, 20, 92, 22, 192, 22, 23, 22, 230, - /* 1220 */ 263, 215, 216, 215, 216, 137, 138, 115, 36, 145, - /* 1230 */ 128, 192, 215, 216, 22, 23, 115, 116, 117, 290, - /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 1250 */ 112, 59, 192, 151, 215, 216, 192, 61, 203, 298, - /* 1260 */ 299, 192, 192, 71, 25, 144, 203, 192, 203, 230, - /* 1270 */ 114, 19, 20, 81, 22, 215, 216, 263, 192, 215, - /* 1280 */ 216, 255, 256, 203, 215, 216, 130, 19, 36, 192, - /* 1290 */ 215, 216, 100, 238, 239, 101, 25, 192, 106, 107, - /* 1300 */ 48, 238, 239, 238, 239, 113, 251, 115, 116, 117, - /* 1310 */ 192, 59, 120, 101, 251, 192, 251, 192, 238, 239, - /* 1320 */ 215, 216, 192, 71, 46, 243, 192, 25, 25, 137, - /* 1330 */ 138, 251, 192, 215, 216, 253, 25, 85, 215, 216, - /* 1340 */ 215, 216, 90, 243, 152, 153, 154, 155, 156, 215, - /* 1350 */ 216, 192, 100, 253, 243, 215, 216, 192, 106, 107, - /* 1360 */ 243, 192, 148, 149, 253, 113, 192, 115, 116, 117, - /* 1370 */ 253, 192, 120, 192, 215, 216, 192, 23, 192, 25, - /* 1380 */ 215, 216, 192, 115, 215, 216, 22, 148, 24, 215, - /* 1390 */ 216, 192, 114, 192, 215, 216, 215, 216, 134, 215, - /* 1400 */ 216, 215, 216, 139, 152, 153, 154, 155, 156, 0, - /* 1410 */ 1, 2, 141, 23, 5, 25, 215, 216, 24, 10, - /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 125, 5, 19, - /* 1430 */ 20, 268, 22, 10, 11, 12, 13, 14, 192, 30, - /* 1440 */ 17, 32, 23, 23, 25, 25, 36, 144, 23, 40, - /* 1450 */ 25, 192, 141, 30, 192, 32, 23, 22, 25, 5, - /* 1460 */ 128, 215, 216, 40, 10, 11, 12, 13, 14, 59, - /* 1470 */ 23, 17, 25, 192, 215, 216, 192, 215, 216, 70, - /* 1480 */ 23, 71, 25, 151, 30, 192, 32, 78, 53, 192, - /* 1490 */ 81, 192, 192, 70, 40, 85, 215, 216, 119, 120, - /* 1500 */ 90, 78, 59, 254, 81, 192, 192, 98, 215, 216, - /* 1510 */ 100, 23, 59, 25, 215, 216, 106, 107, 23, 192, - /* 1520 */ 25, 98, 19, 113, 70, 115, 116, 117, 215, 216, - /* 1530 */ 120, 192, 78, 192, 140, 81, 19, 20, 23, 22, - /* 1540 */ 25, 132, 215, 216, 192, 192, 137, 138, 192, 23, - /* 1550 */ 192, 25, 98, 36, 192, 132, 215, 216, 192, 116, - /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 215, 216, 116, - /* 1570 */ 161, 215, 216, 215, 216, 120, 59, 215, 216, 7, - /* 1580 */ 8, 215, 216, 192, 161, 130, 132, 192, 71, 83, - /* 1590 */ 84, 137, 138, 59, 192, 192, 19, 20, 192, 22, - /* 1600 */ 97, 225, 85, 192, 23, 192, 25, 90, 192, 192, - /* 1610 */ 215, 216, 152, 36, 154, 161, 192, 100, 215, 216, - /* 1620 */ 192, 215, 216, 106, 107, 225, 215, 216, 192, 192, - /* 1630 */ 113, 192, 115, 116, 117, 257, 59, 120, 192, 215, - /* 1640 */ 216, 152, 192, 154, 192, 23, 317, 25, 71, 235, - /* 1650 */ 116, 215, 216, 192, 215, 216, 192, 192, 192, 192, - /* 1660 */ 192, 192, 192, 192, 192, 215, 216, 215, 216, 152, - /* 1670 */ 153, 154, 155, 156, 192, 192, 287, 100, 286, 241, - /* 1680 */ 254, 254, 242, 106, 107, 108, 254, 213, 254, 190, - /* 1690 */ 113, 270, 115, 116, 117, 296, 266, 120, 219, 258, - /* 1700 */ 244, 270, 258, 19, 20, 228, 22, 292, 266, 224, - /* 1710 */ 292, 218, 218, 195, 218, 270, 258, 60, 245, 270, - /* 1720 */ 36, 245, 244, 248, 19, 20, 242, 22, 248, 152, - /* 1730 */ 153, 154, 155, 156, 244, 140, 199, 199, 279, 38, - /* 1740 */ 199, 36, 150, 59, 296, 149, 22, 296, 18, 43, - /* 1750 */ 236, 199, 233, 18, 198, 71, 293, 236, 271, 236, - /* 1760 */ 269, 236, 148, 271, 59, 245, 269, 245, 282, 271, - /* 1770 */ 199, 198, 233, 245, 293, 233, 71, 245, 157, 62, - /* 1780 */ 22, 199, 198, 220, 100, 199, 198, 220, 199, 289, - /* 1790 */ 106, 107, 288, 114, 226, 198, 217, 113, 64, 115, - /* 1800 */ 116, 117, 217, 22, 120, 100, 223, 217, 217, 164, - /* 1810 */ 223, 106, 107, 220, 125, 24, 217, 219, 113, 217, - /* 1820 */ 115, 116, 117, 217, 311, 120, 226, 112, 304, 281, - /* 1830 */ 281, 220, 114, 143, 260, 259, 152, 153, 154, 155, - /* 1840 */ 156, 199, 91, 316, 82, 316, 147, 144, 22, 199, - /* 1850 */ 249, 276, 157, 146, 260, 145, 278, 152, 153, 154, - /* 1860 */ 155, 156, 259, 248, 260, 260, 259, 259, 249, 245, - /* 1870 */ 247, 246, 25, 264, 264, 201, 13, 6, 193, 193, - /* 1880 */ 212, 206, 191, 191, 191, 212, 206, 221, 212, 212, - /* 1890 */ 221, 213, 4, 206, 213, 212, 3, 22, 162, 15, - /* 1900 */ 23, 16, 23, 138, 150, 129, 25, 24, 141, 20, - /* 1910 */ 16, 143, 1, 141, 302, 302, 299, 129, 129, 61, - /* 1920 */ 150, 53, 53, 37, 129, 53, 53, 115, 1, 34, - /* 1930 */ 140, 5, 22, 114, 160, 68, 75, 25, 68, 41, - /* 1940 */ 140, 114, 24, 20, 19, 130, 124, 67, 24, 67, - /* 1950 */ 22, 22, 22, 96, 23, 22, 59, 22, 67, 37, - /* 1960 */ 28, 23, 148, 22, 25, 23, 23, 23, 23, 22, - /* 1970 */ 140, 97, 23, 23, 115, 22, 142, 25, 88, 75, - /* 1980 */ 34, 44, 34, 75, 23, 34, 86, 22, 34, 34, - /* 1990 */ 34, 24, 93, 25, 25, 23, 34, 23, 23, 23, - /* 2000 */ 23, 11, 23, 25, 22, 22, 22, 1, 23, 23, - /* 2010 */ 22, 22, 25, 15, 23, 1, 140, 25, 140, 318, - /* 2020 */ 318, 134, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2030 */ 318, 318, 140, 318, 318, 318, 140, 318, 318, 318, - /* 2040 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2050 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2060 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2070 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2080 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2090 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2100 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2110 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2120 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2130 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2140 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2150 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2160 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2170 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2180 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2190 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2200 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2210 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - /* 2220 */ 318, + /* 0 */ 193, 223, 193, 225, 193, 193, 193, 274, 275, 276, + /* 10 */ 193, 233, 219, 193, 274, 275, 276, 206, 206, 19, + /* 20 */ 193, 219, 216, 216, 217, 216, 217, 193, 295, 216, + /* 30 */ 217, 31, 205, 216, 217, 193, 216, 217, 213, 39, + /* 40 */ 228, 193, 230, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, + /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, + /* 70 */ 195, 193, 197, 253, 216, 262, 274, 275, 276, 204, + /* 80 */ 238, 204, 262, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 264, 274, + /* 100 */ 275, 276, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, + /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, + /* 130 */ 19, 314, 315, 256, 257, 309, 25, 72, 296, 313, + /* 140 */ 193, 266, 102, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, + /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, + /* 170 */ 292, 59, 307, 298, 108, 109, 110, 111, 112, 113, + /* 180 */ 69, 116, 117, 118, 72, 128, 129, 193, 241, 22, + /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, + /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 193, + /* 210 */ 216, 217, 25, 102, 103, 104, 105, 106, 107, 108, + /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, + /* 230 */ 118, 106, 107, 19, 216, 54, 55, 56, 57, 102, + /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 250 */ 113, 304, 25, 46, 47, 48, 49, 43, 44, 45, + /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 270 */ 56, 57, 193, 106, 107, 59, 193, 19, 153, 263, + /* 280 */ 155, 67, 24, 102, 103, 104, 105, 106, 107, 108, + /* 290 */ 109, 110, 111, 112, 113, 216, 217, 59, 230, 216, + /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, + /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 142, + /* 330 */ 59, 193, 116, 117, 118, 119, 253, 204, 122, 123, + /* 340 */ 124, 19, 20, 81, 22, 262, 108, 19, 132, 165, + /* 350 */ 166, 193, 24, 126, 116, 117, 118, 278, 36, 193, + /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 370 */ 112, 113, 239, 240, 216, 217, 215, 106, 107, 241, + /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, + /* 390 */ 73, 120, 26, 71, 193, 22, 193, 231, 81, 128, + /* 400 */ 138, 139, 269, 81, 43, 44, 45, 46, 47, 48, + /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 216, + /* 420 */ 217, 198, 100, 95, 153, 59, 155, 193, 106, 107, + /* 430 */ 235, 236, 59, 193, 193, 249, 114, 251, 116, 117, + /* 440 */ 118, 113, 304, 121, 127, 204, 193, 119, 120, 121, + /* 450 */ 122, 123, 124, 125, 193, 138, 139, 216, 217, 131, + /* 460 */ 138, 139, 193, 102, 103, 104, 105, 106, 107, 108, + /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, + /* 480 */ 239, 240, 116, 117, 118, 76, 193, 193, 19, 116, + /* 490 */ 117, 118, 23, 252, 253, 193, 87, 204, 89, 238, + /* 500 */ 193, 92, 268, 262, 281, 203, 193, 205, 285, 216, + /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, + /* 520 */ 51, 52, 53, 54, 55, 56, 57, 193, 193, 216, + /* 530 */ 217, 19, 239, 240, 59, 23, 106, 107, 108, 109, + /* 540 */ 110, 111, 112, 113, 231, 252, 253, 193, 308, 309, + /* 550 */ 193, 145, 59, 313, 145, 43, 44, 45, 46, 47, + /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 570 */ 164, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 580 */ 111, 112, 113, 119, 193, 193, 122, 123, 124, 193, + /* 590 */ 283, 116, 117, 118, 235, 236, 132, 59, 241, 264, + /* 600 */ 59, 193, 19, 23, 193, 25, 23, 216, 217, 116, + /* 610 */ 117, 118, 216, 217, 102, 103, 104, 105, 106, 107, + /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 640 */ 57, 19, 308, 309, 151, 23, 25, 313, 135, 253, + /* 650 */ 21, 193, 241, 140, 116, 117, 118, 116, 117, 118, + /* 660 */ 268, 304, 22, 301, 302, 43, 44, 45, 46, 47, + /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 680 */ 193, 143, 193, 193, 143, 102, 103, 104, 105, 106, + /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, + /* 700 */ 292, 211, 212, 216, 217, 216, 217, 73, 193, 80, + /* 710 */ 89, 25, 19, 92, 193, 304, 23, 22, 231, 193, + /* 720 */ 231, 193, 22, 143, 102, 103, 104, 105, 106, 107, + /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 750 */ 57, 19, 123, 193, 59, 23, 116, 117, 118, 59, + /* 760 */ 193, 127, 128, 129, 306, 307, 210, 211, 212, 193, + /* 770 */ 22, 111, 112, 113, 284, 43, 44, 45, 46, 47, + /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 790 */ 161, 193, 216, 217, 268, 102, 103, 104, 105, 106, + /* 800 */ 107, 108, 109, 110, 111, 112, 113, 59, 193, 193, + /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 304, + /* 820 */ 239, 240, 19, 263, 138, 139, 23, 211, 212, 231, + /* 830 */ 263, 216, 217, 252, 102, 103, 104, 105, 106, 107, + /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 860 */ 57, 19, 193, 11, 116, 117, 118, 240, 253, 193, + /* 870 */ 201, 239, 240, 193, 134, 206, 136, 137, 193, 252, + /* 880 */ 193, 264, 193, 193, 252, 43, 44, 45, 46, 47, + /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 900 */ 284, 216, 217, 216, 217, 102, 103, 104, 105, 106, + /* 910 */ 107, 108, 109, 110, 111, 112, 113, 193, 231, 193, + /* 920 */ 187, 188, 189, 190, 127, 128, 129, 238, 195, 193, + /* 930 */ 197, 16, 19, 7, 8, 9, 193, 204, 253, 193, + /* 940 */ 216, 217, 216, 217, 102, 103, 104, 105, 106, 107, + /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 970 */ 57, 213, 239, 240, 193, 76, 19, 188, 232, 190, + /* 980 */ 128, 129, 292, 193, 195, 252, 197, 46, 89, 138, + /* 990 */ 139, 92, 77, 204, 79, 193, 269, 216, 217, 266, + /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, + /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, + /* 1030 */ 193, 298, 22, 23, 253, 239, 240, 127, 128, 129, + /* 1040 */ 238, 252, 27, 193, 286, 204, 193, 204, 252, 291, + /* 1050 */ 193, 273, 22, 23, 100, 266, 115, 42, 268, 102, + /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1070 */ 113, 117, 159, 216, 217, 121, 161, 19, 63, 193, + /* 1080 */ 239, 240, 239, 240, 12, 208, 209, 298, 73, 311, + /* 1090 */ 312, 238, 19, 252, 25, 252, 22, 24, 24, 27, + /* 1100 */ 193, 264, 216, 217, 46, 208, 209, 153, 154, 155, + /* 1110 */ 253, 101, 19, 23, 42, 25, 43, 44, 45, 46, + /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1130 */ 57, 101, 19, 59, 25, 63, 43, 44, 45, 46, + /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1150 */ 57, 22, 23, 115, 25, 24, 43, 44, 45, 46, + /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1170 */ 57, 22, 23, 115, 25, 102, 103, 104, 105, 106, + /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 118, 150, 131, + /* 1190 */ 59, 117, 22, 273, 193, 102, 103, 104, 105, 106, + /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 66, 204, + /* 1210 */ 35, 204, 143, 213, 193, 102, 103, 104, 105, 106, + /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 85, 193, 59, + /* 1230 */ 101, 311, 312, 16, 193, 19, 94, 216, 217, 238, + /* 1240 */ 193, 66, 239, 240, 239, 240, 239, 240, 117, 74, + /* 1250 */ 101, 216, 217, 193, 193, 252, 193, 252, 149, 252, + /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1270 */ 54, 55, 56, 57, 193, 193, 193, 5, 59, 216, + /* 1280 */ 217, 25, 10, 11, 12, 13, 14, 117, 146, 17, + /* 1290 */ 193, 291, 193, 232, 77, 76, 79, 216, 217, 216, + /* 1300 */ 217, 31, 30, 309, 32, 130, 87, 313, 89, 39, + /* 1310 */ 193, 92, 40, 216, 217, 216, 217, 108, 102, 103, + /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 1330 */ 299, 300, 193, 216, 217, 116, 117, 118, 19, 20, + /* 1340 */ 193, 22, 70, 309, 135, 193, 264, 313, 193, 140, + /* 1350 */ 78, 193, 226, 81, 59, 36, 193, 309, 193, 29, + /* 1360 */ 193, 313, 193, 33, 145, 193, 59, 48, 216, 217, + /* 1370 */ 98, 216, 217, 193, 216, 217, 193, 244, 59, 216, + /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 254, 216, 217, + /* 1390 */ 71, 193, 244, 193, 193, 65, 216, 217, 193, 216, + /* 1400 */ 217, 145, 254, 244, 85, 133, 15, 100, 193, 90, + /* 1410 */ 138, 139, 117, 254, 216, 217, 216, 217, 193, 100, + /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 19, 121, 193, + /* 1430 */ 193, 216, 217, 114, 162, 116, 117, 118, 244, 244, + /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 129, 254, 254, + /* 1450 */ 313, 60, 216, 217, 19, 256, 257, 193, 120, 121, + /* 1460 */ 153, 154, 155, 149, 150, 25, 24, 99, 216, 217, + /* 1470 */ 152, 193, 153, 154, 155, 156, 157, 0, 1, 2, + /* 1480 */ 216, 217, 5, 22, 158, 24, 160, 10, 11, 12, + /* 1490 */ 13, 14, 193, 23, 17, 25, 193, 19, 20, 193, + /* 1500 */ 22, 133, 193, 22, 22, 193, 22, 30, 193, 32, + /* 1510 */ 19, 20, 129, 22, 36, 216, 217, 40, 193, 216, + /* 1520 */ 217, 193, 216, 217, 116, 216, 217, 36, 216, 217, + /* 1530 */ 193, 216, 217, 193, 53, 152, 193, 59, 23, 19, + /* 1540 */ 25, 216, 217, 61, 216, 217, 23, 70, 25, 71, + /* 1550 */ 59, 116, 193, 216, 217, 78, 216, 217, 81, 216, + /* 1560 */ 217, 59, 71, 85, 193, 23, 193, 25, 90, 23, + /* 1570 */ 23, 25, 25, 7, 8, 98, 85, 193, 100, 193, + /* 1580 */ 59, 90, 142, 141, 106, 107, 193, 216, 217, 216, + /* 1590 */ 217, 100, 114, 193, 116, 117, 118, 106, 107, 121, + /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, + /* 1610 */ 133, 23, 121, 25, 121, 138, 139, 97, 23, 117, + /* 1620 */ 25, 23, 193, 25, 131, 141, 193, 216, 217, 59, + /* 1630 */ 193, 153, 154, 155, 156, 157, 226, 193, 117, 162, + /* 1640 */ 23, 23, 25, 25, 153, 154, 155, 156, 157, 1, + /* 1650 */ 2, 83, 84, 5, 19, 20, 226, 22, 10, 11, + /* 1660 */ 12, 13, 14, 258, 153, 17, 155, 153, 23, 155, + /* 1670 */ 25, 36, 23, 193, 25, 255, 193, 236, 30, 193, + /* 1680 */ 32, 19, 20, 193, 22, 193, 288, 117, 40, 193, + /* 1690 */ 318, 193, 193, 193, 59, 242, 193, 193, 36, 193, + /* 1700 */ 193, 193, 287, 255, 255, 255, 71, 255, 243, 214, + /* 1710 */ 191, 297, 267, 245, 271, 259, 259, 293, 70, 246, + /* 1720 */ 246, 59, 267, 229, 245, 271, 78, 293, 259, 81, + /* 1730 */ 271, 271, 220, 71, 225, 100, 219, 219, 249, 196, + /* 1740 */ 243, 106, 107, 108, 219, 60, 98, 280, 297, 114, + /* 1750 */ 249, 116, 117, 118, 141, 245, 121, 200, 200, 297, + /* 1760 */ 38, 200, 100, 151, 150, 294, 294, 22, 106, 107, + /* 1770 */ 283, 43, 234, 18, 237, 200, 114, 272, 116, 117, + /* 1780 */ 118, 133, 237, 121, 18, 237, 138, 139, 153, 154, + /* 1790 */ 155, 156, 157, 237, 270, 199, 19, 20, 246, 22, + /* 1800 */ 149, 272, 272, 270, 200, 246, 234, 234, 246, 246, + /* 1810 */ 162, 158, 290, 36, 199, 153, 154, 155, 156, 157, + /* 1820 */ 62, 289, 200, 199, 22, 200, 221, 199, 221, 200, + /* 1830 */ 199, 115, 64, 227, 218, 22, 59, 218, 218, 126, + /* 1840 */ 165, 24, 113, 312, 218, 224, 305, 224, 71, 282, + /* 1850 */ 144, 221, 220, 282, 218, 218, 218, 115, 261, 260, + /* 1860 */ 227, 221, 261, 260, 200, 91, 317, 317, 82, 261, + /* 1870 */ 260, 148, 261, 22, 265, 145, 200, 100, 158, 277, + /* 1880 */ 147, 146, 25, 106, 107, 202, 13, 260, 194, 250, + /* 1890 */ 249, 114, 248, 116, 117, 118, 250, 247, 121, 265, + /* 1900 */ 246, 194, 6, 192, 192, 207, 192, 207, 213, 213, + /* 1910 */ 213, 222, 213, 222, 4, 214, 214, 213, 3, 22, + /* 1920 */ 163, 279, 207, 15, 23, 16, 23, 139, 130, 151, + /* 1930 */ 153, 154, 155, 156, 157, 142, 25, 24, 20, 144, + /* 1940 */ 16, 1, 142, 61, 130, 130, 303, 151, 53, 37, + /* 1950 */ 303, 53, 300, 53, 130, 53, 116, 34, 1, 141, + /* 1960 */ 5, 22, 115, 25, 161, 75, 41, 68, 141, 115, + /* 1970 */ 24, 20, 68, 19, 131, 125, 23, 96, 22, 59, + /* 1980 */ 22, 67, 22, 22, 67, 22, 24, 28, 67, 37, + /* 1990 */ 23, 149, 22, 25, 23, 23, 23, 23, 22, 141, + /* 2000 */ 23, 23, 97, 116, 22, 143, 25, 88, 75, 34, + /* 2010 */ 44, 75, 86, 34, 34, 93, 23, 34, 34, 34, + /* 2020 */ 22, 24, 34, 22, 25, 25, 23, 23, 23, 23, + /* 2030 */ 23, 11, 23, 25, 22, 22, 25, 23, 23, 22, + /* 2040 */ 22, 135, 15, 1, 25, 23, 1, 319, 141, 319, + /* 2050 */ 319, 319, 319, 319, 319, 319, 319, 141, 319, 319, + /* 2060 */ 319, 319, 319, 319, 319, 319, 319, 319, 141, 141, + /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2250 */ 319, 319, 319, 319, 319, }; -#define YY_SHIFT_COUNT (571) +#define YY_SHIFT_COUNT (573) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2014) +#define YY_SHIFT_MAX (2045) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1423, 1409, 1454, 1192, 1192, 610, 1252, 1410, 1517, 1684, - /* 10 */ 1684, 1684, 276, 0, 0, 180, 1015, 1684, 1684, 1684, - /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 30 */ 1049, 1049, 1121, 1121, 54, 487, 610, 610, 610, 610, - /* 40 */ 610, 40, 110, 219, 289, 396, 439, 509, 548, 618, - /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015, - /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, - /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684, - /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684, - /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84, - /* 130 */ 84, 84, 84, 277, 315, 401, 97, 461, 251, 66, - /* 140 */ 66, 51, 1156, 66, 66, 324, 324, 66, 452, 452, - /* 150 */ 452, 452, 133, 114, 114, 4, 11, 2037, 2037, 621, - /* 160 */ 621, 621, 567, 398, 398, 398, 398, 937, 937, 228, - /* 170 */ 251, 331, 1052, 66, 66, 66, 66, 66, 66, 66, - /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - /* 190 */ 66, 66, 66, 557, 557, 66, 9, 25, 25, 745, - /* 200 */ 745, 967, 1088, 2037, 2037, 2037, 2037, 2037, 2037, 2037, - /* 210 */ 255, 317, 317, 514, 403, 620, 471, 672, 781, 891, - /* 220 */ 675, 66, 66, 66, 66, 66, 66, 66, 66, 66, - /* 230 */ 66, 508, 66, 66, 66, 66, 66, 66, 66, 66, - /* 240 */ 66, 66, 66, 66, 790, 790, 790, 66, 66, 66, - /* 250 */ 338, 66, 66, 66, 516, 1084, 66, 66, 993, 66, - /* 260 */ 66, 66, 66, 66, 66, 66, 66, 732, 1083, 563, - /* 270 */ 994, 994, 994, 994, 337, 563, 563, 1028, 987, 897, - /* 280 */ 1119, 262, 1214, 1271, 1112, 1214, 1112, 1268, 1239, 262, - /* 290 */ 262, 1239, 262, 1271, 1268, 1302, 1354, 1278, 1168, 1168, - /* 300 */ 1168, 1112, 1303, 1303, 815, 1311, 1264, 1364, 1657, 1657, - /* 310 */ 1595, 1595, 1701, 1701, 1595, 1592, 1596, 1724, 1706, 1730, - /* 320 */ 1730, 1730, 1730, 1595, 1735, 1614, 1596, 1596, 1614, 1724, - /* 330 */ 1706, 1614, 1706, 1614, 1595, 1735, 1621, 1717, 1595, 1735, - /* 340 */ 1758, 1595, 1735, 1595, 1735, 1758, 1679, 1679, 1679, 1734, - /* 350 */ 1781, 1781, 1758, 1679, 1689, 1679, 1734, 1679, 1679, 1645, - /* 360 */ 1791, 1715, 1715, 1758, 1690, 1718, 1690, 1718, 1690, 1718, - /* 370 */ 1690, 1718, 1595, 1751, 1751, 1762, 1762, 1699, 1703, 1826, - /* 380 */ 1595, 1695, 1699, 1707, 1710, 1614, 1847, 1863, 1863, 1871, - /* 390 */ 1871, 1871, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, - /* 400 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 193, 837, 1194, - /* 410 */ 1212, 506, 832, 1054, 1390, 925, 1435, 1394, 1102, 1332, - /* 420 */ 1419, 1196, 1420, 1425, 1433, 1447, 1457, 1488, 1443, 1379, - /* 430 */ 1572, 1455, 1503, 1453, 1495, 1515, 1506, 1526, 1460, 1489, - /* 440 */ 1581, 1622, 1534, 667, 1888, 1893, 1875, 1736, 1884, 1885, - /* 450 */ 1877, 1879, 1765, 1754, 1776, 1881, 1881, 1883, 1767, 1889, - /* 460 */ 1768, 1894, 1911, 1772, 1788, 1881, 1789, 1858, 1886, 1881, - /* 470 */ 1770, 1868, 1869, 1872, 1873, 1795, 1812, 1895, 1790, 1927, - /* 480 */ 1926, 1910, 1819, 1774, 1867, 1912, 1870, 1861, 1898, 1800, - /* 490 */ 1827, 1918, 1923, 1925, 1815, 1822, 1928, 1880, 1929, 1930, - /* 500 */ 1931, 1933, 1882, 1897, 1924, 1857, 1932, 1935, 1891, 1922, - /* 510 */ 1938, 1814, 1941, 1942, 1943, 1944, 1939, 1945, 1947, 1874, - /* 520 */ 1830, 1949, 1950, 1859, 1946, 1953, 1834, 1952, 1948, 1951, - /* 530 */ 1954, 1955, 1890, 1904, 1900, 1937, 1908, 1899, 1956, 1961, - /* 540 */ 1965, 1967, 1968, 1969, 1962, 1972, 1952, 1974, 1975, 1976, - /* 550 */ 1977, 1978, 1979, 1982, 1990, 1983, 1984, 1985, 1986, 1988, - /* 560 */ 1989, 1987, 1887, 1876, 1878, 1892, 1896, 1992, 1991, 1998, - /* 570 */ 2006, 2014, + /* 0 */ 1648, 1477, 1272, 322, 322, 262, 1319, 1478, 1491, 1662, + /* 10 */ 1662, 1662, 317, 0, 0, 214, 1093, 1662, 1662, 1662, + /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 30 */ 271, 271, 1219, 1219, 216, 88, 262, 262, 262, 262, + /* 40 */ 262, 40, 111, 258, 361, 469, 512, 583, 622, 693, + /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, + /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662, + /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662, + /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181, + /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366, + /* 140 */ 475, 475, 629, 1058, 475, 475, 125, 125, 475, 686, + /* 150 */ 686, 686, 660, 686, 57, 184, 184, 77, 77, 2070, + /* 160 */ 2070, 328, 328, 328, 493, 373, 373, 373, 373, 1015, + /* 170 */ 1015, 409, 366, 1129, 1149, 475, 475, 475, 475, 475, + /* 180 */ 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, + /* 190 */ 475, 475, 475, 475, 475, 621, 621, 475, 852, 899, + /* 200 */ 899, 1295, 1295, 406, 851, 2070, 2070, 2070, 2070, 2070, + /* 210 */ 2070, 2070, 1307, 954, 954, 640, 464, 695, 238, 700, + /* 220 */ 538, 541, 748, 475, 475, 475, 475, 475, 475, 475, + /* 230 */ 475, 475, 475, 634, 475, 475, 475, 475, 475, 475, + /* 240 */ 475, 475, 475, 475, 475, 475, 1175, 1175, 1175, 475, + /* 250 */ 475, 475, 580, 475, 475, 475, 1074, 1142, 475, 475, + /* 260 */ 1072, 475, 475, 475, 475, 475, 475, 475, 475, 797, + /* 270 */ 1330, 740, 1131, 1131, 1131, 1131, 1069, 740, 740, 1209, + /* 280 */ 167, 926, 1391, 1038, 1314, 187, 1408, 1314, 1408, 1435, + /* 290 */ 1109, 1038, 1038, 1109, 1038, 187, 1435, 227, 1090, 941, + /* 300 */ 1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440, 513, 1461, + /* 310 */ 1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745, + /* 320 */ 1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614, + /* 330 */ 1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758, + /* 340 */ 1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716, + /* 350 */ 1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716, + /* 360 */ 1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742, + /* 370 */ 1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723, + /* 380 */ 1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873, + /* 390 */ 1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070, + /* 400 */ 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 207, + /* 410 */ 915, 1010, 1030, 1217, 910, 1170, 1470, 1368, 1481, 1442, + /* 420 */ 1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595, + /* 430 */ 1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618, + /* 440 */ 1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757, + /* 450 */ 1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913, + /* 460 */ 1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882, + /* 470 */ 1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923, + /* 480 */ 1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890, + /* 490 */ 1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914, + /* 500 */ 1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963, + /* 510 */ 1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974, + /* 520 */ 1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981, + /* 530 */ 1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922, + /* 540 */ 1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004, + /* 550 */ 2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014, + /* 560 */ 2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019, + /* 570 */ 2022, 2027, 2042, 2045, }; -#define YY_REDUCE_COUNT (406) -#define YY_REDUCE_MIN (-272) -#define YY_REDUCE_MAX (1693) +#define YY_REDUCE_COUNT (408) +#define YY_REDUCE_MIN (-267) +#define YY_REDUCE_MAX (1715) static const short yy_reduce_ofst[] = { - /* 0 */ 109, 113, 272, 760, -178, -176, -192, -183, -180, -134, - /* 10 */ 213, 220, 371, -208, -205, -272, -197, 611, 632, 765, - /* 20 */ 786, 392, 943, 989, 503, 651, 1039, -18, 702, 821, - /* 30 */ 710, 812, -188, 380, -187, 555, 662, 1055, 1063, 1065, - /* 40 */ 1080, -267, -267, -267, -267, -267, -267, -267, -267, -267, - /* 50 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, - /* 60 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267, - /* 70 */ -267, -267, -267, -267, -267, -267, -267, -267, 636, 811, - /* 80 */ 917, 936, 1006, 1008, 1017, 1060, 1064, 1069, 1075, 1105, - /* 90 */ 1118, 1123, 1125, 1134, 1140, 1159, 1165, 1169, 1174, 1179, - /* 100 */ 1181, 1184, 1186, 1201, 1246, 1259, 1262, 1281, 1293, 1299, - /* 110 */ 1313, 1327, 1341, 1352, 1356, 1358, 1362, 1366, 1395, 1403, - /* 120 */ 1406, 1411, 1424, 1436, 1439, 1450, 1452, -267, -267, -267, - /* 130 */ -267, -267, -267, -267, -267, 224, -267, 446, -24, 275, - /* 140 */ 546, 518, 573, 560, 53, -181, -111, 485, 606, 671, - /* 150 */ 606, 671, 683, 8, 93, -267, -267, -267, -267, 155, - /* 160 */ 155, 155, 181, 242, 264, 486, 489, -218, 393, 227, - /* 170 */ 604, 347, 347, -171, 431, 650, 715, -166, 562, 609, - /* 180 */ 716, 764, 18, 823, 769, 833, 838, 957, 759, 119, - /* 190 */ 923, 226, 1014, 542, 603, 451, 949, 654, 659, 762, - /* 200 */ 964, -4, 778, 961, 712, 1082, 1100, 1111, 1026, 1117, - /* 210 */ -204, -174, -151, -8, 77, 198, 305, 327, 388, 540, - /* 220 */ 839, 968, 982, 985, 1004, 1023, 1070, 1086, 1097, 1130, - /* 230 */ 1190, 1163, 1199, 1284, 1297, 1300, 1314, 1339, 1353, 1391, - /* 240 */ 1402, 1413, 1416, 1417, 803, 1376, 1400, 1428, 1437, 1446, - /* 250 */ 1378, 1461, 1464, 1465, 1249, 1329, 1466, 1467, 1414, 1468, - /* 260 */ 305, 1469, 1470, 1471, 1472, 1482, 1483, 1389, 1392, 1438, - /* 270 */ 1426, 1427, 1432, 1434, 1378, 1438, 1438, 1440, 1474, 1499, - /* 280 */ 1399, 1421, 1430, 1456, 1441, 1442, 1444, 1415, 1473, 1431, - /* 290 */ 1445, 1476, 1449, 1478, 1418, 1479, 1477, 1485, 1493, 1494, - /* 300 */ 1496, 1458, 1475, 1480, 1459, 1490, 1484, 1518, 1448, 1451, - /* 310 */ 1537, 1538, 1463, 1481, 1541, 1486, 1487, 1491, 1519, 1514, - /* 320 */ 1521, 1523, 1525, 1552, 1556, 1520, 1492, 1498, 1522, 1497, - /* 330 */ 1539, 1528, 1542, 1532, 1571, 1573, 1500, 1504, 1582, 1584, - /* 340 */ 1563, 1586, 1588, 1589, 1597, 1567, 1579, 1585, 1590, 1568, - /* 350 */ 1583, 1587, 1593, 1591, 1598, 1599, 1600, 1602, 1606, 1513, - /* 360 */ 1524, 1548, 1549, 1611, 1574, 1576, 1594, 1603, 1604, 1607, - /* 370 */ 1605, 1608, 1642, 1527, 1529, 1609, 1610, 1601, 1615, 1575, - /* 380 */ 1650, 1578, 1619, 1623, 1625, 1624, 1674, 1685, 1686, 1691, - /* 390 */ 1692, 1693, 1612, 1613, 1617, 1675, 1668, 1673, 1676, 1677, - /* 400 */ 1680, 1666, 1669, 1678, 1681, 1683, 1687, + /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, + /* 10 */ -180, 83, 133, -207, -198, -267, -175, -6, 166, 313, + /* 20 */ 487, 396, 489, 598, 615, 685, 687, 79, 781, 857, + /* 30 */ 490, 616, 240, 334, -188, 796, 841, 843, 1003, 1005, + /* 40 */ 1007, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 50 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 60 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 70 */ -260, -260, -260, -260, -260, -260, -260, -260, 158, 203, + /* 80 */ 391, 576, 724, 726, 886, 1021, 1035, 1063, 1081, 1083, + /* 90 */ 1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169, + /* 100 */ 1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236, + /* 110 */ 1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328, + /* 120 */ 1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260, + /* 130 */ -260, -260, -260, -260, -260, -260, -260, -53, 138, 302, + /* 140 */ -158, 357, 223, -222, 411, 458, -92, 556, 669, 581, + /* 150 */ 632, 581, -260, 632, 758, 778, 920, -260, -260, -260, + /* 160 */ -260, 161, 161, 161, 307, 234, 392, 526, 790, 195, + /* 170 */ 359, -174, -173, 362, 362, -189, 16, 560, 567, 261, + /* 180 */ 689, 802, 853, -122, -166, 408, 335, 617, 690, 837, + /* 190 */ 1001, 746, 1061, 515, 1082, 994, 1034, -135, 1000, 1048, + /* 200 */ 1137, 877, 897, 186, 627, 1031, 1133, 1148, 1159, 1194, + /* 210 */ 1199, 1195, -194, -142, 18, -152, 68, 201, 253, 269, + /* 220 */ 294, 354, 521, 528, 676, 680, 736, 743, 850, 907, + /* 230 */ 1041, 1047, 1060, 727, 1139, 1147, 1201, 1237, 1278, 1359, + /* 240 */ 1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444, + /* 250 */ 1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498, + /* 260 */ 1441, 1499, 253, 1500, 1503, 1504, 1506, 1507, 1508, 1398, + /* 270 */ 1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465, + /* 280 */ 1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424, + /* 290 */ 1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509, + /* 300 */ 1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543, + /* 310 */ 1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524, + /* 320 */ 1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530, + /* 330 */ 1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532, + /* 340 */ 1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619, + /* 350 */ 1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637, + /* 360 */ 1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603, + /* 370 */ 1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639, + /* 380 */ 1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694, + /* 390 */ 1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696, + /* 400 */ 1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1633, 1633, 1633, 1462, 1230, 1341, 1230, 1230, 1230, 1462, - /* 10 */ 1462, 1462, 1230, 1371, 1371, 1515, 1263, 1230, 1230, 1230, - /* 20 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1461, 1230, 1230, - /* 30 */ 1230, 1230, 1550, 1550, 1230, 1230, 1230, 1230, 1230, 1230, - /* 40 */ 1230, 1230, 1380, 1230, 1387, 1230, 1230, 1230, 1230, 1230, - /* 50 */ 1463, 1464, 1230, 1230, 1230, 1514, 1516, 1479, 1394, 1393, - /* 60 */ 1392, 1391, 1497, 1358, 1385, 1378, 1382, 1457, 1458, 1456, - /* 70 */ 1460, 1464, 1463, 1230, 1381, 1428, 1442, 1427, 1230, 1230, - /* 80 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 90 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 100 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 110 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 120 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1436, 1441, 1447, - /* 130 */ 1440, 1437, 1430, 1429, 1431, 1230, 1432, 1230, 1254, 1230, - /* 140 */ 1230, 1251, 1305, 1230, 1230, 1230, 1230, 1230, 1534, 1533, - /* 150 */ 1230, 1230, 1263, 1422, 1421, 1433, 1434, 1444, 1443, 1522, - /* 160 */ 1586, 1585, 1480, 1230, 1230, 1230, 1230, 1230, 1230, 1550, - /* 170 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 180 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 190 */ 1230, 1230, 1230, 1550, 1550, 1230, 1263, 1550, 1550, 1259, - /* 200 */ 1259, 1365, 1230, 1529, 1332, 1332, 1332, 1332, 1341, 1332, - /* 210 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 220 */ 1230, 1230, 1230, 1230, 1230, 1519, 1517, 1230, 1230, 1230, - /* 230 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 240 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 250 */ 1230, 1230, 1230, 1230, 1337, 1230, 1230, 1230, 1230, 1230, - /* 260 */ 1230, 1230, 1230, 1230, 1230, 1230, 1579, 1230, 1492, 1319, - /* 270 */ 1337, 1337, 1337, 1337, 1339, 1320, 1318, 1331, 1264, 1237, - /* 280 */ 1625, 1397, 1386, 1338, 1360, 1386, 1360, 1622, 1384, 1397, - /* 290 */ 1397, 1384, 1397, 1338, 1622, 1280, 1602, 1275, 1371, 1371, - /* 300 */ 1371, 1360, 1365, 1365, 1459, 1338, 1331, 1230, 1625, 1625, - /* 310 */ 1346, 1346, 1624, 1624, 1346, 1480, 1609, 1406, 1308, 1314, - /* 320 */ 1314, 1314, 1314, 1346, 1248, 1384, 1609, 1609, 1384, 1406, - /* 330 */ 1308, 1384, 1308, 1384, 1346, 1248, 1496, 1619, 1346, 1248, - /* 340 */ 1470, 1346, 1248, 1346, 1248, 1470, 1306, 1306, 1306, 1295, - /* 350 */ 1230, 1230, 1470, 1306, 1280, 1306, 1295, 1306, 1306, 1568, - /* 360 */ 1230, 1474, 1474, 1470, 1364, 1359, 1364, 1359, 1364, 1359, - /* 370 */ 1364, 1359, 1346, 1560, 1560, 1374, 1374, 1379, 1365, 1465, - /* 380 */ 1346, 1230, 1379, 1377, 1375, 1384, 1298, 1582, 1582, 1578, - /* 390 */ 1578, 1578, 1630, 1630, 1529, 1595, 1263, 1263, 1263, 1263, - /* 400 */ 1595, 1282, 1282, 1264, 1264, 1263, 1595, 1230, 1230, 1230, - /* 410 */ 1230, 1230, 1230, 1590, 1230, 1524, 1481, 1350, 1230, 1230, - /* 420 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 430 */ 1230, 1230, 1535, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 440 */ 1230, 1230, 1230, 1411, 1230, 1233, 1526, 1230, 1230, 1230, - /* 450 */ 1230, 1230, 1230, 1230, 1230, 1388, 1389, 1351, 1230, 1230, - /* 460 */ 1230, 1230, 1230, 1230, 1230, 1403, 1230, 1230, 1230, 1398, - /* 470 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1621, 1230, - /* 480 */ 1230, 1230, 1230, 1230, 1230, 1495, 1494, 1230, 1230, 1348, - /* 490 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 500 */ 1230, 1230, 1230, 1278, 1230, 1230, 1230, 1230, 1230, 1230, - /* 510 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 520 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1376, 1230, 1230, - /* 530 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 540 */ 1230, 1230, 1565, 1366, 1230, 1230, 1612, 1230, 1230, 1230, - /* 550 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, - /* 560 */ 1230, 1606, 1322, 1413, 1230, 1412, 1416, 1252, 1230, 1242, - /* 570 */ 1230, 1230, + /* 0 */ 1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466, + /* 10 */ 1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233, + /* 20 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233, + /* 30 */ 1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233, + /* 40 */ 1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233, + /* 50 */ 1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396, + /* 60 */ 1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460, + /* 70 */ 1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233, + /* 80 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 90 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 100 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 110 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 120 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444, + /* 130 */ 1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257, + /* 140 */ 1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538, + /* 150 */ 1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447, + /* 160 */ 1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233, + /* 170 */ 1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 180 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 190 */ 1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554, + /* 200 */ 1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335, + /* 210 */ 1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 220 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233, + /* 230 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 240 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 250 */ 1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233, + /* 260 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233, + /* 270 */ 1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334, + /* 280 */ 1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626, + /* 290 */ 1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278, + /* 300 */ 1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233, + /* 310 */ 1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409, + /* 320 */ 1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613, + /* 330 */ 1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623, + /* 340 */ 1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309, + /* 350 */ 1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309, + /* 360 */ 1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362, + /* 370 */ 1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382, + /* 380 */ 1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586, + /* 390 */ 1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266, + /* 400 */ 1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233, + /* 410 */ 1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353, + /* 420 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 430 */ 1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233, + /* 440 */ 1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233, + /* 450 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354, + /* 460 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233, + /* 470 */ 1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 480 */ 1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233, + /* 490 */ 1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 500 */ 1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233, + /* 510 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 520 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379, + /* 530 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 540 */ 1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233, + /* 550 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 560 */ 1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255, + /* 570 */ 1233, 1245, 1233, 1233, }; /********** End of lemon-generated parsing tables *****************************/ @@ -160751,6 +162728,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* SLASH => nothing */ 0, /* REM => nothing */ 0, /* CONCAT => nothing */ + 0, /* PTR => nothing */ 0, /* COLLATE => nothing */ 0, /* BITNOT => nothing */ 0, /* ON => nothing */ @@ -161023,212 +163001,213 @@ static const char *const yyTokenName[] = { /* 109 */ "SLASH", /* 110 */ "REM", /* 111 */ "CONCAT", - /* 112 */ "COLLATE", - /* 113 */ "BITNOT", - /* 114 */ "ON", - /* 115 */ "INDEXED", - /* 116 */ "STRING", - /* 117 */ "JOIN_KW", - /* 118 */ "CONSTRAINT", - /* 119 */ "DEFAULT", - /* 120 */ "NULL", - /* 121 */ "PRIMARY", - /* 122 */ "UNIQUE", - /* 123 */ "CHECK", - /* 124 */ "REFERENCES", - /* 125 */ "AUTOINCR", - /* 126 */ "INSERT", - /* 127 */ "DELETE", - /* 128 */ "UPDATE", - /* 129 */ "SET", - /* 130 */ "DEFERRABLE", - /* 131 */ "FOREIGN", - /* 132 */ "DROP", - /* 133 */ "UNION", - /* 134 */ "ALL", - /* 135 */ "EXCEPT", - /* 136 */ "INTERSECT", - /* 137 */ "SELECT", - /* 138 */ "VALUES", - /* 139 */ "DISTINCT", - /* 140 */ "DOT", - /* 141 */ "FROM", - /* 142 */ "JOIN", - /* 143 */ "USING", - /* 144 */ "ORDER", - /* 145 */ "GROUP", - /* 146 */ "HAVING", - /* 147 */ "LIMIT", - /* 148 */ "WHERE", - /* 149 */ "RETURNING", - /* 150 */ "INTO", - /* 151 */ "NOTHING", - /* 152 */ "FLOAT", - /* 153 */ "BLOB", - /* 154 */ "INTEGER", - /* 155 */ "VARIABLE", - /* 156 */ "CASE", - /* 157 */ "WHEN", - /* 158 */ "THEN", - /* 159 */ "ELSE", - /* 160 */ "INDEX", - /* 161 */ "ALTER", - /* 162 */ "ADD", - /* 163 */ "WINDOW", - /* 164 */ "OVER", - /* 165 */ "FILTER", - /* 166 */ "COLUMN", - /* 167 */ "AGG_FUNCTION", - /* 168 */ "AGG_COLUMN", - /* 169 */ "TRUEFALSE", - /* 170 */ "ISNOT", - /* 171 */ "FUNCTION", - /* 172 */ "UMINUS", - /* 173 */ "UPLUS", - /* 174 */ "TRUTH", - /* 175 */ "REGISTER", - /* 176 */ "VECTOR", - /* 177 */ "SELECT_COLUMN", - /* 178 */ "IF_NULL_ROW", - /* 179 */ "ASTERISK", - /* 180 */ "SPAN", - /* 181 */ "ERROR", - /* 182 */ "SPACE", - /* 183 */ "ILLEGAL", - /* 184 */ "input", - /* 185 */ "cmdlist", - /* 186 */ "ecmd", - /* 187 */ "cmdx", - /* 188 */ "explain", - /* 189 */ "cmd", - /* 190 */ "transtype", - /* 191 */ "trans_opt", - /* 192 */ "nm", - /* 193 */ "savepoint_opt", - /* 194 */ "create_table", - /* 195 */ "create_table_args", - /* 196 */ "createkw", - /* 197 */ "temp", - /* 198 */ "ifnotexists", - /* 199 */ "dbnm", - /* 200 */ "columnlist", - /* 201 */ "conslist_opt", - /* 202 */ "table_option_set", - /* 203 */ "select", - /* 204 */ "table_option", - /* 205 */ "columnname", - /* 206 */ "carglist", - /* 207 */ "typetoken", - /* 208 */ "typename", - /* 209 */ "signed", - /* 210 */ "plus_num", - /* 211 */ "minus_num", - /* 212 */ "scanpt", - /* 213 */ "scantok", - /* 214 */ "ccons", - /* 215 */ "term", - /* 216 */ "expr", - /* 217 */ "onconf", - /* 218 */ "sortorder", - /* 219 */ "autoinc", - /* 220 */ "eidlist_opt", - /* 221 */ "refargs", - /* 222 */ "defer_subclause", - /* 223 */ "generated", - /* 224 */ "refarg", - /* 225 */ "refact", - /* 226 */ "init_deferred_pred_opt", - /* 227 */ "conslist", - /* 228 */ "tconscomma", - /* 229 */ "tcons", - /* 230 */ "sortlist", - /* 231 */ "eidlist", - /* 232 */ "defer_subclause_opt", - /* 233 */ "orconf", - /* 234 */ "resolvetype", - /* 235 */ "raisetype", - /* 236 */ "ifexists", - /* 237 */ "fullname", - /* 238 */ "selectnowith", - /* 239 */ "oneselect", - /* 240 */ "wqlist", - /* 241 */ "multiselect_op", - /* 242 */ "distinct", - /* 243 */ "selcollist", - /* 244 */ "from", - /* 245 */ "where_opt", - /* 246 */ "groupby_opt", - /* 247 */ "having_opt", - /* 248 */ "orderby_opt", - /* 249 */ "limit_opt", - /* 250 */ "window_clause", - /* 251 */ "values", - /* 252 */ "nexprlist", - /* 253 */ "sclp", - /* 254 */ "as", - /* 255 */ "seltablist", - /* 256 */ "stl_prefix", - /* 257 */ "joinop", - /* 258 */ "indexed_opt", - /* 259 */ "on_opt", - /* 260 */ "using_opt", - /* 261 */ "exprlist", - /* 262 */ "xfullname", - /* 263 */ "idlist", - /* 264 */ "nulls", - /* 265 */ "with", - /* 266 */ "where_opt_ret", - /* 267 */ "setlist", - /* 268 */ "insert_cmd", - /* 269 */ "idlist_opt", - /* 270 */ "upsert", - /* 271 */ "returning", - /* 272 */ "filter_over", - /* 273 */ "likeop", - /* 274 */ "between_op", - /* 275 */ "in_op", - /* 276 */ "paren_exprlist", - /* 277 */ "case_operand", - /* 278 */ "case_exprlist", - /* 279 */ "case_else", - /* 280 */ "uniqueflag", - /* 281 */ "collate", - /* 282 */ "vinto", - /* 283 */ "nmnum", - /* 284 */ "trigger_decl", - /* 285 */ "trigger_cmd_list", - /* 286 */ "trigger_time", - /* 287 */ "trigger_event", - /* 288 */ "foreach_clause", - /* 289 */ "when_clause", - /* 290 */ "trigger_cmd", - /* 291 */ "trnm", - /* 292 */ "tridxby", - /* 293 */ "database_kw_opt", - /* 294 */ "key_opt", - /* 295 */ "add_column_fullname", - /* 296 */ "kwcolumn_opt", - /* 297 */ "create_vtab", - /* 298 */ "vtabarglist", - /* 299 */ "vtabarg", - /* 300 */ "vtabargtoken", - /* 301 */ "lp", - /* 302 */ "anylist", - /* 303 */ "wqitem", - /* 304 */ "wqas", - /* 305 */ "windowdefn_list", - /* 306 */ "windowdefn", - /* 307 */ "window", - /* 308 */ "frame_opt", - /* 309 */ "part_opt", - /* 310 */ "filter_clause", - /* 311 */ "over_clause", - /* 312 */ "range_or_rows", - /* 313 */ "frame_bound", - /* 314 */ "frame_bound_s", - /* 315 */ "frame_bound_e", - /* 316 */ "frame_exclude_opt", - /* 317 */ "frame_exclude", + /* 112 */ "PTR", + /* 113 */ "COLLATE", + /* 114 */ "BITNOT", + /* 115 */ "ON", + /* 116 */ "INDEXED", + /* 117 */ "STRING", + /* 118 */ "JOIN_KW", + /* 119 */ "CONSTRAINT", + /* 120 */ "DEFAULT", + /* 121 */ "NULL", + /* 122 */ "PRIMARY", + /* 123 */ "UNIQUE", + /* 124 */ "CHECK", + /* 125 */ "REFERENCES", + /* 126 */ "AUTOINCR", + /* 127 */ "INSERT", + /* 128 */ "DELETE", + /* 129 */ "UPDATE", + /* 130 */ "SET", + /* 131 */ "DEFERRABLE", + /* 132 */ "FOREIGN", + /* 133 */ "DROP", + /* 134 */ "UNION", + /* 135 */ "ALL", + /* 136 */ "EXCEPT", + /* 137 */ "INTERSECT", + /* 138 */ "SELECT", + /* 139 */ "VALUES", + /* 140 */ "DISTINCT", + /* 141 */ "DOT", + /* 142 */ "FROM", + /* 143 */ "JOIN", + /* 144 */ "USING", + /* 145 */ "ORDER", + /* 146 */ "GROUP", + /* 147 */ "HAVING", + /* 148 */ "LIMIT", + /* 149 */ "WHERE", + /* 150 */ "RETURNING", + /* 151 */ "INTO", + /* 152 */ "NOTHING", + /* 153 */ "FLOAT", + /* 154 */ "BLOB", + /* 155 */ "INTEGER", + /* 156 */ "VARIABLE", + /* 157 */ "CASE", + /* 158 */ "WHEN", + /* 159 */ "THEN", + /* 160 */ "ELSE", + /* 161 */ "INDEX", + /* 162 */ "ALTER", + /* 163 */ "ADD", + /* 164 */ "WINDOW", + /* 165 */ "OVER", + /* 166 */ "FILTER", + /* 167 */ "COLUMN", + /* 168 */ "AGG_FUNCTION", + /* 169 */ "AGG_COLUMN", + /* 170 */ "TRUEFALSE", + /* 171 */ "ISNOT", + /* 172 */ "FUNCTION", + /* 173 */ "UMINUS", + /* 174 */ "UPLUS", + /* 175 */ "TRUTH", + /* 176 */ "REGISTER", + /* 177 */ "VECTOR", + /* 178 */ "SELECT_COLUMN", + /* 179 */ "IF_NULL_ROW", + /* 180 */ "ASTERISK", + /* 181 */ "SPAN", + /* 182 */ "ERROR", + /* 183 */ "SPACE", + /* 184 */ "ILLEGAL", + /* 185 */ "input", + /* 186 */ "cmdlist", + /* 187 */ "ecmd", + /* 188 */ "cmdx", + /* 189 */ "explain", + /* 190 */ "cmd", + /* 191 */ "transtype", + /* 192 */ "trans_opt", + /* 193 */ "nm", + /* 194 */ "savepoint_opt", + /* 195 */ "create_table", + /* 196 */ "create_table_args", + /* 197 */ "createkw", + /* 198 */ "temp", + /* 199 */ "ifnotexists", + /* 200 */ "dbnm", + /* 201 */ "columnlist", + /* 202 */ "conslist_opt", + /* 203 */ "table_option_set", + /* 204 */ "select", + /* 205 */ "table_option", + /* 206 */ "columnname", + /* 207 */ "carglist", + /* 208 */ "typetoken", + /* 209 */ "typename", + /* 210 */ "signed", + /* 211 */ "plus_num", + /* 212 */ "minus_num", + /* 213 */ "scanpt", + /* 214 */ "scantok", + /* 215 */ "ccons", + /* 216 */ "term", + /* 217 */ "expr", + /* 218 */ "onconf", + /* 219 */ "sortorder", + /* 220 */ "autoinc", + /* 221 */ "eidlist_opt", + /* 222 */ "refargs", + /* 223 */ "defer_subclause", + /* 224 */ "generated", + /* 225 */ "refarg", + /* 226 */ "refact", + /* 227 */ "init_deferred_pred_opt", + /* 228 */ "conslist", + /* 229 */ "tconscomma", + /* 230 */ "tcons", + /* 231 */ "sortlist", + /* 232 */ "eidlist", + /* 233 */ "defer_subclause_opt", + /* 234 */ "orconf", + /* 235 */ "resolvetype", + /* 236 */ "raisetype", + /* 237 */ "ifexists", + /* 238 */ "fullname", + /* 239 */ "selectnowith", + /* 240 */ "oneselect", + /* 241 */ "wqlist", + /* 242 */ "multiselect_op", + /* 243 */ "distinct", + /* 244 */ "selcollist", + /* 245 */ "from", + /* 246 */ "where_opt", + /* 247 */ "groupby_opt", + /* 248 */ "having_opt", + /* 249 */ "orderby_opt", + /* 250 */ "limit_opt", + /* 251 */ "window_clause", + /* 252 */ "values", + /* 253 */ "nexprlist", + /* 254 */ "sclp", + /* 255 */ "as", + /* 256 */ "seltablist", + /* 257 */ "stl_prefix", + /* 258 */ "joinop", + /* 259 */ "indexed_opt", + /* 260 */ "on_opt", + /* 261 */ "using_opt", + /* 262 */ "exprlist", + /* 263 */ "xfullname", + /* 264 */ "idlist", + /* 265 */ "nulls", + /* 266 */ "with", + /* 267 */ "where_opt_ret", + /* 268 */ "setlist", + /* 269 */ "insert_cmd", + /* 270 */ "idlist_opt", + /* 271 */ "upsert", + /* 272 */ "returning", + /* 273 */ "filter_over", + /* 274 */ "likeop", + /* 275 */ "between_op", + /* 276 */ "in_op", + /* 277 */ "paren_exprlist", + /* 278 */ "case_operand", + /* 279 */ "case_exprlist", + /* 280 */ "case_else", + /* 281 */ "uniqueflag", + /* 282 */ "collate", + /* 283 */ "vinto", + /* 284 */ "nmnum", + /* 285 */ "trigger_decl", + /* 286 */ "trigger_cmd_list", + /* 287 */ "trigger_time", + /* 288 */ "trigger_event", + /* 289 */ "foreach_clause", + /* 290 */ "when_clause", + /* 291 */ "trigger_cmd", + /* 292 */ "trnm", + /* 293 */ "tridxby", + /* 294 */ "database_kw_opt", + /* 295 */ "key_opt", + /* 296 */ "add_column_fullname", + /* 297 */ "kwcolumn_opt", + /* 298 */ "create_vtab", + /* 299 */ "vtabarglist", + /* 300 */ "vtabarg", + /* 301 */ "vtabargtoken", + /* 302 */ "lp", + /* 303 */ "anylist", + /* 304 */ "wqitem", + /* 305 */ "wqas", + /* 306 */ "windowdefn_list", + /* 307 */ "windowdefn", + /* 308 */ "window", + /* 309 */ "frame_opt", + /* 310 */ "part_opt", + /* 311 */ "filter_clause", + /* 312 */ "over_clause", + /* 313 */ "range_or_rows", + /* 314 */ "frame_bound", + /* 315 */ "frame_bound_s", + /* 316 */ "frame_bound_e", + /* 317 */ "frame_exclude_opt", + /* 318 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -161448,195 +163427,196 @@ static const char *const yyRuleName[] = { /* 209 */ "expr ::= NOT expr", /* 210 */ "expr ::= BITNOT expr", /* 211 */ "expr ::= PLUS|MINUS expr", - /* 212 */ "between_op ::= BETWEEN", - /* 213 */ "between_op ::= NOT BETWEEN", - /* 214 */ "expr ::= expr between_op expr AND expr", - /* 215 */ "in_op ::= IN", - /* 216 */ "in_op ::= NOT IN", - /* 217 */ "expr ::= expr in_op LP exprlist RP", - /* 218 */ "expr ::= LP select RP", - /* 219 */ "expr ::= expr in_op LP select RP", - /* 220 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 221 */ "expr ::= EXISTS LP select RP", - /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 224 */ "case_exprlist ::= WHEN expr THEN expr", - /* 225 */ "case_else ::= ELSE expr", - /* 226 */ "case_else ::=", - /* 227 */ "case_operand ::= expr", - /* 228 */ "case_operand ::=", - /* 229 */ "exprlist ::=", - /* 230 */ "nexprlist ::= nexprlist COMMA expr", - /* 231 */ "nexprlist ::= expr", - /* 232 */ "paren_exprlist ::=", - /* 233 */ "paren_exprlist ::= LP exprlist RP", - /* 234 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 235 */ "uniqueflag ::= UNIQUE", - /* 236 */ "uniqueflag ::=", - /* 237 */ "eidlist_opt ::=", - /* 238 */ "eidlist_opt ::= LP eidlist RP", - /* 239 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 240 */ "eidlist ::= nm collate sortorder", - /* 241 */ "collate ::=", - /* 242 */ "collate ::= COLLATE ID|STRING", - /* 243 */ "cmd ::= DROP INDEX ifexists fullname", - /* 244 */ "cmd ::= VACUUM vinto", - /* 245 */ "cmd ::= VACUUM nm vinto", - /* 246 */ "vinto ::= INTO expr", - /* 247 */ "vinto ::=", - /* 248 */ "cmd ::= PRAGMA nm dbnm", - /* 249 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 250 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 251 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 252 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 253 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 254 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 255 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 256 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 257 */ "trigger_time ::= BEFORE|AFTER", - /* 258 */ "trigger_time ::= INSTEAD OF", - /* 259 */ "trigger_time ::=", - /* 260 */ "trigger_event ::= DELETE|INSERT", - /* 261 */ "trigger_event ::= UPDATE", - /* 262 */ "trigger_event ::= UPDATE OF idlist", - /* 263 */ "when_clause ::=", - /* 264 */ "when_clause ::= WHEN expr", - /* 265 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 266 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 267 */ "trnm ::= nm DOT nm", - /* 268 */ "tridxby ::= INDEXED BY nm", - /* 269 */ "tridxby ::= NOT INDEXED", - /* 270 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 271 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 272 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 273 */ "trigger_cmd ::= scanpt select scanpt", - /* 274 */ "expr ::= RAISE LP IGNORE RP", - /* 275 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 276 */ "raisetype ::= ROLLBACK", - /* 277 */ "raisetype ::= ABORT", - /* 278 */ "raisetype ::= FAIL", - /* 279 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 280 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 281 */ "cmd ::= DETACH database_kw_opt expr", - /* 282 */ "key_opt ::=", - /* 283 */ "key_opt ::= KEY expr", - /* 284 */ "cmd ::= REINDEX", - /* 285 */ "cmd ::= REINDEX nm dbnm", - /* 286 */ "cmd ::= ANALYZE", - /* 287 */ "cmd ::= ANALYZE nm dbnm", - /* 288 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 289 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 290 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 291 */ "add_column_fullname ::= fullname", - /* 292 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 293 */ "cmd ::= create_vtab", - /* 294 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 295 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 296 */ "vtabarg ::=", - /* 297 */ "vtabargtoken ::= ANY", - /* 298 */ "vtabargtoken ::= lp anylist RP", - /* 299 */ "lp ::= LP", - /* 300 */ "with ::= WITH wqlist", - /* 301 */ "with ::= WITH RECURSIVE wqlist", - /* 302 */ "wqas ::= AS", - /* 303 */ "wqas ::= AS MATERIALIZED", - /* 304 */ "wqas ::= AS NOT MATERIALIZED", - /* 305 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 306 */ "wqlist ::= wqitem", - /* 307 */ "wqlist ::= wqlist COMMA wqitem", - /* 308 */ "windowdefn_list ::= windowdefn", - /* 309 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 310 */ "windowdefn ::= nm AS LP window RP", - /* 311 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 312 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 313 */ "window ::= ORDER BY sortlist frame_opt", - /* 314 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 315 */ "window ::= frame_opt", - /* 316 */ "window ::= nm frame_opt", - /* 317 */ "frame_opt ::=", - /* 318 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 319 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 320 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 321 */ "frame_bound_s ::= frame_bound", - /* 322 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 323 */ "frame_bound_e ::= frame_bound", - /* 324 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 325 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 326 */ "frame_bound ::= CURRENT ROW", - /* 327 */ "frame_exclude_opt ::=", - /* 328 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 329 */ "frame_exclude ::= NO OTHERS", - /* 330 */ "frame_exclude ::= CURRENT ROW", - /* 331 */ "frame_exclude ::= GROUP|TIES", - /* 332 */ "window_clause ::= WINDOW windowdefn_list", - /* 333 */ "filter_over ::= filter_clause over_clause", - /* 334 */ "filter_over ::= over_clause", - /* 335 */ "filter_over ::= filter_clause", - /* 336 */ "over_clause ::= OVER LP window RP", - /* 337 */ "over_clause ::= OVER nm", - /* 338 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 339 */ "input ::= cmdlist", - /* 340 */ "cmdlist ::= cmdlist ecmd", - /* 341 */ "cmdlist ::= ecmd", - /* 342 */ "ecmd ::= SEMI", - /* 343 */ "ecmd ::= cmdx SEMI", - /* 344 */ "ecmd ::= explain cmdx SEMI", - /* 345 */ "trans_opt ::=", - /* 346 */ "trans_opt ::= TRANSACTION", - /* 347 */ "trans_opt ::= TRANSACTION nm", - /* 348 */ "savepoint_opt ::= SAVEPOINT", - /* 349 */ "savepoint_opt ::=", - /* 350 */ "cmd ::= create_table create_table_args", - /* 351 */ "table_option_set ::= table_option", - /* 352 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 353 */ "columnlist ::= columnname carglist", - /* 354 */ "nm ::= ID|INDEXED", - /* 355 */ "nm ::= STRING", - /* 356 */ "nm ::= JOIN_KW", - /* 357 */ "typetoken ::= typename", - /* 358 */ "typename ::= ID|STRING", - /* 359 */ "signed ::= plus_num", - /* 360 */ "signed ::= minus_num", - /* 361 */ "carglist ::= carglist ccons", - /* 362 */ "carglist ::=", - /* 363 */ "ccons ::= NULL onconf", - /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 365 */ "ccons ::= AS generated", - /* 366 */ "conslist_opt ::= COMMA conslist", - /* 367 */ "conslist ::= conslist tconscomma tcons", - /* 368 */ "conslist ::= tcons", - /* 369 */ "tconscomma ::=", - /* 370 */ "defer_subclause_opt ::= defer_subclause", - /* 371 */ "resolvetype ::= raisetype", - /* 372 */ "selectnowith ::= oneselect", - /* 373 */ "oneselect ::= values", - /* 374 */ "sclp ::= selcollist COMMA", - /* 375 */ "as ::= ID|STRING", - /* 376 */ "returning ::=", - /* 377 */ "expr ::= term", - /* 378 */ "likeop ::= LIKE_KW|MATCH", - /* 379 */ "exprlist ::= nexprlist", - /* 380 */ "nmnum ::= plus_num", - /* 381 */ "nmnum ::= nm", - /* 382 */ "nmnum ::= ON", - /* 383 */ "nmnum ::= DELETE", - /* 384 */ "nmnum ::= DEFAULT", - /* 385 */ "plus_num ::= INTEGER|FLOAT", - /* 386 */ "foreach_clause ::=", - /* 387 */ "foreach_clause ::= FOR EACH ROW", - /* 388 */ "trnm ::= nm", - /* 389 */ "tridxby ::=", - /* 390 */ "database_kw_opt ::= DATABASE", - /* 391 */ "database_kw_opt ::=", - /* 392 */ "kwcolumn_opt ::=", - /* 393 */ "kwcolumn_opt ::= COLUMNKW", - /* 394 */ "vtabarglist ::= vtabarg", - /* 395 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 396 */ "vtabarg ::= vtabarg vtabargtoken", - /* 397 */ "anylist ::=", - /* 398 */ "anylist ::= anylist LP anylist RP", - /* 399 */ "anylist ::= anylist ANY", - /* 400 */ "with ::=", + /* 212 */ "expr ::= expr PTR expr", + /* 213 */ "between_op ::= BETWEEN", + /* 214 */ "between_op ::= NOT BETWEEN", + /* 215 */ "expr ::= expr between_op expr AND expr", + /* 216 */ "in_op ::= IN", + /* 217 */ "in_op ::= NOT IN", + /* 218 */ "expr ::= expr in_op LP exprlist RP", + /* 219 */ "expr ::= LP select RP", + /* 220 */ "expr ::= expr in_op LP select RP", + /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 222 */ "expr ::= EXISTS LP select RP", + /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 225 */ "case_exprlist ::= WHEN expr THEN expr", + /* 226 */ "case_else ::= ELSE expr", + /* 227 */ "case_else ::=", + /* 228 */ "case_operand ::= expr", + /* 229 */ "case_operand ::=", + /* 230 */ "exprlist ::=", + /* 231 */ "nexprlist ::= nexprlist COMMA expr", + /* 232 */ "nexprlist ::= expr", + /* 233 */ "paren_exprlist ::=", + /* 234 */ "paren_exprlist ::= LP exprlist RP", + /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 236 */ "uniqueflag ::= UNIQUE", + /* 237 */ "uniqueflag ::=", + /* 238 */ "eidlist_opt ::=", + /* 239 */ "eidlist_opt ::= LP eidlist RP", + /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 241 */ "eidlist ::= nm collate sortorder", + /* 242 */ "collate ::=", + /* 243 */ "collate ::= COLLATE ID|STRING", + /* 244 */ "cmd ::= DROP INDEX ifexists fullname", + /* 245 */ "cmd ::= VACUUM vinto", + /* 246 */ "cmd ::= VACUUM nm vinto", + /* 247 */ "vinto ::= INTO expr", + /* 248 */ "vinto ::=", + /* 249 */ "cmd ::= PRAGMA nm dbnm", + /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 258 */ "trigger_time ::= BEFORE|AFTER", + /* 259 */ "trigger_time ::= INSTEAD OF", + /* 260 */ "trigger_time ::=", + /* 261 */ "trigger_event ::= DELETE|INSERT", + /* 262 */ "trigger_event ::= UPDATE", + /* 263 */ "trigger_event ::= UPDATE OF idlist", + /* 264 */ "when_clause ::=", + /* 265 */ "when_clause ::= WHEN expr", + /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 268 */ "trnm ::= nm DOT nm", + /* 269 */ "tridxby ::= INDEXED BY nm", + /* 270 */ "tridxby ::= NOT INDEXED", + /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt select scanpt", + /* 275 */ "expr ::= RAISE LP IGNORE RP", + /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 277 */ "raisetype ::= ROLLBACK", + /* 278 */ "raisetype ::= ABORT", + /* 279 */ "raisetype ::= FAIL", + /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 282 */ "cmd ::= DETACH database_kw_opt expr", + /* 283 */ "key_opt ::=", + /* 284 */ "key_opt ::= KEY expr", + /* 285 */ "cmd ::= REINDEX", + /* 286 */ "cmd ::= REINDEX nm dbnm", + /* 287 */ "cmd ::= ANALYZE", + /* 288 */ "cmd ::= ANALYZE nm dbnm", + /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 292 */ "add_column_fullname ::= fullname", + /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 294 */ "cmd ::= create_vtab", + /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 297 */ "vtabarg ::=", + /* 298 */ "vtabargtoken ::= ANY", + /* 299 */ "vtabargtoken ::= lp anylist RP", + /* 300 */ "lp ::= LP", + /* 301 */ "with ::= WITH wqlist", + /* 302 */ "with ::= WITH RECURSIVE wqlist", + /* 303 */ "wqas ::= AS", + /* 304 */ "wqas ::= AS MATERIALIZED", + /* 305 */ "wqas ::= AS NOT MATERIALIZED", + /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 307 */ "wqlist ::= wqitem", + /* 308 */ "wqlist ::= wqlist COMMA wqitem", + /* 309 */ "windowdefn_list ::= windowdefn", + /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 311 */ "windowdefn ::= nm AS LP window RP", + /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 314 */ "window ::= ORDER BY sortlist frame_opt", + /* 315 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 316 */ "window ::= frame_opt", + /* 317 */ "window ::= nm frame_opt", + /* 318 */ "frame_opt ::=", + /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 322 */ "frame_bound_s ::= frame_bound", + /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 324 */ "frame_bound_e ::= frame_bound", + /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 327 */ "frame_bound ::= CURRENT ROW", + /* 328 */ "frame_exclude_opt ::=", + /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 330 */ "frame_exclude ::= NO OTHERS", + /* 331 */ "frame_exclude ::= CURRENT ROW", + /* 332 */ "frame_exclude ::= GROUP|TIES", + /* 333 */ "window_clause ::= WINDOW windowdefn_list", + /* 334 */ "filter_over ::= filter_clause over_clause", + /* 335 */ "filter_over ::= over_clause", + /* 336 */ "filter_over ::= filter_clause", + /* 337 */ "over_clause ::= OVER LP window RP", + /* 338 */ "over_clause ::= OVER nm", + /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 340 */ "input ::= cmdlist", + /* 341 */ "cmdlist ::= cmdlist ecmd", + /* 342 */ "cmdlist ::= ecmd", + /* 343 */ "ecmd ::= SEMI", + /* 344 */ "ecmd ::= cmdx SEMI", + /* 345 */ "ecmd ::= explain cmdx SEMI", + /* 346 */ "trans_opt ::=", + /* 347 */ "trans_opt ::= TRANSACTION", + /* 348 */ "trans_opt ::= TRANSACTION nm", + /* 349 */ "savepoint_opt ::= SAVEPOINT", + /* 350 */ "savepoint_opt ::=", + /* 351 */ "cmd ::= create_table create_table_args", + /* 352 */ "table_option_set ::= table_option", + /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 354 */ "columnlist ::= columnname carglist", + /* 355 */ "nm ::= ID|INDEXED", + /* 356 */ "nm ::= STRING", + /* 357 */ "nm ::= JOIN_KW", + /* 358 */ "typetoken ::= typename", + /* 359 */ "typename ::= ID|STRING", + /* 360 */ "signed ::= plus_num", + /* 361 */ "signed ::= minus_num", + /* 362 */ "carglist ::= carglist ccons", + /* 363 */ "carglist ::=", + /* 364 */ "ccons ::= NULL onconf", + /* 365 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 366 */ "ccons ::= AS generated", + /* 367 */ "conslist_opt ::= COMMA conslist", + /* 368 */ "conslist ::= conslist tconscomma tcons", + /* 369 */ "conslist ::= tcons", + /* 370 */ "tconscomma ::=", + /* 371 */ "defer_subclause_opt ::= defer_subclause", + /* 372 */ "resolvetype ::= raisetype", + /* 373 */ "selectnowith ::= oneselect", + /* 374 */ "oneselect ::= values", + /* 375 */ "sclp ::= selcollist COMMA", + /* 376 */ "as ::= ID|STRING", + /* 377 */ "returning ::=", + /* 378 */ "expr ::= term", + /* 379 */ "likeop ::= LIKE_KW|MATCH", + /* 380 */ "exprlist ::= nexprlist", + /* 381 */ "nmnum ::= plus_num", + /* 382 */ "nmnum ::= nm", + /* 383 */ "nmnum ::= ON", + /* 384 */ "nmnum ::= DELETE", + /* 385 */ "nmnum ::= DEFAULT", + /* 386 */ "plus_num ::= INTEGER|FLOAT", + /* 387 */ "foreach_clause ::=", + /* 388 */ "foreach_clause ::= FOR EACH ROW", + /* 389 */ "trnm ::= nm", + /* 390 */ "tridxby ::=", + /* 391 */ "database_kw_opt ::= DATABASE", + /* 392 */ "database_kw_opt ::=", + /* 393 */ "kwcolumn_opt ::=", + /* 394 */ "kwcolumn_opt ::= COLUMNKW", + /* 395 */ "vtabarglist ::= vtabarg", + /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 397 */ "vtabarg ::= vtabarg vtabargtoken", + /* 398 */ "anylist ::=", + /* 399 */ "anylist ::= anylist LP anylist RP", + /* 400 */ "anylist ::= anylist ANY", + /* 401 */ "with ::=", }; #endif /* NDEBUG */ @@ -161762,99 +163742,99 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 203: /* select */ - case 238: /* selectnowith */ - case 239: /* oneselect */ - case 251: /* values */ + case 204: /* select */ + case 239: /* selectnowith */ + case 240: /* oneselect */ + case 252: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy303)); -} - break; - case 215: /* term */ - case 216: /* expr */ - case 245: /* where_opt */ - case 247: /* having_opt */ - case 259: /* on_opt */ - case 266: /* where_opt_ret */ - case 277: /* case_operand */ - case 279: /* case_else */ - case 282: /* vinto */ - case 289: /* when_clause */ - case 294: /* key_opt */ - case 310: /* filter_clause */ +sqlite3SelectDelete(pParse->db, (yypminor->yy47)); +} + break; + case 216: /* term */ + case 217: /* expr */ + case 246: /* where_opt */ + case 248: /* having_opt */ + case 260: /* on_opt */ + case 267: /* where_opt_ret */ + case 278: /* case_operand */ + case 280: /* case_else */ + case 283: /* vinto */ + case 290: /* when_clause */ + case 295: /* key_opt */ + case 311: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy626)); -} - break; - case 220: /* eidlist_opt */ - case 230: /* sortlist */ - case 231: /* eidlist */ - case 243: /* selcollist */ - case 246: /* groupby_opt */ - case 248: /* orderby_opt */ - case 252: /* nexprlist */ - case 253: /* sclp */ - case 261: /* exprlist */ - case 267: /* setlist */ - case 276: /* paren_exprlist */ - case 278: /* case_exprlist */ - case 309: /* part_opt */ +sqlite3ExprDelete(pParse->db, (yypminor->yy528)); +} + break; + case 221: /* eidlist_opt */ + case 231: /* sortlist */ + case 232: /* eidlist */ + case 244: /* selcollist */ + case 247: /* groupby_opt */ + case 249: /* orderby_opt */ + case 253: /* nexprlist */ + case 254: /* sclp */ + case 262: /* exprlist */ + case 268: /* setlist */ + case 277: /* paren_exprlist */ + case 279: /* case_exprlist */ + case 310: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy562)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); } break; - case 237: /* fullname */ - case 244: /* from */ - case 255: /* seltablist */ - case 256: /* stl_prefix */ - case 262: /* xfullname */ + case 238: /* fullname */ + case 245: /* from */ + case 256: /* seltablist */ + case 257: /* stl_prefix */ + case 263: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy607)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); } break; - case 240: /* wqlist */ + case 241: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy43)); +sqlite3WithDelete(pParse->db, (yypminor->yy521)); } break; - case 250: /* window_clause */ - case 305: /* windowdefn_list */ + case 251: /* window_clause */ + case 306: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy375)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); } break; - case 260: /* using_opt */ - case 263: /* idlist */ - case 269: /* idlist_opt */ + case 261: /* using_opt */ + case 264: /* idlist */ + case 270: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy240)); +sqlite3IdListDelete(pParse->db, (yypminor->yy254)); } break; - case 272: /* filter_over */ - case 306: /* windowdefn */ - case 307: /* window */ - case 308: /* frame_opt */ - case 311: /* over_clause */ + case 273: /* filter_over */ + case 307: /* windowdefn */ + case 308: /* window */ + case 309: /* frame_opt */ + case 312: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy375)); +sqlite3WindowDelete(pParse->db, (yypminor->yy41)); } break; - case 285: /* trigger_cmd_list */ - case 290: /* trigger_cmd */ + case 286: /* trigger_cmd_list */ + case 291: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy95)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); } break; - case 287: /* trigger_event */ + case 288: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy570).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); } break; - case 313: /* frame_bound */ - case 314: /* frame_bound_s */ - case 315: /* frame_bound_e */ + case 314: /* frame_bound */ + case 315: /* frame_bound_s */ + case 316: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy81).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -162145,407 +164125,408 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 188, /* (0) explain ::= EXPLAIN */ - 188, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 187, /* (2) cmdx ::= cmd */ - 189, /* (3) cmd ::= BEGIN transtype trans_opt */ - 190, /* (4) transtype ::= */ - 190, /* (5) transtype ::= DEFERRED */ - 190, /* (6) transtype ::= IMMEDIATE */ - 190, /* (7) transtype ::= EXCLUSIVE */ - 189, /* (8) cmd ::= COMMIT|END trans_opt */ - 189, /* (9) cmd ::= ROLLBACK trans_opt */ - 189, /* (10) cmd ::= SAVEPOINT nm */ - 189, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 189, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 194, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 196, /* (14) createkw ::= CREATE */ - 198, /* (15) ifnotexists ::= */ - 198, /* (16) ifnotexists ::= IF NOT EXISTS */ - 197, /* (17) temp ::= TEMP */ - 197, /* (18) temp ::= */ - 195, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ - 195, /* (20) create_table_args ::= AS select */ - 202, /* (21) table_option_set ::= */ - 202, /* (22) table_option_set ::= table_option_set COMMA table_option */ - 204, /* (23) table_option ::= WITHOUT nm */ - 204, /* (24) table_option ::= nm */ - 205, /* (25) columnname ::= nm typetoken */ - 207, /* (26) typetoken ::= */ - 207, /* (27) typetoken ::= typename LP signed RP */ - 207, /* (28) typetoken ::= typename LP signed COMMA signed RP */ - 208, /* (29) typename ::= typename ID|STRING */ - 212, /* (30) scanpt ::= */ - 213, /* (31) scantok ::= */ - 214, /* (32) ccons ::= CONSTRAINT nm */ - 214, /* (33) ccons ::= DEFAULT scantok term */ - 214, /* (34) ccons ::= DEFAULT LP expr RP */ - 214, /* (35) ccons ::= DEFAULT PLUS scantok term */ - 214, /* (36) ccons ::= DEFAULT MINUS scantok term */ - 214, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ - 214, /* (38) ccons ::= NOT NULL onconf */ - 214, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 214, /* (40) ccons ::= UNIQUE onconf */ - 214, /* (41) ccons ::= CHECK LP expr RP */ - 214, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ - 214, /* (43) ccons ::= defer_subclause */ - 214, /* (44) ccons ::= COLLATE ID|STRING */ - 223, /* (45) generated ::= LP expr RP */ - 223, /* (46) generated ::= LP expr RP ID */ - 219, /* (47) autoinc ::= */ - 219, /* (48) autoinc ::= AUTOINCR */ - 221, /* (49) refargs ::= */ - 221, /* (50) refargs ::= refargs refarg */ - 224, /* (51) refarg ::= MATCH nm */ - 224, /* (52) refarg ::= ON INSERT refact */ - 224, /* (53) refarg ::= ON DELETE refact */ - 224, /* (54) refarg ::= ON UPDATE refact */ - 225, /* (55) refact ::= SET NULL */ - 225, /* (56) refact ::= SET DEFAULT */ - 225, /* (57) refact ::= CASCADE */ - 225, /* (58) refact ::= RESTRICT */ - 225, /* (59) refact ::= NO ACTION */ - 222, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 222, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 226, /* (62) init_deferred_pred_opt ::= */ - 226, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 226, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 201, /* (65) conslist_opt ::= */ - 228, /* (66) tconscomma ::= COMMA */ - 229, /* (67) tcons ::= CONSTRAINT nm */ - 229, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 229, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ - 229, /* (70) tcons ::= CHECK LP expr RP onconf */ - 229, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 232, /* (72) defer_subclause_opt ::= */ - 217, /* (73) onconf ::= */ - 217, /* (74) onconf ::= ON CONFLICT resolvetype */ - 233, /* (75) orconf ::= */ - 233, /* (76) orconf ::= OR resolvetype */ - 234, /* (77) resolvetype ::= IGNORE */ - 234, /* (78) resolvetype ::= REPLACE */ - 189, /* (79) cmd ::= DROP TABLE ifexists fullname */ - 236, /* (80) ifexists ::= IF EXISTS */ - 236, /* (81) ifexists ::= */ - 189, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 189, /* (83) cmd ::= DROP VIEW ifexists fullname */ - 189, /* (84) cmd ::= select */ - 203, /* (85) select ::= WITH wqlist selectnowith */ - 203, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ - 203, /* (87) select ::= selectnowith */ - 238, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ - 241, /* (89) multiselect_op ::= UNION */ - 241, /* (90) multiselect_op ::= UNION ALL */ - 241, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ - 239, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 239, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 251, /* (94) values ::= VALUES LP nexprlist RP */ - 251, /* (95) values ::= values COMMA LP nexprlist RP */ - 242, /* (96) distinct ::= DISTINCT */ - 242, /* (97) distinct ::= ALL */ - 242, /* (98) distinct ::= */ - 253, /* (99) sclp ::= */ - 243, /* (100) selcollist ::= sclp scanpt expr scanpt as */ - 243, /* (101) selcollist ::= sclp scanpt STAR */ - 243, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ - 254, /* (103) as ::= AS nm */ - 254, /* (104) as ::= */ - 244, /* (105) from ::= */ - 244, /* (106) from ::= FROM seltablist */ - 256, /* (107) stl_prefix ::= seltablist joinop */ - 256, /* (108) stl_prefix ::= */ - 255, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - 255, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - 255, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - 255, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 199, /* (113) dbnm ::= */ - 199, /* (114) dbnm ::= DOT nm */ - 237, /* (115) fullname ::= nm */ - 237, /* (116) fullname ::= nm DOT nm */ - 262, /* (117) xfullname ::= nm */ - 262, /* (118) xfullname ::= nm DOT nm */ - 262, /* (119) xfullname ::= nm DOT nm AS nm */ - 262, /* (120) xfullname ::= nm AS nm */ - 257, /* (121) joinop ::= COMMA|JOIN */ - 257, /* (122) joinop ::= JOIN_KW JOIN */ - 257, /* (123) joinop ::= JOIN_KW nm JOIN */ - 257, /* (124) joinop ::= JOIN_KW nm nm JOIN */ - 259, /* (125) on_opt ::= ON expr */ - 259, /* (126) on_opt ::= */ - 258, /* (127) indexed_opt ::= */ - 258, /* (128) indexed_opt ::= INDEXED BY nm */ - 258, /* (129) indexed_opt ::= NOT INDEXED */ - 260, /* (130) using_opt ::= USING LP idlist RP */ - 260, /* (131) using_opt ::= */ - 248, /* (132) orderby_opt ::= */ - 248, /* (133) orderby_opt ::= ORDER BY sortlist */ - 230, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ - 230, /* (135) sortlist ::= expr sortorder nulls */ - 218, /* (136) sortorder ::= ASC */ - 218, /* (137) sortorder ::= DESC */ - 218, /* (138) sortorder ::= */ - 264, /* (139) nulls ::= NULLS FIRST */ - 264, /* (140) nulls ::= NULLS LAST */ - 264, /* (141) nulls ::= */ - 246, /* (142) groupby_opt ::= */ - 246, /* (143) groupby_opt ::= GROUP BY nexprlist */ - 247, /* (144) having_opt ::= */ - 247, /* (145) having_opt ::= HAVING expr */ - 249, /* (146) limit_opt ::= */ - 249, /* (147) limit_opt ::= LIMIT expr */ - 249, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ - 249, /* (149) limit_opt ::= LIMIT expr COMMA expr */ - 189, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 245, /* (151) where_opt ::= */ - 245, /* (152) where_opt ::= WHERE expr */ - 266, /* (153) where_opt_ret ::= */ - 266, /* (154) where_opt_ret ::= WHERE expr */ - 266, /* (155) where_opt_ret ::= RETURNING selcollist */ - 266, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ - 189, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - 267, /* (158) setlist ::= setlist COMMA nm EQ expr */ - 267, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 267, /* (160) setlist ::= nm EQ expr */ - 267, /* (161) setlist ::= LP idlist RP EQ expr */ - 189, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 189, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 270, /* (164) upsert ::= */ - 270, /* (165) upsert ::= RETURNING selcollist */ - 270, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - 270, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - 270, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ - 270, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - 271, /* (170) returning ::= RETURNING selcollist */ - 268, /* (171) insert_cmd ::= INSERT orconf */ - 268, /* (172) insert_cmd ::= REPLACE */ - 269, /* (173) idlist_opt ::= */ - 269, /* (174) idlist_opt ::= LP idlist RP */ - 263, /* (175) idlist ::= idlist COMMA nm */ - 263, /* (176) idlist ::= nm */ - 216, /* (177) expr ::= LP expr RP */ - 216, /* (178) expr ::= ID|INDEXED */ - 216, /* (179) expr ::= JOIN_KW */ - 216, /* (180) expr ::= nm DOT nm */ - 216, /* (181) expr ::= nm DOT nm DOT nm */ - 215, /* (182) term ::= NULL|FLOAT|BLOB */ - 215, /* (183) term ::= STRING */ - 215, /* (184) term ::= INTEGER */ - 216, /* (185) expr ::= VARIABLE */ - 216, /* (186) expr ::= expr COLLATE ID|STRING */ - 216, /* (187) expr ::= CAST LP expr AS typetoken RP */ - 216, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ - 216, /* (189) expr ::= ID|INDEXED LP STAR RP */ - 216, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - 216, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ - 215, /* (192) term ::= CTIME_KW */ - 216, /* (193) expr ::= LP nexprlist COMMA expr RP */ - 216, /* (194) expr ::= expr AND expr */ - 216, /* (195) expr ::= expr OR expr */ - 216, /* (196) expr ::= expr LT|GT|GE|LE expr */ - 216, /* (197) expr ::= expr EQ|NE expr */ - 216, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 216, /* (199) expr ::= expr PLUS|MINUS expr */ - 216, /* (200) expr ::= expr STAR|SLASH|REM expr */ - 216, /* (201) expr ::= expr CONCAT expr */ - 273, /* (202) likeop ::= NOT LIKE_KW|MATCH */ - 216, /* (203) expr ::= expr likeop expr */ - 216, /* (204) expr ::= expr likeop expr ESCAPE expr */ - 216, /* (205) expr ::= expr ISNULL|NOTNULL */ - 216, /* (206) expr ::= expr NOT NULL */ - 216, /* (207) expr ::= expr IS expr */ - 216, /* (208) expr ::= expr IS NOT expr */ - 216, /* (209) expr ::= NOT expr */ - 216, /* (210) expr ::= BITNOT expr */ - 216, /* (211) expr ::= PLUS|MINUS expr */ - 274, /* (212) between_op ::= BETWEEN */ - 274, /* (213) between_op ::= NOT BETWEEN */ - 216, /* (214) expr ::= expr between_op expr AND expr */ - 275, /* (215) in_op ::= IN */ - 275, /* (216) in_op ::= NOT IN */ - 216, /* (217) expr ::= expr in_op LP exprlist RP */ - 216, /* (218) expr ::= LP select RP */ - 216, /* (219) expr ::= expr in_op LP select RP */ - 216, /* (220) expr ::= expr in_op nm dbnm paren_exprlist */ - 216, /* (221) expr ::= EXISTS LP select RP */ - 216, /* (222) expr ::= CASE case_operand case_exprlist case_else END */ - 278, /* (223) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 278, /* (224) case_exprlist ::= WHEN expr THEN expr */ - 279, /* (225) case_else ::= ELSE expr */ - 279, /* (226) case_else ::= */ - 277, /* (227) case_operand ::= expr */ - 277, /* (228) case_operand ::= */ - 261, /* (229) exprlist ::= */ - 252, /* (230) nexprlist ::= nexprlist COMMA expr */ - 252, /* (231) nexprlist ::= expr */ - 276, /* (232) paren_exprlist ::= */ - 276, /* (233) paren_exprlist ::= LP exprlist RP */ - 189, /* (234) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 280, /* (235) uniqueflag ::= UNIQUE */ - 280, /* (236) uniqueflag ::= */ - 220, /* (237) eidlist_opt ::= */ - 220, /* (238) eidlist_opt ::= LP eidlist RP */ - 231, /* (239) eidlist ::= eidlist COMMA nm collate sortorder */ - 231, /* (240) eidlist ::= nm collate sortorder */ - 281, /* (241) collate ::= */ - 281, /* (242) collate ::= COLLATE ID|STRING */ - 189, /* (243) cmd ::= DROP INDEX ifexists fullname */ - 189, /* (244) cmd ::= VACUUM vinto */ - 189, /* (245) cmd ::= VACUUM nm vinto */ - 282, /* (246) vinto ::= INTO expr */ - 282, /* (247) vinto ::= */ - 189, /* (248) cmd ::= PRAGMA nm dbnm */ - 189, /* (249) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 189, /* (250) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 189, /* (251) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 189, /* (252) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 210, /* (253) plus_num ::= PLUS INTEGER|FLOAT */ - 211, /* (254) minus_num ::= MINUS INTEGER|FLOAT */ - 189, /* (255) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 284, /* (256) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 286, /* (257) trigger_time ::= BEFORE|AFTER */ - 286, /* (258) trigger_time ::= INSTEAD OF */ - 286, /* (259) trigger_time ::= */ - 287, /* (260) trigger_event ::= DELETE|INSERT */ - 287, /* (261) trigger_event ::= UPDATE */ - 287, /* (262) trigger_event ::= UPDATE OF idlist */ - 289, /* (263) when_clause ::= */ - 289, /* (264) when_clause ::= WHEN expr */ - 285, /* (265) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 285, /* (266) trigger_cmd_list ::= trigger_cmd SEMI */ - 291, /* (267) trnm ::= nm DOT nm */ - 292, /* (268) tridxby ::= INDEXED BY nm */ - 292, /* (269) tridxby ::= NOT INDEXED */ - 290, /* (270) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 290, /* (271) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 290, /* (272) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 290, /* (273) trigger_cmd ::= scanpt select scanpt */ - 216, /* (274) expr ::= RAISE LP IGNORE RP */ - 216, /* (275) expr ::= RAISE LP raisetype COMMA nm RP */ - 235, /* (276) raisetype ::= ROLLBACK */ - 235, /* (277) raisetype ::= ABORT */ - 235, /* (278) raisetype ::= FAIL */ - 189, /* (279) cmd ::= DROP TRIGGER ifexists fullname */ - 189, /* (280) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 189, /* (281) cmd ::= DETACH database_kw_opt expr */ - 294, /* (282) key_opt ::= */ - 294, /* (283) key_opt ::= KEY expr */ - 189, /* (284) cmd ::= REINDEX */ - 189, /* (285) cmd ::= REINDEX nm dbnm */ - 189, /* (286) cmd ::= ANALYZE */ - 189, /* (287) cmd ::= ANALYZE nm dbnm */ - 189, /* (288) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 189, /* (289) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 189, /* (290) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 295, /* (291) add_column_fullname ::= fullname */ - 189, /* (292) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 189, /* (293) cmd ::= create_vtab */ - 189, /* (294) cmd ::= create_vtab LP vtabarglist RP */ - 297, /* (295) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 299, /* (296) vtabarg ::= */ - 300, /* (297) vtabargtoken ::= ANY */ - 300, /* (298) vtabargtoken ::= lp anylist RP */ - 301, /* (299) lp ::= LP */ - 265, /* (300) with ::= WITH wqlist */ - 265, /* (301) with ::= WITH RECURSIVE wqlist */ - 304, /* (302) wqas ::= AS */ - 304, /* (303) wqas ::= AS MATERIALIZED */ - 304, /* (304) wqas ::= AS NOT MATERIALIZED */ - 303, /* (305) wqitem ::= nm eidlist_opt wqas LP select RP */ - 240, /* (306) wqlist ::= wqitem */ - 240, /* (307) wqlist ::= wqlist COMMA wqitem */ - 305, /* (308) windowdefn_list ::= windowdefn */ - 305, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 306, /* (310) windowdefn ::= nm AS LP window RP */ - 307, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 307, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 307, /* (313) window ::= ORDER BY sortlist frame_opt */ - 307, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - 307, /* (315) window ::= frame_opt */ - 307, /* (316) window ::= nm frame_opt */ - 308, /* (317) frame_opt ::= */ - 308, /* (318) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 308, /* (319) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 312, /* (320) range_or_rows ::= RANGE|ROWS|GROUPS */ - 314, /* (321) frame_bound_s ::= frame_bound */ - 314, /* (322) frame_bound_s ::= UNBOUNDED PRECEDING */ - 315, /* (323) frame_bound_e ::= frame_bound */ - 315, /* (324) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 313, /* (325) frame_bound ::= expr PRECEDING|FOLLOWING */ - 313, /* (326) frame_bound ::= CURRENT ROW */ - 316, /* (327) frame_exclude_opt ::= */ - 316, /* (328) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 317, /* (329) frame_exclude ::= NO OTHERS */ - 317, /* (330) frame_exclude ::= CURRENT ROW */ - 317, /* (331) frame_exclude ::= GROUP|TIES */ - 250, /* (332) window_clause ::= WINDOW windowdefn_list */ - 272, /* (333) filter_over ::= filter_clause over_clause */ - 272, /* (334) filter_over ::= over_clause */ - 272, /* (335) filter_over ::= filter_clause */ - 311, /* (336) over_clause ::= OVER LP window RP */ - 311, /* (337) over_clause ::= OVER nm */ - 310, /* (338) filter_clause ::= FILTER LP WHERE expr RP */ - 184, /* (339) input ::= cmdlist */ - 185, /* (340) cmdlist ::= cmdlist ecmd */ - 185, /* (341) cmdlist ::= ecmd */ - 186, /* (342) ecmd ::= SEMI */ - 186, /* (343) ecmd ::= cmdx SEMI */ - 186, /* (344) ecmd ::= explain cmdx SEMI */ - 191, /* (345) trans_opt ::= */ - 191, /* (346) trans_opt ::= TRANSACTION */ - 191, /* (347) trans_opt ::= TRANSACTION nm */ - 193, /* (348) savepoint_opt ::= SAVEPOINT */ - 193, /* (349) savepoint_opt ::= */ - 189, /* (350) cmd ::= create_table create_table_args */ - 202, /* (351) table_option_set ::= table_option */ - 200, /* (352) columnlist ::= columnlist COMMA columnname carglist */ - 200, /* (353) columnlist ::= columnname carglist */ - 192, /* (354) nm ::= ID|INDEXED */ - 192, /* (355) nm ::= STRING */ - 192, /* (356) nm ::= JOIN_KW */ - 207, /* (357) typetoken ::= typename */ - 208, /* (358) typename ::= ID|STRING */ - 209, /* (359) signed ::= plus_num */ - 209, /* (360) signed ::= minus_num */ - 206, /* (361) carglist ::= carglist ccons */ - 206, /* (362) carglist ::= */ - 214, /* (363) ccons ::= NULL onconf */ - 214, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - 214, /* (365) ccons ::= AS generated */ - 201, /* (366) conslist_opt ::= COMMA conslist */ - 227, /* (367) conslist ::= conslist tconscomma tcons */ - 227, /* (368) conslist ::= tcons */ - 228, /* (369) tconscomma ::= */ - 232, /* (370) defer_subclause_opt ::= defer_subclause */ - 234, /* (371) resolvetype ::= raisetype */ - 238, /* (372) selectnowith ::= oneselect */ - 239, /* (373) oneselect ::= values */ - 253, /* (374) sclp ::= selcollist COMMA */ - 254, /* (375) as ::= ID|STRING */ - 271, /* (376) returning ::= */ - 216, /* (377) expr ::= term */ - 273, /* (378) likeop ::= LIKE_KW|MATCH */ - 261, /* (379) exprlist ::= nexprlist */ - 283, /* (380) nmnum ::= plus_num */ - 283, /* (381) nmnum ::= nm */ - 283, /* (382) nmnum ::= ON */ - 283, /* (383) nmnum ::= DELETE */ - 283, /* (384) nmnum ::= DEFAULT */ - 210, /* (385) plus_num ::= INTEGER|FLOAT */ - 288, /* (386) foreach_clause ::= */ - 288, /* (387) foreach_clause ::= FOR EACH ROW */ - 291, /* (388) trnm ::= nm */ - 292, /* (389) tridxby ::= */ - 293, /* (390) database_kw_opt ::= DATABASE */ - 293, /* (391) database_kw_opt ::= */ - 296, /* (392) kwcolumn_opt ::= */ - 296, /* (393) kwcolumn_opt ::= COLUMNKW */ - 298, /* (394) vtabarglist ::= vtabarg */ - 298, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - 299, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 302, /* (397) anylist ::= */ - 302, /* (398) anylist ::= anylist LP anylist RP */ - 302, /* (399) anylist ::= anylist ANY */ - 265, /* (400) with ::= */ + 189, /* (0) explain ::= EXPLAIN */ + 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 188, /* (2) cmdx ::= cmd */ + 190, /* (3) cmd ::= BEGIN transtype trans_opt */ + 191, /* (4) transtype ::= */ + 191, /* (5) transtype ::= DEFERRED */ + 191, /* (6) transtype ::= IMMEDIATE */ + 191, /* (7) transtype ::= EXCLUSIVE */ + 190, /* (8) cmd ::= COMMIT|END trans_opt */ + 190, /* (9) cmd ::= ROLLBACK trans_opt */ + 190, /* (10) cmd ::= SAVEPOINT nm */ + 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 197, /* (14) createkw ::= CREATE */ + 199, /* (15) ifnotexists ::= */ + 199, /* (16) ifnotexists ::= IF NOT EXISTS */ + 198, /* (17) temp ::= TEMP */ + 198, /* (18) temp ::= */ + 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 196, /* (20) create_table_args ::= AS select */ + 203, /* (21) table_option_set ::= */ + 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 205, /* (23) table_option ::= WITHOUT nm */ + 205, /* (24) table_option ::= nm */ + 206, /* (25) columnname ::= nm typetoken */ + 208, /* (26) typetoken ::= */ + 208, /* (27) typetoken ::= typename LP signed RP */ + 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + 209, /* (29) typename ::= typename ID|STRING */ + 213, /* (30) scanpt ::= */ + 214, /* (31) scantok ::= */ + 215, /* (32) ccons ::= CONSTRAINT nm */ + 215, /* (33) ccons ::= DEFAULT scantok term */ + 215, /* (34) ccons ::= DEFAULT LP expr RP */ + 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ + 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ + 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + 215, /* (38) ccons ::= NOT NULL onconf */ + 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 215, /* (40) ccons ::= UNIQUE onconf */ + 215, /* (41) ccons ::= CHECK LP expr RP */ + 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + 215, /* (43) ccons ::= defer_subclause */ + 215, /* (44) ccons ::= COLLATE ID|STRING */ + 224, /* (45) generated ::= LP expr RP */ + 224, /* (46) generated ::= LP expr RP ID */ + 220, /* (47) autoinc ::= */ + 220, /* (48) autoinc ::= AUTOINCR */ + 222, /* (49) refargs ::= */ + 222, /* (50) refargs ::= refargs refarg */ + 225, /* (51) refarg ::= MATCH nm */ + 225, /* (52) refarg ::= ON INSERT refact */ + 225, /* (53) refarg ::= ON DELETE refact */ + 225, /* (54) refarg ::= ON UPDATE refact */ + 226, /* (55) refact ::= SET NULL */ + 226, /* (56) refact ::= SET DEFAULT */ + 226, /* (57) refact ::= CASCADE */ + 226, /* (58) refact ::= RESTRICT */ + 226, /* (59) refact ::= NO ACTION */ + 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 227, /* (62) init_deferred_pred_opt ::= */ + 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 202, /* (65) conslist_opt ::= */ + 229, /* (66) tconscomma ::= COMMA */ + 230, /* (67) tcons ::= CONSTRAINT nm */ + 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + 230, /* (70) tcons ::= CHECK LP expr RP onconf */ + 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 233, /* (72) defer_subclause_opt ::= */ + 218, /* (73) onconf ::= */ + 218, /* (74) onconf ::= ON CONFLICT resolvetype */ + 234, /* (75) orconf ::= */ + 234, /* (76) orconf ::= OR resolvetype */ + 235, /* (77) resolvetype ::= IGNORE */ + 235, /* (78) resolvetype ::= REPLACE */ + 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ + 237, /* (80) ifexists ::= IF EXISTS */ + 237, /* (81) ifexists ::= */ + 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ + 190, /* (84) cmd ::= select */ + 204, /* (85) select ::= WITH wqlist selectnowith */ + 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + 204, /* (87) select ::= selectnowith */ + 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + 242, /* (89) multiselect_op ::= UNION */ + 242, /* (90) multiselect_op ::= UNION ALL */ + 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 252, /* (94) values ::= VALUES LP nexprlist RP */ + 252, /* (95) values ::= values COMMA LP nexprlist RP */ + 243, /* (96) distinct ::= DISTINCT */ + 243, /* (97) distinct ::= ALL */ + 243, /* (98) distinct ::= */ + 254, /* (99) sclp ::= */ + 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ + 244, /* (101) selcollist ::= sclp scanpt STAR */ + 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ + 255, /* (103) as ::= AS nm */ + 255, /* (104) as ::= */ + 245, /* (105) from ::= */ + 245, /* (106) from ::= FROM seltablist */ + 257, /* (107) stl_prefix ::= seltablist joinop */ + 257, /* (108) stl_prefix ::= */ + 256, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 256, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 256, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 256, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 200, /* (113) dbnm ::= */ + 200, /* (114) dbnm ::= DOT nm */ + 238, /* (115) fullname ::= nm */ + 238, /* (116) fullname ::= nm DOT nm */ + 263, /* (117) xfullname ::= nm */ + 263, /* (118) xfullname ::= nm DOT nm */ + 263, /* (119) xfullname ::= nm DOT nm AS nm */ + 263, /* (120) xfullname ::= nm AS nm */ + 258, /* (121) joinop ::= COMMA|JOIN */ + 258, /* (122) joinop ::= JOIN_KW JOIN */ + 258, /* (123) joinop ::= JOIN_KW nm JOIN */ + 258, /* (124) joinop ::= JOIN_KW nm nm JOIN */ + 260, /* (125) on_opt ::= ON expr */ + 260, /* (126) on_opt ::= */ + 259, /* (127) indexed_opt ::= */ + 259, /* (128) indexed_opt ::= INDEXED BY nm */ + 259, /* (129) indexed_opt ::= NOT INDEXED */ + 261, /* (130) using_opt ::= USING LP idlist RP */ + 261, /* (131) using_opt ::= */ + 249, /* (132) orderby_opt ::= */ + 249, /* (133) orderby_opt ::= ORDER BY sortlist */ + 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ + 231, /* (135) sortlist ::= expr sortorder nulls */ + 219, /* (136) sortorder ::= ASC */ + 219, /* (137) sortorder ::= DESC */ + 219, /* (138) sortorder ::= */ + 265, /* (139) nulls ::= NULLS FIRST */ + 265, /* (140) nulls ::= NULLS LAST */ + 265, /* (141) nulls ::= */ + 247, /* (142) groupby_opt ::= */ + 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ + 248, /* (144) having_opt ::= */ + 248, /* (145) having_opt ::= HAVING expr */ + 250, /* (146) limit_opt ::= */ + 250, /* (147) limit_opt ::= LIMIT expr */ + 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ + 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ + 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 246, /* (151) where_opt ::= */ + 246, /* (152) where_opt ::= WHERE expr */ + 267, /* (153) where_opt_ret ::= */ + 267, /* (154) where_opt_ret ::= WHERE expr */ + 267, /* (155) where_opt_ret ::= RETURNING selcollist */ + 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ + 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 268, /* (160) setlist ::= nm EQ expr */ + 268, /* (161) setlist ::= LP idlist RP EQ expr */ + 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 271, /* (164) upsert ::= */ + 271, /* (165) upsert ::= RETURNING selcollist */ + 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ + 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 272, /* (170) returning ::= RETURNING selcollist */ + 269, /* (171) insert_cmd ::= INSERT orconf */ + 269, /* (172) insert_cmd ::= REPLACE */ + 270, /* (173) idlist_opt ::= */ + 270, /* (174) idlist_opt ::= LP idlist RP */ + 264, /* (175) idlist ::= idlist COMMA nm */ + 264, /* (176) idlist ::= nm */ + 217, /* (177) expr ::= LP expr RP */ + 217, /* (178) expr ::= ID|INDEXED */ + 217, /* (179) expr ::= JOIN_KW */ + 217, /* (180) expr ::= nm DOT nm */ + 217, /* (181) expr ::= nm DOT nm DOT nm */ + 216, /* (182) term ::= NULL|FLOAT|BLOB */ + 216, /* (183) term ::= STRING */ + 216, /* (184) term ::= INTEGER */ + 217, /* (185) expr ::= VARIABLE */ + 217, /* (186) expr ::= expr COLLATE ID|STRING */ + 217, /* (187) expr ::= CAST LP expr AS typetoken RP */ + 217, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + 217, /* (189) expr ::= ID|INDEXED LP STAR RP */ + 217, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 217, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + 216, /* (192) term ::= CTIME_KW */ + 217, /* (193) expr ::= LP nexprlist COMMA expr RP */ + 217, /* (194) expr ::= expr AND expr */ + 217, /* (195) expr ::= expr OR expr */ + 217, /* (196) expr ::= expr LT|GT|GE|LE expr */ + 217, /* (197) expr ::= expr EQ|NE expr */ + 217, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 217, /* (199) expr ::= expr PLUS|MINUS expr */ + 217, /* (200) expr ::= expr STAR|SLASH|REM expr */ + 217, /* (201) expr ::= expr CONCAT expr */ + 274, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + 217, /* (203) expr ::= expr likeop expr */ + 217, /* (204) expr ::= expr likeop expr ESCAPE expr */ + 217, /* (205) expr ::= expr ISNULL|NOTNULL */ + 217, /* (206) expr ::= expr NOT NULL */ + 217, /* (207) expr ::= expr IS expr */ + 217, /* (208) expr ::= expr IS NOT expr */ + 217, /* (209) expr ::= NOT expr */ + 217, /* (210) expr ::= BITNOT expr */ + 217, /* (211) expr ::= PLUS|MINUS expr */ + 217, /* (212) expr ::= expr PTR expr */ + 275, /* (213) between_op ::= BETWEEN */ + 275, /* (214) between_op ::= NOT BETWEEN */ + 217, /* (215) expr ::= expr between_op expr AND expr */ + 276, /* (216) in_op ::= IN */ + 276, /* (217) in_op ::= NOT IN */ + 217, /* (218) expr ::= expr in_op LP exprlist RP */ + 217, /* (219) expr ::= LP select RP */ + 217, /* (220) expr ::= expr in_op LP select RP */ + 217, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + 217, /* (222) expr ::= EXISTS LP select RP */ + 217, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + 279, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 279, /* (225) case_exprlist ::= WHEN expr THEN expr */ + 280, /* (226) case_else ::= ELSE expr */ + 280, /* (227) case_else ::= */ + 278, /* (228) case_operand ::= expr */ + 278, /* (229) case_operand ::= */ + 262, /* (230) exprlist ::= */ + 253, /* (231) nexprlist ::= nexprlist COMMA expr */ + 253, /* (232) nexprlist ::= expr */ + 277, /* (233) paren_exprlist ::= */ + 277, /* (234) paren_exprlist ::= LP exprlist RP */ + 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 281, /* (236) uniqueflag ::= UNIQUE */ + 281, /* (237) uniqueflag ::= */ + 221, /* (238) eidlist_opt ::= */ + 221, /* (239) eidlist_opt ::= LP eidlist RP */ + 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + 232, /* (241) eidlist ::= nm collate sortorder */ + 282, /* (242) collate ::= */ + 282, /* (243) collate ::= COLLATE ID|STRING */ + 190, /* (244) cmd ::= DROP INDEX ifexists fullname */ + 190, /* (245) cmd ::= VACUUM vinto */ + 190, /* (246) cmd ::= VACUUM nm vinto */ + 283, /* (247) vinto ::= INTO expr */ + 283, /* (248) vinto ::= */ + 190, /* (249) cmd ::= PRAGMA nm dbnm */ + 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 287, /* (258) trigger_time ::= BEFORE|AFTER */ + 287, /* (259) trigger_time ::= INSTEAD OF */ + 287, /* (260) trigger_time ::= */ + 288, /* (261) trigger_event ::= DELETE|INSERT */ + 288, /* (262) trigger_event ::= UPDATE */ + 288, /* (263) trigger_event ::= UPDATE OF idlist */ + 290, /* (264) when_clause ::= */ + 290, /* (265) when_clause ::= WHEN expr */ + 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + 292, /* (268) trnm ::= nm DOT nm */ + 293, /* (269) tridxby ::= INDEXED BY nm */ + 293, /* (270) tridxby ::= NOT INDEXED */ + 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 291, /* (274) trigger_cmd ::= scanpt select scanpt */ + 217, /* (275) expr ::= RAISE LP IGNORE RP */ + 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + 236, /* (277) raisetype ::= ROLLBACK */ + 236, /* (278) raisetype ::= ABORT */ + 236, /* (279) raisetype ::= FAIL */ + 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 190, /* (282) cmd ::= DETACH database_kw_opt expr */ + 295, /* (283) key_opt ::= */ + 295, /* (284) key_opt ::= KEY expr */ + 190, /* (285) cmd ::= REINDEX */ + 190, /* (286) cmd ::= REINDEX nm dbnm */ + 190, /* (287) cmd ::= ANALYZE */ + 190, /* (288) cmd ::= ANALYZE nm dbnm */ + 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 296, /* (292) add_column_fullname ::= fullname */ + 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 190, /* (294) cmd ::= create_vtab */ + 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 300, /* (297) vtabarg ::= */ + 301, /* (298) vtabargtoken ::= ANY */ + 301, /* (299) vtabargtoken ::= lp anylist RP */ + 302, /* (300) lp ::= LP */ + 266, /* (301) with ::= WITH wqlist */ + 266, /* (302) with ::= WITH RECURSIVE wqlist */ + 305, /* (303) wqas ::= AS */ + 305, /* (304) wqas ::= AS MATERIALIZED */ + 305, /* (305) wqas ::= AS NOT MATERIALIZED */ + 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + 241, /* (307) wqlist ::= wqitem */ + 241, /* (308) wqlist ::= wqlist COMMA wqitem */ + 306, /* (309) windowdefn_list ::= windowdefn */ + 306, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 307, /* (311) windowdefn ::= nm AS LP window RP */ + 308, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (314) window ::= ORDER BY sortlist frame_opt */ + 308, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + 308, /* (316) window ::= frame_opt */ + 308, /* (317) window ::= nm frame_opt */ + 309, /* (318) frame_opt ::= */ + 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + 315, /* (322) frame_bound_s ::= frame_bound */ + 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + 316, /* (324) frame_bound_e ::= frame_bound */ + 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + 314, /* (327) frame_bound ::= CURRENT ROW */ + 317, /* (328) frame_exclude_opt ::= */ + 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 318, /* (330) frame_exclude ::= NO OTHERS */ + 318, /* (331) frame_exclude ::= CURRENT ROW */ + 318, /* (332) frame_exclude ::= GROUP|TIES */ + 251, /* (333) window_clause ::= WINDOW windowdefn_list */ + 273, /* (334) filter_over ::= filter_clause over_clause */ + 273, /* (335) filter_over ::= over_clause */ + 273, /* (336) filter_over ::= filter_clause */ + 312, /* (337) over_clause ::= OVER LP window RP */ + 312, /* (338) over_clause ::= OVER nm */ + 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + 185, /* (340) input ::= cmdlist */ + 186, /* (341) cmdlist ::= cmdlist ecmd */ + 186, /* (342) cmdlist ::= ecmd */ + 187, /* (343) ecmd ::= SEMI */ + 187, /* (344) ecmd ::= cmdx SEMI */ + 187, /* (345) ecmd ::= explain cmdx SEMI */ + 192, /* (346) trans_opt ::= */ + 192, /* (347) trans_opt ::= TRANSACTION */ + 192, /* (348) trans_opt ::= TRANSACTION nm */ + 194, /* (349) savepoint_opt ::= SAVEPOINT */ + 194, /* (350) savepoint_opt ::= */ + 190, /* (351) cmd ::= create_table create_table_args */ + 203, /* (352) table_option_set ::= table_option */ + 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + 201, /* (354) columnlist ::= columnname carglist */ + 193, /* (355) nm ::= ID|INDEXED */ + 193, /* (356) nm ::= STRING */ + 193, /* (357) nm ::= JOIN_KW */ + 208, /* (358) typetoken ::= typename */ + 209, /* (359) typename ::= ID|STRING */ + 210, /* (360) signed ::= plus_num */ + 210, /* (361) signed ::= minus_num */ + 207, /* (362) carglist ::= carglist ccons */ + 207, /* (363) carglist ::= */ + 215, /* (364) ccons ::= NULL onconf */ + 215, /* (365) ccons ::= GENERATED ALWAYS AS generated */ + 215, /* (366) ccons ::= AS generated */ + 202, /* (367) conslist_opt ::= COMMA conslist */ + 228, /* (368) conslist ::= conslist tconscomma tcons */ + 228, /* (369) conslist ::= tcons */ + 229, /* (370) tconscomma ::= */ + 233, /* (371) defer_subclause_opt ::= defer_subclause */ + 235, /* (372) resolvetype ::= raisetype */ + 239, /* (373) selectnowith ::= oneselect */ + 240, /* (374) oneselect ::= values */ + 254, /* (375) sclp ::= selcollist COMMA */ + 255, /* (376) as ::= ID|STRING */ + 272, /* (377) returning ::= */ + 217, /* (378) expr ::= term */ + 274, /* (379) likeop ::= LIKE_KW|MATCH */ + 262, /* (380) exprlist ::= nexprlist */ + 284, /* (381) nmnum ::= plus_num */ + 284, /* (382) nmnum ::= nm */ + 284, /* (383) nmnum ::= ON */ + 284, /* (384) nmnum ::= DELETE */ + 284, /* (385) nmnum ::= DEFAULT */ + 211, /* (386) plus_num ::= INTEGER|FLOAT */ + 289, /* (387) foreach_clause ::= */ + 289, /* (388) foreach_clause ::= FOR EACH ROW */ + 292, /* (389) trnm ::= nm */ + 293, /* (390) tridxby ::= */ + 294, /* (391) database_kw_opt ::= DATABASE */ + 294, /* (392) database_kw_opt ::= */ + 297, /* (393) kwcolumn_opt ::= */ + 297, /* (394) kwcolumn_opt ::= COLUMNKW */ + 299, /* (395) vtabarglist ::= vtabarg */ + 299, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + 300, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 303, /* (398) anylist ::= */ + 303, /* (399) anylist ::= anylist LP anylist RP */ + 303, /* (400) anylist ::= anylist ANY */ + 266, /* (401) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -162763,195 +164744,196 @@ static const signed char yyRuleInfoNRhs[] = { -2, /* (209) expr ::= NOT expr */ -2, /* (210) expr ::= BITNOT expr */ -2, /* (211) expr ::= PLUS|MINUS expr */ - -1, /* (212) between_op ::= BETWEEN */ - -2, /* (213) between_op ::= NOT BETWEEN */ - -5, /* (214) expr ::= expr between_op expr AND expr */ - -1, /* (215) in_op ::= IN */ - -2, /* (216) in_op ::= NOT IN */ - -5, /* (217) expr ::= expr in_op LP exprlist RP */ - -3, /* (218) expr ::= LP select RP */ - -5, /* (219) expr ::= expr in_op LP select RP */ - -5, /* (220) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (221) expr ::= EXISTS LP select RP */ - -5, /* (222) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (223) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (224) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (225) case_else ::= ELSE expr */ - 0, /* (226) case_else ::= */ - -1, /* (227) case_operand ::= expr */ - 0, /* (228) case_operand ::= */ - 0, /* (229) exprlist ::= */ - -3, /* (230) nexprlist ::= nexprlist COMMA expr */ - -1, /* (231) nexprlist ::= expr */ - 0, /* (232) paren_exprlist ::= */ - -3, /* (233) paren_exprlist ::= LP exprlist RP */ - -12, /* (234) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (235) uniqueflag ::= UNIQUE */ - 0, /* (236) uniqueflag ::= */ - 0, /* (237) eidlist_opt ::= */ - -3, /* (238) eidlist_opt ::= LP eidlist RP */ - -5, /* (239) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (240) eidlist ::= nm collate sortorder */ - 0, /* (241) collate ::= */ - -2, /* (242) collate ::= COLLATE ID|STRING */ - -4, /* (243) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (244) cmd ::= VACUUM vinto */ - -3, /* (245) cmd ::= VACUUM nm vinto */ - -2, /* (246) vinto ::= INTO expr */ - 0, /* (247) vinto ::= */ - -3, /* (248) cmd ::= PRAGMA nm dbnm */ - -5, /* (249) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (250) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (251) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (252) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (253) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (254) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (255) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (256) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (257) trigger_time ::= BEFORE|AFTER */ - -2, /* (258) trigger_time ::= INSTEAD OF */ - 0, /* (259) trigger_time ::= */ - -1, /* (260) trigger_event ::= DELETE|INSERT */ - -1, /* (261) trigger_event ::= UPDATE */ - -3, /* (262) trigger_event ::= UPDATE OF idlist */ - 0, /* (263) when_clause ::= */ - -2, /* (264) when_clause ::= WHEN expr */ - -3, /* (265) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (266) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (267) trnm ::= nm DOT nm */ - -3, /* (268) tridxby ::= INDEXED BY nm */ - -2, /* (269) tridxby ::= NOT INDEXED */ - -9, /* (270) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (271) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (272) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (273) trigger_cmd ::= scanpt select scanpt */ - -4, /* (274) expr ::= RAISE LP IGNORE RP */ - -6, /* (275) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (276) raisetype ::= ROLLBACK */ - -1, /* (277) raisetype ::= ABORT */ - -1, /* (278) raisetype ::= FAIL */ - -4, /* (279) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (280) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (281) cmd ::= DETACH database_kw_opt expr */ - 0, /* (282) key_opt ::= */ - -2, /* (283) key_opt ::= KEY expr */ - -1, /* (284) cmd ::= REINDEX */ - -3, /* (285) cmd ::= REINDEX nm dbnm */ - -1, /* (286) cmd ::= ANALYZE */ - -3, /* (287) cmd ::= ANALYZE nm dbnm */ - -6, /* (288) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (289) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (290) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (291) add_column_fullname ::= fullname */ - -8, /* (292) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (293) cmd ::= create_vtab */ - -4, /* (294) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (295) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (296) vtabarg ::= */ - -1, /* (297) vtabargtoken ::= ANY */ - -3, /* (298) vtabargtoken ::= lp anylist RP */ - -1, /* (299) lp ::= LP */ - -2, /* (300) with ::= WITH wqlist */ - -3, /* (301) with ::= WITH RECURSIVE wqlist */ - -1, /* (302) wqas ::= AS */ - -2, /* (303) wqas ::= AS MATERIALIZED */ - -3, /* (304) wqas ::= AS NOT MATERIALIZED */ - -6, /* (305) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (306) wqlist ::= wqitem */ - -3, /* (307) wqlist ::= wqlist COMMA wqitem */ - -1, /* (308) windowdefn_list ::= windowdefn */ - -3, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (310) windowdefn ::= nm AS LP window RP */ - -5, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (313) window ::= ORDER BY sortlist frame_opt */ - -5, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - -1, /* (315) window ::= frame_opt */ - -2, /* (316) window ::= nm frame_opt */ - 0, /* (317) frame_opt ::= */ - -3, /* (318) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (319) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (320) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (321) frame_bound_s ::= frame_bound */ - -2, /* (322) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (323) frame_bound_e ::= frame_bound */ - -2, /* (324) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (325) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (326) frame_bound ::= CURRENT ROW */ - 0, /* (327) frame_exclude_opt ::= */ - -2, /* (328) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (329) frame_exclude ::= NO OTHERS */ - -2, /* (330) frame_exclude ::= CURRENT ROW */ - -1, /* (331) frame_exclude ::= GROUP|TIES */ - -2, /* (332) window_clause ::= WINDOW windowdefn_list */ - -2, /* (333) filter_over ::= filter_clause over_clause */ - -1, /* (334) filter_over ::= over_clause */ - -1, /* (335) filter_over ::= filter_clause */ - -4, /* (336) over_clause ::= OVER LP window RP */ - -2, /* (337) over_clause ::= OVER nm */ - -5, /* (338) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (339) input ::= cmdlist */ - -2, /* (340) cmdlist ::= cmdlist ecmd */ - -1, /* (341) cmdlist ::= ecmd */ - -1, /* (342) ecmd ::= SEMI */ - -2, /* (343) ecmd ::= cmdx SEMI */ - -3, /* (344) ecmd ::= explain cmdx SEMI */ - 0, /* (345) trans_opt ::= */ - -1, /* (346) trans_opt ::= TRANSACTION */ - -2, /* (347) trans_opt ::= TRANSACTION nm */ - -1, /* (348) savepoint_opt ::= SAVEPOINT */ - 0, /* (349) savepoint_opt ::= */ - -2, /* (350) cmd ::= create_table create_table_args */ - -1, /* (351) table_option_set ::= table_option */ - -4, /* (352) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (353) columnlist ::= columnname carglist */ - -1, /* (354) nm ::= ID|INDEXED */ - -1, /* (355) nm ::= STRING */ - -1, /* (356) nm ::= JOIN_KW */ - -1, /* (357) typetoken ::= typename */ - -1, /* (358) typename ::= ID|STRING */ - -1, /* (359) signed ::= plus_num */ - -1, /* (360) signed ::= minus_num */ - -2, /* (361) carglist ::= carglist ccons */ - 0, /* (362) carglist ::= */ - -2, /* (363) ccons ::= NULL onconf */ - -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (365) ccons ::= AS generated */ - -2, /* (366) conslist_opt ::= COMMA conslist */ - -3, /* (367) conslist ::= conslist tconscomma tcons */ - -1, /* (368) conslist ::= tcons */ - 0, /* (369) tconscomma ::= */ - -1, /* (370) defer_subclause_opt ::= defer_subclause */ - -1, /* (371) resolvetype ::= raisetype */ - -1, /* (372) selectnowith ::= oneselect */ - -1, /* (373) oneselect ::= values */ - -2, /* (374) sclp ::= selcollist COMMA */ - -1, /* (375) as ::= ID|STRING */ - 0, /* (376) returning ::= */ - -1, /* (377) expr ::= term */ - -1, /* (378) likeop ::= LIKE_KW|MATCH */ - -1, /* (379) exprlist ::= nexprlist */ - -1, /* (380) nmnum ::= plus_num */ - -1, /* (381) nmnum ::= nm */ - -1, /* (382) nmnum ::= ON */ - -1, /* (383) nmnum ::= DELETE */ - -1, /* (384) nmnum ::= DEFAULT */ - -1, /* (385) plus_num ::= INTEGER|FLOAT */ - 0, /* (386) foreach_clause ::= */ - -3, /* (387) foreach_clause ::= FOR EACH ROW */ - -1, /* (388) trnm ::= nm */ - 0, /* (389) tridxby ::= */ - -1, /* (390) database_kw_opt ::= DATABASE */ - 0, /* (391) database_kw_opt ::= */ - 0, /* (392) kwcolumn_opt ::= */ - -1, /* (393) kwcolumn_opt ::= COLUMNKW */ - -1, /* (394) vtabarglist ::= vtabarg */ - -3, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (397) anylist ::= */ - -4, /* (398) anylist ::= anylist LP anylist RP */ - -2, /* (399) anylist ::= anylist ANY */ - 0, /* (400) with ::= */ + -3, /* (212) expr ::= expr PTR expr */ + -1, /* (213) between_op ::= BETWEEN */ + -2, /* (214) between_op ::= NOT BETWEEN */ + -5, /* (215) expr ::= expr between_op expr AND expr */ + -1, /* (216) in_op ::= IN */ + -2, /* (217) in_op ::= NOT IN */ + -5, /* (218) expr ::= expr in_op LP exprlist RP */ + -3, /* (219) expr ::= LP select RP */ + -5, /* (220) expr ::= expr in_op LP select RP */ + -5, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (222) expr ::= EXISTS LP select RP */ + -5, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (225) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (226) case_else ::= ELSE expr */ + 0, /* (227) case_else ::= */ + -1, /* (228) case_operand ::= expr */ + 0, /* (229) case_operand ::= */ + 0, /* (230) exprlist ::= */ + -3, /* (231) nexprlist ::= nexprlist COMMA expr */ + -1, /* (232) nexprlist ::= expr */ + 0, /* (233) paren_exprlist ::= */ + -3, /* (234) paren_exprlist ::= LP exprlist RP */ + -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (236) uniqueflag ::= UNIQUE */ + 0, /* (237) uniqueflag ::= */ + 0, /* (238) eidlist_opt ::= */ + -3, /* (239) eidlist_opt ::= LP eidlist RP */ + -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (241) eidlist ::= nm collate sortorder */ + 0, /* (242) collate ::= */ + -2, /* (243) collate ::= COLLATE ID|STRING */ + -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (245) cmd ::= VACUUM vinto */ + -3, /* (246) cmd ::= VACUUM nm vinto */ + -2, /* (247) vinto ::= INTO expr */ + 0, /* (248) vinto ::= */ + -3, /* (249) cmd ::= PRAGMA nm dbnm */ + -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (258) trigger_time ::= BEFORE|AFTER */ + -2, /* (259) trigger_time ::= INSTEAD OF */ + 0, /* (260) trigger_time ::= */ + -1, /* (261) trigger_event ::= DELETE|INSERT */ + -1, /* (262) trigger_event ::= UPDATE */ + -3, /* (263) trigger_event ::= UPDATE OF idlist */ + 0, /* (264) when_clause ::= */ + -2, /* (265) when_clause ::= WHEN expr */ + -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (268) trnm ::= nm DOT nm */ + -3, /* (269) tridxby ::= INDEXED BY nm */ + -2, /* (270) tridxby ::= NOT INDEXED */ + -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (274) trigger_cmd ::= scanpt select scanpt */ + -4, /* (275) expr ::= RAISE LP IGNORE RP */ + -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (277) raisetype ::= ROLLBACK */ + -1, /* (278) raisetype ::= ABORT */ + -1, /* (279) raisetype ::= FAIL */ + -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (282) cmd ::= DETACH database_kw_opt expr */ + 0, /* (283) key_opt ::= */ + -2, /* (284) key_opt ::= KEY expr */ + -1, /* (285) cmd ::= REINDEX */ + -3, /* (286) cmd ::= REINDEX nm dbnm */ + -1, /* (287) cmd ::= ANALYZE */ + -3, /* (288) cmd ::= ANALYZE nm dbnm */ + -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (292) add_column_fullname ::= fullname */ + -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (294) cmd ::= create_vtab */ + -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (297) vtabarg ::= */ + -1, /* (298) vtabargtoken ::= ANY */ + -3, /* (299) vtabargtoken ::= lp anylist RP */ + -1, /* (300) lp ::= LP */ + -2, /* (301) with ::= WITH wqlist */ + -3, /* (302) with ::= WITH RECURSIVE wqlist */ + -1, /* (303) wqas ::= AS */ + -2, /* (304) wqas ::= AS MATERIALIZED */ + -3, /* (305) wqas ::= AS NOT MATERIALIZED */ + -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (307) wqlist ::= wqitem */ + -3, /* (308) wqlist ::= wqlist COMMA wqitem */ + -1, /* (309) windowdefn_list ::= windowdefn */ + -3, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (311) windowdefn ::= nm AS LP window RP */ + -5, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (314) window ::= ORDER BY sortlist frame_opt */ + -5, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (316) window ::= frame_opt */ + -2, /* (317) window ::= nm frame_opt */ + 0, /* (318) frame_opt ::= */ + -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (322) frame_bound_s ::= frame_bound */ + -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (324) frame_bound_e ::= frame_bound */ + -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (327) frame_bound ::= CURRENT ROW */ + 0, /* (328) frame_exclude_opt ::= */ + -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (330) frame_exclude ::= NO OTHERS */ + -2, /* (331) frame_exclude ::= CURRENT ROW */ + -1, /* (332) frame_exclude ::= GROUP|TIES */ + -2, /* (333) window_clause ::= WINDOW windowdefn_list */ + -2, /* (334) filter_over ::= filter_clause over_clause */ + -1, /* (335) filter_over ::= over_clause */ + -1, /* (336) filter_over ::= filter_clause */ + -4, /* (337) over_clause ::= OVER LP window RP */ + -2, /* (338) over_clause ::= OVER nm */ + -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (340) input ::= cmdlist */ + -2, /* (341) cmdlist ::= cmdlist ecmd */ + -1, /* (342) cmdlist ::= ecmd */ + -1, /* (343) ecmd ::= SEMI */ + -2, /* (344) ecmd ::= cmdx SEMI */ + -3, /* (345) ecmd ::= explain cmdx SEMI */ + 0, /* (346) trans_opt ::= */ + -1, /* (347) trans_opt ::= TRANSACTION */ + -2, /* (348) trans_opt ::= TRANSACTION nm */ + -1, /* (349) savepoint_opt ::= SAVEPOINT */ + 0, /* (350) savepoint_opt ::= */ + -2, /* (351) cmd ::= create_table create_table_args */ + -1, /* (352) table_option_set ::= table_option */ + -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (354) columnlist ::= columnname carglist */ + -1, /* (355) nm ::= ID|INDEXED */ + -1, /* (356) nm ::= STRING */ + -1, /* (357) nm ::= JOIN_KW */ + -1, /* (358) typetoken ::= typename */ + -1, /* (359) typename ::= ID|STRING */ + -1, /* (360) signed ::= plus_num */ + -1, /* (361) signed ::= minus_num */ + -2, /* (362) carglist ::= carglist ccons */ + 0, /* (363) carglist ::= */ + -2, /* (364) ccons ::= NULL onconf */ + -4, /* (365) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (366) ccons ::= AS generated */ + -2, /* (367) conslist_opt ::= COMMA conslist */ + -3, /* (368) conslist ::= conslist tconscomma tcons */ + -1, /* (369) conslist ::= tcons */ + 0, /* (370) tconscomma ::= */ + -1, /* (371) defer_subclause_opt ::= defer_subclause */ + -1, /* (372) resolvetype ::= raisetype */ + -1, /* (373) selectnowith ::= oneselect */ + -1, /* (374) oneselect ::= values */ + -2, /* (375) sclp ::= selcollist COMMA */ + -1, /* (376) as ::= ID|STRING */ + 0, /* (377) returning ::= */ + -1, /* (378) expr ::= term */ + -1, /* (379) likeop ::= LIKE_KW|MATCH */ + -1, /* (380) exprlist ::= nexprlist */ + -1, /* (381) nmnum ::= plus_num */ + -1, /* (382) nmnum ::= nm */ + -1, /* (383) nmnum ::= ON */ + -1, /* (384) nmnum ::= DELETE */ + -1, /* (385) nmnum ::= DEFAULT */ + -1, /* (386) plus_num ::= INTEGER|FLOAT */ + 0, /* (387) foreach_clause ::= */ + -3, /* (388) foreach_clause ::= FOR EACH ROW */ + -1, /* (389) trnm ::= nm */ + 0, /* (390) tridxby ::= */ + -1, /* (391) database_kw_opt ::= DATABASE */ + 0, /* (392) database_kw_opt ::= */ + 0, /* (393) kwcolumn_opt ::= */ + -1, /* (394) kwcolumn_opt ::= COLUMNKW */ + -1, /* (395) vtabarglist ::= vtabarg */ + -3, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (398) anylist ::= */ + -4, /* (399) anylist ::= anylist LP anylist RP */ + -2, /* (400) anylist ::= anylist ANY */ + 0, /* (401) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -163003,16 +164985,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy64);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy64 = TK_DEFERRED;} +{yymsp[1].minor.yy394 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 320: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==320); -{yymsp[0].minor.yy64 = yymsp[0].major; /*A-overwrites-X*/} + case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -163035,7 +165017,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy64,0,0,yymsp[-2].minor.yy64); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); } break; case 14: /* createkw ::= CREATE */ @@ -163048,39 +165030,39 @@ static YYACTIONTYPE yy_reduce( case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); case 81: /* ifexists ::= */ yytestcase(yyruleno==81); case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 241: /* collate ::= */ yytestcase(yyruleno==241); -{yymsp[1].minor.yy64 = 0;} + case 242: /* collate ::= */ yytestcase(yyruleno==242); +{yymsp[1].minor.yy394 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy64 = 1;} +{yymsp[-2].minor.yy394 = 1;} break; case 17: /* temp ::= TEMP */ -{yymsp[0].minor.yy64 = pParse->db->init.busy==0;} +{yymsp[0].minor.yy394 = pParse->db->init.busy==0;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy51,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy303); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy303); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); } break; case 21: /* table_option_set ::= */ -{yymsp[1].minor.yy51 = 0;} +{yymsp[1].minor.yy285 = 0;} break; case 22: /* table_option_set ::= table_option_set COMMA table_option */ -{yylhsminor.yy51 = yymsp[-2].minor.yy51|yymsp[0].minor.yy51;} - yymsp[-2].minor.yy51 = yylhsminor.yy51; +{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} + yymsp[-2].minor.yy285 = yylhsminor.yy285; break; case 23: /* table_option ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy51 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy51 = 0; + yymsp[-1].minor.yy285 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -163088,13 +165070,13 @@ static YYACTIONTYPE yy_reduce( case 24: /* table_option ::= nm */ { if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ - yylhsminor.yy51 = TF_Strict; + yylhsminor.yy285 = TF_Strict; }else{ - yylhsminor.yy51 = 0; + yylhsminor.yy285 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } - yymsp[0].minor.yy51 = yylhsminor.yy51; + yymsp[0].minor.yy285 = yylhsminor.yy285; break; case 25: /* columnname ::= nm typetoken */ {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} @@ -163120,7 +165102,7 @@ static YYACTIONTYPE yy_reduce( case 30: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy600 = yyLookaheadToken.z; + yymsp[1].minor.yy522 = yyLookaheadToken.z; } break; case 31: /* scantok ::= */ @@ -163134,17 +165116,17 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 33: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy626,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy626,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 35: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy626,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 36: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy626, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -163159,161 +165141,161 @@ static YYACTIONTYPE yy_reduce( } break; case 38: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy64);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} break; case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy64,yymsp[0].minor.yy64,yymsp[-2].minor.yy64);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} break; case 40: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy64,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 41: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy626,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy562,yymsp[0].minor.yy64);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} break; case 43: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy64);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} break; case 44: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 45: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy626,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} break; case 46: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy626,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} break; case 48: /* autoinc ::= AUTOINCR */ -{yymsp[0].minor.yy64 = 1;} +{yymsp[0].minor.yy394 = 1;} break; case 49: /* refargs ::= */ -{ yymsp[1].minor.yy64 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 50: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy64 = (yymsp[-1].minor.yy64 & ~yymsp[0].minor.yy83.mask) | yymsp[0].minor.yy83.value; } +{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } break; case 51: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy83.value = 0; yymsp[-1].minor.yy83.mask = 0x000000; } +{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } break; case 52: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy83.value = 0; yymsp[-2].minor.yy83.mask = 0x000000; } +{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } break; case 53: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy83.value = yymsp[0].minor.yy64; yymsp[-2].minor.yy83.mask = 0x0000ff; } +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } break; case 54: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy83.value = yymsp[0].minor.yy64<<8; yymsp[-2].minor.yy83.mask = 0x00ff00; } +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } break; case 55: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy64 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} break; case 56: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy64 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 57: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy64 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} break; case 58: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy64 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} break; case 59: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy64 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} break; case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy64 = 0;} +{yymsp[-2].minor.yy394 = 0;} break; case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); -{yymsp[-1].minor.yy64 = yymsp[0].minor.yy64;} +{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 213: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==213); - case 216: /* in_op ::= NOT IN */ yytestcase(yyruleno==216); - case 242: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==242); -{yymsp[-1].minor.yy64 = 1;} + case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214); + case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217); + case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); +{yymsp[-1].minor.yy394 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy64 = 0;} +{yymsp[-1].minor.yy394 = 0;} break; case 66: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy562,yymsp[0].minor.yy64,yymsp[-2].minor.yy64,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} break; case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy562,yymsp[0].minor.yy64,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 70: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy626,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy562, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy562, yymsp[-1].minor.yy64); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy64); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); } break; case 73: /* onconf ::= */ case 75: /* orconf ::= */ yytestcase(yyruleno==75); -{yymsp[1].minor.yy64 = OE_Default;} +{yymsp[1].minor.yy394 = OE_Default;} break; case 74: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy64 = yymsp[0].minor.yy64;} +{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} break; case 77: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy64 = OE_Ignore;} +{yymsp[0].minor.yy394 = OE_Ignore;} break; case 78: /* resolvetype ::= REPLACE */ case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); -{yymsp[0].minor.yy64 = OE_Replace;} +{yymsp[0].minor.yy394 = OE_Replace;} break; case 79: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy607, 0, yymsp[-1].minor.yy64); + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); } break; case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy562, yymsp[0].minor.yy303, yymsp[-7].minor.yy64, yymsp[-5].minor.yy64); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); } break; case 83: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy607, 1, yymsp[-1].minor.yy64); + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); } break; case 84: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy303, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy303); + sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); } break; case 85: /* select ::= WITH wqlist selectnowith */ -{yymsp[-2].minor.yy303 = attachWithToSelect(pParse,yymsp[0].minor.yy303,yymsp[-1].minor.yy43);} +{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} break; case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{yymsp[-3].minor.yy303 = attachWithToSelect(pParse,yymsp[0].minor.yy303,yymsp[-1].minor.yy43);} +{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} break; case 87: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy303; + Select *p = yymsp[0].minor.yy47; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy303 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy47 = p; /*A-overwrites-X*/ } break; case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy303; - Select *pLhs = yymsp[-2].minor.yy303; + Select *pRhs = yymsp[0].minor.yy47; + Select *pLhs = yymsp[-2].minor.yy47; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -163323,140 +165305,140 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy64; + pRhs->op = (u8)yymsp[-1].minor.yy394; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy64!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy303 = pRhs; + yymsp[-2].minor.yy47 = pRhs; } break; case 89: /* multiselect_op ::= UNION */ case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); -{yymsp[0].minor.yy64 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} break; case 90: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy64 = TK_ALL;} +{yymsp[-1].minor.yy394 = TK_ALL;} break; case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy303 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy562,yymsp[-5].minor.yy607,yymsp[-4].minor.yy626,yymsp[-3].minor.yy562,yymsp[-2].minor.yy626,yymsp[-1].minor.yy562,yymsp[-7].minor.yy64,yymsp[0].minor.yy626); + yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); } break; case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy303 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy562,yymsp[-6].minor.yy607,yymsp[-5].minor.yy626,yymsp[-4].minor.yy562,yymsp[-3].minor.yy626,yymsp[-1].minor.yy562,yymsp[-8].minor.yy64,yymsp[0].minor.yy626); - if( yymsp[-9].minor.yy303 ){ - yymsp[-9].minor.yy303->pWinDefn = yymsp[-2].minor.yy375; + yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); + if( yymsp[-9].minor.yy47 ){ + yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy375); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); } } break; case 94: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy303 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy562,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); } break; case 95: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy303; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy562,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy47; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy303 = pRight; + yymsp[-4].minor.yy47 = pRight; }else{ - yymsp[-4].minor.yy303 = pLeft; + yymsp[-4].minor.yy47 = pLeft; } } break; case 96: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy64 = SF_Distinct;} +{yymsp[0].minor.yy394 = SF_Distinct;} break; case 97: /* distinct ::= ALL */ -{yymsp[0].minor.yy64 = SF_All;} +{yymsp[0].minor.yy394 = SF_All;} break; case 99: /* sclp ::= */ case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 229: /* exprlist ::= */ yytestcase(yyruleno==229); - case 232: /* paren_exprlist ::= */ yytestcase(yyruleno==232); - case 237: /* eidlist_opt ::= */ yytestcase(yyruleno==237); -{yymsp[1].minor.yy562 = 0;} + case 230: /* exprlist ::= */ yytestcase(yyruleno==230); + case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); + case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); +{yymsp[1].minor.yy322 = 0;} break; case 100: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy562, yymsp[-2].minor.yy626); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy562, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy562,yymsp[-3].minor.yy600,yymsp[-1].minor.yy600); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); } break; case 101: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy562 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy562, p); + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); } break; case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); + Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562, pDot); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); } break; case 103: /* as ::= AS nm */ case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114); - case 253: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==253); - case 254: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==254); + case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); + case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 105: /* from ::= */ case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); -{yymsp[1].minor.yy607 = 0;} +{yymsp[1].minor.yy131 = 0;} break; case 106: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy607 = yymsp[0].minor.yy607; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy607); + yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131); } break; case 107: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy607 && yymsp[-1].minor.yy607->nSrc>0) ) yymsp[-1].minor.yy607->a[yymsp[-1].minor.yy607->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy64; + if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; } break; case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy607,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy626,yymsp[0].minor.yy240); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy607, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0); } break; case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy607,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy626,yymsp[0].minor.yy240); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy607, yymsp[-4].minor.yy562); + yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322); } break; case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy607,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy303,yymsp[-1].minor.yy626,yymsp[0].minor.yy240); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); } break; case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy607==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy626==0 && yymsp[0].minor.yy240==0 ){ - yymsp[-6].minor.yy607 = yymsp[-4].minor.yy607; - }else if( yymsp[-4].minor.yy607->nSrc==1 ){ - yymsp[-6].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy607,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy626,yymsp[0].minor.yy240); - if( yymsp[-6].minor.yy607 ){ - SrcItem *pNew = &yymsp[-6].minor.yy607->a[yymsp[-6].minor.yy607->nSrc-1]; - SrcItem *pOld = yymsp[-4].minor.yy607->a; + if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){ + yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131; + }else if( yymsp[-4].minor.yy131->nSrc==1 ){ + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + if( yymsp[-6].minor.yy131 ){ + SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy131->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -163469,12 +165451,12 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy607); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy607); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy607,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy607,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy626,yymsp[0].minor.yy240); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); } } break; @@ -163484,65 +165466,65 @@ static YYACTIONTYPE yy_reduce( break; case 115: /* fullname ::= nm */ { - yylhsminor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy607 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy607->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy607 = yylhsminor.yy607; + yymsp[0].minor.yy131 = yylhsminor.yy131; break; case 116: /* fullname ::= nm DOT nm */ { - yylhsminor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy607 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy607->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy607 = yylhsminor.yy607; + yymsp[-2].minor.yy131 = yylhsminor.yy131; break; case 117: /* xfullname ::= nm */ -{yymsp[0].minor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; case 118: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 119: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy607 ) yymsp[-4].minor.yy607->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 120: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy607 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy607 ) yymsp[-2].minor.yy607->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 121: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy64 = JT_INNER; } +{ yymsp[0].minor.yy394 = JT_INNER; } break; case 122: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy64 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 123: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy64 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 124: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy64 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 125: /* on_opt ::= ON expr */ case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145); case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); - case 225: /* case_else ::= ELSE expr */ yytestcase(yyruleno==225); - case 246: /* vinto ::= INTO expr */ yytestcase(yyruleno==246); -{yymsp[-1].minor.yy626 = yymsp[0].minor.yy626;} + case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226); + case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} break; case 126: /* on_opt ::= */ case 144: /* having_opt ::= */ yytestcase(yyruleno==144); case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); case 151: /* where_opt ::= */ yytestcase(yyruleno==151); case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 226: /* case_else ::= */ yytestcase(yyruleno==226); - case 228: /* case_operand ::= */ yytestcase(yyruleno==228); - case 247: /* vinto ::= */ yytestcase(yyruleno==247); -{yymsp[1].minor.yy626 = 0;} + case 227: /* case_else ::= */ yytestcase(yyruleno==227); + case 229: /* case_operand ::= */ yytestcase(yyruleno==229); + case 248: /* vinto ::= */ yytestcase(yyruleno==248); +{yymsp[1].minor.yy528 = 0;} break; case 128: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -163551,185 +165533,181 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; case 130: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy240 = yymsp[-1].minor.yy240;} +{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} break; case 131: /* using_opt ::= */ case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173); -{yymsp[1].minor.yy240 = 0;} +{yymsp[1].minor.yy254 = 0;} break; case 133: /* orderby_opt ::= ORDER BY sortlist */ case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); -{yymsp[-2].minor.yy562 = yymsp[0].minor.yy562;} +{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} break; case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562,yymsp[-2].minor.yy626); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy562,yymsp[-1].minor.yy64,yymsp[0].minor.yy64); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); } break; case 135: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy562 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy626); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy562,yymsp[-1].minor.yy64,yymsp[0].minor.yy64); + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); } break; case 136: /* sortorder ::= ASC */ -{yymsp[0].minor.yy64 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} break; case 137: /* sortorder ::= DESC */ -{yymsp[0].minor.yy64 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy394 = SQLITE_SO_DESC;} break; case 138: /* sortorder ::= */ case 141: /* nulls ::= */ yytestcase(yyruleno==141); -{yymsp[1].minor.yy64 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} break; case 139: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy64 = SQLITE_SO_ASC;} +{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} break; case 140: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy64 = SQLITE_SO_DESC;} +{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} break; case 147: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy626 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy626,0);} +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} break; case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy626 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy626,yymsp[0].minor.yy626);} +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; case 149: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy626 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy626,yymsp[-2].minor.yy626);} +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} break; case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy607, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy607,yymsp[0].minor.yy626,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0); } break; case 155: /* where_opt_ret ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy562); yymsp[-1].minor.yy626 = 0;} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} break; case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy562); yymsp[-3].minor.yy626 = yymsp[-2].minor.yy626;} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} break; case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy607, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy562,"set list"); - yymsp[-5].minor.yy607 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy607, yymsp[-1].minor.yy607); - sqlite3Update(pParse,yymsp[-5].minor.yy607,yymsp[-2].minor.yy562,yymsp[0].minor.yy626,yymsp[-6].minor.yy64,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); + yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131); + sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); } break; case 158: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy562, yymsp[0].minor.yy626); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy562, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); } break; case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy562 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy562, yymsp[-3].minor.yy240, yymsp[0].minor.yy626); + yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; case 160: /* setlist ::= nm EQ expr */ { - yylhsminor.yy562 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy626); - sqlite3ExprListSetName(pParse, yylhsminor.yy562, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy562 = yylhsminor.yy562; + yymsp[-2].minor.yy322 = yylhsminor.yy322; break; case 161: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy562 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy240, yymsp[0].minor.yy626); + yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy607, yymsp[-1].minor.yy303, yymsp[-2].minor.yy240, yymsp[-5].minor.yy64, yymsp[0].minor.yy138); + sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); } break; case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-4].minor.yy607, 0, yymsp[-3].minor.yy240, yymsp[-6].minor.yy64, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); } break; case 164: /* upsert ::= */ -{ yymsp[1].minor.yy138 = 0; } +{ yymsp[1].minor.yy444 = 0; } break; case 165: /* upsert ::= RETURNING selcollist */ -{ yymsp[-1].minor.yy138 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy562); } +{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } break; case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ -{ yymsp[-11].minor.yy138 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy562,yymsp[-6].minor.yy626,yymsp[-2].minor.yy562,yymsp[-1].minor.yy626,yymsp[0].minor.yy138);} +{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} break; case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ -{ yymsp[-8].minor.yy138 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy562,yymsp[-3].minor.yy626,0,0,yymsp[0].minor.yy138); } +{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } break; case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ -{ yymsp[-4].minor.yy138 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } +{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ -{ yymsp[-7].minor.yy138 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy562,yymsp[-1].minor.yy626,0);} +{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} break; case 170: /* returning ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy562);} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} break; case 174: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy240 = yymsp[-1].minor.yy240;} +{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} break; case 175: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy240 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy240,&yymsp[0].minor.yy0);} +{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} break; case 176: /* idlist ::= nm */ -{yymsp[0].minor.yy240 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} +{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; case 177: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy626 = yymsp[-1].minor.yy626;} +{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} break; case 178: /* expr ::= ID|INDEXED */ case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179); -{yymsp[0].minor.yy626=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 180: /* expr ::= nm DOT nm */ { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); - sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); - } - yylhsminor.yy626 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy626 = yylhsminor.yy626; + yymsp[-2].minor.yy528 = yylhsminor.yy528; break; case 181: /* expr ::= nm DOT nm DOT nm */ { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); - sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); + sqlite3RenameTokenRemap(pParse, 0, temp1); } - yylhsminor.yy626 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy626 = yylhsminor.yy626; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; case 182: /* term ::= NULL|FLOAT|BLOB */ case 183: /* term ::= STRING */ yytestcase(yyruleno==183); -{yymsp[0].minor.yy626=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 184: /* term ::= INTEGER */ { - yylhsminor.yy626 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } - yymsp[0].minor.yy626 = yylhsminor.yy626; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; case 185: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy626 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy626, n); + yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -163738,65 +165716,65 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy626 = 0; + yymsp[0].minor.yy528 = 0; }else{ - yymsp[0].minor.yy626 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy626 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy626->iTable); + yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); } } } break; case 186: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy626 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy626, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); } break; case 187: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy626 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy626, yymsp[-3].minor.yy626, 0); + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); } break; case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy626 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy562, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy64); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); } - yymsp[-4].minor.yy626 = yylhsminor.yy626; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; case 189: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy626 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy626 = yylhsminor.yy626; + yymsp[-3].minor.yy528 = yylhsminor.yy528; break; case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { - yylhsminor.yy626 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy562, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy64); - sqlite3WindowAttach(pParse, yylhsminor.yy626, yymsp[0].minor.yy375); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } - yymsp[-5].minor.yy626 = yylhsminor.yy626; + yymsp[-5].minor.yy528 = yylhsminor.yy528; break; case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { - yylhsminor.yy626 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy626, yymsp[0].minor.yy375); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } - yymsp[-4].minor.yy626 = yylhsminor.yy626; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; case 192: /* term ::= CTIME_KW */ { - yylhsminor.yy626 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy626 = yylhsminor.yy626; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; case 193: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy562, yymsp[-1].minor.yy626); - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy626 ){ - yymsp[-4].minor.yy626->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy626->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); @@ -163804,7 +165782,7 @@ static YYACTIONTYPE yy_reduce( } break; case 194: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy626=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy626,yymsp[0].minor.yy626);} +{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; case 195: /* expr ::= expr OR expr */ case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196); @@ -163813,7 +165791,7 @@ static YYACTIONTYPE yy_reduce( case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199); case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200); case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201); -{yymsp[-2].minor.yy626=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy626,yymsp[0].minor.yy626);} +{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; case 202: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} @@ -163823,11 +165801,11 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy626); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy626); - yymsp[-2].minor.yy626 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy626, 0); - if( yymsp[-2].minor.yy626 ) yymsp[-2].minor.yy626->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); + yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); + if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; } break; case 204: /* expr ::= expr likeop expr ESCAPE expr */ @@ -163835,62 +165813,70 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy626); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy626); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy626); - yymsp[-4].minor.yy626 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy626, 0); - if( yymsp[-4].minor.yy626 ) yymsp[-4].minor.yy626->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; } break; case 205: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy626 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy626,0);} +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} break; case 206: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy626 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy626,0);} +{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} break; case 207: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy626 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy626,yymsp[0].minor.yy626); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy626, yymsp[-2].minor.yy626, TK_ISNULL); + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); } break; case 208: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy626 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy626,yymsp[0].minor.yy626); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy626, yymsp[-3].minor.yy626, TK_NOTNULL); + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); } break; case 209: /* expr ::= NOT expr */ case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210); -{yymsp[-1].minor.yy626 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy626, 0);/*A-overwrites-B*/} +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} break; case 211: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy626 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy626, 0); + yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); /*A-overwrites-B*/ } break; - case 212: /* between_op ::= BETWEEN */ - case 215: /* in_op ::= IN */ yytestcase(yyruleno==215); -{yymsp[0].minor.yy64 = 0;} + case 212: /* expr ::= expr PTR expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); +} + yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 214: /* expr ::= expr between_op expr AND expr */ + case 213: /* between_op ::= BETWEEN */ + case 216: /* in_op ::= IN */ yytestcase(yyruleno==216); +{yymsp[0].minor.yy394 = 0;} + break; + case 215: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy626); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy626); - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy626, 0); - if( yymsp[-4].minor.yy626 ){ - yymsp[-4].minor.yy626->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy64 ) yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy626, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 217: /* expr ::= expr in_op LP exprlist RP */ + case 218: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy562==0 ){ + if( yymsp[-1].minor.yy322==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -163899,205 +165885,205 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy626); - yymsp[-4].minor.yy626 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy64 ? "1" : "0"); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0"); }else{ - Expr *pRHS = yymsp[-1].minor.yy562->a[0].pExpr; - if( yymsp[-1].minor.yy562->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy626->op!=TK_VECTOR ){ - yymsp[-1].minor.yy562->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy562); + Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; + if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ + yymsp[-1].minor.yy322->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy626, pRHS); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); }else{ - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy626, 0); - if( yymsp[-4].minor.yy626==0 ){ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy562); - }else if( yymsp[-4].minor.yy626->pLeft->op==TK_VECTOR ){ - int nExpr = yymsp[-4].minor.yy626->pLeft->x.pList->nExpr; - Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy562); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); if( pSelectRHS ){ parserDoubleLinkSelect(pParse, pSelectRHS); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy626, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); } }else{ - yymsp[-4].minor.yy626->x.pList = yymsp[-1].minor.yy562; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy626); + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); } } - if( yymsp[-3].minor.yy64 ) yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy626, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } } break; - case 218: /* expr ::= LP select RP */ + case 219: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy626 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy626, yymsp[-1].minor.yy303); + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); } break; - case 219: /* expr ::= expr in_op LP select RP */ + case 220: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy626, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy626, yymsp[-1].minor.yy303); - if( yymsp[-3].minor.yy64 ) yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy626, 0); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 220: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy562 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy562); - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy626, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy626, pSelect); - if( yymsp[-3].minor.yy64 ) yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy626, 0); + if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 221: /* expr ::= EXISTS LP select RP */ + case 222: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy626 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy303); + p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); } break; - case 222: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 223: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy626, 0); - if( yymsp[-4].minor.yy626 ){ - yymsp[-4].minor.yy626->x.pList = yymsp[-1].minor.yy626 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy562,yymsp[-1].minor.yy626) : yymsp[-2].minor.yy562; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy626); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy562); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy626); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } } break; - case 223: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562, yymsp[-2].minor.yy626); - yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562, yymsp[0].minor.yy626); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); } break; - case 224: /* case_exprlist ::= WHEN expr THEN expr */ + case 225: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy562 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy626); - yymsp[-3].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy562, yymsp[0].minor.yy626); + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); } break; - case 227: /* case_operand ::= expr */ -{yymsp[0].minor.yy626 = yymsp[0].minor.yy626; /*A-overwrites-X*/} + case 228: /* case_operand ::= expr */ +{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/} break; - case 230: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy562,yymsp[0].minor.yy626);} + case 231: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} break; - case 231: /* nexprlist ::= expr */ -{yymsp[0].minor.yy562 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy626); /*A-overwrites-Y*/} + case 232: /* nexprlist ::= expr */ +{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} break; - case 233: /* paren_exprlist ::= LP exprlist RP */ - case 238: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==238); -{yymsp[-2].minor.yy562 = yymsp[-1].minor.yy562;} + case 234: /* paren_exprlist ::= LP exprlist RP */ + case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); +{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} break; - case 234: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy562, yymsp[-10].minor.yy64, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy626, SQLITE_SO_ASC, yymsp[-8].minor.yy64, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 235: /* uniqueflag ::= UNIQUE */ - case 277: /* raisetype ::= ABORT */ yytestcase(yyruleno==277); -{yymsp[0].minor.yy64 = OE_Abort;} + case 236: /* uniqueflag ::= UNIQUE */ + case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); +{yymsp[0].minor.yy394 = OE_Abort;} break; - case 236: /* uniqueflag ::= */ -{yymsp[1].minor.yy64 = OE_None;} + case 237: /* uniqueflag ::= */ +{yymsp[1].minor.yy394 = OE_None;} break; - case 239: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy562 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy562, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy64, yymsp[0].minor.yy64); + yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); } break; - case 240: /* eidlist ::= nm collate sortorder */ + case 241: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy562 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy64, yymsp[0].minor.yy64); /*A-overwrites-Y*/ + yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ } break; - case 243: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy607, yymsp[-1].minor.yy64);} + case 244: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} break; - case 244: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy626);} + case 245: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} break; - case 245: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy626);} + case 246: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} break; - case 248: /* cmd ::= PRAGMA nm dbnm */ + case 249: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 249: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 250: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 251: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 252: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 255: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy95, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); } break; - case 256: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy64, yymsp[-4].minor.yy570.a, yymsp[-4].minor.yy570.b, yymsp[-2].minor.yy607, yymsp[0].minor.yy626, yymsp[-10].minor.yy64, yymsp[-8].minor.yy64); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 257: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy64 = yymsp[0].major; /*A-overwrites-X*/ } + case 258: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 258: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy64 = TK_INSTEAD;} + case 259: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy394 = TK_INSTEAD;} break; - case 259: /* trigger_time ::= */ -{ yymsp[1].minor.yy64 = TK_BEFORE; } + case 260: /* trigger_time ::= */ +{ yymsp[1].minor.yy394 = TK_BEFORE; } break; - case 260: /* trigger_event ::= DELETE|INSERT */ - case 261: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==261); -{yymsp[0].minor.yy570.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy570.b = 0;} + case 261: /* trigger_event ::= DELETE|INSERT */ + case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); +{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} break; - case 262: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy570.a = TK_UPDATE; yymsp[-2].minor.yy570.b = yymsp[0].minor.yy240;} + case 263: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} break; - case 263: /* when_clause ::= */ - case 282: /* key_opt ::= */ yytestcase(yyruleno==282); -{ yymsp[1].minor.yy626 = 0; } + case 264: /* when_clause ::= */ + case 283: /* key_opt ::= */ yytestcase(yyruleno==283); +{ yymsp[1].minor.yy528 = 0; } break; - case 264: /* when_clause ::= WHEN expr */ - case 283: /* key_opt ::= KEY expr */ yytestcase(yyruleno==283); -{ yymsp[-1].minor.yy626 = yymsp[0].minor.yy626; } + case 265: /* when_clause ::= WHEN expr */ + case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); +{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } break; - case 265: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy95!=0 ); - yymsp[-2].minor.yy95->pLast->pNext = yymsp[-1].minor.yy95; - yymsp[-2].minor.yy95->pLast = yymsp[-1].minor.yy95; + assert( yymsp[-2].minor.yy33!=0 ); + yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; + yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 266: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy95!=0 ); - yymsp[-1].minor.yy95->pLast = yymsp[-1].minor.yy95; + assert( yymsp[-1].minor.yy33!=0 ); + yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 267: /* trnm ::= nm DOT nm */ + case 268: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -164105,369 +166091,369 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 268: /* tridxby ::= INDEXED BY nm */ + case 269: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 269: /* tridxby ::= NOT INDEXED */ + case 270: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 270: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy95 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy607, yymsp[-3].minor.yy562, yymsp[-1].minor.yy626, yymsp[-7].minor.yy64, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy600);} - yymsp[-8].minor.yy95 = yylhsminor.yy95; + case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-8].minor.yy33 = yylhsminor.yy33; break; - case 271: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy95 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy240,yymsp[-2].minor.yy303,yymsp[-6].minor.yy64,yymsp[-1].minor.yy138,yymsp[-7].minor.yy600,yymsp[0].minor.yy600);/*yylhsminor.yy95-overwrites-yymsp[-6].minor.yy64*/ + yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ } - yymsp[-7].minor.yy95 = yylhsminor.yy95; + yymsp[-7].minor.yy33 = yylhsminor.yy33; break; - case 272: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy95 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy626, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy600);} - yymsp[-5].minor.yy95 = yylhsminor.yy95; + case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-5].minor.yy33 = yylhsminor.yy33; break; - case 273: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy95 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy303, yymsp[-2].minor.yy600, yymsp[0].minor.yy600); /*yylhsminor.yy95-overwrites-yymsp[-1].minor.yy303*/} - yymsp[-2].minor.yy95 = yylhsminor.yy95; + case 274: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} + yymsp[-2].minor.yy33 = yylhsminor.yy33; break; - case 274: /* expr ::= RAISE LP IGNORE RP */ + case 275: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy626 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy626 ){ - yymsp[-3].minor.yy626->affExpr = OE_Ignore; + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy528 ){ + yymsp[-3].minor.yy528->affExpr = OE_Ignore; } } break; - case 275: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy626 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy626 ) { - yymsp[-5].minor.yy626->affExpr = (char)yymsp[-3].minor.yy64; + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy528 ) { + yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; } } break; - case 276: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy64 = OE_Rollback;} + case 277: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy394 = OE_Rollback;} break; - case 278: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy64 = OE_Fail;} + case 279: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy394 = OE_Fail;} break; - case 279: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy607,yymsp[-1].minor.yy64); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); } break; - case 280: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy626, yymsp[-1].minor.yy626, yymsp[0].minor.yy626); + sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); } break; - case 281: /* cmd ::= DETACH database_kw_opt expr */ + case 282: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy626); + sqlite3Detach(pParse, yymsp[0].minor.yy528); } break; - case 284: /* cmd ::= REINDEX */ + case 285: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 285: /* cmd ::= REINDEX nm dbnm */ + case 286: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 286: /* cmd ::= ANALYZE */ + case 287: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 287: /* cmd ::= ANALYZE nm dbnm */ + case 288: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 288: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy607,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); } break; - case 289: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 290: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { - sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy607, &yymsp[0].minor.yy0); + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); } break; - case 291: /* add_column_fullname ::= fullname */ + case 292: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy607); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); } break; - case 292: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy607, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 293: /* cmd ::= create_vtab */ + case 294: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 294: /* cmd ::= create_vtab LP vtabarglist RP */ + case 295: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 295: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy64); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); } break; - case 296: /* vtabarg ::= */ + case 297: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 297: /* vtabargtoken ::= ANY */ - case 298: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==298); - case 299: /* lp ::= LP */ yytestcase(yyruleno==299); + case 298: /* vtabargtoken ::= ANY */ + case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); + case 300: /* lp ::= LP */ yytestcase(yyruleno==300); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 300: /* with ::= WITH wqlist */ - case 301: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==301); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy43, 1); } + case 301: /* with ::= WITH wqlist */ + case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } break; - case 302: /* wqas ::= AS */ -{yymsp[0].minor.yy534 = M10d_Any;} + case 303: /* wqas ::= AS */ +{yymsp[0].minor.yy516 = M10d_Any;} break; - case 303: /* wqas ::= AS MATERIALIZED */ -{yymsp[-1].minor.yy534 = M10d_Yes;} + case 304: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy516 = M10d_Yes;} break; - case 304: /* wqas ::= AS NOT MATERIALIZED */ -{yymsp[-2].minor.yy534 = M10d_No;} + case 305: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy516 = M10d_No;} break; - case 305: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy255 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy562, yymsp[-1].minor.yy303, yymsp[-3].minor.yy534); /*A-overwrites-X*/ + yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ } break; - case 306: /* wqlist ::= wqitem */ + case 307: /* wqlist ::= wqitem */ { - yymsp[0].minor.yy43 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy255); /*A-overwrites-X*/ + yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ } break; - case 307: /* wqlist ::= wqlist COMMA wqitem */ + case 308: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-2].minor.yy43 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy43, yymsp[0].minor.yy255); + yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); } break; - case 308: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy375 = yymsp[0].minor.yy375; } - yymsp[0].minor.yy375 = yylhsminor.yy375; + case 309: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy41 = yymsp[0].minor.yy41; } + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 309: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy375!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy375, yymsp[-2].minor.yy375); - yymsp[0].minor.yy375->pNextWin = yymsp[-2].minor.yy375; - yylhsminor.yy375 = yymsp[0].minor.yy375; + assert( yymsp[0].minor.yy41!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); + yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[-2].minor.yy375 = yylhsminor.yy375; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 310: /* windowdefn ::= nm AS LP window RP */ + case 311: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy375) ){ - yymsp[-1].minor.yy375->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy41) ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy375 = yymsp[-1].minor.yy375; + yylhsminor.yy41 = yymsp[-1].minor.yy41; } - yymsp[-4].minor.yy375 = yylhsminor.yy375; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 311: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy375 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy375, yymsp[-2].minor.yy562, yymsp[-1].minor.yy562, 0); + yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); } break; - case 312: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy375 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy375, yymsp[-2].minor.yy562, yymsp[-1].minor.yy562, &yymsp[-5].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy375 = yylhsminor.yy375; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 313: /* window ::= ORDER BY sortlist frame_opt */ + case 314: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy375 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy375, 0, yymsp[-1].minor.yy562, 0); + yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); } break; - case 314: /* window ::= nm ORDER BY sortlist frame_opt */ + case 315: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy375 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy375, 0, yymsp[-1].minor.yy562, &yymsp[-4].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy375 = yylhsminor.yy375; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 315: /* window ::= frame_opt */ - case 334: /* filter_over ::= over_clause */ yytestcase(yyruleno==334); + case 316: /* window ::= frame_opt */ + case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335); { - yylhsminor.yy375 = yymsp[0].minor.yy375; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[0].minor.yy375 = yylhsminor.yy375; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 316: /* window ::= nm frame_opt */ + case 317: /* window ::= nm frame_opt */ { - yylhsminor.yy375 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy375, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy375 = yylhsminor.yy375; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 317: /* frame_opt ::= */ + case 318: /* frame_opt ::= */ { - yymsp[1].minor.yy375 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 318: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy375 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy64, yymsp[-1].minor.yy81.eType, yymsp[-1].minor.yy81.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy534); + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); } - yymsp[-2].minor.yy375 = yylhsminor.yy375; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 319: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy375 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy64, yymsp[-3].minor.yy81.eType, yymsp[-3].minor.yy81.pExpr, yymsp[-1].minor.yy81.eType, yymsp[-1].minor.yy81.pExpr, yymsp[0].minor.yy534); + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); } - yymsp[-5].minor.yy375 = yylhsminor.yy375; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 321: /* frame_bound_s ::= frame_bound */ - case 323: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==323); -{yylhsminor.yy81 = yymsp[0].minor.yy81;} - yymsp[0].minor.yy81 = yylhsminor.yy81; + case 322: /* frame_bound_s ::= frame_bound */ + case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); +{yylhsminor.yy595 = yymsp[0].minor.yy595;} + yymsp[0].minor.yy595 = yylhsminor.yy595; break; - case 322: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 324: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==324); - case 326: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==326); -{yylhsminor.yy81.eType = yymsp[-1].major; yylhsminor.yy81.pExpr = 0;} - yymsp[-1].minor.yy81 = yylhsminor.yy81; + case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); + case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); +{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 325: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy81.eType = yymsp[0].major; yylhsminor.yy81.pExpr = yymsp[-1].minor.yy626;} - yymsp[-1].minor.yy81 = yylhsminor.yy81; + case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 327: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy534 = 0;} + case 328: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy516 = 0;} break; - case 328: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy534 = yymsp[0].minor.yy534;} + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} break; - case 329: /* frame_exclude ::= NO OTHERS */ - case 330: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==330); -{yymsp[-1].minor.yy534 = yymsp[-1].major; /*A-overwrites-X*/} + case 330: /* frame_exclude ::= NO OTHERS */ + case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); +{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 331: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy534 = yymsp[0].major; /*A-overwrites-X*/} + case 332: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} break; - case 332: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy375 = yymsp[0].minor.yy375; } + case 333: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } break; - case 333: /* filter_over ::= filter_clause over_clause */ + case 334: /* filter_over ::= filter_clause over_clause */ { - if( yymsp[0].minor.yy375 ){ - yymsp[0].minor.yy375->pFilter = yymsp[-1].minor.yy626; + if( yymsp[0].minor.yy41 ){ + yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy626); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } - yylhsminor.yy375 = yymsp[0].minor.yy375; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[-1].minor.yy375 = yylhsminor.yy375; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 335: /* filter_over ::= filter_clause */ + case 336: /* filter_over ::= filter_clause */ { - yylhsminor.yy375 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy375 ){ - yylhsminor.yy375->eFrmType = TK_FILTER; - yylhsminor.yy375->pFilter = yymsp[0].minor.yy626; + yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy41 ){ + yylhsminor.yy41->eFrmType = TK_FILTER; + yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy626); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); } } - yymsp[0].minor.yy375 = yylhsminor.yy375; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 336: /* over_clause ::= OVER LP window RP */ + case 337: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy375 = yymsp[-1].minor.yy375; - assert( yymsp[-3].minor.yy375!=0 ); + yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; + assert( yymsp[-3].minor.yy41!=0 ); } break; - case 337: /* over_clause ::= OVER nm */ + case 338: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy375 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy375 ){ - yymsp[-1].minor.yy375->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy41 ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 338: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy626 = yymsp[-1].minor.yy626; } + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } break; default: - /* (339) input ::= cmdlist */ yytestcase(yyruleno==339); - /* (340) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==340); - /* (341) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=341); - /* (342) ecmd ::= SEMI */ yytestcase(yyruleno==342); - /* (343) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==343); - /* (344) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=344); - /* (345) trans_opt ::= */ yytestcase(yyruleno==345); - /* (346) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==346); - /* (347) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==347); - /* (348) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==348); - /* (349) savepoint_opt ::= */ yytestcase(yyruleno==349); - /* (350) cmd ::= create_table create_table_args */ yytestcase(yyruleno==350); - /* (351) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=351); - /* (352) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==352); - /* (353) columnlist ::= columnname carglist */ yytestcase(yyruleno==353); - /* (354) nm ::= ID|INDEXED */ yytestcase(yyruleno==354); - /* (355) nm ::= STRING */ yytestcase(yyruleno==355); - /* (356) nm ::= JOIN_KW */ yytestcase(yyruleno==356); - /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); - /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); - /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); - /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); - /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); - /* (362) carglist ::= */ yytestcase(yyruleno==362); - /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); - /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); - /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); - /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); - /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); - /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) tconscomma ::= */ yytestcase(yyruleno==369); - /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); - /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); - /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); - /* (373) oneselect ::= values */ yytestcase(yyruleno==373); - /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); - /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); - /* (376) returning ::= */ yytestcase(yyruleno==376); - /* (377) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=377); - /* (378) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==378); - /* (379) exprlist ::= nexprlist */ yytestcase(yyruleno==379); - /* (380) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=380); - /* (381) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=381); - /* (382) nmnum ::= ON */ yytestcase(yyruleno==382); - /* (383) nmnum ::= DELETE */ yytestcase(yyruleno==383); - /* (384) nmnum ::= DEFAULT */ yytestcase(yyruleno==384); - /* (385) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==385); - /* (386) foreach_clause ::= */ yytestcase(yyruleno==386); - /* (387) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==387); - /* (388) trnm ::= nm */ yytestcase(yyruleno==388); - /* (389) tridxby ::= */ yytestcase(yyruleno==389); - /* (390) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==390); - /* (391) database_kw_opt ::= */ yytestcase(yyruleno==391); - /* (392) kwcolumn_opt ::= */ yytestcase(yyruleno==392); - /* (393) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==393); - /* (394) vtabarglist ::= vtabarg */ yytestcase(yyruleno==394); - /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==395); - /* (396) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==396); - /* (397) anylist ::= */ yytestcase(yyruleno==397); - /* (398) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==398); - /* (399) anylist ::= anylist ANY */ yytestcase(yyruleno==399); - /* (400) with ::= */ yytestcase(yyruleno==400); + /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); + /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); + /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); + /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); + /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); + /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); + /* (346) trans_opt ::= */ yytestcase(yyruleno==346); + /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); + /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); + /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); + /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); + /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); + /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); + /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); + /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); + /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355); + /* (356) nm ::= STRING */ yytestcase(yyruleno==356); + /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357); + /* (358) typetoken ::= typename */ yytestcase(yyruleno==358); + /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359); + /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361); + /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362); + /* (363) carglist ::= */ yytestcase(yyruleno==363); + /* (364) ccons ::= NULL onconf */ yytestcase(yyruleno==364); + /* (365) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==365); + /* (366) ccons ::= AS generated */ yytestcase(yyruleno==366); + /* (367) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==367); + /* (368) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==368); + /* (369) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=369); + /* (370) tconscomma ::= */ yytestcase(yyruleno==370); + /* (371) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=371); + /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372); + /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373); + /* (374) oneselect ::= values */ yytestcase(yyruleno==374); + /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375); + /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376); + /* (377) returning ::= */ yytestcase(yyruleno==377); + /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); + /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380); + /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381); + /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) nmnum ::= ON */ yytestcase(yyruleno==383); + /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384); + /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385); + /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386); + /* (387) foreach_clause ::= */ yytestcase(yyruleno==387); + /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388); + /* (389) trnm ::= nm */ yytestcase(yyruleno==389); + /* (390) tridxby ::= */ yytestcase(yyruleno==390); + /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391); + /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392); + /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393); + /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394); + /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395); + /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396); + /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397); + /* (398) anylist ::= */ yytestcase(yyruleno==398); + /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399); + /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400); + /* (401) with ::= */ yytestcase(yyruleno==401); break; /********** End reduce actions ************************************************/ }; @@ -165590,6 +167576,9 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; + }else if( z[1]=='>' ){ + *tokenType = TK_PTR; + return 2 + (z[2]=='>'); } *tokenType = TK_MINUS; return 1; @@ -165859,13 +167848,9 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ } /* -** Run the parser on the given SQL string. The parser structure is -** passed in. An SQLITE_ status code is returned. If an error occurs -** then an and attempt is made to write an error message into -** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that -** error message. +** Run the parser on the given SQL string. */ -SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ int nErr = 0; /* Number of errors encountered */ void *pEngine; /* The LEMON-generated LALR(1) parser */ int n = 0; /* Length of the next token token */ @@ -165886,7 +167871,6 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr } pParse->rc = SQLITE_OK; pParse->zTail = zSql; - assert( pzErrMsg!=0 ); #ifdef SQLITE_DEBUG if( db->flags & SQLITE_ParserTrace ){ printf("parser: [[[%s]]]\n", zSql); @@ -165929,6 +167913,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr #endif /* SQLITE_OMIT_WINDOWFUNC */ if( AtomicLoad(&db->u1.isInterrupted) ){ pParse->rc = SQLITE_INTERRUPT; + pParse->nErr++; break; } if( tokenType==TK_SPACE ){ @@ -165958,7 +167943,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ }else{ - sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); + Token x; + x.z = zSql; + x.n = n; + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x); break; } } @@ -165986,41 +167974,26 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM_BKPT; } - if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ - pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); - } - assert( pzErrMsg!=0 ); - if( pParse->zErrMsg ){ - *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s in \"%s\"", - *pzErrMsg, pParse->zTail); - pParse->zErrMsg = 0; + if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ + if( pParse->zErrMsg==0 ){ + pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); + } + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); nErr++; } pParse->zTail = zSql; - if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ - sqlite3VdbeDelete(pParse->pVdbe); - pParse->pVdbe = 0; - } -#ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->nested==0 ){ - sqlite3DbFree(db, pParse->aTableLock); - pParse->aTableLock = 0; - pParse->nTableLock = 0; - } -#endif #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_free(pParse->apVtabLock); #endif - if( !IN_SPECIAL_PARSE ){ + if( pParse->pNewTable && !IN_SPECIAL_PARSE ){ /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } - if( !IN_RENAME_OBJECT ){ + if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } sqlite3DbFree(db, pParse->pVList); @@ -166605,9 +168578,6 @@ SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*); #ifdef SQLITE_ENABLE_FTS5 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); #endif -#ifdef SQLITE_ENABLE_JSON1 -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*); -#endif #ifdef SQLITE_ENABLE_STMTVTAB SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif @@ -166642,8 +168612,8 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { sqlite3DbstatRegister, #endif sqlite3TestExtInit, -#ifdef SQLITE_ENABLE_JSON1 - sqlite3Json1Init, +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) + sqlite3JsonTableFunctions, #endif #ifdef SQLITE_ENABLE_STMTVTAB sqlite3StmtVtabInit, @@ -169152,6 +171122,19 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ return z; } +/* +** Return the byte offset of the most recent error +*/ +SQLITE_API int sqlite3_error_offset(sqlite3 *db){ + int iOffset = -1; + if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ + sqlite3_mutex_enter(db->mutex); + iOffset = db->errByteOffset; + sqlite3_mutex_leave(db->mutex); + } + return iOffset; +} + #ifndef SQLITE_OMIT_UTF16 /* ** Return UTF-16 encoded English language explanation of the most recent @@ -169412,6 +171395,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = 1; } db->aLimit[limitId] = newLimit; } @@ -170572,12 +172557,16 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** sqlite3_test_control(). */ case SQLITE_TESTCTRL_FAULT_INSTALL: { - /* MSVC is picky about pulling func ptrs from va lists. - ** http://support.microsoft.com/kb/47961 + /* A bug in MSVC prevents it from understanding pointers to functions + ** types in the second argument to va_arg(). Work around the problem + ** using a typedef. + ** http://support.microsoft.com/kb/47961 <-- dead hyperlink + ** Search at http://web.archive.org/ to find the 2015-03-16 archive + ** of the link above to see the original text. ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); */ - typedef int(*TESTCALLBACKFUNC_t)(int); - sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); + typedef int(*sqlite3FaultFuncType)(int); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType); rc = sqlite3FaultSim(0); break; } @@ -170704,13 +172693,27 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); + ** + ** If parameter onoff is 1, subsequent calls to localtime() fail. + ** If 2, then invoke xAlt() instead of localtime(). If 0, normal + ** processing. + ** + ** xAlt arguments are void pointers, but they really want to be: ** - ** If parameter onoff is non-zero, subsequent calls to localtime() - ** and its variants fail. If onoff is zero, undo this setting. + ** int xAlt(const time_t*, struct tm*); + ** + ** xAlt should write results in to struct tm object of its 2nd argument + ** and return zero on success, or return non-zero on failure. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + if( sqlite3GlobalConfig.bLocaltimeFault==2 ){ + typedef int(*sqlite3LocaltimeType)(const void*,void*); + sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType); + }else{ + sqlite3GlobalConfig.xAltLocaltime = 0; + } break; } @@ -170815,12 +172818,16 @@ SQLITE_API int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_IMPOSTER: { sqlite3 *db = va_arg(ap, sqlite3*); + int iDb; sqlite3_mutex_enter(db->mutex); - db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); - db->init.busy = db->init.imposterTable = va_arg(ap,int); - db->init.newTnum = va_arg(ap,int); - if( db->init.busy==0 && db->init.newTnum>0 ){ - sqlite3ResetAllSchemasOfConnection(db); + iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + if( iDb>=0 ){ + db->init.iDb = iDb; + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } } sqlite3_mutex_leave(db->mutex); break; @@ -170896,6 +172903,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, + ** double fIn, // Input value + ** int *pLogEst, // sqlite3LogEstFromDouble(fIn) + ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst) + ** int *pLogEst2 // sqlite3LogEst(*pInt) + ** ); + ** + ** Test access for the LogEst conversion routines. + */ + case SQLITE_TESTCTRL_LOGEST: { + double rIn = va_arg(ap, double); + LogEst rLogEst = sqlite3LogEstFromDouble(rIn); + u64 iInt = sqlite3LogEstToInt(rLogEst); + va_arg(ap, int*)[0] = rLogEst; + va_arg(ap, u64*)[0] = iInt; + va_arg(ap, int*)[0] = sqlite3LogEst(iInt); + break; + } + + #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -172876,7 +174903,7 @@ SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *) SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); /* fts3_tokenize_vtab.c */ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*)); /* fts3_unicode2.c (functions generated by parsing unicode text files) */ #ifndef SQLITE_DISABLE_FTS3_UNICODE @@ -172909,6 +174936,12 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); SQLITE_EXTENSION_INIT1 #endif +typedef struct Fts3HashWrapper Fts3HashWrapper; +struct Fts3HashWrapper { + Fts3Hash hash; /* Hash table */ + int nRef; /* Number of pointers to this object */ +}; + static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( @@ -173773,7 +175806,7 @@ static int fts3InitVtab( sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ char **pzErr /* Write any error message here */ ){ - Fts3Hash *pHash = (Fts3Hash *)pAux; + Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash; Fts3Table *p = 0; /* Pointer to allocated vtab */ int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ @@ -176608,9 +178641,12 @@ static const sqlite3_module fts3Module = { ** allocated for the tokenizer hash table. */ static void hashDestroy(void *p){ - Fts3Hash *pHash = (Fts3Hash *)p; - sqlite3Fts3HashClear(pHash); - sqlite3_free(pHash); + Fts3HashWrapper *pHash = (Fts3HashWrapper *)p; + pHash->nRef--; + if( pHash->nRef<=0 ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } } /* @@ -176640,7 +178676,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const */ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ int rc = SQLITE_OK; - Fts3Hash *pHash = 0; + Fts3HashWrapper *pHash = 0; const sqlite3_tokenizer_module *pSimple = 0; const sqlite3_tokenizer_module *pPorter = 0; #ifndef SQLITE_DISABLE_FTS3_UNICODE @@ -176668,23 +178704,24 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ sqlite3Fts3PorterTokenizerModule(&pPorter); /* Allocate and initialize the hash-table used to store tokenizers. */ - pHash = sqlite3_malloc(sizeof(Fts3Hash)); + pHash = sqlite3_malloc(sizeof(Fts3HashWrapper)); if( !pHash ){ rc = SQLITE_NOMEM; }else{ - sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); + sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1); + pHash->nRef = 0; } /* Load the built-in tokenizers into the hash table */ if( rc==SQLITE_OK ){ - if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) - || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) + if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter) #ifndef SQLITE_DISABLE_FTS3_UNICODE - || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) + || sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode) #endif #ifdef SQLITE_ENABLE_ICU - || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) + || (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu)) #endif ){ rc = SQLITE_NOMEM; @@ -176693,7 +178730,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ #ifdef SQLITE_TEST if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ExprInitTestInterface(db, pHash); + rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash); } #endif @@ -176702,23 +178739,26 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ ** module with sqlite. */ if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) + && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer")) && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) ){ + pHash->nRef++; rc = sqlite3_create_module_v2( db, "fts3", &fts3Module, (void *)pHash, hashDestroy ); if( rc==SQLITE_OK ){ + pHash->nRef++; rc = sqlite3_create_module_v2( - db, "fts4", &fts3Module, (void *)pHash, 0 + db, "fts4", &fts3Module, (void *)pHash, hashDestroy ); } if( rc==SQLITE_OK ){ - rc = sqlite3Fts3InitTok(db, (void *)pHash); + pHash->nRef++; + rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy); } return rc; } @@ -176727,7 +178767,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ /* An error has occurred. Delete the hash table and return the error code. */ assert( rc!=SQLITE_OK ); if( pHash ){ - sqlite3Fts3HashClear(pHash); + sqlite3Fts3HashClear(&pHash->hash); sqlite3_free(pHash); } return rc; @@ -177074,7 +179114,7 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( assert( nDoclist>0 ); assert( *pbEof==0 ); - assert( p || *piDocid==0 ); + assert_fts3_nc( p || *piDocid==0 ); assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); if( p==0 ){ @@ -182791,7 +184831,7 @@ static int fts3tokRowidMethod( ** Register the fts3tok module with database connection db. Return SQLITE_OK ** if successful or an error code if sqlite3_create_module() fails. */ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){ static const sqlite3_module fts3tok_module = { 0, /* iVersion */ fts3tokConnectMethod, /* xCreate */ @@ -182820,7 +184860,9 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ }; int rc; /* Return code */ - rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); + rc = sqlite3_create_module_v2( + db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy + ); return rc; } @@ -191179,7 +193221,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ /************** End of fts3_unicode2.c ***************************************/ -/************** Begin file json1.c *******************************************/ +/************** Begin file json.c ********************************************/ /* ** 2015-08-12 ** @@ -191192,10 +193234,10 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ****************************************************************************** ** -** This SQLite extension implements JSON functions. The interface is -** modeled after MySQL JSON functions: +** This SQLite JSON functions. ** -** https://dev.mysql.com/doc/refman/5.7/en/json.html +** This file began as an extension in ext/misc/json1.c in 2015. That +** extension proved so useful that it has now been moved into the core. ** ** For the time being, all JSON is stored as pure text. (We might add ** a JSONB type in the future which stores a binary encoding of JSON in @@ -191203,48 +193245,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** This implementation parses JSON text at 250 MB/s, so it is hard to see ** how JSONB might improve on that.) */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) -#if !defined(SQLITEINT_H) -/* #include "sqlite3ext.h" */ -#endif -SQLITE_EXTENSION_INIT1 -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* Mark a function parameter as unused, to suppress nuisance compiler -** warnings. */ -#ifndef UNUSED_PARAM -# define UNUSED_PARAM(X) (void)(X) -#endif - -#ifndef LARGEST_INT64 -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - -#ifndef deliberate_fall_through -# define deliberate_fall_through -#endif - -/* -** Versions of isspace(), isalnum() and isdigit() to which it is safe -** to pass signed char values. -*/ -#ifdef sqlite3Isdigit - /* Use the SQLite core versions if this routine is part of the - ** SQLite amalgamation */ -# define safe_isdigit(x) sqlite3Isdigit(x) -# define safe_isalnum(x) sqlite3Isalnum(x) -# define safe_isxdigit(x) sqlite3Isxdigit(x) -#else - /* Use the standard library for separate compilation */ -#include /* amalgamator: keep */ -# define safe_isdigit(x) isdigit((unsigned char)(x)) -# define safe_isalnum(x) isalnum((unsigned char)(x)) -# define safe_isxdigit(x) isxdigit((unsigned char)(x)) -#endif +#ifndef SQLITE_OMIT_JSON +/* #include "sqliteInt.h" */ /* ** Growing our own isspace() routine this way is twice as fast as @@ -191269,44 +193271,14 @@ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) +#define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) -#ifndef SQLITE_AMALGAMATION - /* Unsigned integer types. These are already defined in the sqliteInt.h, - ** but the definitions need to be repeated for separate compilation. */ - typedef sqlite3_uint64 u64; - typedef unsigned int u32; - typedef unsigned short int u16; - typedef unsigned char u8; -# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) -# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 -# endif -# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) -# define ALWAYS(X) (1) -# define NEVER(X) (0) -# elif !defined(NDEBUG) -# define ALWAYS(X) ((X)?1:(assert(0),0)) -# define NEVER(X) ((X)?(assert(0),1):0) -# else -# define ALWAYS(X) (X) -# define NEVER(X) (X) -# endif -# define testcase(X) -#endif #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) # define VVA(X) #else # define VVA(X) X #endif -/* -** Some of the testcase() macros in this file are problematic for gcov -** in that they generate false-miss errors randomly. This is a gcov problem, -** not a problem in this case. But to work around it, we disable the -** problematic test cases for production builds. -*/ -#define json_testcase(X) - /* Objects */ typedef struct JsonString JsonString; typedef struct JsonNode JsonNode; @@ -191764,10 +193736,10 @@ static u8 jsonHexToInt(int h){ */ static u32 jsonHexToInt4(const char *z){ u32 v; - assert( safe_isxdigit(z[0]) ); - assert( safe_isxdigit(z[1]) ); - assert( safe_isxdigit(z[2]) ); - assert( safe_isxdigit(z[3]) ); + assert( sqlite3Isxdigit(z[0]) ); + assert( sqlite3Isxdigit(z[1]) ); + assert( sqlite3Isxdigit(z[2]) ); + assert( sqlite3Isxdigit(z[3]) ); v = (jsonHexToInt(z[0])<<12) + (jsonHexToInt(z[1])<<8) + (jsonHexToInt(z[2])<<4) @@ -192002,7 +193974,7 @@ static int jsonParseAddNode( */ static int jsonIs4Hex(const char *z){ int i; - for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0; return 1; } @@ -192021,13 +193993,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ int x; JsonNode *pNode; const char *z = pParse->zJson; - while( safe_isspace(z[i]) ){ i++; } + while( fast_isspace(z[i]) ){ i++; } if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); if( x<0 ){ @@ -192040,14 +194012,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( z[j]!=':' ) return -1; j++; x = jsonParseValue(pParse, j); pParse->iDepth--; if( x<0 ) return -1; j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } c = z[j]; if( c==',' ) continue; if( c!='}' ) return -1; @@ -192061,7 +194033,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( iThis<0 ) return -1; memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); pParse->iDepth--; @@ -192070,7 +194042,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ return -1; } j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } c = z[j]; if( c==',' ) continue; if( c!=']' ) return -1; @@ -192107,17 +194079,17 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ return j+1; }else if( c=='n' && strncmp(z+i,"null",4)==0 - && !safe_isalnum(z[i+4]) ){ + && !sqlite3Isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_NULL, 0, 0); return i+4; }else if( c=='t' && strncmp(z+i,"true",4)==0 - && !safe_isalnum(z[i+4]) ){ + && !sqlite3Isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); return i+4; }else if( c=='f' && strncmp(z+i,"false",5)==0 - && !safe_isalnum(z[i+5]) ){ + && !sqlite3Isalnum(z[i+5]) ){ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); return i+5; }else if( c=='-' || (c>='0' && c<='9') ){ @@ -192188,7 +194160,7 @@ static int jsonParse( if( pParse->oom ) i = -1; if( i>0 ){ assert( pParse->iDepth==0 ); - while( safe_isspace(zJson[i]) ) i++; + while( fast_isspace(zJson[i]) ) i++; if( zJson[i] ) i = -1; } if( i<=0 ){ @@ -192371,14 +194343,15 @@ static JsonNode *jsonLookupStep( *pzErr = zPath; return 0; } + testcase( nKey==0 ); }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; - } - if( nKey==0 ){ - *pzErr = zPath; - return 0; + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } } j = 1; for(;;){ @@ -192416,7 +194389,7 @@ static JsonNode *jsonLookupStep( }else if( zPath[0]=='[' ){ i = 0; j = 1; - while( safe_isdigit(zPath[j]) ){ + while( sqlite3Isdigit(zPath[j]) ){ i = i*10 + zPath[j] - '0'; j++; } @@ -192437,13 +194410,13 @@ static JsonNode *jsonLookupStep( j = 1; } j = 2; - if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ unsigned int x = 0; j = 3; do{ x = x*10 + zPath[j] - '0'; j++; - }while( safe_isdigit(zPath[j]) ); + }while( sqlite3Isdigit(zPath[j]) ); if( x>i ) return 0; i -= x; } @@ -192662,7 +194635,7 @@ static void jsonTest1Func( int argc, sqlite3_value **argv ){ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); } #endif /* SQLITE_DEBUG */ @@ -192683,7 +194656,7 @@ static void jsonQuoteFunc( sqlite3_value **argv ){ JsonString jx; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); jsonInit(&jx, ctx); jsonAppendValue(&jx, argv[0]); @@ -192754,13 +194727,34 @@ static void jsonArrayLengthFunc( sqlite3_result_int64(ctx, n); } +/* +** Bit values for the flags passed into jsonExtractFunc() or +** jsonSetFunc() via the user-data value. +*/ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ + /* ** json_extract(JSON, PATH, ...) +** "->"(JSON,PATH) +** "->>"(JSON,PATH) ** -** Return the element described by PATH. Return NULL if there is no -** PATH element. If there are multiple PATHs, then return a JSON array -** with the result from each path. Throw an error if the JSON or any PATH -** is malformed. +** Return the element described by PATH. Return NULL if that PATH element +** is not found. +** +** If JSON_JSON is set or if more that one PATH argument is supplied then +** always return a JSON representation of the result. If JSON_SQL is set, +** then always return an SQL representation of the result. If neither flag +** is present and argc==2, then return JSON for objects and arrays and SQL +** for all other values. +** +** When multiple PATH arguments are supplied, the result is a JSON array +** containing the result of each PATH. +** +** Abbreviated JSON path expressions are allows if JSON_ABPATH, for +** compatibility with PG. */ static void jsonExtractFunc( sqlite3_context *ctx, @@ -192770,35 +194764,77 @@ static void jsonExtractFunc( JsonParse *p; /* The parse */ JsonNode *pNode; const char *zPath; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); JsonString jx; - int i; if( argc<2 ) return; p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; - jsonInit(&jx, ctx); - jsonAppendChar(&jx, '['); - for(i=1; inErr ) break; - if( argc>2 ){ + if( argc==2 ){ + /* With a single PATH argument */ + zPath = (const char*)sqlite3_value_text(argv[1]); + if( zPath==0 ) return; + if( flags & JSON_ABPATH ){ + if( zPath[0]!='$' ){ + /* The -> and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + */ + jsonInit(&jx, ctx); + if( sqlite3Isdigit(zPath[0]) ){ + jsonAppendRaw(&jx, "$[", 2); + jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); + jsonAppendRaw(&jx, "]", 2); + }else{ + jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='[')); + jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); + jsonAppendChar(&jx, 0); + } + pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); + jsonReset(&jx); + }else{ + pNode = jsonLookup(p, zPath, 0, ctx); + } + if( pNode ){ + if( flags & JSON_JSON ){ + jsonReturnJson(pNode, ctx, 0); + }else{ + jsonReturn(pNode, ctx, 0); + sqlite3_result_subtype(ctx, 0); + } + } + }else{ + pNode = jsonLookup(p, zPath, 0, ctx); + if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); + } + }else{ + /* Two or more PATH arguments results in a JSON array with each + ** element of the array being the value selected by one of the PATHs */ + int i; + jsonInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=1; inErr ) break; jsonAppendSeparator(&jx); if( pNode ){ jsonRenderNode(pNode, &jx, 0); }else{ jsonAppendRaw(&jx, "null", 4); } - }else if( pNode ){ - jsonReturn(pNode, ctx, 0); } + if( i==argc ){ + jsonAppendChar(&jx, ']'); + jsonResult(&jx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + jsonReset(&jx); } - if( argc>2 && i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); - sqlite3_result_subtype(ctx, JSON_SUBTYPE); - } - jsonReset(&jx); } /* This is the RFC 7396 MergePatch algorithm. @@ -192894,7 +194930,7 @@ static void jsonPatchFunc( JsonParse y; /* The patch */ JsonNode *pResult; /* The result of the merge */ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ jsonParseReset(&x); @@ -193015,7 +195051,7 @@ static void jsonReplaceFunc( if( x.nErr ) goto replace_err; if( pNode ){ assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 ); - json_testcase( pNode->eU!=0 && pNode->eU!=1 ); + testcase( pNode->eU!=0 && pNode->eU!=1 ); pNode->jnFlags |= (u8)JNODE_REPLACE; VVA( pNode->eU = 4 ); pNode->u.iReplace = i + 1; @@ -193031,6 +195067,7 @@ static void jsonReplaceFunc( jsonParseReset(&x); } + /* ** json_set(JSON, PATH, VALUE, ...) ** @@ -193053,7 +195090,7 @@ static void jsonSetFunc( const char *zPath; u32 i; int bApnd; - int bIsSet = *(int*)sqlite3_user_data(ctx); + int bIsSet = sqlite3_user_data(ctx)!=0; if( argc<1 ) return; if( (argc&1)==0 ) { @@ -193072,8 +195109,8 @@ static void jsonSetFunc( }else if( x.nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ - json_testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 ); - assert( pNode->eU!=3 || pNode->eU!=5 ); + testcase( pNode->eU!=0 && pNode->eU!=1 ); + assert( pNode->eU!=3 && pNode->eU!=5 ); VVA( pNode->eU = 4 ); pNode->jnFlags |= (u8)JNODE_REPLACE; pNode->u.iReplace = i + 1; @@ -193093,8 +195130,8 @@ static void jsonSetFunc( ** json_type(JSON) ** json_type(JSON, PATH) ** -** Return the top-level "type" of a JSON string. Throw an error if -** either the JSON or PATH inputs are not well-formed. +** Return the top-level "type" of a JSON string. json_type() raises an +** error if either the JSON or PATH inputs are not well-formed. */ static void jsonTypeFunc( sqlite3_context *ctx, @@ -193130,7 +195167,7 @@ static void jsonValidFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); p = jsonParseCached(ctx, argv, 0); sqlite3_result_int(ctx, p!=0); } @@ -193150,7 +195187,7 @@ static void jsonArrayStep( sqlite3_value **argv ){ JsonString *pStr; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ @@ -193210,8 +195247,8 @@ static void jsonGroupInverse( char *z; char c; JsonString *pStr; - UNUSED_PARAM(argc); - UNUSED_PARAM(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); #ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will @@ -193255,7 +195292,7 @@ static void jsonObjectStep( JsonString *pStr; const char *z; u32 n; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ @@ -193346,10 +195383,10 @@ static int jsonEachConnect( #define JEACH_JSON 8 #define JEACH_ROOT 9 - UNUSED_PARAM(pzErr); - UNUSED_PARAM(argv); - UNUSED_PARAM(argc); - UNUSED_PARAM(pAux); + UNUSED_PARAMETER(pzErr); + UNUSED_PARAMETER(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(pAux); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); @@ -193372,7 +195409,7 @@ static int jsonEachDisconnect(sqlite3_vtab *pVtab){ static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ JsonEachCursor *pCur; - UNUSED_PARAM(p); + UNUSED_PARAMETER(p); pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); @@ -193432,7 +195469,7 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ p->eType = pUp->eType; if( pUp->eType==JSON_ARRAY ){ assert( pUp->eU==0 || pUp->eU==3 ); - json_testcase( pUp->eU==3 ); + testcase( pUp->eU==3 ); VVA( pUp->eU = 3 ); if( iUp==p->i-1 ){ pUp->u.iKey = 0; @@ -193462,6 +195499,33 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ return SQLITE_OK; } +/* Append an object label to the JSON Path being constructed +** in pStr. +*/ +static void jsonAppendObjectPathElement( + JsonString *pStr, + JsonNode *pNode +){ + int jj, nn; + const char *z; + assert( pNode->eType==JSON_STRING ); + assert( pNode->jnFlags & JNODE_LABEL ); + assert( pNode->eU==1 ); + z = pNode->u.zJContent; + nn = pNode->n; + assert( nn>=2 ); + assert( z[0]=='"' ); + assert( z[nn-1]=='"' ); + if( nn>2 && sqlite3Isalpha(z[1]) ){ + for(jj=2; jjeType==JSON_OBJECT ); if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + jsonAppendObjectPathElement(pStr, pNode); } } @@ -193560,8 +195621,7 @@ static int jsonEachColumn( if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); }else if( p->eType==JSON_OBJECT ){ - assert( pThis->eU==1 ); - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + jsonAppendObjectPathElement(&x, pThis); } } jsonResult(&x); @@ -193619,7 +195679,7 @@ static int jsonEachBestIndex( /* This implementation assumes that JSON and ROOT are the last two ** columns in the table */ assert( JEACH_ROOT == JEACH_JSON+1 ); - UNUSED_PARAM(tab); + UNUSED_PARAMETER(tab); aIdx[0] = aIdx[1] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ @@ -193675,8 +195735,8 @@ static int jsonEachFilter( const char *zRoot = 0; sqlite3_int64 n; - UNUSED_PARAM(idxStr); - UNUSED_PARAM(argc); + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; z = (const char*)sqlite3_value_text(argv[0]); @@ -193801,108 +195861,68 @@ static sqlite3_module jsonTreeModule = { 0 /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/**************************************************************************** -** The following routines are the only publically visible identifiers in this -** file. Call the following routines in order to register the various SQL -** functions and the virtual table implemented by this file. -****************************************************************************/ - -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ - int rc = SQLITE_OK; - unsigned int i; - static const struct { - const char *zName; - int nArg; - int flag; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } aFunc[] = { - { "json", 1, 0, jsonRemoveFunc }, - { "json_array", -1, 0, jsonArrayFunc }, - { "json_array_length", 1, 0, jsonArrayLengthFunc }, - { "json_array_length", 2, 0, jsonArrayLengthFunc }, - { "json_extract", -1, 0, jsonExtractFunc }, - { "json_insert", -1, 0, jsonSetFunc }, - { "json_object", -1, 0, jsonObjectFunc }, - { "json_patch", 2, 0, jsonPatchFunc }, - { "json_quote", 1, 0, jsonQuoteFunc }, - { "json_remove", -1, 0, jsonRemoveFunc }, - { "json_replace", -1, 0, jsonReplaceFunc }, - { "json_set", -1, 1, jsonSetFunc }, - { "json_type", 1, 0, jsonTypeFunc }, - { "json_type", 2, 0, jsonTypeFunc }, - { "json_valid", 1, 0, jsonValidFunc }, - +#endif /* !defined(SQLITE_OMIT_JSON) */ + +/* +** Register JSON functions. +*/ +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ +#ifndef SQLITE_OMIT_JSON + static FuncDef aJsonFunc[] = { + JFUNCTION(json, 1, 0, jsonRemoveFunc), + JFUNCTION(json_array, -1, 0, jsonArrayFunc), + JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), + JFUNCTION(json_extract, -1, 0, jsonExtractFunc), + JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1, 0, jsonSetFunc), + JFUNCTION(json_object, -1, 0, jsonObjectFunc), + JFUNCTION(json_patch, 2, 0, jsonPatchFunc), + JFUNCTION(json_quote, 1, 0, jsonQuoteFunc), + JFUNCTION(json_remove, -1, 0, jsonRemoveFunc), + JFUNCTION(json_replace, -1, 0, jsonReplaceFunc), + JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1, 0, jsonTypeFunc), + JFUNCTION(json_type, 2, 0, jsonTypeFunc), + JFUNCTION(json_valid, 1, 0, jsonValidFunc), #if SQLITE_DEBUG - /* DEBUG and TESTING functions */ - { "json_parse", 1, 0, jsonParseFunc }, - { "json_test1", 1, 0, jsonTest1Func }, -#endif - }; - static const struct { - const char *zName; - int nArg; - void (*xStep)(sqlite3_context*,int,sqlite3_value**); - void (*xFinal)(sqlite3_context*); - void (*xValue)(sqlite3_context*); - } aAgg[] = { - { "json_group_array", 1, - jsonArrayStep, jsonArrayFinal, jsonArrayValue }, - { "json_group_object", 2, - jsonObjectStep, jsonObjectFinal, jsonObjectValue }, + JFUNCTION(json_parse, 1, 0, jsonParseFunc), + JFUNCTION(json_test1, 1, 0, jsonTest1Func), +#endif + WAGGREGATE(json_group_array, 1, 0, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS), + WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) }; -#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); +#endif +} + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +/* +** Register the JSON table-valued functions +*/ +SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){ + int rc = SQLITE_OK; static const struct { - const char *zName; - sqlite3_module *pModule; + const char *zName; + sqlite3_module *pModule; } aMod[] = { { "json_each", &jsonEachModule }, { "json_tree", &jsonTreeModule }, }; -#endif - static const int enc = - SQLITE_UTF8 | - SQLITE_DETERMINISTIC | - SQLITE_INNOCUOUS; - for(i=0; iz[0]) ) p->z++; + while( fast_isspace(p->z[0]) ) p->z++; return p->z[0]; } @@ -203306,7 +205323,7 @@ static char *rbuVacuumTableStart( ** the caller has to use an OFFSET clause to extract only the required ** rows from the sourct table, just as it does for an RBU update operation. */ -char *rbuVacuumIndexStart( +static char *rbuVacuumIndexStart( sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter /* RBU iterator object */ ){ @@ -208151,6 +210168,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ){ pIdxInfo->orderByConsumed = 1; } + sqlite3VtabWriteAll(pIdxInfo); return SQLITE_OK; } @@ -224760,8 +226778,12 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ int iRowidOff; iRowidOff = fts5LeafFirstRowidOff(pNew); if( iRowidOff ){ - pIter->pLeaf = pNew; - pIter->iLeafOffset = iRowidOff; + if( iRowidOff>=pNew->szLeaf ){ + p->rc = FTS5_CORRUPT; + }else{ + pIter->pLeaf = pNew; + pIter->iLeafOffset = iRowidOff; + } } } @@ -228442,7 +230464,7 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ - if( nToken ) memcpy(&buf.p[1], pToken, nToken); + if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to @@ -230501,7 +232523,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){ rc = sqlite3_step(pSorter->pStmt); if( rc==SQLITE_DONE ){ rc = SQLITE_OK; - CsrFlagSet(pCsr, FTS5CSR_EOF); + CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT); }else if( rc==SQLITE_ROW ){ const u8 *a; const u8 *aBlob; @@ -232490,7 +234512,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2021-11-27 14:13:22 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe", -1, SQLITE_TRANSIENT); } /* diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h index 6bf2c58aed..1c267a40a9 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h @@ -147,9 +147,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.37.0" -#define SQLITE_VERSION_NUMBER 3037000 -#define SQLITE_SOURCE_ID "2021-11-27 14:13:22 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a" +#define SQLITE_VERSION "3.38.5" +#define SQLITE_VERSION_NUMBER 3038005 +#define SQLITE_SOURCE_ID "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -567,7 +567,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ /* ** CAPI3REF: Flags For File Open Operations @@ -3825,13 +3825,14 @@ SQLITE_API void sqlite3_free_filename(char*); ** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving -** interfaces are: +** interfaces include the following: ** **
    **
  • sqlite3_errcode() **
  • sqlite3_extended_errcode() **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() +**
  • sqlite3_error_offset() **
** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -3846,6 +3847,13 @@ SQLITE_API void sqlite3_free_filename(char*); ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -3865,6 +3873,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Prepared Statement Object @@ -4276,6 +4285,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a ** read-only no-op if the table already exists, but ** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -4344,6 +4357,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used as arguments @@ -4965,6 +4980,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** ** Warning: ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. In a multithreaded environment, ** an unprotected sqlite3_value object may only be used safely with @@ -4978,7 +4997,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** -** The these routines may attempt to convert the datatype of the result. +** These routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions @@ -5003,7 +5022,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** TEXT BLOB No change ** BLOB INTEGER [CAST] to INTEGER ** BLOB FLOAT [CAST] to REAL -** BLOB TEXT Add a zero terminator if needed +** BLOB TEXT [CAST] to TEXT, ensure zero terminator ** ** )^ ** @@ -7123,24 +7142,56 @@ struct sqlite3_index_info { ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of +** an operator that is part of a constraint term in the WHERE clause of ** a query that uses a [virtual table]. -*/ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -#define SQLITE_INDEX_CONSTRAINT_NE 68 -#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -#define SQLITE_INDEX_CONSTRAINT_IS 72 -#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is no commonly needed. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -7169,7 +7220,7 @@ struct sqlite3_index_info { ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is -** NULL then no new module is create and any existing modules with the +** NULL then no new module is created and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] @@ -7945,7 +7996,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 -#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -8468,6 +8520,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
SQLITE_STMTSTATUS_FILTER_HIT
+** SQLITE_STMTSTATUS_FILTER_MISS
+**
^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal. +** ** [[SQLITE_STMTSTATUS_MEMUSED]]
SQLITE_STMTSTATUS_MEMUSED
**
^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually @@ -8482,6 +8544,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 /* @@ -9450,19 +9514,269 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info ** ** This function may only be called from within a call to the [xBestIndex] -** method of a [virtual table]. +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. +** +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. +** +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: ** -** The first argument must be the sqlite3_index_info object that is the -** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the sqlite3_index_info -** structure passed to xBestIndex. This function returns a pointer to a buffer -** containing the name of the collation sequence for the corresponding -** constraint. +**
    +**
  1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

  2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

  3. Otherwise, "BINARY" is returned. +**

*/ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
  1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

  2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

  3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all "aOrderBy" columns +** are adjacent.)^ ^(Furthermore, only a single row for each particular +** combination of values in the columns identified by the "aOrderBy" field +** needs to be returned.)^ ^It is always ok for two or more rows with the same +** values in all "aOrderBy" columns to be returned, as long as all such rows +** are adjacent. ^The virtual table may, if it chooses, omit extra rows +** that have the same value for all columns identified by "aOrderBy". +** ^However omitting the extra rows is optional. +** This mode is used for a DISTINCT query. +**

+** +** ^For the purposes of comparing virtual table output values to see if the +** values are same value for sorting purposes, two NULL values are considered +** to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** the "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**
    +**
  1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

  2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

+** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
    +**
  1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. +** +**

  2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

)^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing use the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
+**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
+**        rc==SQLITE_OK && pVal
+**        rc=sqlite3_vtab_in_next(pList, &pVal)
+**    ){
+**      // do something with pVal
+**    }
+**    if( rc!=SQLITE_OK ){
+**      // an error has occurred
+**    }
+** 
)^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); + /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3.go index 6ade8c9712..e037857db4 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go @@ -4,6 +4,7 @@ // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. +//go:build cgo // +build cgo package sqlite3 @@ -233,8 +234,14 @@ const ( columnTimestamp string = "timestamp" ) +// This variable can be replaced with -ldflags like below: +// go build -ldflags="-X 'github.com/mattn/go-sqlite3.driverName=my-sqlite3'" +var driverName = "sqlite3" + func init() { - sql.Register("sqlite3", &SQLiteDriver{}) + if driverName != "" { + sql.Register(driverName, &SQLiteDriver{}) + } } // Version returns SQLite library version information. @@ -290,6 +297,51 @@ const ( /*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/ ) +// Standard File Control Opcodes +// See: https://www.sqlite.org/c3ref/c_fcntl_begin_atomic_write.html +const ( + SQLITE_FCNTL_LOCKSTATE = int(1) + SQLITE_FCNTL_GET_LOCKPROXYFILE = int(2) + SQLITE_FCNTL_SET_LOCKPROXYFILE = int(3) + SQLITE_FCNTL_LAST_ERRNO = int(4) + SQLITE_FCNTL_SIZE_HINT = int(5) + SQLITE_FCNTL_CHUNK_SIZE = int(6) + SQLITE_FCNTL_FILE_POINTER = int(7) + SQLITE_FCNTL_SYNC_OMITTED = int(8) + SQLITE_FCNTL_WIN32_AV_RETRY = int(9) + SQLITE_FCNTL_PERSIST_WAL = int(10) + SQLITE_FCNTL_OVERWRITE = int(11) + SQLITE_FCNTL_VFSNAME = int(12) + SQLITE_FCNTL_POWERSAFE_OVERWRITE = int(13) + SQLITE_FCNTL_PRAGMA = int(14) + SQLITE_FCNTL_BUSYHANDLER = int(15) + SQLITE_FCNTL_TEMPFILENAME = int(16) + SQLITE_FCNTL_MMAP_SIZE = int(18) + SQLITE_FCNTL_TRACE = int(19) + SQLITE_FCNTL_HAS_MOVED = int(20) + SQLITE_FCNTL_SYNC = int(21) + SQLITE_FCNTL_COMMIT_PHASETWO = int(22) + SQLITE_FCNTL_WIN32_SET_HANDLE = int(23) + SQLITE_FCNTL_WAL_BLOCK = int(24) + SQLITE_FCNTL_ZIPVFS = int(25) + SQLITE_FCNTL_RBU = int(26) + SQLITE_FCNTL_VFS_POINTER = int(27) + SQLITE_FCNTL_JOURNAL_POINTER = int(28) + SQLITE_FCNTL_WIN32_GET_HANDLE = int(29) + SQLITE_FCNTL_PDB = int(30) + SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = int(31) + SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = int(32) + SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = int(33) + SQLITE_FCNTL_LOCK_TIMEOUT = int(34) + SQLITE_FCNTL_DATA_VERSION = int(35) + SQLITE_FCNTL_SIZE_LIMIT = int(36) + SQLITE_FCNTL_CKPT_DONE = int(37) + SQLITE_FCNTL_RESERVE_BYTES = int(38) + SQLITE_FCNTL_CKPT_START = int(39) + SQLITE_FCNTL_EXTERNAL_READER = int(40) + SQLITE_FCNTL_CKSM_FILE = int(41) +) + // SQLiteDriver implements driver.Driver. type SQLiteDriver struct { Extensions []string @@ -1806,6 +1858,31 @@ func (c *SQLiteConn) SetLimit(id int, newVal int) int { return int(C._sqlite3_limit(c.db, C.int(id), C.int(newVal))) } +// SetFileControlInt invokes the xFileControl method on a given database. The +// dbName is the name of the database. It will default to "main" if left blank. +// The op is one of the opcodes prefixed by "SQLITE_FCNTL_". The arg argument +// and return code are both opcode-specific. Please see the SQLite documentation. +// +// This method is not thread-safe as the returned error code can be changed by +// another call if invoked concurrently. +// +// See: sqlite3_file_control, https://www.sqlite.org/c3ref/file_control.html +func (c *SQLiteConn) SetFileControlInt(dbName string, op int, arg int) error { + if dbName == "" { + dbName = "main" + } + + cDBName := C.CString(dbName) + defer C.free(unsafe.Pointer(cDBName)) + + cArg := C.int(arg) + rv := C.sqlite3_file_control(c.db, cDBName, C.int(op), unsafe.Pointer(&cArg)) + if rv != C.SQLITE_OK { + return c.lastError() + } + return nil +} + // Close the statement. func (s *SQLiteStmt) Close() error { s.mu.Lock() diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go deleted file mode 100644 index 7cfce76326..0000000000 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2019 Yasuhiro Matsumoto . -// -// Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file. - -// +build sqlite_json sqlite_json1 json1 - -package sqlite3 - -/* -#cgo CFLAGS: -DSQLITE_ENABLE_JSON1 -*/ -import "C" diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go index b2e18bbcbb..b43e4821b8 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go @@ -33,7 +33,7 @@ import ( // The callback is passed a SQLitePreUpdateData struct with the data for // the update, as well as methods for fetching copies of impacted data. // -// If there is an existing update hook for this connection, it will be +// If there is an existing preupdate hook for this connection, it will be // removed. If callback is nil the existing hook (if any) will be removed // without creating a new one. func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go index 8df453dea3..c510a15b43 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go @@ -13,7 +13,7 @@ package sqlite3 // The callback is passed a SQLitePreUpdateData struct with the data for // the update, as well as methods for fetching copies of impacted data. // -// If there is an existing update hook for this connection, it will be +// If there is an existing preupdate hook for this connection, it will be // removed. If callback is nil the existing hook (if any) will be removed // without creating a new one. func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h index fd6e2d4e86..301cba6cca 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h @@ -349,6 +349,13 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); + /* Version 3.38.0 and later */ + int (*error_offset)(sqlite3*); + int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); + int (*vtab_distinct)(sqlite3_index_info*); + int (*vtab_in)(sqlite3_index_info*,int,int); + int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); + int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); }; /* @@ -660,6 +667,13 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_total_changes64 sqlite3_api->total_changes64 /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +/* Version 3.38.0 and later */ +#define sqlite3_error_offset sqlite3_api->error_offset +#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value +#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct +#define sqlite3_vtab_in sqlite3_api->vtab_in +#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first +#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/vendor/github.com/moby/term/tc.go b/vendor/github.com/moby/term/tc.go index 65556027a6..8a5e09f584 100644 --- a/vendor/github.com/moby/term/tc.go +++ b/vendor/github.com/moby/term/tc.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package term diff --git a/vendor/github.com/moby/term/term.go b/vendor/github.com/moby/term/term.go index 29c6acf1c7..2dd3d090df 100644 --- a/vendor/github.com/moby/term/term.go +++ b/vendor/github.com/moby/term/term.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows // Package term provides structures and helper functions to work with @@ -6,18 +7,14 @@ package term import ( "errors" - "fmt" "io" "os" - "os/signal" "golang.org/x/sys/unix" ) -var ( - // ErrInvalidState is returned if the state of the terminal is invalid. - ErrInvalidState = errors.New("Invalid terminal state") -) +// ErrInvalidState is returned if the state of the terminal is invalid. +var ErrInvalidState = errors.New("Invalid terminal state") // State represents the state of the terminal. type State struct { @@ -81,7 +78,6 @@ func DisableEcho(fd uintptr, state *State) error { if err := tcset(fd, &newState); err != nil { return err } - handleInterrupt(fd, state) return nil } @@ -93,7 +89,6 @@ func SetRawTerminal(fd uintptr) (*State, error) { if err != nil { return nil, err } - handleInterrupt(fd, oldState) return oldState, err } @@ -103,18 +98,3 @@ func SetRawTerminal(fd uintptr) (*State, error) { func SetRawTerminalOutput(fd uintptr) (*State, error) { return nil, nil } - -func handleInterrupt(fd uintptr, state *State) { - sigchan := make(chan os.Signal, 1) - signal.Notify(sigchan, os.Interrupt) - go func() { - for range sigchan { - // quit cleanly and the new terminal item is on a new line - fmt.Println() - signal.Stop(sigchan) - close(sigchan) - RestoreTerminal(fd, state) - os.Exit(1) - } - }() -} diff --git a/vendor/github.com/moby/term/term_windows.go b/vendor/github.com/moby/term/term_windows.go index ba82960d4a..3cdc8edbda 100644 --- a/vendor/github.com/moby/term/term_windows.go +++ b/vendor/github.com/moby/term/term_windows.go @@ -66,10 +66,6 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { } } - // Temporarily use STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and - // STD_ERROR_HANDLE from syscall rather than x/sys/windows as long as - // go-ansiterm hasn't switch to x/sys/windows. - // TODO: switch back to x/sys/windows once go-ansiterm has switched if emulateStdin { h := uint32(windows.STD_INPUT_HANDLE) stdIn = windowsconsole.NewAnsiReader(int(h)) diff --git a/vendor/github.com/moby/term/termios.go b/vendor/github.com/moby/term/termios.go index 0f028e2273..99c0f7de60 100644 --- a/vendor/github.com/moby/term/termios.go +++ b/vendor/github.com/moby/term/termios.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package term diff --git a/vendor/github.com/moby/term/termios_bsd.go b/vendor/github.com/moby/term/termios_bsd.go index 922dd4baab..45f77e03c7 100644 --- a/vendor/github.com/moby/term/termios_bsd.go +++ b/vendor/github.com/moby/term/termios_bsd.go @@ -1,3 +1,4 @@ +//go:build darwin || freebsd || openbsd || netbsd // +build darwin freebsd openbsd netbsd package term diff --git a/vendor/github.com/moby/term/termios_nonbsd.go b/vendor/github.com/moby/term/termios_nonbsd.go index 038fd61ba1..88b7b21563 100644 --- a/vendor/github.com/moby/term/termios_nonbsd.go +++ b/vendor/github.com/moby/term/termios_nonbsd.go @@ -1,4 +1,5 @@ -//+build !darwin,!freebsd,!netbsd,!openbsd,!windows +//go:build !darwin && !freebsd && !netbsd && !openbsd && !windows +// +build !darwin,!freebsd,!netbsd,!openbsd,!windows package term diff --git a/vendor/github.com/moby/term/windows/ansi_reader.go b/vendor/github.com/moby/term/windows/ansi_reader.go index 155251521b..f32aa537ef 100644 --- a/vendor/github.com/moby/term/windows/ansi_reader.go +++ b/vendor/github.com/moby/term/windows/ansi_reader.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package windowsconsole @@ -190,7 +191,6 @@ func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) stri // -S Suspends printing on the screen (does not stop the program). // -U Deletes all characters on the current line. Also called the KILL key. // -E Quits current command and creates a core - } // +Key generates ESC N Key diff --git a/vendor/github.com/moby/term/windows/ansi_writer.go b/vendor/github.com/moby/term/windows/ansi_writer.go index ccb5ef0775..4243307fd3 100644 --- a/vendor/github.com/moby/term/windows/ansi_writer.go +++ b/vendor/github.com/moby/term/windows/ansi_writer.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package windowsconsole diff --git a/vendor/github.com/moby/term/windows/console.go b/vendor/github.com/moby/term/windows/console.go index 993694ddcd..116b74e8f5 100644 --- a/vendor/github.com/moby/term/windows/console.go +++ b/vendor/github.com/moby/term/windows/console.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package windowsconsole diff --git a/vendor/github.com/moby/term/winsize.go b/vendor/github.com/moby/term/winsize.go index 1ef98d5996..bea8d4595c 100644 --- a/vendor/github.com/moby/term/winsize.go +++ b/vendor/github.com/moby/term/winsize.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package term diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go index f7d2eaf0b3..5db5d1a7bf 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go @@ -39,6 +39,8 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go command.AbortWith("Found no test suites") } + internal.VerifyCLIAndFrameworkVersion(suites) + opc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers()) opc.StartCompiling(suites, goFlagsConfig) diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go new file mode 100644 index 0000000000..9da1bab3db --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go @@ -0,0 +1,54 @@ +package internal + +import ( + "fmt" + "os/exec" + "regexp" + "strings" + + "github.com/onsi/ginkgo/v2/formatter" + "github.com/onsi/ginkgo/v2/types" +) + +var versiorRe = regexp.MustCompile(`v(\d+\.\d+\.\d+)`) + +func VerifyCLIAndFrameworkVersion(suites TestSuites) { + cliVersion := types.VERSION + mismatches := map[string][]string{} + + for _, suite := range suites { + cmd := exec.Command("go", "list", "-m", "github.com/onsi/ginkgo/v2") + cmd.Dir = suite.Path + output, err := cmd.CombinedOutput() + if err != nil { + continue + } + components := strings.Split(string(output), " ") + if len(components) != 2 { + continue + } + matches := versiorRe.FindStringSubmatch(components[1]) + if matches == nil || len(matches) != 2 { + continue + } + libraryVersion := matches[1] + if cliVersion != libraryVersion { + mismatches[libraryVersion] = append(mismatches[libraryVersion], suite.PackageName) + } + } + + if len(mismatches) == 0 { + return + } + + fmt.Println(formatter.F("{{red}}{{bold}}Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:{{/}}")) + + fmt.Println(formatter.Fi(1, "Ginkgo CLI Version:")) + fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}}", cliVersion)) + fmt.Println(formatter.Fi(1, "Mismatched package versions found:")) + for version, packages := range mismatches { + fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}} used by %s", version, strings.Join(packages, ", "))) + } + fmt.Println("") + fmt.Println(formatter.Fiw(1, formatter.COLS, "{{gray}}Ginkgo will continue to attempt to run but you may see errors (including flag parsing errors) and should either update your go.mod or your version of the Ginkgo CLI to match.\n\nTo install the matching version of the CLI run\n {{bold}}go install github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file. Alternatively you can use\n {{bold}}go run github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file to invoke the matching version of the Ginkgo CLI.\n\nIf you are attempting to test multiple packages that each have a different version of the Ginkgo library with a single Ginkgo CLI that is currently unsupported.\n{{/}}")) +} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go index 4328ab3910..67ec5ab757 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go @@ -47,7 +47,7 @@ func packageNameForImport(f *ast.File, path string) *string { // or nil otherwise. func importSpec(f *ast.File, path string) *ast.ImportSpec { for _, s := range f.Imports { - if importPath(s) == path { + if strings.HasPrefix(importPath(s), path) { return s } } diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go index 8ee0acc818..aaed4d570e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go @@ -24,7 +24,7 @@ func BuildRunCommand() command.Command { panic(err) } - interruptHandler := interrupt_handler.NewInterruptHandler(0, nil) + interruptHandler := interrupt_handler.NewInterruptHandler(nil) interrupt_handler.SwallowSigQuit() return command.Command{ @@ -69,6 +69,8 @@ func (r *SpecRunner) RunSpecs(args []string, additionalArgs []string) { skippedSuites := suites.WithState(internal.TestSuiteStateSkippedByFilter) suites = suites.WithoutState(internal.TestSuiteStateSkippedByFilter) + internal.VerifyCLIAndFrameworkVersion(suites) + if len(skippedSuites) > 0 { fmt.Println("Will skip:") for _, skippedSuite := range skippedSuites { @@ -115,7 +117,7 @@ OUTER_LOOP: } suites[suiteIdx] = suite - if r.interruptHandler.Status().Interrupted { + if r.interruptHandler.Status().Interrupted() { opc.StopAndDrain() break OUTER_LOOP } diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go index 83dbeb1e89..bde4193ce7 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go @@ -22,7 +22,7 @@ func BuildWatchCommand() command.Command { if err != nil { panic(err) } - interruptHandler := interrupt_handler.NewInterruptHandler(0, nil) + interruptHandler := interrupt_handler.NewInterruptHandler(nil) interrupt_handler.SwallowSigQuit() return command.Command{ @@ -65,6 +65,8 @@ type SpecWatcher struct { func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) { suites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter) + internal.VerifyCLIAndFrameworkVersion(suites) + if len(suites) == 0 { command.AbortWith("Found no test suites") } @@ -127,7 +129,7 @@ func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) { w.updateSeed() w.computeSuccinctMode(len(suites)) for idx := range suites { - if w.interruptHandler.Status().Interrupted { + if w.interruptHandler.Status().Interrupted() { return } deltaTracker.WillRun(suites[idx]) @@ -156,7 +158,7 @@ func (w *SpecWatcher) compileAndRun(suite internal.TestSuite, additionalArgs []s fmt.Println(suite.CompilationError.Error()) return suite } - if w.interruptHandler.Status().Interrupted { + if w.interruptHandler.Status().Interrupted() { return suite } suite = internal.RunCompiledSuite(suite, w.suiteConfig, w.reporterConfig, w.cliConfig, w.goFlagsConfig, additionalArgs) diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go index aca7d1c433..ac6f510408 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go @@ -1,39 +1,38 @@ package interrupt_handler import ( - "fmt" "os" "os/signal" - "runtime" "sync" "syscall" "time" - "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/internal/parallel_support" ) -const TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION = 30 * time.Second -const TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT = 10 const ABORT_POLLING_INTERVAL = 500 * time.Millisecond -const ABORT_REPEAT_INTERRUPT_DURATION = 30 * time.Second type InterruptCause uint const ( InterruptCauseInvalid InterruptCause = iota - InterruptCauseSignal - InterruptCauseTimeout InterruptCauseAbortByOtherProcess ) +type InterruptLevel uint + +const ( + InterruptLevelUninterrupted InterruptLevel = iota + InterruptLevelCleanupAndReport + InterruptLevelReportOnly + InterruptLevelBailOut +) + func (ic InterruptCause) String() string { switch ic { case InterruptCauseSignal: return "Interrupted by User" - case InterruptCauseTimeout: - return "Interrupted by Timeout" case InterruptCauseAbortByOtherProcess: return "Interrupted by Other Ginkgo Process" } @@ -41,37 +40,49 @@ func (ic InterruptCause) String() string { } type InterruptStatus struct { - Interrupted bool - Channel chan interface{} - Cause InterruptCause + Channel chan interface{} + Level InterruptLevel + Cause InterruptCause +} + +func (s InterruptStatus) Interrupted() bool { + return s.Level != InterruptLevelUninterrupted +} + +func (s InterruptStatus) Message() string { + return s.Cause.String() +} + +func (s InterruptStatus) ShouldIncludeProgressReport() bool { + return s.Cause != InterruptCauseAbortByOtherProcess } type InterruptHandlerInterface interface { Status() InterruptStatus - SetInterruptPlaceholderMessage(string) - ClearInterruptPlaceholderMessage() - InterruptMessageWithStackTraces() string } type InterruptHandler struct { - c chan interface{} - lock *sync.Mutex - interrupted bool - interruptPlaceholderMessage string - interruptCause InterruptCause - client parallel_support.Client - stop chan interface{} + c chan interface{} + lock *sync.Mutex + level InterruptLevel + cause InterruptCause + client parallel_support.Client + stop chan interface{} + signals []os.Signal } -func NewInterruptHandler(timeout time.Duration, client parallel_support.Client) *InterruptHandler { +func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler { + if len(signals) == 0 { + signals = []os.Signal{os.Interrupt, syscall.SIGTERM} + } handler := &InterruptHandler{ - c: make(chan interface{}), - lock: &sync.Mutex{}, - interrupted: false, - stop: make(chan interface{}), - client: client, + c: make(chan interface{}), + lock: &sync.Mutex{}, + stop: make(chan interface{}), + client: client, + signals: signals, } - handler.registerForInterrupts(timeout) + handler.registerForInterrupts() return handler } @@ -79,30 +90,22 @@ func (handler *InterruptHandler) Stop() { close(handler.stop) } -func (handler *InterruptHandler) registerForInterrupts(timeout time.Duration) { +func (handler *InterruptHandler) registerForInterrupts() { // os signal handling signalChannel := make(chan os.Signal, 1) - signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) - - // timeout handling - var timeoutChannel <-chan time.Time - var timeoutTimer *time.Timer - if timeout > 0 { - timeoutTimer = time.NewTimer(timeout) - timeoutChannel = timeoutTimer.C - } + signal.Notify(signalChannel, handler.signals...) // cross-process abort handling - var abortChannel chan bool + var abortChannel chan interface{} if handler.client != nil { - abortChannel = make(chan bool) + abortChannel = make(chan interface{}) go func() { pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL) for { select { case <-pollTicker.C: if handler.client.ShouldAbort() { - abortChannel <- true + close(abortChannel) pollTicker.Stop() return } @@ -114,55 +117,37 @@ func (handler *InterruptHandler) registerForInterrupts(timeout time.Duration) { }() } - // listen for any interrupt signals - // note that some (timeouts, cross-process aborts) will only trigger once - // for these we set up a ticker to keep interrupting the suite until it ends - // this ensures any `AfterEach` or `AfterSuite`s that get stuck cleaning up - // get interrupted eventually - go func() { + go func(abortChannel chan interface{}) { var interruptCause InterruptCause - var repeatChannel <-chan time.Time - var repeatTicker *time.Ticker for { select { case <-signalChannel: interruptCause = InterruptCauseSignal - case <-timeoutChannel: - interruptCause = InterruptCauseTimeout - repeatInterruptTimeout := timeout / time.Duration(TIMEOUT_REPEAT_INTERRUPT_FRACTION_OF_TIMEOUT) - if repeatInterruptTimeout > TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION { - repeatInterruptTimeout = TIMEOUT_REPEAT_INTERRUPT_MAXIMUM_DURATION - } - timeoutTimer.Stop() - repeatTicker = time.NewTicker(repeatInterruptTimeout) - repeatChannel = repeatTicker.C case <-abortChannel: interruptCause = InterruptCauseAbortByOtherProcess - repeatTicker = time.NewTicker(ABORT_REPEAT_INTERRUPT_DURATION) - repeatChannel = repeatTicker.C - case <-repeatChannel: - //do nothing, just interrupt again using the same interruptCause case <-handler.stop: - if timeoutTimer != nil { - timeoutTimer.Stop() - } - if repeatTicker != nil { - repeatTicker.Stop() - } signal.Stop(signalChannel) return } + abortChannel = nil + handler.lock.Lock() - handler.interruptCause = interruptCause - if handler.interruptPlaceholderMessage != "" { - fmt.Println(handler.interruptPlaceholderMessage) + oldLevel := handler.level + handler.cause = interruptCause + if handler.level == InterruptLevelUninterrupted { + handler.level = InterruptLevelCleanupAndReport + } else if handler.level == InterruptLevelCleanupAndReport { + handler.level = InterruptLevelReportOnly + } else if handler.level == InterruptLevelReportOnly { + handler.level = InterruptLevelBailOut + } + if handler.level != oldLevel { + close(handler.c) + handler.c = make(chan interface{}) } - handler.interrupted = true - close(handler.c) - handler.c = make(chan interface{}) handler.lock.Unlock() } - }() + }(abortChannel) } func (handler *InterruptHandler) Status() InterruptStatus { @@ -170,43 +155,8 @@ func (handler *InterruptHandler) Status() InterruptStatus { defer handler.lock.Unlock() return InterruptStatus{ - Interrupted: handler.interrupted, - Channel: handler.c, - Cause: handler.interruptCause, - } -} - -func (handler *InterruptHandler) SetInterruptPlaceholderMessage(message string) { - handler.lock.Lock() - defer handler.lock.Unlock() - - handler.interruptPlaceholderMessage = message -} - -func (handler *InterruptHandler) ClearInterruptPlaceholderMessage() { - handler.lock.Lock() - defer handler.lock.Unlock() - - handler.interruptPlaceholderMessage = "" -} - -func (handler *InterruptHandler) InterruptMessageWithStackTraces() string { - handler.lock.Lock() - out := fmt.Sprintf("%s\n\n", handler.interruptCause.String()) - defer handler.lock.Unlock() - if handler.interruptCause == InterruptCauseAbortByOtherProcess { - return out - } - out += "Here's a stack trace of all running goroutines:\n" - buf := make([]byte, 8192) - for { - n := runtime.Stack(buf, true) - if n < len(buf) { - buf = buf[:n] - break - } - buf = make([]byte, 2*len(buf)) + Level: handler.level, + Channel: handler.c, + Cause: handler.cause, } - out += formatter.Fi(1, "%s", string(buf)) - return out } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go index 7d5cb0b631..b3cd64292a 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go @@ -42,6 +42,8 @@ type Client interface { PostSuiteWillBegin(report types.Report) error PostDidRun(report types.SpecReport) error PostSuiteDidEnd(report types.Report) error + PostReportBeforeSuiteCompleted(state types.SpecState) error + BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) BlockUntilNonprimaryProcsHaveFinished() error @@ -49,6 +51,7 @@ type Client interface { FetchNextCounter() (int, error) PostAbort() error ShouldAbort() bool + PostEmitProgressReport(report types.ProgressReport) error Write(p []byte) (int, error) } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go index d076d5d1c1..6547c7a66e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go @@ -94,6 +94,23 @@ func (client *httpClient) PostSuiteDidEnd(report types.Report) error { return client.post("/suite-did-end", report) } +func (client *httpClient) PostEmitProgressReport(report types.ProgressReport) error { + return client.post("/progress-report", report) +} + +func (client *httpClient) PostReportBeforeSuiteCompleted(state types.SpecState) error { + return client.post("/report-before-suite-completed", state) +} + +func (client *httpClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) { + var state types.SpecState + err := client.poll("/report-before-suite-state", &state) + if err == ErrorGone { + return types.SpecStateFailed, nil + } + return state, err +} + func (client *httpClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { beforeSuiteState := BeforeSuiteState{ State: state, diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go index ca1dcdca55..d2c71ab1b2 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go @@ -26,7 +26,7 @@ type httpServer struct { handler *ServerHandler } -//Create a new server, automatically selecting a port +// Create a new server, automatically selecting a port func newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer, error) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { @@ -38,7 +38,7 @@ func newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer, }, nil } -//Start the server. You don't need to `go s.Start()`, just `s.Start()` +// Start the server. You don't need to `go s.Start()`, just `s.Start()` func (server *httpServer) Start() { httpServer := &http.Server{} mux := http.NewServeMux() @@ -49,8 +49,11 @@ func (server *httpServer) Start() { mux.HandleFunc("/did-run", server.didRun) mux.HandleFunc("/suite-did-end", server.specSuiteDidEnd) mux.HandleFunc("/emit-output", server.emitOutput) + mux.HandleFunc("/progress-report", server.emitProgressReport) //synchronization endpoints + mux.HandleFunc("/report-before-suite-completed", server.handleReportBeforeSuiteCompleted) + mux.HandleFunc("/report-before-suite-state", server.handleReportBeforeSuiteState) mux.HandleFunc("/before-suite-completed", server.handleBeforeSuiteCompleted) mux.HandleFunc("/before-suite-state", server.handleBeforeSuiteState) mux.HandleFunc("/have-nonprimary-procs-finished", server.handleHaveNonprimaryProcsFinished) @@ -62,12 +65,12 @@ func (server *httpServer) Start() { go httpServer.Serve(server.listener) } -//Stop the server +// Stop the server func (server *httpServer) Close() { server.listener.Close() } -//The address the server can be reached it. Pass this into the `ForwardingReporter`. +// The address the server can be reached it. Pass this into the `ForwardingReporter`. func (server *httpServer) Address() string { return "http://" + server.listener.Addr().String() } @@ -92,7 +95,7 @@ func (server *httpServer) RegisterAlive(node int, alive func() bool) { // Streaming Endpoints // -//The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters` +// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters` func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object interface{}) bool { defer request.Body.Close() if json.NewDecoder(request.Body).Decode(object) != nil { @@ -155,6 +158,31 @@ func (server *httpServer) emitOutput(writer http.ResponseWriter, request *http.R server.handleError(server.handler.EmitOutput(output, &n), writer) } +func (server *httpServer) emitProgressReport(writer http.ResponseWriter, request *http.Request) { + var report types.ProgressReport + if !server.decode(writer, request, &report) { + return + } + server.handleError(server.handler.EmitProgressReport(report, voidReceiver), writer) +} + +func (server *httpServer) handleReportBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) { + var state types.SpecState + if !server.decode(writer, request, &state) { + return + } + + server.handleError(server.handler.ReportBeforeSuiteCompleted(state, voidReceiver), writer) +} + +func (server *httpServer) handleReportBeforeSuiteState(writer http.ResponseWriter, request *http.Request) { + var state types.SpecState + if server.handleError(server.handler.ReportBeforeSuiteState(voidSender, &state), writer) { + return + } + json.NewEncoder(writer).Encode(state) +} + func (server *httpServer) handleBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) { var beforeSuiteState BeforeSuiteState if !server.decode(writer, request, &beforeSuiteState) { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go index 4e83b09703..59e8e6fd0a 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go @@ -72,6 +72,23 @@ func (client *rpcClient) Write(p []byte) (int, error) { return n, err } +func (client *rpcClient) PostEmitProgressReport(report types.ProgressReport) error { + return client.client.Call("Server.EmitProgressReport", report, voidReceiver) +} + +func (client *rpcClient) PostReportBeforeSuiteCompleted(state types.SpecState) error { + return client.client.Call("Server.ReportBeforeSuiteCompleted", state, voidReceiver) +} + +func (client *rpcClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) { + var state types.SpecState + err := client.poll("Server.ReportBeforeSuiteState", &state) + if err == ErrorGone { + return types.SpecStateFailed, nil + } + return state, err +} + func (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { beforeSuiteState := BeforeSuiteState{ State: state, diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go index ca471cf394..a6d98793e9 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go @@ -18,16 +18,17 @@ var voidSender Void // It handles all the business logic to avoid duplication between the two servers type ServerHandler struct { - done chan interface{} - outputDestination io.Writer - reporter reporters.Reporter - alives []func() bool - lock *sync.Mutex - beforeSuiteState BeforeSuiteState - parallelTotal int - counter int - counterLock *sync.Mutex - shouldAbort bool + done chan interface{} + outputDestination io.Writer + reporter reporters.Reporter + alives []func() bool + lock *sync.Mutex + beforeSuiteState BeforeSuiteState + reportBeforeSuiteState types.SpecState + parallelTotal int + counter int + counterLock *sync.Mutex + shouldAbort bool numSuiteDidBegins int numSuiteDidEnds int @@ -37,11 +38,12 @@ type ServerHandler struct { func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHandler { return &ServerHandler{ - reporter: reporter, - lock: &sync.Mutex{}, - counterLock: &sync.Mutex{}, - alives: make([]func() bool, parallelTotal), - beforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid}, + reporter: reporter, + lock: &sync.Mutex{}, + counterLock: &sync.Mutex{}, + alives: make([]func() bool, parallelTotal), + beforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid}, + parallelTotal: parallelTotal, outputDestination: os.Stdout, done: make(chan interface{}), @@ -108,6 +110,13 @@ func (handler *ServerHandler) EmitOutput(output []byte, n *int) error { return err } +func (handler *ServerHandler) EmitProgressReport(report types.ProgressReport, _ *Void) error { + handler.lock.Lock() + defer handler.lock.Unlock() + handler.reporter.EmitProgressReport(report) + return nil +} + func (handler *ServerHandler) registerAlive(proc int, alive func() bool) { handler.lock.Lock() defer handler.lock.Unlock() @@ -133,6 +142,29 @@ func (handler *ServerHandler) haveNonprimaryProcsFinished() bool { return true } +func (handler *ServerHandler) ReportBeforeSuiteCompleted(reportBeforeSuiteState types.SpecState, _ *Void) error { + handler.lock.Lock() + defer handler.lock.Unlock() + handler.reportBeforeSuiteState = reportBeforeSuiteState + + return nil +} + +func (handler *ServerHandler) ReportBeforeSuiteState(_ Void, reportBeforeSuiteState *types.SpecState) error { + proc1IsAlive := handler.procIsAlive(1) + handler.lock.Lock() + defer handler.lock.Unlock() + if handler.reportBeforeSuiteState == types.SpecStateInvalid { + if proc1IsAlive { + return ErrorEarly + } else { + return ErrorGone + } + } + *reportBeforeSuiteState = handler.reportBeforeSuiteState + return nil +} + func (handler *ServerHandler) BeforeSuiteCompleted(beforeSuiteState BeforeSuiteState, _ *Void) error { handler.lock.Lock() defer handler.lock.Unlock() diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go index 0edd44bce3..7a27220cac 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go @@ -12,6 +12,7 @@ import ( "io" "runtime" "strings" + "time" "github.com/onsi/ginkgo/v2/formatter" "github.com/onsi/ginkgo/v2/types" @@ -29,6 +30,8 @@ type DefaultReporter struct { specDenoter string retryDenoter string formatter formatter.Formatter + + runningInParallel bool } func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter { @@ -96,221 +99,521 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) { } } -func (r *DefaultReporter) WillRun(report types.SpecReport) { - if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) { +func (r *DefaultReporter) SuiteDidEnd(report types.Report) { + failures := report.SpecReports.WithState(types.SpecStateFailureStates) + if len(failures) > 0 { + r.emitBlock("\n") + if len(failures) > 1 { + r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures))) + } else { + r.emitBlock(r.f("{{red}}{{bold}}Summarizing 1 Failure:{{/}}")) + } + for _, specReport := range failures { + highlightColor, heading := "{{red}}", "[FAIL]" + switch specReport.State { + case types.SpecStatePanicked: + highlightColor, heading = "{{magenta}}", "[PANICKED!]" + case types.SpecStateAborted: + highlightColor, heading = "{{coral}}", "[ABORTED]" + case types.SpecStateTimedout: + highlightColor, heading = "{{orange}}", "[TIMEDOUT]" + case types.SpecStateInterrupted: + highlightColor, heading = "{{orange}}", "[INTERRUPTED]" + } + locationBlock := r.codeLocationBlock(specReport, highlightColor, false, true) + r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock)) + } + } + + //summarize the suite + if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded { + r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime)) return } - r.emitDelimiter() - indentation := uint(0) - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - r.emitBlock(r.f("{{bold}}[%s] %s{{/}}", report.LeafNodeType.String(), report.LeafNodeText)) + r.emitBlock("\n") + color, status := "{{green}}{{bold}}", "SUCCESS!" + if !report.SuiteSucceeded { + color, status = "{{red}}{{bold}}", "FAIL!" + } + + specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes + r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}", + specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates), + report.PreRunStats.TotalSpecs, + report.RunTime.Seconds()), + ) + + switch len(report.SpecialSuiteFailureReasons) { + case 0: + r.emit(r.f(color+"%s{{/}} -- ", status)) + case 1: + r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0])) + default: + r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", "))) + } + + if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 { + r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n")) } else { - if len(report.ContainerHierarchyTexts) > 0 { - r.emitBlock(r.cycleJoin(report.ContainerHierarchyTexts, " ")) - indentation = 1 + r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed))) + r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates))) + if specs.CountOfFlakedSpecs() > 0 { + r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs())) } - line := r.fi(indentation, "{{bold}}%s{{/}}", report.LeafNodeText) - labels := report.Labels() - if len(labels) > 0 { - line += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels, ", ")) + if specs.CountOfRepeatedSpecs() > 0 { + r.emit(r.f("{{light-yellow}}{{bold}}%d Repeated{{/}} | ", specs.CountOfRepeatedSpecs())) } - r.emitBlock(line) + r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending))) + r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped))) } - r.emitBlock(r.fi(indentation, "{{gray}}%s{{/}}", report.LeafNodeLocation)) } -func (r *DefaultReporter) DidRun(report types.SpecReport) { +func (r *DefaultReporter) WillRun(report types.SpecReport) { v := r.conf.Verbosity() - var header, highlightColor string - includeRuntime, emitGinkgoWriterOutput, stream, denoter := true, true, false, r.specDenoter - succinctLocationBlock := v.Is(types.VerbosityLevelSuccinct) + if v.LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) || report.RunningInParallel { + return + } - hasGW := report.CapturedGinkgoWriterOutput != "" - hasStd := report.CapturedStdOutErr != "" - hasEmittableReports := report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) || (report.ReportEntries.HasVisibility(types.ReportEntryVisibilityFailureOrVerbose) && (!report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose))) + r.emitDelimiter(0) + r.emitBlock(r.f(r.codeLocationBlock(report, "{{/}}", v.Is(types.VerbosityLevelVeryVerbose), false))) +} + +func (r *DefaultReporter) DidRun(report types.SpecReport) { + v := r.conf.Verbosity() + inParallel := report.RunningInParallel + header := r.specDenoter if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - denoter = fmt.Sprintf("[%s]", report.LeafNodeType) + header = fmt.Sprintf("[%s]", report.LeafNodeType) } + highlightColor := r.highlightColorForState(report.State) + + // have we already been streaming the timeline? + timelineHasBeenStreaming := v.GTE(types.VerbosityLevelVerbose) && !inParallel + + // should we show the timeline? + var timeline types.Timeline + showTimeline := !timelineHasBeenStreaming && (v.GTE(types.VerbosityLevelVerbose) || report.Failed()) + if showTimeline { + timeline = report.Timeline().WithoutHiddenReportEntries() + keepVeryVerboseSpecEvents := v.Is(types.VerbosityLevelVeryVerbose) || + (v.Is(types.VerbosityLevelVerbose) && r.conf.ShowNodeEvents) || + (report.Failed() && r.conf.ShowNodeEvents) + if !keepVeryVerboseSpecEvents { + timeline = timeline.WithoutVeryVerboseSpecEvents() + } + if len(timeline) == 0 && report.CapturedGinkgoWriterOutput == "" { + // the timeline is completely empty - don't show it + showTimeline = false + } + if v.LT(types.VerbosityLevelVeryVerbose) && report.CapturedGinkgoWriterOutput == "" && len(timeline) > 0 { + //if we aren't -vv and the timeline only has a single failure, don't show it as it will appear at the end of the report + failure, isFailure := timeline[0].(types.Failure) + if isFailure && (len(timeline) == 1 || (len(timeline) == 2 && failure.AdditionalFailure != nil)) { + showTimeline = false + } + } + } + + // should we have a separate section for always-visible reports? + showSeparateVisibilityAlwaysReportsSection := !timelineHasBeenStreaming && !showTimeline && report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) + + // should we have a separate section for captured stdout/stderr + showSeparateStdSection := inParallel && (report.CapturedStdOutErr != "") + + // given all that - do we have any actual content to show? or are we a single denoter in a stream? + reportHasContent := v.Is(types.VerbosityLevelVeryVerbose) || showTimeline || showSeparateVisibilityAlwaysReportsSection || showSeparateStdSection || report.Failed() || (v.Is(types.VerbosityLevelVerbose) && !report.State.Is(types.SpecStateSkipped)) + + // should we show a runtime? + includeRuntime := !report.State.Is(types.SpecStateSkipped|types.SpecStatePending) || (report.State.Is(types.SpecStateSkipped) && report.Failure.Message != "") + + // should we show the codelocation block? + showCodeLocation := !timelineHasBeenStreaming || !report.State.Is(types.SpecStatePassed) switch report.State { case types.SpecStatePassed: - highlightColor, succinctLocationBlock = "{{green}}", v.LT(types.VerbosityLevelVerbose) - emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW + if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) && !reportHasContent { + return + } if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports { - header = fmt.Sprintf("%s PASSED", denoter) - } else { - return - } - } else { - header, stream = denoter, true - if report.NumAttempts > 1 { - header, stream = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), false - } - if report.RunTime > r.conf.SlowSpecThreshold { - header, stream = fmt.Sprintf("%s [SLOW TEST]", header), false - } + header = fmt.Sprintf("%s PASSED", header) } - if hasStd || emitGinkgoWriterOutput || hasEmittableReports { - stream = false + if report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 { + header, reportHasContent = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), true } case types.SpecStatePending: - highlightColor = "{{yellow}}" - includeRuntime, emitGinkgoWriterOutput = false, false - if v.Is(types.VerbosityLevelSuccinct) { - header, stream = "P", true - } else { - header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose) + header = "P" + if v.GT(types.VerbosityLevelSuccinct) { + header, reportHasContent = "P [PENDING]", true } case types.SpecStateSkipped: - highlightColor = "{{cyan}}" - if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) { - header = "S [SKIPPED]" - } else { - header, stream = "S", true + header = "S" + if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && report.Failure.Message != "") { + header, reportHasContent = "S [SKIPPED]", true + } + default: + header = fmt.Sprintf("%s [%s]", header, r.humanReadableState(report.State)) + if report.MaxMustPassRepeatedly > 1 { + header = fmt.Sprintf("%s DURING REPETITION #%d", header, report.NumAttempts) } - case types.SpecStateFailed: - highlightColor, header = "{{red}}", fmt.Sprintf("%s [FAILED]", denoter) - case types.SpecStatePanicked: - highlightColor, header = "{{magenta}}", fmt.Sprintf("%s! [PANICKED]", denoter) - case types.SpecStateInterrupted: - highlightColor, header = "{{orange}}", fmt.Sprintf("%s! [INTERRUPTED]", denoter) - case types.SpecStateAborted: - highlightColor, header = "{{coral}}", fmt.Sprintf("%s! [ABORTED]", denoter) } - // Emit stream and return - if stream { + // If we have no content to show, jsut emit the header and return + if !reportHasContent { r.emit(r.f(highlightColor + header + "{{/}}")) return } - // Emit header - r.emitDelimiter() if includeRuntime { header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds()) } - r.emitBlock(r.f(highlightColor + header + "{{/}}")) - // Emit Code Location Block - r.emitBlock(r.codeLocationBlock(report, highlightColor, succinctLocationBlock, false)) + // Emit header + if !timelineHasBeenStreaming { + r.emitDelimiter(0) + } + r.emitBlock(r.f(highlightColor + header + "{{/}}")) + if showCodeLocation { + r.emitBlock(r.codeLocationBlock(report, highlightColor, v.Is(types.VerbosityLevelVeryVerbose), false)) + } //Emit Stdout/Stderr Output - if hasStd { + if showSeparateStdSection { r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Begin Captured StdOut/StdErr Output >>{{/}}")) - r.emitBlock(r.fi(2, "%s", report.CapturedStdOutErr)) - r.emitBlock(r.fi(1, "{{gray}}<< End Captured StdOut/StdErr Output{{/}}")) + r.emitBlock(r.fi(1, "{{gray}}Captured StdOut/StdErr Output >>{{/}}")) + r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr)) + r.emitBlock(r.fi(1, "{{gray}}<< Captured StdOut/StdErr Output{{/}}")) } - //Emit Captured GinkgoWriter Output - if emitGinkgoWriterOutput && hasGW { + if showSeparateVisibilityAlwaysReportsSection { r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}")) - r.emitBlock(r.fi(2, "%s", report.CapturedGinkgoWriterOutput)) - r.emitBlock(r.fi(1, "{{gray}}<< End Captured GinkgoWriter Output{{/}}")) + r.emitBlock(r.fi(1, "{{gray}}Report Entries >>{{/}}")) + for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) { + r.emitReportEntry(1, entry) + } + r.emitBlock(r.fi(1, "{{gray}}<< Report Entries{{/}}")) } - if hasEmittableReports { + if showTimeline { r.emitBlock("\n") - r.emitBlock(r.fi(1, "{{gray}}Begin Report Entries >>{{/}}")) - reportEntries := report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) - if !report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose) { - reportEntries = report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose) - } - for _, entry := range reportEntries { - r.emitBlock(r.fi(2, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))) - if representation := entry.StringRepresentation(); representation != "" { - r.emitBlock(r.fi(3, representation)) - } - } - r.emitBlock(r.fi(1, "{{gray}}<< End Report Entries{{/}}")) + r.emitBlock(r.fi(1, "{{gray}}Timeline >>{{/}}")) + r.emitTimeline(1, report, timeline) + r.emitBlock(r.fi(1, "{{gray}}<< Timeline{{/}}")) } // Emit Failure Message - if !report.Failure.IsZero() { + if !report.Failure.IsZero() && !v.Is(types.VerbosityLevelVeryVerbose) { r.emitBlock("\n") - r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.Message)) - r.emitBlock(r.fi(1, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.Location)) - if report.Failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(1, highlightColor+"%s{{/}}", report.Failure.ForwardedPanic)) + r.emitFailure(1, report.State, report.Failure, true) + if len(report.AdditionalFailures) > 0 { + r.emitBlock(r.fi(1, "\nThere were {{bold}}{{red}}additional failures{{/}} detected. To view them in detail run {{bold}}ginkgo -vv{{/}}")) } + } - if r.conf.FullTrace || report.Failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(1, highlightColor+"Full Stack Trace{{/}}")) - r.emitBlock(r.fi(2, "%s", report.Failure.Location.FullStackTrace)) + r.emitDelimiter(0) +} + +func (r *DefaultReporter) highlightColorForState(state types.SpecState) string { + switch state { + case types.SpecStatePassed: + return "{{green}}" + case types.SpecStatePending: + return "{{yellow}}" + case types.SpecStateSkipped: + return "{{cyan}}" + case types.SpecStateFailed: + return "{{red}}" + case types.SpecStateTimedout: + return "{{orange}}" + case types.SpecStatePanicked: + return "{{magenta}}" + case types.SpecStateInterrupted: + return "{{orange}}" + case types.SpecStateAborted: + return "{{coral}}" + default: + return "{{gray}}" + } +} + +func (r *DefaultReporter) humanReadableState(state types.SpecState) string { + return strings.ToUpper(state.String()) +} + +func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, timeline types.Timeline) { + isVeryVerbose := r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) + gw := report.CapturedGinkgoWriterOutput + cursor := 0 + for _, entry := range timeline { + tl := entry.GetTimelineLocation() + if tl.Offset < len(gw) { + r.emit(r.fi(indent, "%s", gw[cursor:tl.Offset])) + cursor = tl.Offset + } else if cursor < len(gw) { + r.emit(r.fi(indent, "%s", gw[cursor:])) + cursor = len(gw) + } + switch x := entry.(type) { + case types.Failure: + if isVeryVerbose { + r.emitFailure(indent, report.State, x, false) + } else { + r.emitShortFailure(indent, report.State, x) + } + case types.AdditionalFailure: + if isVeryVerbose { + r.emitFailure(indent, x.State, x.Failure, true) + } else { + r.emitShortFailure(indent, x.State, x.Failure) + } + case types.ReportEntry: + r.emitReportEntry(indent, x) + case types.ProgressReport: + r.emitProgressReport(indent, false, x) + case types.SpecEvent: + if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents { + r.emitSpecEvent(indent, x, isVeryVerbose) + } } } + if cursor < len(gw) { + r.emit(r.fi(indent, "%s", gw[cursor:])) + } +} - r.emitDelimiter() +func (r *DefaultReporter) EmitFailure(state types.SpecState, failure types.Failure) { + if r.conf.Verbosity().Is(types.VerbosityLevelVerbose) { + r.emitShortFailure(1, state, failure) + } else if r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) { + r.emitFailure(1, state, failure, true) + } } -func (r *DefaultReporter) SuiteDidEnd(report types.Report) { - failures := report.SpecReports.WithState(types.SpecStateFailureStates) - if len(failures) > 0 { - r.emitBlock("\n\n") - if len(failures) > 1 { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures))) +func (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, failure types.Failure) { + r.emitBlock(r.fi(indent, r.highlightColorForState(state)+"[%s]{{/}} in [%s] - %s {{gray}}@ %s{{/}}", + r.humanReadableState(state), + failure.FailureNodeType, + failure.Location, + failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), + )) +} + +func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) { + highlightColor := r.highlightColorForState(state) + r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message)) + r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + if failure.ForwardedPanic != "" { + r.emitBlock("\n") + r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic)) + } + + if r.conf.FullTrace || failure.ForwardedPanic != "" { + r.emitBlock("\n") + r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}")) + r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace)) + } + + if !failure.ProgressReport.IsZero() { + r.emitBlock("\n") + r.emitProgressReport(indent, false, failure.ProgressReport) + } + + if failure.AdditionalFailure != nil && includeAdditionalFailure { + r.emitBlock("\n") + r.emitFailure(indent, failure.AdditionalFailure.State, failure.AdditionalFailure.Failure, true) + } +} + +func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) { + r.emitDelimiter(1) + + if report.RunningInParallel { + r.emit(r.fi(1, "{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess)) + } + shouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose) + r.emitProgressReport(1, shouldEmitGW, report) + r.emitDelimiter(1) +} + +func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) { + if report.Message != "" { + r.emitBlock(r.fi(indent, report.Message+"\n")) + indent += 1 + } + if report.LeafNodeText != "" { + subjectIndent := indent + if len(report.ContainerHierarchyTexts) > 0 { + r.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, " "))) + r.emit(" ") + subjectIndent = 0 + } + r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time().Sub(report.SpecStartTime).Round(time.Millisecond))) + r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation)) + indent += 1 + } + if report.CurrentNodeType != types.NodeTypeInvalid { + r.emit(r.fi(indent, "In {{bold}}{{orange}}[%s]{{/}}", report.CurrentNodeType)) + if report.CurrentNodeText != "" && !report.CurrentNodeType.Is(types.NodeTypeIt) { + r.emit(r.f(" {{bold}}{{orange}}%s{{/}}", report.CurrentNodeText)) + } + + r.emit(r.f(" (Node Runtime: %s)\n", report.Time().Sub(report.CurrentNodeStartTime).Round(time.Millisecond))) + r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentNodeLocation)) + indent += 1 + } + if report.CurrentStepText != "" { + r.emit(r.fi(indent, "At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\n", report.CurrentStepText, report.Time().Sub(report.CurrentStepStartTime).Round(time.Millisecond))) + r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentStepLocation)) + indent += 1 + } + + if indent > 0 { + indent -= 1 + } + + if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" { + r.emit("\n") + r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}")) + limit, lines := 10, strings.Split(report.CapturedGinkgoWriterOutput, "\n") + if len(lines) <= limit { + r.emitBlock(r.fi(indent+1, "%s", report.CapturedGinkgoWriterOutput)) } else { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing 1 Failure:{{/}}")) + r.emitBlock(r.fi(indent+1, "{{gray}}...{{/}}")) + for _, line := range lines[len(lines)-limit-1:] { + r.emitBlock(r.fi(indent+1, "%s", line)) + } } - for _, specReport := range failures { - highlightColor, heading := "{{red}}", "[FAIL]" - switch specReport.State { - case types.SpecStatePanicked: - highlightColor, heading = "{{magenta}}", "[PANICKED!]" - case types.SpecStateAborted: - highlightColor, heading = "{{coral}}", "[ABORTED]" - case types.SpecStateInterrupted: - highlightColor, heading = "{{orange}}", "[INTERRUPTED]" + r.emitBlock(r.fi(indent, "{{gray}}<< End Captured GinkgoWriter Output{{/}}")) + } + + if !report.SpecGoroutine().IsZero() { + r.emit("\n") + r.emit(r.fi(indent, "{{bold}}{{underline}}Spec Goroutine{{/}}\n")) + r.emitGoroutines(indent, report.SpecGoroutine()) + } + + if len(report.AdditionalReports) > 0 { + r.emit("\n") + r.emitBlock(r.fi(indent, "{{gray}}Begin Additional Progress Reports >>{{/}}")) + for i, additionalReport := range report.AdditionalReports { + r.emit(r.fi(indent+1, additionalReport)) + if i < len(report.AdditionalReports)-1 { + r.emitBlock(r.fi(indent+1, "{{gray}}%s{{/}}", strings.Repeat("-", 10))) } - locationBlock := r.codeLocationBlock(specReport, highlightColor, true, true) - r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock)) } + r.emitBlock(r.fi(indent, "{{gray}}<< End Additional Progress Reports{{/}}")) } - //summarize the suite - if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded { - r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime)) + highlightedGoroutines := report.HighlightedGoroutines() + if len(highlightedGoroutines) > 0 { + r.emit("\n") + r.emit(r.fi(indent, "{{bold}}{{underline}}Goroutines of Interest{{/}}\n")) + r.emitGoroutines(indent, highlightedGoroutines...) + } + + otherGoroutines := report.OtherGoroutines() + if len(otherGoroutines) > 0 { + r.emit("\n") + r.emit(r.fi(indent, "{{gray}}{{bold}}{{underline}}Other Goroutines{{/}}\n")) + r.emitGoroutines(indent, otherGoroutines...) + } +} + +func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) { + if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || entry.Visibility == types.ReportEntryVisibilityNever { return } + r.emitReportEntry(1, entry) +} - r.emitBlock("\n") - color, status := "{{green}}{{bold}}", "SUCCESS!" - if !report.SuiteSucceeded { - color, status = "{{red}}{{bold}}", "FAIL!" +func (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) { + r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))) + if representation := entry.StringRepresentation(); representation != "" { + r.emitBlock(r.fi(indent+1, representation)) } +} - specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes - r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}", - specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates), - report.PreRunStats.TotalSpecs, - report.RunTime.Seconds()), - ) +func (r *DefaultReporter) EmitSpecEvent(event types.SpecEvent) { + v := r.conf.Verbosity() + if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && (r.conf.ShowNodeEvents || !event.IsOnlyVisibleAtVeryVerbose())) { + r.emitSpecEvent(1, event, r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose)) + } +} - switch len(report.SpecialSuiteFailureReasons) { - case 0: - r.emit(r.f(color+"%s{{/}} -- ", status)) - case 1: - r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0])) - default: - r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", "))) +func (r *DefaultReporter) emitSpecEvent(indent uint, event types.SpecEvent, includeLocation bool) { + location := "" + if includeLocation { + location = fmt.Sprintf("- %s ", event.CodeLocation.String()) } + switch event.SpecEventType { + case types.SpecEventInvalid: + return + case types.SpecEventByStart: + r.emitBlock(r.fi(indent, "{{bold}}STEP:{{/}} %s {{gray}}%s@ %s{{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + case types.SpecEventByEnd: + r.emitBlock(r.fi(indent, "{{bold}}END STEP:{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) + case types.SpecEventNodeStart: + r.emitBlock(r.fi(indent, "> Enter {{bold}}[%s]{{/}} %s {{gray}}%s@ %s{{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + case types.SpecEventNodeEnd: + r.emitBlock(r.fi(indent, "< Exit {{bold}}[%s]{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) + case types.SpecEventSpecRepeat: + r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{green}}Passed{{/}}{{bold}}. Repeating %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + case types.SpecEventSpecRetry: + r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{red}}Failed{{/}}{{bold}}. Retrying %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) + } +} - if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 { - r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n")) - } else { - r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed))) - r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates))) - if specs.CountOfFlakedSpecs() > 0 { - r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs())) +func (r *DefaultReporter) emitGoroutines(indent uint, goroutines ...types.Goroutine) { + for idx, g := range goroutines { + color := "{{gray}}" + if g.HasHighlights() { + color = "{{orange}}" + } + r.emit(r.fi(indent, color+"goroutine %d [%s]{{/}}\n", g.ID, g.State)) + for _, fc := range g.Stack { + if fc.Highlight { + r.emit(r.fi(indent, color+"{{bold}}> %s{{/}}\n", fc.Function)) + r.emit(r.fi(indent+2, color+"{{bold}}%s:%d{{/}}\n", fc.Filename, fc.Line)) + r.emitSource(indent+3, fc) + } else { + r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", fc.Function)) + r.emit(r.fi(indent+2, "{{gray}}%s:%d{{/}}\n", fc.Filename, fc.Line)) + } + } + + if idx+1 < len(goroutines) { + r.emit("\n") + } + } +} + +func (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) { + lines := fc.Source + if len(lines) == 0 { + return + } + + lTrim := 100000 + for _, line := range lines { + lTrimLine := len(line) - len(strings.TrimLeft(line, " \t")) + if lTrimLine < lTrim && len(line) > 0 { + lTrim = lTrimLine + } + } + if lTrim == 100000 { + lTrim = 0 + } + + for idx, line := range lines { + if len(line) > lTrim { + line = line[lTrim:] + } + if idx == fc.SourceHighlight { + r.emit(r.fi(indent, "{{bold}}{{orange}}> %s{{/}}\n", line)) + } else { + r.emit(r.fi(indent, "| %s\n", line)) } - r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending))) - r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped))) } } @@ -335,11 +638,11 @@ func (r *DefaultReporter) emitBlock(s string) { } } -func (r *DefaultReporter) emitDelimiter() { +func (r *DefaultReporter) emitDelimiter(indent uint) { if r.lastEmissionWasDelimiter { return } - r.emitBlock(r.f("{{gray}}%s{{/}}", strings.Repeat("-", 30))) + r.emitBlock(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30))) r.lastEmissionWasDelimiter = true } @@ -356,13 +659,14 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string { return r.formatter.CycleJoin(elements, joiner, []string{"{{/}}", "{{gray}}"}) } -func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, succinct bool, usePreciseFailureLocation bool) string { +func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string { texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{} texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...) + if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText)) } else { - texts = append(texts, report.LeafNodeText) + texts = append(texts, r.f(report.LeafNodeText)) } labels = append(labels, report.LeafNodeLabels) locations = append(locations, report.LeafNodeLocation) @@ -372,24 +676,58 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo failureLocation = report.Failure.Location } + highlightIndex := -1 switch report.Failure.FailureNodeContext { case types.FailureNodeAtTopLevel: - texts = append([]string{r.f(highlightColor+"{{bold}}TOP-LEVEL [%s]{{/}}", report.Failure.FailureNodeType)}, texts...) + texts = append([]string{fmt.Sprintf("TOP-LEVEL [%s]", report.Failure.FailureNodeType)}, texts...) locations = append([]types.CodeLocation{failureLocation}, locations...) labels = append([][]string{{}}, labels...) + highlightIndex = 0 case types.FailureNodeInContainer: i := report.Failure.FailureNodeContainerIndex - texts[i] = r.f(highlightColor+"{{bold}}%s [%s]{{/}}", texts[i], report.Failure.FailureNodeType) + texts[i] = fmt.Sprintf("%s [%s]", texts[i], report.Failure.FailureNodeType) locations[i] = failureLocation + highlightIndex = i case types.FailureNodeIsLeafNode: i := len(texts) - 1 - texts[i] = r.f(highlightColor+"{{bold}}[%s] %s{{/}}", report.LeafNodeType, report.LeafNodeText) + texts[i] = fmt.Sprintf("[%s] %s", report.LeafNodeType, report.LeafNodeText) locations[i] = failureLocation + highlightIndex = i + default: + //there is no failure, so we highlight the leaf ndoe + highlightIndex = len(texts) - 1 } out := "" - if succinct { - out += r.f("%s", r.cycleJoin(texts, " ")) + if veryVerbose { + for i := range texts { + if i == highlightIndex { + out += r.fi(uint(i), highlightColor+"{{bold}}%s{{/}}", texts[i]) + } else { + out += r.fi(uint(i), "%s", texts[i]) + } + if len(labels[i]) > 0 { + out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", ")) + } + out += "\n" + out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) + } + } else { + for i := range texts { + style := "{{/}}" + if i%2 == 1 { + style = "{{gray}}" + } + if i == highlightIndex { + style = highlightColor + "{{bold}}" + } + out += r.f(style+"%s", texts[i]) + if i < len(texts)-1 { + out += " " + } else { + out += r.f("{{/}}") + } + } flattenedLabels := report.Labels() if len(flattenedLabels) > 0 { out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", ")) @@ -398,17 +736,15 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo if usePreciseFailureLocation { out += r.f("{{gray}}%s{{/}}", failureLocation) } else { - out += r.f("{{gray}}%s{{/}}", locations[len(locations)-1]) - } - } else { - for i := range texts { - out += r.fi(uint(i), "%s", texts[i]) - if len(labels[i]) > 0 { - out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", ")) + leafLocation := locations[len(locations)-1] + if (report.Failure.FailureNodeLocation != types.CodeLocation{}) && (report.Failure.FailureNodeLocation != leafLocation) { + out += r.fi(1, highlightColor+"[%s]{{/}} {{gray}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.FailureNodeLocation) + out += r.fi(1, "{{gray}}[%s] %s{{/}}", report.LeafNodeType, leafLocation) + } else { + out += r.f("{{gray}}%s{{/}}", leafLocation) } - out += "\n" - out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) } + } return out } diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go index 89d30076bf..613072ebf1 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go @@ -35,7 +35,7 @@ func ReportViaDeprecatedReporter(reporter DeprecatedReporter, report types.Repor FailOnPending: report.SuiteConfig.FailOnPending, FailFast: report.SuiteConfig.FailFast, FlakeAttempts: report.SuiteConfig.FlakeAttempts, - EmitSpecProgress: report.SuiteConfig.EmitSpecProgress, + EmitSpecProgress: false, DryRun: report.SuiteConfig.DryRun, ParallelNode: report.SuiteConfig.ParallelProcess, ParallelTotal: report.SuiteConfig.ParallelTotal, diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go index febcc650b0..fb87e24d71 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go @@ -15,12 +15,29 @@ import ( "fmt" "os" "strings" - "time" "github.com/onsi/ginkgo/v2/config" "github.com/onsi/ginkgo/v2/types" ) +type JunitReportConfig struct { + // Spec States for which no timeline should be emitted for system-err + // set this to types.SpecStatePassed|types.SpecStateSkipped|types.SpecStatePending to only match failing specs + OmitTimelinesForSpecState types.SpecState + + // Enable OmitFailureMessageAttr to prevent failure messages appearing in the "message" attribute of the Failure and Error tags + OmitFailureMessageAttr bool + + //Enable OmitCapturedStdOutErr to prevent captured stdout/stderr appearing in system-out + OmitCapturedStdOutErr bool + + // Enable OmitSpecLabels to prevent labels from appearing in the spec name + OmitSpecLabels bool + + // Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name + OmitLeafNodeType bool +} + type JUnitTestSuites struct { XMLName xml.Name `xml:"testsuites"` // Tests maps onto the total number of specs in all test suites (this includes any suite nodes such as BeforeSuite) @@ -128,6 +145,10 @@ type JUnitFailure struct { } func GenerateJUnitReport(report types.Report, dst string) error { + return GenerateJUnitReportWithConfig(report, dst, JunitReportConfig{}) +} + +func GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig) error { suite := JUnitTestSuite{ Name: report.SuiteDescription, Package: report.SuitePath, @@ -149,7 +170,6 @@ func GenerateJUnitReport(report types.Report, dst string) error { {"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)}, {"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)}, {"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)}, - {"EmitSpecProgress", fmt.Sprintf("%t", report.SuiteConfig.EmitSpecProgress)}, {"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)}, {"ParallelTotal", fmt.Sprintf("%d", report.SuiteConfig.ParallelTotal)}, {"OutputInterceptorMode", report.SuiteConfig.OutputInterceptorMode}, @@ -158,21 +178,29 @@ func GenerateJUnitReport(report types.Report, dst string) error { } for _, spec := range report.SpecReports { name := fmt.Sprintf("[%s]", spec.LeafNodeType) + if config.OmitLeafNodeType { + name = "" + } if spec.FullText() != "" { name = name + " " + spec.FullText() } labels := spec.Labels() - if len(labels) > 0 { + if len(labels) > 0 && !config.OmitSpecLabels { name = name + " [" + strings.Join(labels, ", ") + "]" } + name = strings.TrimSpace(name) test := JUnitTestCase{ Name: name, Classname: report.SuiteDescription, Status: spec.State.String(), Time: spec.RunTime.Seconds(), - SystemOut: systemOutForUnstructureReporters(spec), - SystemErr: spec.CapturedGinkgoWriterOutput, + } + if !spec.State.Is(config.OmitTimelinesForSpecState) { + test.SystemErr = systemErrForUnstructuredReporters(spec) + } + if !config.OmitCapturedStdOutErr { + test.SystemOut = systemOutForUnstructuredReporters(spec) } suite.Tests += 1 @@ -191,28 +219,50 @@ func GenerateJUnitReport(report types.Report, dst string) error { test.Failure = &JUnitFailure{ Message: spec.Failure.Message, Type: "failed", - Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), + Description: failureDescriptionForUnstructuredReporters(spec), + } + if config.OmitFailureMessageAttr { + test.Failure.Message = "" + } + suite.Failures += 1 + case types.SpecStateTimedout: + test.Failure = &JUnitFailure{ + Message: spec.Failure.Message, + Type: "timedout", + Description: failureDescriptionForUnstructuredReporters(spec), + } + if config.OmitFailureMessageAttr { + test.Failure.Message = "" } suite.Failures += 1 case types.SpecStateInterrupted: test.Error = &JUnitError{ - Message: "interrupted", + Message: spec.Failure.Message, Type: "interrupted", - Description: spec.Failure.Message, + Description: failureDescriptionForUnstructuredReporters(spec), + } + if config.OmitFailureMessageAttr { + test.Error.Message = "" } suite.Errors += 1 case types.SpecStateAborted: test.Failure = &JUnitFailure{ Message: spec.Failure.Message, Type: "aborted", - Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), + Description: failureDescriptionForUnstructuredReporters(spec), + } + if config.OmitFailureMessageAttr { + test.Failure.Message = "" } suite.Errors += 1 case types.SpecStatePanicked: test.Error = &JUnitError{ Message: spec.Failure.ForwardedPanic, Type: "panicked", - Description: fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace), + Description: failureDescriptionForUnstructuredReporters(spec), + } + if config.OmitFailureMessageAttr { + test.Error.Message = "" } suite.Errors += 1 } @@ -278,21 +328,23 @@ func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error) return messages, f.Close() } -func systemOutForUnstructureReporters(spec types.SpecReport) string { - systemOut := spec.CapturedStdOutErr - if len(spec.ReportEntries) > 0 { - systemOut += "\nReport Entries:\n" - for i, entry := range spec.ReportEntries { - systemOut += fmt.Sprintf("%s\n%s\n%s\n", entry.Name, entry.Location, entry.Time.Format(time.RFC3339Nano)) - if representation := entry.StringRepresentation(); representation != "" { - systemOut += representation + "\n" - } - if i+1 < len(spec.ReportEntries) { - systemOut += "--\n" - } - } +func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string { + out := &strings.Builder{} + NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitFailure(0, spec.State, spec.Failure, true) + if len(spec.AdditionalFailures) > 0 { + out.WriteString("\nThere were additional failures detected after the initial failure. These are visible in the timeline\n") } - return systemOut + return out.String() +} + +func systemErrForUnstructuredReporters(spec types.SpecReport) string { + out := &strings.Builder{} + NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline()) + return out.String() +} + +func systemOutForUnstructuredReporters(spec types.SpecReport) string { + return spec.CapturedStdOutErr } // Deprecated JUnitReporter (so folks can still compile their suites) diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go index 29f84e7c1b..5e726c464e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go @@ -9,11 +9,21 @@ type Reporter interface { WillRun(report types.SpecReport) DidRun(report types.SpecReport) SuiteDidEnd(report types.Report) + + //Timeline emission + EmitFailure(state types.SpecState, failure types.Failure) + EmitProgressReport(progressReport types.ProgressReport) + EmitReportEntry(entry types.ReportEntry) + EmitSpecEvent(event types.SpecEvent) } type NoopReporter struct{} -func (n NoopReporter) SuiteWillBegin(report types.Report) {} -func (n NoopReporter) WillRun(report types.SpecReport) {} -func (n NoopReporter) DidRun(report types.SpecReport) {} -func (n NoopReporter) SuiteDidEnd(report types.Report) {} +func (n NoopReporter) SuiteWillBegin(report types.Report) {} +func (n NoopReporter) WillRun(report types.SpecReport) {} +func (n NoopReporter) DidRun(report types.SpecReport) {} +func (n NoopReporter) SuiteDidEnd(report types.Report) {} +func (n NoopReporter) EmitFailure(state types.SpecState, failure types.Failure) {} +func (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport) {} +func (n NoopReporter) EmitReportEntry(entry types.ReportEntry) {} +func (n NoopReporter) EmitSpecEvent(event types.SpecEvent) {} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go index f9b1117ca5..c1863496dc 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go @@ -60,20 +60,24 @@ func GenerateTeamcityReport(report types.Report, dst string) error { } fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='%s']\n", name, tcEscape(message)) case types.SpecStateFailed: - details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) + details := failureDescriptionForUnstructuredReporters(spec) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='failed - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) case types.SpecStatePanicked: - details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) + details := failureDescriptionForUnstructuredReporters(spec) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\n", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details)) + case types.SpecStateTimedout: + details := failureDescriptionForUnstructuredReporters(spec) + fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='timedout - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) case types.SpecStateInterrupted: - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted' details='%s']\n", name, tcEscape(spec.Failure.Message)) + details := failureDescriptionForUnstructuredReporters(spec) + fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) case types.SpecStateAborted: - details := fmt.Sprintf("%s\n%s", spec.Failure.Location.String(), spec.Failure.Location.FullStackTrace) + details := failureDescriptionForUnstructuredReporters(spec) fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) } - fmt.Fprintf(f, "##teamcity[testStdOut name='%s' out='%s']\n", name, tcEscape(systemOutForUnstructureReporters(spec))) - fmt.Fprintf(f, "##teamcity[testStdErr name='%s' out='%s']\n", name, tcEscape(spec.CapturedGinkgoWriterOutput)) + fmt.Fprintf(f, "##teamcity[testStdOut name='%s' out='%s']\n", name, tcEscape(systemOutForUnstructuredReporters(spec))) + fmt.Fprintf(f, "##teamcity[testStdErr name='%s' out='%s']\n", name, tcEscape(systemErrForUnstructuredReporters(spec))) fmt.Fprintf(f, "##teamcity[testFinished name='%s' duration='%d']\n", name, int(spec.RunTime.Seconds()*1000.0)) } fmt.Fprintf(f, "##teamcity[testSuiteFinished name='%s']\n", tcEscape(report.SuiteDescription)) diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go index 07ef4c3a7f..4ec636eb21 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/config.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go @@ -26,10 +26,13 @@ type SuiteConfig struct { FailOnPending bool FailFast bool FlakeAttempts int - EmitSpecProgress bool DryRun bool + PollProgressAfter time.Duration + PollProgressInterval time.Duration Timeout time.Duration OutputInterceptorMode string + SourceRoots []string + GracePeriod time.Duration ParallelProcess int ParallelTotal int @@ -42,6 +45,7 @@ func NewDefaultSuiteConfig() SuiteConfig { Timeout: time.Hour, ParallelProcess: 1, ParallelTotal: 1, + GracePeriod: 30 * time.Second, } } @@ -76,13 +80,12 @@ func (vl VerbosityLevel) LT(comp VerbosityLevel) bool { // Configuration for Ginkgo's reporter type ReporterConfig struct { - NoColor bool - SlowSpecThreshold time.Duration - Succinct bool - Verbose bool - VeryVerbose bool - FullTrace bool - AlwaysEmitGinkgoWriter bool + NoColor bool + Succinct bool + Verbose bool + VeryVerbose bool + FullTrace bool + ShowNodeEvents bool JSONReport string JUnitReport string @@ -105,9 +108,7 @@ func (rc ReporterConfig) WillGenerateReport() bool { } func NewDefaultReporterConfig() ReporterConfig { - return ReporterConfig{ - SlowSpecThreshold: 5 * time.Second, - } + return ReporterConfig{} } // Configuration for the Ginkgo CLI @@ -230,6 +231,9 @@ type deprecatedConfig struct { SlowSpecThresholdWithFLoatUnits float64 Stream bool Notify bool + EmitSpecProgress bool + SlowSpecThreshold time.Duration + AlwaysEmitGinkgoWriter bool } // Flags @@ -270,10 +274,16 @@ var SuiteConfigFlags = GinkgoFlags{ {KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."}, - {KeyPath: "S.EmitSpecProgress", Name: "progress", SectionKey: "debug", - Usage: "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter."}, + {KeyPath: "S.PollProgressAfter", Name: "poll-progress-after", SectionKey: "debug", UsageDefaultValue: "0", + Usage: "Emit node progress reports periodically if node hasn't completed after this duration."}, + {KeyPath: "S.PollProgressInterval", Name: "poll-progress-interval", SectionKey: "debug", UsageDefaultValue: "10s", + Usage: "The rate at which to emit node progress reports after poll-progress-after has elapsed."}, + {KeyPath: "S.SourceRoots", Name: "source-root", SectionKey: "debug", + Usage: "The location to look for source code when generating progress reports. You can pass multiple --source-root flags."}, {KeyPath: "S.Timeout", Name: "timeout", SectionKey: "debug", UsageDefaultValue: "1h", Usage: "Test suite fails if it does not complete within the specified timeout."}, + {KeyPath: "S.GracePeriod", Name: "grace-period", SectionKey: "debug", UsageDefaultValue: "30s", + Usage: "When interrupted, Ginkgo will wait for GracePeriod for the current running node to exit before moving on to the next one."}, {KeyPath: "S.OutputInterceptorMode", Name: "output-interceptor-mode", SectionKey: "debug", UsageArgument: "dup, swap, or none", Usage: "If set, ginkgo will use the specified output interception strategy when running in parallel. Defaults to dup on unix and swap on windows."}, @@ -290,6 +300,8 @@ var SuiteConfigFlags = GinkgoFlags{ {KeyPath: "D.RegexScansFilePath", DeprecatedName: "regexScansFilePath", DeprecatedDocLink: "removed--regexscansfilepath", DeprecatedVersion: "2.0.0"}, {KeyPath: "D.DebugParallel", DeprecatedName: "debug", DeprecatedDocLink: "removed--debug", DeprecatedVersion: "2.0.0"}, + {KeyPath: "D.EmitSpecProgress", DeprecatedName: "progress", SectionKey: "debug", + DeprecatedVersion: "2.5.0", Usage: ". The functionality provided by --progress was confusing and is no longer needed. Use --show-node-events instead to see node entry and exit events included in the timeline of failed and verbose specs. Or you can run with -vv to always see all node events. Lastly, --poll-progress-after and the PollProgressAfter decorator now provide a better mechanism for debugging specs that tend to get stuck."}, } // ParallelConfigFlags provides flags for the Ginkgo test process (not the CLI) @@ -306,8 +318,6 @@ var ParallelConfigFlags = GinkgoFlags{ var ReporterConfigFlags = GinkgoFlags{ {KeyPath: "R.NoColor", Name: "no-color", SectionKey: "output", DeprecatedName: "noColor", DeprecatedDocLink: "changed-command-line-flags", Usage: "If set, suppress color output in default reporter."}, - {KeyPath: "R.SlowSpecThreshold", Name: "slow-spec-threshold", SectionKey: "output", UsageArgument: "duration", UsageDefaultValue: "5s", - Usage: "Specs that take longer to run than this threshold are flagged as slow by the default reporter."}, {KeyPath: "R.Verbose", Name: "v", SectionKey: "output", Usage: "If set, emits more output including GinkgoWriter contents."}, {KeyPath: "R.VeryVerbose", Name: "vv", SectionKey: "output", @@ -316,8 +326,8 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "If set, default reporter prints out a very succinct report"}, {KeyPath: "R.FullTrace", Name: "trace", SectionKey: "output", Usage: "If set, default reporter prints out the full stack trace when a failure occurs"}, - {KeyPath: "R.AlwaysEmitGinkgoWriter", Name: "always-emit-ginkgo-writer", SectionKey: "output", DeprecatedName: "reportPassed", DeprecatedDocLink: "renamed--reportpassed", - Usage: "If set, default reporter prints out captured output of passed tests."}, + {KeyPath: "R.ShowNodeEvents", Name: "show-node-events", SectionKey: "output", + Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."}, @@ -330,6 +340,8 @@ var ReporterConfigFlags = GinkgoFlags{ Usage: "use --slow-spec-threshold instead and pass in a duration string (e.g. '5s', not '5.0')"}, {KeyPath: "D.NoisyPendings", DeprecatedName: "noisyPendings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, {KeyPath: "D.NoisySkippings", DeprecatedName: "noisySkippings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, + {KeyPath: "D.SlowSpecThreshold", DeprecatedName: "slow-spec-threshold", SectionKey: "output", Usage: "--slow-spec-threshold has been deprecated and will be removed in a future version of Ginkgo. This feature has proved to be more noisy than useful. You can use --poll-progress-after, instead, to get more actionable feedback about potentially slow specs and understand where they might be getting stuck.", DeprecatedVersion: "2.5.0"}, + {KeyPath: "D.AlwaysEmitGinkgoWriter", DeprecatedName: "always-emit-ginkgo-writer", SectionKey: "output", Usage: " - use -v instead, or one of Ginkgo's machine-readable report formats to get GinkgoWriter output for passing specs."}, } // BuildTestSuiteFlagSet attaches to the CommandLine flagset and provides flags for the Ginkgo test process @@ -381,6 +393,10 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re errors = append(errors, GinkgoErrors.DryRunInParallelConfiguration()) } + if suiteConfig.GracePeriod <= 0 { + errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero()) + } + if len(suiteConfig.FocusFiles) > 0 { _, err := ParseFileFilters(suiteConfig.FocusFiles) if err != nil { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go b/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go index 2948dfa0c9..f267bdefd5 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go @@ -83,6 +83,13 @@ func (d deprecations) Nodot() Deprecation { } } +func (d deprecations) SuppressProgressReporting() Deprecation { + return Deprecation{ + Message: "Improvements to how reporters emit timeline information means that SuppressProgressReporting is no longer necessary and has been deprecated.", + Version: "2.5.0", + } +} + type DeprecationTracker struct { deprecations map[Deprecation][]CodeLocation lock *sync.Mutex diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go index 40331d2982..a0f59fb4b2 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go @@ -108,8 +108,8 @@ Please ensure all assertions are inside leaf nodes such as {{bold}}BeforeEach{{/ func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocation) error { docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite" - if nodeType.Is(NodeTypeReportAfterSuite) { - docLink = "reporting-nodes---reportaftersuite" + if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) { + docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite" } return GinkgoError{ @@ -125,8 +125,8 @@ func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocatio func (g ginkgoErrors) SuiteNodeDuringRunPhase(nodeType NodeType, cl CodeLocation) error { docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite" - if nodeType.Is(NodeTypeReportAfterSuite) { - docLink = "reporting-nodes---reportaftersuite" + if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) { + docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite" } return GinkgoError{ @@ -180,6 +180,15 @@ func (g ginkgoErrors) InvalidDeclarationOfFocusedAndPending(cl CodeLocation, nod } } +func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl CodeLocation, nodeType NodeType) error { + return GinkgoError{ + Heading: "Invalid Combination of Decorators: FlakeAttempts and MustPassRepeatedly", + Message: formatter.F(`[%s] node was decorated with both FlakeAttempts and MustPassRepeatedly. At most one is allowed.`, nodeType), + CodeLocation: cl, + DocLink: "node-decorators-overview", + } +} + func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error { return GinkgoError{ Heading: "Unknown Decorator", @@ -189,20 +198,55 @@ func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decor } } +func (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error { + return GinkgoError{ + Heading: "Invalid Function", + Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t), + CodeLocation: cl, + DocLink: "node-decorators-overview", + } +} + func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error { + mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" + if nodeType.Is(NodeTypeContainer) { + mustGet = "{{bold}}func(){{/}}" + } return GinkgoError{ Heading: "Invalid Function", - Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. + Message: formatter.F(`[%s] node must be passed `+mustGet+`. You passed {{bold}}%s{{/}} instead.`, nodeType, t), CodeLocation: cl, DocLink: "node-decorators-overview", } } +func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error { + mustGet := "{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" + return GinkgoError{ + Heading: "Invalid Function", + Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function. +You passed {{bold}}%s{{/}} instead.`, t), + CodeLocation: cl, + DocLink: "node-decorators-overview", + } +} + +func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error { + mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}" + return GinkgoError{ + Heading: "Invalid Function", + Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function. +You passed {{bold}}%s{{/}} instead.`, t), + CodeLocation: cl, + DocLink: "node-decorators-overview", + } +} + func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ Heading: "Multiple Functions", - Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but more than one was passed in.`, nodeType), + Message: formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType), CodeLocation: cl, DocLink: "node-decorators-overview", } @@ -211,12 +255,30 @@ func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ Heading: "Missing Functions", - Message: formatter.F(`[%s] node must be passed a single {{bold}}func(){{/}} - but none was passed in.`, nodeType), + Message: formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType), CodeLocation: cl, DocLink: "node-decorators-overview", } } +func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error { + return GinkgoError{ + Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", + Message: formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`, nodeType), + CodeLocation: cl, + DocLink: "spec-timeouts-and-interruptible-nodes", + } +} + +func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error { + return GinkgoError{ + Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", + Message: formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`), + CodeLocation: cl, + DocLink: "spec-timeouts-and-interruptible-nodes", + } +} + /* Ordered Container errors */ func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ @@ -258,7 +320,7 @@ func (g ginkgoErrors) PushingCleanupNodeDuringTreeConstruction(cl CodeLocation) func (g ginkgoErrors) PushingCleanupInReportingNode(cl CodeLocation, nodeType NodeType) error { return GinkgoError{ Heading: fmt.Sprintf("DeferCleanup cannot be called in %s", nodeType), - Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a ReportAfterEach or ReportAfterSuite.", + Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a Reporting node.", CodeLocation: cl, DocLink: "cleaning-up-our-cleanup-code-defercleanup", } @@ -380,6 +442,15 @@ func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error { } } +func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error { + return GinkgoError{ + Heading: fmt.Sprintf("No parameters have been passed to the Table Function"), + Message: fmt.Sprintf("The Table Function expected at least 1 parameter"), + CodeLocation: cl, + DocLink: "table-specs", + } +} + func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error { return GinkgoError{ Heading: "DescribeTable passed incorrect parameter type", @@ -498,6 +569,13 @@ func (g ginkgoErrors) DryRunInParallelConfiguration() error { } } +func (g ginkgoErrors) GracePeriodCannotBeZero() error { + return GinkgoError{ + Heading: "Ginkgo requires a positive --grace-period.", + Message: "Please set --grace-period to a positive duration. The default is 30s.", + } +} + func (g ginkgoErrors) ConflictingVerbosityConfiguration() error { return GinkgoError{ Heading: "Conflicting reporter verbosity settings.", @@ -532,3 +610,12 @@ func (g ginkgoErrors) BothRepeatAndUntilItFails() error { Message: "--until-it-fails directs Ginkgo to rerun specs indefinitely until they fail. --repeat directs Ginkgo to rerun specs a set number of times. You can't set both... which would you like?", } } + +/* Stack-Trace parsing errors */ + +func (g ginkgoErrors) FailedToParseStackTrace(message string) error { + return GinkgoError{ + Heading: "Failed to Parse Stack Trace", + Message: message, + } +} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go index c64866c602..7b1524b52e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go @@ -6,8 +6,8 @@ import ( "time" ) -//ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports -//and across the network connection when running in parallel +// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports +// and across the network connection when running in parallel type ReportEntryValue struct { raw interface{} //unexported to prevent gob from freaking out about unregistered structs AsJSON string @@ -50,7 +50,6 @@ func (rev ReportEntryValue) MarshalJSON() ([]byte, error) { }{ Representation: rev.String(), } - asJSON, err := json.Marshal(rev.raw) if err != nil { return nil, err @@ -86,10 +85,12 @@ func (rev *ReportEntryValue) GobDecode(data []byte) error { type ReportEntry struct { // Visibility captures the visibility policy for this ReportEntry Visibility ReportEntryVisibility - // Time captures the time the AddReportEntry was called - Time time.Time // Location captures the location of the AddReportEntry call Location CodeLocation + + Time time.Time //need this for backwards compatibility + TimelineLocation TimelineLocation + // Name captures the name of this report Name string // Value captures the (optional) object passed into AddReportEntry - this can be @@ -98,7 +99,7 @@ type ReportEntry struct { Value ReportEntryValue } -// ColorableStringer is an interface that ReportEntry values can satisfy. If they do then ColorableStirng() is used to generate their representation. +// ColorableStringer is an interface that ReportEntry values can satisfy. If they do then ColorableString() is used to generate their representation. type ColorableStringer interface { ColorableString() string } @@ -121,6 +122,10 @@ func (entry ReportEntry) GetRawValue() interface{} { return entry.Value.GetRawValue() } +func (entry ReportEntry) GetTimelineLocation() TimelineLocation { + return entry.TimelineLocation +} + type ReportEntries []ReportEntry func (re ReportEntries) HasVisibility(visibilities ...ReportEntryVisibility) bool { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go index f30d23c667..3e979ba8cc 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/types.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go @@ -2,6 +2,8 @@ package types import ( "encoding/json" + "fmt" + "sort" "strings" "time" ) @@ -56,19 +58,20 @@ type Report struct { SuiteConfig SuiteConfig //SpecReports is a list of all SpecReports generated by this test run + //It is empty when the SuiteReport is provided to ReportBeforeSuite SpecReports SpecReports } -//PreRunStats contains a set of stats captured before the test run begins. This is primarily used -//by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) -//and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. +// PreRunStats contains a set of stats captured before the test run begins. This is primarily used +// by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) +// and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. type PreRunStats struct { TotalSpecs int SpecsThatWillRun int } -//Add is ued by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes -//to form a complete final report. +// Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes +// to form a complete final report. func (report Report) Add(other Report) Report { report.SuiteSucceeded = report.SuiteSucceeded && other.SuiteSucceeded @@ -147,14 +150,24 @@ type SpecReport struct { // ParallelProcess captures the parallel process that this spec ran on ParallelProcess int + // RunningInParallel captures whether this spec is part of a suite that ran in parallel + RunningInParallel bool + //Failure is populated if a spec has failed, panicked, been interrupted, or skipped by the user (e.g. calling Skip()) //It includes detailed information about the Failure Failure Failure - // NumAttempts captures the number of times this Spec was run. Flakey specs can be retried with - // ginkgo --flake-attempts=N + // NumAttempts captures the number of times this Spec was run. + // Flakey specs can be retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. + // Repeated specs can be retried with the use of the MustPassRepeatedly decorator NumAttempts int + // MaxFlakeAttempts captures whether the spec has been retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. + MaxFlakeAttempts int + + // MaxMustPassRepeatedly captures whether the spec has the MustPassRepeatedly decorator + MaxMustPassRepeatedly int + // CapturedGinkgoWriterOutput contains text printed to the GinkgoWriter CapturedGinkgoWriterOutput string @@ -165,6 +178,15 @@ type SpecReport struct { // ReportEntries contains any reports added via `AddReportEntry` ReportEntries ReportEntries + + // ProgressReports contains any progress reports generated during this spec. These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator + ProgressReports []ProgressReport + + // AdditionalFailures contains any failures that occurred after the initial spec failure. These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode. + AdditionalFailures []AdditionalFailure + + // SpecEvents capture additional events that occur during the spec run + SpecEvents SpecEvents } func (report SpecReport) MarshalJSON() ([]byte, error) { @@ -184,9 +206,14 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { ParallelProcess int Failure *Failure `json:",omitempty"` NumAttempts int - CapturedGinkgoWriterOutput string `json:",omitempty"` - CapturedStdOutErr string `json:",omitempty"` - ReportEntries ReportEntries `json:",omitempty"` + MaxFlakeAttempts int + MaxMustPassRepeatedly int + CapturedGinkgoWriterOutput string `json:",omitempty"` + CapturedStdOutErr string `json:",omitempty"` + ReportEntries ReportEntries `json:",omitempty"` + ProgressReports []ProgressReport `json:",omitempty"` + AdditionalFailures []AdditionalFailure `json:",omitempty"` + SpecEvents SpecEvents `json:",omitempty"` }{ ContainerHierarchyTexts: report.ContainerHierarchyTexts, ContainerHierarchyLocations: report.ContainerHierarchyLocations, @@ -203,6 +230,8 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { Failure: nil, ReportEntries: nil, NumAttempts: report.NumAttempts, + MaxFlakeAttempts: report.MaxFlakeAttempts, + MaxMustPassRepeatedly: report.MaxMustPassRepeatedly, CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput, CapturedStdOutErr: report.CapturedStdOutErr, } @@ -213,6 +242,15 @@ func (report SpecReport) MarshalJSON() ([]byte, error) { if len(report.ReportEntries) > 0 { out.ReportEntries = report.ReportEntries } + if len(report.ProgressReports) > 0 { + out.ProgressReports = report.ProgressReports + } + if len(report.AdditionalFailures) > 0 { + out.AdditionalFailures = report.AdditionalFailures + } + if len(report.SpecEvents) > 0 { + out.SpecEvents = report.SpecEvents + } return json.Marshal(out) } @@ -230,13 +268,13 @@ func (report SpecReport) CombinedOutput() string { return report.CapturedStdOutErr + "\n" + report.CapturedGinkgoWriterOutput } -//Failed returns true if report.State is one of the SpecStateFailureStates +// Failed returns true if report.State is one of the SpecStateFailureStates // (SpecStateFailed, SpecStatePanicked, SpecStateinterrupted, SpecStateAborted) func (report SpecReport) Failed() bool { return report.State.Is(SpecStateFailureStates) } -//FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText +// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText func (report SpecReport) FullText() string { texts := []string{} texts = append(texts, report.ContainerHierarchyTexts...) @@ -246,7 +284,7 @@ func (report SpecReport) FullText() string { return strings.Join(texts, " ") } -//Labels returns a deduped set of all the spec's Labels. +// Labels returns a deduped set of all the spec's Labels. func (report SpecReport) Labels() []string { out := []string{} seen := map[string]bool{} @@ -268,7 +306,7 @@ func (report SpecReport) Labels() []string { return out } -//MatchesLabelFilter returns true if the spec satisfies the passed in label filter query +// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { filter, err := ParseLabelFilter(query) if err != nil { @@ -277,29 +315,54 @@ func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { return filter(report.Labels()), nil } -//FileName() returns the name of the file containing the spec +// FileName() returns the name of the file containing the spec func (report SpecReport) FileName() string { return report.LeafNodeLocation.FileName } -//LineNumber() returns the line number of the leaf node +// LineNumber() returns the line number of the leaf node func (report SpecReport) LineNumber() int { return report.LeafNodeLocation.LineNumber } -//FailureMessage() returns the failure message (or empty string if the test hasn't failed) +// FailureMessage() returns the failure message (or empty string if the test hasn't failed) func (report SpecReport) FailureMessage() string { return report.Failure.Message } -//FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed) +// FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed) func (report SpecReport) FailureLocation() CodeLocation { return report.Failure.Location } +// Timeline() returns a timeline view of the report +func (report SpecReport) Timeline() Timeline { + timeline := Timeline{} + if !report.Failure.IsZero() { + timeline = append(timeline, report.Failure) + if report.Failure.AdditionalFailure != nil { + timeline = append(timeline, *(report.Failure.AdditionalFailure)) + } + } + for _, additionalFailure := range report.AdditionalFailures { + timeline = append(timeline, additionalFailure) + } + for _, reportEntry := range report.ReportEntries { + timeline = append(timeline, reportEntry) + } + for _, progressReport := range report.ProgressReports { + timeline = append(timeline, progressReport) + } + for _, specEvent := range report.SpecEvents { + timeline = append(timeline, specEvent) + } + sort.Sort(timeline) + return timeline +} + type SpecReports []SpecReport -//WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes +// WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports { count := 0 for i := range reports { @@ -319,7 +382,7 @@ func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports { return out } -//WithState returns the subset of SpecReports with State matching one of the requested SpecStates +// WithState returns the subset of SpecReports with State matching one of the requested SpecStates func (reports SpecReports) WithState(states SpecState) SpecReports { count := 0 for i := range reports { @@ -338,7 +401,7 @@ func (reports SpecReports) WithState(states SpecState) SpecReports { return out } -//CountWithState returns the number of SpecReports with State matching one of the requested SpecStates +// CountWithState returns the number of SpecReports with State matching one of the requested SpecStates func (reports SpecReports) CountWithState(states SpecState) int { n := 0 for i := range reports { @@ -349,17 +412,75 @@ func (reports SpecReports) CountWithState(states SpecState) int { return n } -//CountWithState returns the number of SpecReports that passed after multiple attempts +// If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts. func (reports SpecReports) CountOfFlakedSpecs() int { n := 0 for i := range reports { - if reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 { + if reports[i].MaxFlakeAttempts > 1 && reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 { n += 1 } } return n } +// If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts +func (reports SpecReports) CountOfRepeatedSpecs() int { + n := 0 + for i := range reports { + if reports[i].MaxMustPassRepeatedly > 1 && reports[i].State.Is(SpecStateFailureStates) && reports[i].NumAttempts > 1 { + n += 1 + } + } + return n +} + +// TimelineLocation captures the location of an event in the spec's timeline +type TimelineLocation struct { + //Offset is the offset (in bytes) of the event relative to the GinkgoWriter stream + Offset int `json:",omitempty"` + + //Order is the order of the event with respect to other events. The absolute value of Order + //is irrelevant. All that matters is that an event with a lower Order occurs before ane vent with a higher Order + Order int `json:",omitempty"` + + Time time.Time +} + +// TimelineEvent represent an event on the timeline +// consumers of Timeline will need to check the concrete type of each entry to determine how to handle it +type TimelineEvent interface { + GetTimelineLocation() TimelineLocation +} + +type Timeline []TimelineEvent + +func (t Timeline) Len() int { return len(t) } +func (t Timeline) Less(i, j int) bool { + return t[i].GetTimelineLocation().Order < t[j].GetTimelineLocation().Order +} +func (t Timeline) Swap(i, j int) { t[i], t[j] = t[j], t[i] } +func (t Timeline) WithoutHiddenReportEntries() Timeline { + out := Timeline{} + for _, event := range t { + if reportEntry, isReportEntry := event.(ReportEntry); isReportEntry && reportEntry.Visibility == ReportEntryVisibilityNever { + continue + } + out = append(out, event) + } + return out +} + +func (t Timeline) WithoutVeryVerboseSpecEvents() Timeline { + out := Timeline{} + for _, event := range t { + if specEvent, isSpecEvent := event.(SpecEvent); isSpecEvent && specEvent.IsOnlyVisibleAtVeryVerbose() { + continue + } + out = append(out, event) + } + return out +} + // Failure captures failure information for an individual test type Failure struct { // Message - the failure message passed into Fail(...). When using a matcher library @@ -372,6 +493,8 @@ type Failure struct { // This CodeLocation will include a fully-populated StackTrace Location CodeLocation + TimelineLocation TimelineLocation + // ForwardedPanic - if the failure represents a captured panic (i.e. Summary.State == SpecStatePanicked) // then ForwardedPanic will be populated with a string representation of the captured panic. ForwardedPanic string `json:",omitempty"` @@ -379,19 +502,32 @@ type Failure struct { // FailureNodeContext - one of three contexts describing the node in which the failure occurred: // FailureNodeIsLeafNode means the failure occurred in the leaf node of the associated SpecReport. None of the other FailureNode fields will be populated // FailureNodeAtTopLevel means the failure occurred in a non-leaf node that is defined at the top-level of the spec (i.e. not in a container). FailureNodeType and FailureNodeLocation will be populated. - // FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container. FailureNodeType, FailureNodeLocaiton, and FailureNodeContainerIndex will be populated. + // FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container. FailureNodeType, FailureNodeLocation, and FailureNodeContainerIndex will be populated. // // FailureNodeType will contain the NodeType of the node in which the failure occurred. // FailureNodeLocation will contain the CodeLocation of the node in which the failure occurred. // If populated, FailureNodeContainerIndex will be the index into SpecReport.ContainerHierarchyTexts and SpecReport.ContainerHierarchyLocations that represents the parent container of the node in which the failure occurred. - FailureNodeContext FailureNodeContext - FailureNodeType NodeType - FailureNodeLocation CodeLocation - FailureNodeContainerIndex int + FailureNodeContext FailureNodeContext `json:",omitempty"` + + FailureNodeType NodeType `json:",omitempty"` + + FailureNodeLocation CodeLocation `json:",omitempty"` + + FailureNodeContainerIndex int `json:",omitempty"` + + //ProgressReport is populated if the spec was interrupted or timed out + ProgressReport ProgressReport `json:",omitempty"` + + //AdditionalFailure is non-nil if a follow-on failure occurred within the same node after the primary failure. This only happens when a node has timed out or been interrupted. In such cases the AdditionalFailure can include information about where/why the spec was stuck. + AdditionalFailure *AdditionalFailure `json:",omitempty"` } func (f Failure) IsZero() bool { - return f == Failure{} + return f.Message == "" && (f.Location == CodeLocation{}) +} + +func (f Failure) GetTimelineLocation() TimelineLocation { + return f.TimelineLocation } // FailureNodeContext captures the location context for the node containing the failing line of code @@ -424,6 +560,18 @@ func (fnc FailureNodeContext) MarshalJSON() ([]byte, error) { return fncEnumSupport.MarshJSON(uint(fnc)) } +// AdditionalFailure capturs any additional failures that occur after the initial failure of a psec +// these typically occur in clean up nodes after the spec has failed. +// We can't simply use Failure as we want to track the SpecState to know what kind of failure this is +type AdditionalFailure struct { + State SpecState + Failure Failure +} + +func (f AdditionalFailure) GetTimelineLocation() TimelineLocation { + return f.Failure.TimelineLocation +} + // SpecState captures the state of a spec // To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)` type SpecState uint @@ -438,6 +586,7 @@ const ( SpecStateAborted SpecStatePanicked SpecStateInterrupted + SpecStateTimedout ) var ssEnumSupport = NewEnumSupport(map[uint]string{ @@ -449,6 +598,7 @@ var ssEnumSupport = NewEnumSupport(map[uint]string{ uint(SpecStateAborted): "aborted", uint(SpecStatePanicked): "panicked", uint(SpecStateInterrupted): "interrupted", + uint(SpecStateTimedout): "timedout", }) func (ss SpecState) String() string { @@ -463,12 +613,131 @@ func (ss SpecState) MarshalJSON() ([]byte, error) { return ssEnumSupport.MarshJSON(uint(ss)) } -var SpecStateFailureStates = SpecStateFailed | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted +var SpecStateFailureStates = SpecStateFailed | SpecStateTimedout | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted func (ss SpecState) Is(states SpecState) bool { return ss&states != 0 } +// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace +type ProgressReport struct { + Message string `json:",omitempty"` + ParallelProcess int `json:",omitempty"` + RunningInParallel bool `json:",omitempty"` + + ContainerHierarchyTexts []string `json:",omitempty"` + LeafNodeText string `json:",omitempty"` + LeafNodeLocation CodeLocation `json:",omitempty"` + SpecStartTime time.Time `json:",omitempty"` + + CurrentNodeType NodeType `json:",omitempty"` + CurrentNodeText string `json:",omitempty"` + CurrentNodeLocation CodeLocation `json:",omitempty"` + CurrentNodeStartTime time.Time `json:",omitempty"` + + CurrentStepText string `json:",omitempty"` + CurrentStepLocation CodeLocation `json:",omitempty"` + CurrentStepStartTime time.Time `json:",omitempty"` + + AdditionalReports []string `json:",omitempty"` + + CapturedGinkgoWriterOutput string `json:",omitempty"` + TimelineLocation TimelineLocation `json:",omitempty"` + + Goroutines []Goroutine `json:",omitempty"` +} + +func (pr ProgressReport) IsZero() bool { + return pr.CurrentNodeType == NodeTypeInvalid +} + +func (pr ProgressReport) Time() time.Time { + return pr.TimelineLocation.Time +} + +func (pr ProgressReport) SpecGoroutine() Goroutine { + for _, goroutine := range pr.Goroutines { + if goroutine.IsSpecGoroutine { + return goroutine + } + } + return Goroutine{} +} + +func (pr ProgressReport) HighlightedGoroutines() []Goroutine { + out := []Goroutine{} + for _, goroutine := range pr.Goroutines { + if goroutine.IsSpecGoroutine || !goroutine.HasHighlights() { + continue + } + out = append(out, goroutine) + } + return out +} + +func (pr ProgressReport) OtherGoroutines() []Goroutine { + out := []Goroutine{} + for _, goroutine := range pr.Goroutines { + if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { + continue + } + out = append(out, goroutine) + } + return out +} + +func (pr ProgressReport) WithoutCapturedGinkgoWriterOutput() ProgressReport { + out := pr + out.CapturedGinkgoWriterOutput = "" + return out +} + +func (pr ProgressReport) WithoutOtherGoroutines() ProgressReport { + out := pr + filteredGoroutines := []Goroutine{} + for _, goroutine := range pr.Goroutines { + if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { + filteredGoroutines = append(filteredGoroutines, goroutine) + } + } + out.Goroutines = filteredGoroutines + return out +} + +func (pr ProgressReport) GetTimelineLocation() TimelineLocation { + return pr.TimelineLocation +} + +type Goroutine struct { + ID uint64 + State string + Stack []FunctionCall + IsSpecGoroutine bool +} + +func (g Goroutine) IsZero() bool { + return g.ID == 0 +} + +func (g Goroutine) HasHighlights() bool { + for _, fc := range g.Stack { + if fc.Highlight { + return true + } + } + + return false +} + +type FunctionCall struct { + Function string + Filename string + Line int + Highlight bool `json:",omitempty"` + Source []string `json:",omitempty"` + SourceHighlight int `json:",omitempty"` +} + // NodeType captures the type of a given Ginkgo Node type NodeType uint @@ -493,6 +762,7 @@ const ( NodeTypeReportBeforeEach NodeTypeReportAfterEach + NodeTypeReportBeforeSuite NodeTypeReportAfterSuite NodeTypeCleanupInvalid @@ -502,7 +772,9 @@ const ( ) var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt -var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite +var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite +var NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite +var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite var ntEnumSupport = NewEnumSupport(map[uint]string{ uint(NodeTypeInvalid): "INVALID NODE TYPE", @@ -520,9 +792,10 @@ var ntEnumSupport = NewEnumSupport(map[uint]string{ uint(NodeTypeSynchronizedAfterSuite): "SynchronizedAfterSuite", uint(NodeTypeReportBeforeEach): "ReportBeforeEach", uint(NodeTypeReportAfterEach): "ReportAfterEach", + uint(NodeTypeReportBeforeSuite): "ReportBeforeSuite", uint(NodeTypeReportAfterSuite): "ReportAfterSuite", - uint(NodeTypeCleanupInvalid): "INVALID CLEANUP NODE", - uint(NodeTypeCleanupAfterEach): "DeferCleanup", + uint(NodeTypeCleanupInvalid): "DeferCleanup", + uint(NodeTypeCleanupAfterEach): "DeferCleanup (Each)", uint(NodeTypeCleanupAfterAll): "DeferCleanup (All)", uint(NodeTypeCleanupAfterSuite): "DeferCleanup (Suite)", }) @@ -542,3 +815,99 @@ func (nt NodeType) MarshalJSON() ([]byte, error) { func (nt NodeType) Is(nodeTypes NodeType) bool { return nt&nodeTypes != 0 } + +/* +SpecEvent captures a vareity of events that can occur when specs run. See SpecEventType for the list of available events. +*/ +type SpecEvent struct { + SpecEventType SpecEventType + + CodeLocation CodeLocation + TimelineLocation TimelineLocation + + Message string `json:",omitempty"` + Duration time.Duration `json:",omitempty"` + NodeType NodeType `json:",omitempty"` + Attempt int `json:",omitempty"` +} + +func (se SpecEvent) GetTimelineLocation() TimelineLocation { + return se.TimelineLocation +} + +func (se SpecEvent) IsOnlyVisibleAtVeryVerbose() bool { + return se.SpecEventType.Is(SpecEventByEnd | SpecEventNodeStart | SpecEventNodeEnd) +} + +func (se SpecEvent) GomegaString() string { + out := &strings.Builder{} + out.WriteString("[" + se.SpecEventType.String() + " SpecEvent] ") + if se.Message != "" { + out.WriteString("Message=") + out.WriteString(`"` + se.Message + `",`) + } + if se.Duration != 0 { + out.WriteString("Duration=" + se.Duration.String() + ",") + } + if se.NodeType != NodeTypeInvalid { + out.WriteString("NodeType=" + se.NodeType.String() + ",") + } + if se.Attempt != 0 { + out.WriteString(fmt.Sprintf("Attempt=%d", se.Attempt) + ",") + } + out.WriteString("CL=" + se.CodeLocation.String() + ",") + out.WriteString(fmt.Sprintf("TL.Offset=%d", se.TimelineLocation.Offset)) + + return out.String() +} + +type SpecEvents []SpecEvent + +func (se SpecEvents) WithType(seType SpecEventType) SpecEvents { + out := SpecEvents{} + for _, event := range se { + if event.SpecEventType.Is(seType) { + out = append(out, event) + } + } + return out +} + +type SpecEventType uint + +const ( + SpecEventInvalid SpecEventType = 0 + + SpecEventByStart SpecEventType = 1 << iota + SpecEventByEnd + SpecEventNodeStart + SpecEventNodeEnd + SpecEventSpecRepeat + SpecEventSpecRetry +) + +var seEnumSupport = NewEnumSupport(map[uint]string{ + uint(SpecEventInvalid): "INVALID SPEC EVENT", + uint(SpecEventByStart): "By", + uint(SpecEventByEnd): "By (End)", + uint(SpecEventNodeStart): "Node", + uint(SpecEventNodeEnd): "Node (End)", + uint(SpecEventSpecRepeat): "Repeat", + uint(SpecEventSpecRetry): "Retry", +}) + +func (se SpecEventType) String() string { + return seEnumSupport.String(uint(se)) +} +func (se *SpecEventType) UnmarshalJSON(b []byte) error { + out, err := seEnumSupport.UnmarshJSON(b) + *se = SpecEventType(out) + return err +} +func (se SpecEventType) MarshalJSON() ([]byte, error) { + return seEnumSupport.MarshJSON(uint(se)) +} + +func (se SpecEventType) Is(specEventTypes SpecEventType) bool { + return se&specEventTypes != 0 +} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index c799014918..b874ca0fd6 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.1.6" +const VERSION = "2.6.0" diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go index c315ef0656..125de64971 100644 --- a/vendor/github.com/onsi/gomega/types/types.go +++ b/vendor/github.com/onsi/gomega/types/types.go @@ -1,12 +1,13 @@ package types import ( + "context" "time" ) type GomegaFailHandler func(message string, callerSkip ...int) -//A simple *testing.T interface wrapper +// A simple *testing.T interface wrapper type GomegaTestingT interface { Helper() Fatalf(format string, args ...interface{}) @@ -18,11 +19,11 @@ type Gomega interface { Expect(actual interface{}, extra ...interface{}) Assertion ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Assertion - Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion - EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion + Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion + EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion - Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion - ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion + Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion + ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion SetDefaultEventuallyTimeout(time.Duration) SetDefaultEventuallyPollingInterval(time.Duration) @@ -30,9 +31,9 @@ type Gomega interface { SetDefaultConsistentlyPollingInterval(time.Duration) } -//All Gomega matchers must implement the GomegaMatcher interface +// All Gomega matchers must implement the GomegaMatcher interface // -//For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers +// For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers type GomegaMatcher interface { Match(actual interface{}) (success bool, err error) FailureMessage(actual interface{}) (message string) @@ -70,6 +71,10 @@ type AsyncAssertion interface { WithOffset(offset int) AsyncAssertion WithTimeout(interval time.Duration) AsyncAssertion WithPolling(interval time.Duration) AsyncAssertion + Within(timeout time.Duration) AsyncAssertion + ProbeEvery(interval time.Duration) AsyncAssertion + WithContext(ctx context.Context) AsyncAssertion + WithArguments(argsToForward ...interface{}) AsyncAssertion } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers 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 581cf7cdfa..6f9e6fd3ab 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 @@ -59,4 +59,13 @@ const ( // AnnotationBaseImageName is the annotation key for the image reference of the image's base image. AnnotationBaseImageName = "org.opencontainers.image.base.name" + + // AnnotationArtifactCreated is the annotation key for the date and time on which the artifact was built, conforming to RFC 3339. + AnnotationArtifactCreated = "org.opencontainers.artifact.created" + + // AnnotationArtifactDescription is the annotation key for the human readable description for the artifact. + AnnotationArtifactDescription = "org.opencontainers.artifact.description" + + // AnnotationReferrersFiltersApplied is the annotation key for the comma separated list of filters applied by the registry in the referrers listing. + AnnotationReferrersFiltersApplied = "org.opencontainers.referrers.filtersApplied" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go new file mode 100644 index 0000000000..03d76ce437 --- /dev/null +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go @@ -0,0 +1,34 @@ +// Copyright 2022 The Linux Foundation +// +// 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 v1 + +// Artifact describes an artifact manifest. +// This structure provides `application/vnd.oci.artifact.manifest.v1+json` mediatype when marshalled to JSON. +type Artifact struct { + // MediaType is the media type of the object this schema refers to. + MediaType string `json:"mediaType"` + + // ArtifactType is the IANA media type of the artifact this schema refers to. + ArtifactType string `json:"artifactType"` + + // Blobs is a collection of blobs referenced by this manifest. + Blobs []Descriptor `json:"blobs,omitempty"` + + // Subject (reference) is an optional link from the artifact to another manifest forming an association between the artifact and the other manifest. + Subject *Descriptor `json:"subject,omitempty"` + + // Annotations contains arbitrary metadata for the artifact manifest. + Annotations map[string]string `json:"annotations,omitempty"` +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go index 6e442a0853..9654aa5af6 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Linux Foundation +// Copyright 2016-2022 The Linux Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,10 +35,18 @@ type Descriptor struct { // Annotations contains arbitrary metadata relating to the targeted content. Annotations map[string]string `json:"annotations,omitempty"` + // Data is an embedding of the targeted content. This is encoded as a base64 + // string when marshalled to JSON (automatically, by encoding/json). If + // present, Data can be used directly to avoid fetching the targeted content. + Data []byte `json:"data,omitempty"` + // Platform describes the platform which the image in the manifest runs on. // // This should only be used when referring to a manifest. Platform *Platform `json:"platform,omitempty"` + + // ArtifactType is the IANA media type of this artifact. + ArtifactType string `json:"artifactType,omitempty"` } // Platform describes the platform which the image in the manifest runs on. diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go index 82da6c6a89..ed4a56e59e 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go @@ -21,7 +21,7 @@ import "github.com/opencontainers/image-spec/specs-go" type Index struct { specs.Versioned - // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json` + // MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json` MediaType string `json:"mediaType,omitempty"` // Manifests references platform specific manifests. diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go index d72d15ce4b..730a09359b 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Linux Foundation +// Copyright 2016-2022 The Linux Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import "github.com/opencontainers/image-spec/specs-go" type Manifest struct { specs.Versioned - // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json` + // MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json` MediaType string `json:"mediaType,omitempty"` // Config references a configuration object for a container, by digest. @@ -30,6 +30,9 @@ type Manifest struct { // Layers is an indexed list of layers referenced by the manifest. Layers []Descriptor `json:"layers"` + // Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest. + Subject *Descriptor `json:"subject,omitempty"` + // Annotations contains arbitrary metadata for the image manifest. Annotations map[string]string `json:"annotations,omitempty"` } diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go index 4f35ac134f..935b481e3e 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go @@ -54,4 +54,7 @@ const ( // MediaTypeImageConfig specifies the media type for the image configuration. MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" + + // MediaTypeArtifactManifest specifies the media type for a content descriptor. + MediaTypeArtifactManifest = "application/vnd.oci.artifact.manifest.v1+json" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index 31f99cf645..d279035796 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -20,12 +20,12 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 1 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 0 + VersionMinor = 1 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 2 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "-rc2" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_catalogsources.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_catalogsources.yaml index 2836d66fed..6f03afbf22 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_catalogsources.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_catalogsources.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: catalogsources.operators.coreos.com spec: @@ -127,6 +127,9 @@ spec: type: integer publisher: type: string + runAsRoot: + description: RunAsRoot allows admins to indicate that they wish to run the CatalogSource pod in a privileged pod as root. This should only be enabled when running older catalog images which could not be run as non-root. + type: boolean secrets: description: Secrets represent set of secrets that can be used to access the contents of the catalog. It is best to keep this list small, since each will need to be tried for every catalog entry. type: array @@ -152,7 +155,7 @@ spec: description: Represents the state of a CatalogSource. Note that Message and Reason represent the original status information, which may be migrated to be conditions based in the future. Any new features introduced will use conditions. type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_clusterserviceversions.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_clusterserviceversions.yaml index 37b41c4608..7eb672aa5f 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_clusterserviceversions.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_clusterserviceversions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: clusterserviceversions.operators.coreos.com spec: @@ -550,7 +550,7 @@ spec: - verbs properties: apiGroups: - description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. + description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. type: array items: type: string @@ -1528,7 +1528,7 @@ spec: description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. type: string ports: - description: List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated. + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. type: array items: description: ContainerPort represents a network port in a single container. @@ -1966,10 +1966,10 @@ spec: description: 'EnableServiceLinks indicates whether information about services should be injected into pod''s environment variables, matching the syntax of Docker links. Optional: Defaults to true.' type: boolean ephemeralContainers: - description: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. + description: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. type: array items: - description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted. \n This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate." + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." type: object required: - name @@ -2772,6 +2772,9 @@ spec: hostPID: description: 'Use the host''s pid namespace. Optional: Default to false.' type: boolean + hostUsers: + description: 'Use the host''s user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.' + type: boolean hostname: description: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value. type: string @@ -3160,7 +3163,7 @@ spec: description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. type: string ports: - description: List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated. + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. type: array items: description: ContainerPort represents a network port in a single container. @@ -3575,7 +3578,7 @@ spec: type: string x-kubernetes-map-type: atomic os: - description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. \n If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions \n If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature" + description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. \n If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions \n If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup" type: object required: - name @@ -3794,16 +3797,28 @@ spec: type: object additionalProperties: type: string + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + type: array + items: + type: string + x-kubernetes-list-type: atomic maxSkew: description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' type: integer format: int32 minDomains: - description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate." + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." type: integer format: int32 + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a alpha-level feature enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string topologyKey: - description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes match the node selector. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. type: string whenUnsatisfiable: description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' @@ -4746,7 +4761,7 @@ spec: - verbs properties: apiGroups: - description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. + description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. type: array items: type: string diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_installplans.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_installplans.yaml index 8e9b85e371..b85b77c562 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_installplans.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_installplans.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: installplans.operators.coreos.com spec: diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_olmconfigs.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_olmconfigs.yaml index 44dfcd937e..c6ebe96815 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_olmconfigs.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_olmconfigs.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: olmconfigs.operators.coreos.com spec: @@ -50,7 +50,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorconditions.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorconditions.yaml index aa6bd41955..ef4b7bef73 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorconditions.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorconditions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operatorconditions.operators.coreos.com spec: @@ -45,7 +45,7 @@ spec: overrides: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - message @@ -95,7 +95,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime @@ -162,7 +162,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime @@ -209,7 +209,7 @@ spec: overrides: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - message @@ -259,7 +259,7 @@ spec: conditions: type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorgroups.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorgroups.yaml index b62f3996a9..f6794075b9 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorgroups.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operatorgroups.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operatorgroups.operators.coreos.com spec: @@ -99,7 +99,7 @@ spec: description: Conditions is an array of the OperatorGroup's conditions. type: array items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" type: object required: - lastTransitionTime diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operators.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operators.yaml index e7dce32925..73b202874f 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operators.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_operators.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: operators.operators.coreos.com spec: diff --git a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_subscriptions.yaml b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_subscriptions.yaml index 3523401502..0ebb188ac0 100644 --- a/vendor/github.com/operator-framework/api/crds/operators.coreos.com_subscriptions.yaml +++ b/vendor/github.com/operator-framework/api/crds/operators.coreos.com_subscriptions.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.9.0 creationTimestamp: null name: subscriptions.operators.coreos.com spec: diff --git a/vendor/github.com/operator-framework/api/crds/zz_defs.go b/vendor/github.com/operator-framework/api/crds/zz_defs.go index ea65d5c73e..aaa0ea110d 100644 --- a/vendor/github.com/operator-framework/api/crds/zz_defs.go +++ b/vendor/github.com/operator-framework/api/crds/zz_defs.go @@ -85,7 +85,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _operatorsCoreosCom_catalogsourcesYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7b\x6b\x73\xdc\xb6\x92\xf6\x77\xff\x8a\x2e\xbd\x6f\x95\xa4\xec\x0c\x65\x25\xa7\xb2\x27\xb3\xb9\x94\x22\xdb\x59\x55\x62\x5b\x65\xd9\xde\xda\x63\x79\xd7\x18\xb2\x87\x83\x08\x04\x68\x00\x94\x34\x39\x75\xfe\xfb\x56\x37\x00\x92\x73\xe1\xcc\x48\x71\xf4\xc5\x16\x88\x6b\x5f\x9f\x7e\x00\x89\x5a\xbe\x47\xeb\xa4\xd1\x13\x10\xb5\xc4\x7b\x8f\x9a\x7e\x73\xd9\xcd\xdf\x5d\x26\xcd\xc9\xed\xe9\x93\x1b\xa9\x8b\x09\x9c\x37\xce\x9b\xea\x0d\x3a\xd3\xd8\x1c\x9f\xe1\x4c\x6a\xe9\xa5\xd1\x4f\x2a\xf4\xa2\x10\x5e\x4c\x9e\x00\x08\xad\x8d\x17\xd4\xec\xe8\x57\x80\xdc\x68\x6f\x8d\x52\x68\xc7\x25\xea\xec\xa6\x99\xe2\xb4\x91\xaa\x40\xcb\x93\xa7\xa5\x6f\x9f\x66\xdf\x65\x4f\x9f\x00\xe4\x16\x79\xf8\x5b\x59\xa1\xf3\xa2\xaa\x27\xa0\x1b\xa5\x9e\x00\x68\x51\xe1\x04\x72\xe1\x85\x32\x65\xd8\x84\xcb\x4c\x8d\x56\x78\x63\x5d\x96\x1b\x8b\x86\xfe\xa9\x9e\xb8\x1a\x73\x5a\xbd\xb4\xa6\xa9\x27\xb0\xb1\x4f\x98\x2f\x6d\x52\x78\x2c\x8d\x95\xe9\x77\x80\x31\x18\x55\xf1\xff\xe3\xe1\xc3\xb2\x57\xbc\x2c\xb7\x2b\xe9\xfc\xaf\xeb\xdf\x7e\x93\xce\xf3\xf7\x5a\x35\x56\xa8\xd5\x0d\xf3\x27\x37\x37\xd6\xbf\xea\x96\xa7\xe5\x72\xe1\x9d\xcd\xc3\x67\xa9\xcb\x46\x09\xbb\x32\xf6\x09\x80\xcb\x4d\x8d\x13\xe0\xa1\xb5\xc8\xb1\x78\x02\x10\x45\x18\xa7\x1a\x83\x28\x0a\x56\x8b\x50\x97\x56\x6a\x8f\xf6\xdc\xa8\xa6\xd2\xed\x52\xd4\xa7\x40\x97\x5b\x59\x7b\x16\xfd\xdb\x39\x42\x6d\xd1\xfb\x05\x8b\x04\xcc\x0c\xfc\x1c\xd3\xda\xed\x28\x80\xdf\x9d\xd1\x97\xc2\xcf\x27\x90\x91\x84\xb3\x42\xba\x5a\x89\x05\xed\xa6\xd7\x2b\xa8\xe9\x59\xf8\xd6\x6b\xf7\x0b\xda\xba\xf3\x56\xea\x72\xdb\x56\xa8\xdf\xfe\x7b\x08\xa2\x79\xbb\xa8\xd7\xb7\xb0\xd2\xb8\xef\xfa\x75\x33\x55\xd2\xcd\xd1\xee\xbf\x89\x76\xc8\xda\x1e\x2e\x37\x7c\x19\xd8\x48\x6f\xd2\xe4\x50\xd9\x9a\x33\xac\x2d\x70\x56\xae\x9f\xb1\x10\x3e\x35\x86\x4e\xb7\xa7\x42\xd5\x73\x71\x1a\x1b\x5d\x3e\xc7\x4a\x74\xf6\x60\x6a\xd4\x67\x97\x17\xef\xbf\xb9\x5a\xf9\x00\xcb\xd2\x59\xb2\x73\x90\x0e\x04\x58\xac\x8d\x93\xde\xd8\x05\x49\xeb\xfc\xea\xbd\x1b\xc1\xf9\x9b\x67\x6e\x04\x42\x17\xad\xe3\x41\x2d\xf2\x1b\x51\xa2\xcb\xd6\xf6\x6a\xa6\xbf\x63\xee\x7b\xcd\x16\x3f\x37\xd2\x62\xd1\xdf\x05\x89\x27\xc9\x64\xa5\x99\xe4\xdf\x6b\xaa\x2d\xad\xe9\x7b\x8e\x1c\x7e\x7a\x51\x6e\xa9\x7d\xe5\x84\x87\x24\x86\xd0\x0f\x0a\x0a\x70\xe8\xd8\x04\xa2\x8f\x61\x11\x65\x17\x4c\x43\x3a\x3a\xbf\x45\x87\x3a\x84\x3c\x6a\x16\x3a\x9e\x29\x83\x2b\xb4\x34\x90\xdc\xbd\x51\x05\x45\xc2\x5b\xb4\x1e\x2c\xe6\xa6\xd4\xf2\x8f\x76\x36\x07\xde\xf0\x32\x4a\x78\x74\x1e\xd8\x6b\xb5\x50\x70\x2b\x54\x83\x41\x94\x95\x58\x80\x45\x9a\x17\x1a\xdd\x9b\x81\xbb\xb8\x0c\x5e\x1a\x8b\x20\xf5\xcc\x4c\x60\xee\x7d\xed\x26\x27\x27\xa5\xf4\x29\x86\xe7\xa6\xaa\x1a\x2d\xfd\xe2\x84\xc3\xb1\x9c\x36\x14\x0e\x4f\x0a\xbc\x45\x75\xe2\x64\x39\x16\x36\x9f\x4b\x8f\xb9\x6f\x2c\x9e\x88\x5a\x8e\x79\xb3\x9a\xe3\x78\x56\x15\xff\xcf\xc6\xa8\xef\x0e\x57\xc4\xb7\xd1\x98\x21\x85\xcd\xad\xb2\xa6\xe0\x19\xac\x28\x0c\x0f\x67\xe9\x44\x4a\x4d\x24\x95\x37\xcf\xaf\xde\x42\xda\x40\x10\x7b\x90\x70\xd7\xd5\x75\xc2\x26\x41\x49\x3d\x43\x1b\x7a\xce\xac\xa9\x78\x16\xd4\x45\x6d\xa4\xf6\xc1\xa5\x95\x44\xed\xc1\x35\xd3\x4a\x7a\xc7\x36\x87\xce\x93\x1e\x32\x38\xe7\x14\x06\x53\x84\xa6\x26\x4f\x2a\x32\xb8\xd0\x70\x2e\x2a\x54\xe7\xc2\xe1\x5f\x2e\x6a\x92\xa8\x1b\x93\xf8\xf6\x17\x76\x3f\x03\xaf\x0f\x58\xf3\x31\x80\x94\x21\xf7\xea\x3c\xe4\x94\x10\x3c\x70\x53\x04\x86\x2d\xbe\x48\x3f\xa2\x28\x2c\xba\x0d\x1f\xd6\x1c\x32\x74\x0c\x76\x32\x37\x8e\xf4\x27\x3c\xbc\xfe\xed\x25\xe4\x42\x43\xe3\x90\x9c\x27\x37\x5a\x93\x41\x78\x03\x82\x72\xd9\x18\xef\xa5\x63\x03\xb2\x58\x4a\xe7\xed\x22\x83\x17\xc6\x56\xc2\x4f\xe0\xfb\xd4\x34\xe6\xe9\x8c\x05\x59\xff\x38\xf9\xbe\x36\xd6\xff\x08\xaf\xb5\x5a\xd0\xa4\x05\xdc\xcd\x51\xc3\x55\x7b\x36\xf8\xa1\xf7\xcb\x2f\xb6\xce\x33\xb8\x28\xb5\xb1\xa9\x27\x59\xd5\x45\x25\x4a\x84\x99\x44\xc5\x76\xed\xd0\x67\xab\x1a\xdc\xaa\x45\x08\x70\x69\x26\xcb\x97\xa2\xde\x29\x9a\xf3\xd4\x93\xd6\xa2\xe5\xfb\xc9\xbb\xfb\xe8\x0d\x9b\x32\x1d\x89\xfe\x2b\xf2\x1b\x10\x71\x95\x4a\xd4\x63\xc7\x6e\xd3\x13\xd3\x7e\x12\x38\x4f\x13\x90\xfc\xba\xe6\x8b\x18\xb9\xb2\x87\x1e\xbb\x7f\xb2\x07\x8f\xed\x60\xc8\x4e\xa1\xbd\xdc\x94\x45\xf6\x58\xa3\xb4\x75\x7e\x69\x8a\x70\xec\x9d\xab\xfc\xd2\xef\x0d\x78\x5f\x1b\x87\x0e\x0a\x39\x9b\xa1\xa5\xb8\x63\x6e\xd1\x5a\x59\xa0\x83\x99\xb1\xac\xaf\xda\x14\xec\x93\xad\xfe\x96\x52\xed\xa5\x29\xf6\x55\x0c\x2d\xcd\x09\x23\x18\x63\x34\xc3\xc1\xe3\x6e\xf4\x76\xd8\xe1\xbc\xf4\xa3\x4d\x81\x57\xa8\x30\xf7\xc6\x6e\xee\xb1\x22\x93\x57\xbd\x01\x31\xea\xa7\xdf\xee\xe6\x32\x9f\x43\xd5\x38\x8e\xba\xde\x36\xb8\x24\x17\x6f\x60\x26\x3d\x18\x0d\x82\x97\xa5\x58\xbf\x3e\xb2\x12\x3e\x9f\xc7\x1e\x87\x0e\x94\x98\xa2\x72\xab\xf3\x4c\x91\x53\x6e\xd1\x28\x2c\x68\x42\x8e\x25\x3c\xe7\xc0\x11\x76\x48\x09\x42\x28\x6b\xf1\xf6\x76\x99\xc1\x2e\x2b\x0b\x82\x97\xc6\x4a\xbf\x38\x57\xc2\xb9\x21\x9b\x5e\x93\xee\xc5\x8c\xcd\x47\xce\x24\x16\x23\x90\xba\x90\x54\xd2\xb8\x74\xf6\x43\xd7\xce\x9b\x51\x5f\x4a\x70\xbd\xfe\x49\x42\xa9\x0f\xdc\x49\xa5\x48\x58\x05\xce\x44\xa3\x38\x48\xfe\x81\xd6\x80\x64\xeb\xb4\x6c\x57\xda\xa4\xcf\xdb\x85\xb7\xe5\xac\x0e\xf3\x86\xcf\x6a\xb4\xc7\x7b\x3f\xec\x5d\x6b\xe7\x3d\xb8\xda\x34\x94\x53\xc2\x14\xc1\x68\x0e\x84\x9f\x14\x96\x22\x5f\x7c\xa2\xed\x7f\xb2\x48\x1b\xc9\x3d\x16\x9f\x32\xc6\xf9\x4b\x2e\x46\x02\x32\x1c\xb5\x51\xd2\x09\x41\x6a\x52\x39\x39\x9b\xf4\x73\x16\x90\x95\xe5\xdc\x53\xaf\x58\x78\x2c\x6f\x80\x7d\xae\xfd\x48\xa9\x5f\x48\x8d\xf6\xc3\x57\x1f\xd7\x7a\x06\xc8\xc6\xb9\x4a\x29\x73\xd7\xb7\x4f\xdb\x68\x90\x9a\xfc\x1d\xd2\x01\xe1\xac\xa8\xa4\x63\x44\x7a\x74\x79\x75\x76\xbc\x74\x12\xa8\x4c\x81\x23\x3a\x5f\x61\xd0\xe9\x43\x4f\xde\x4e\x13\x3a\x4c\xcb\x08\x4f\xcb\x90\x4d\x44\x6f\xc9\x05\xe5\xcc\xb8\x26\x09\xcc\x50\x60\x99\x62\xbb\xf8\xd5\x19\x7c\x9a\x0a\x87\x4a\x6a\x0c\xb2\xab\xad\xbc\x95\x0a\x4b\x5a\x51\xa7\xda\xd3\x65\x70\xde\x58\x8a\x67\x6a\x11\x0d\x03\x36\x6b\x45\x3a\x68\xf4\x8a\xb9\x25\xcb\x0a\x98\xaf\xaf\x2c\xea\xed\x08\x75\x5d\xf1\x88\x05\x65\x71\x91\xfa\xb1\x6e\xfc\x5c\xe8\x41\xe5\x12\x52\xa4\x89\xa5\x0e\xa3\x64\x11\xa0\x39\x5a\x6b\x6c\x06\xff\x45\xb1\xb3\xa1\x0a\x1b\x8c\x2a\xd0\xa6\xea\x0e\x24\xc5\x4b\x37\x4a\x42\x62\xc4\x1e\x71\x60\x14\xcc\x06\xc1\x0f\x9f\x39\x62\x7e\x0a\x38\xc8\xb8\x24\xed\x37\x83\x6b\x4d\x80\x52\xc0\xac\x21\x08\x98\x6a\x8b\xe0\x73\x7d\xd1\x24\x27\x4c\x13\xf4\x96\x1f\xb5\xdb\xae\x84\x8c\xa6\xd6\xd6\x19\x36\x10\x2c\x34\x97\x6c\xcf\xe7\x82\x21\x8b\x76\x39\x33\x03\x53\x57\x21\x02\xba\xa6\x26\xf8\xe3\xe8\xa4\x9a\x44\x93\x2f\xa5\x9f\xda\x14\x6e\xa3\x00\x68\x5b\xb5\xc5\x5a\xd8\x36\x62\x3b\x84\x7c\x2e\x34\xd5\x7a\x74\xd0\x16\x2b\x13\xf6\xa2\x65\xc5\xd4\x34\x9e\x6d\x2c\xfa\xea\xcc\x34\xba\x00\x0a\x2a\x1d\x9c\xbe\x69\xa6\x68\x35\x7a\x64\x44\x5d\x98\xdc\x11\x98\xce\xb1\xf6\xee\x24\x79\xd3\x49\x6d\x8a\x71\xfa\x65\x2c\x92\x93\x9c\x1c\x1e\x3c\x36\x1a\x41\x92\xfc\x04\x82\xae\x06\x7a\xa1\x6e\xaa\xe1\x00\x3f\xde\x3e\x98\x3a\x74\x62\xdc\xd8\xc9\x1b\x45\x65\x73\xc7\xe9\x6c\xda\x68\x9f\xb4\xe8\xfa\x03\x69\xa2\xc7\x59\x44\x70\x1e\xa2\xdb\xa1\xeb\x4f\xbd\x3d\x68\x0b\x6b\xc5\xd0\x11\xa4\xc7\x6a\x4b\x86\x5b\x27\x54\x28\xb6\x51\x2d\xd6\x6d\x94\x01\x80\xf7\x82\x72\x31\x17\xbf\xe1\x0b\x85\x2b\xbd\x00\xb2\xe7\x88\xf3\x39\xab\xc7\x3c\xe6\xad\xac\x15\xc2\xf7\x37\xb8\x18\x85\xca\x18\x67\x33\xcc\xfd\x8f\xd1\x9f\xa9\x0f\xf7\x67\xe7\x4e\xd4\xc3\xf7\xe9\x7f\x3f\x0e\x9d\x78\xaf\x2c\xbf\x1b\x11\x85\x9f\xb0\xa5\x6d\x3d\x56\x24\xf4\x9c\x07\xac\xa4\xec\x20\x81\x30\x17\xc9\x87\x8f\x95\xc1\xf3\xaa\xf6\x0b\xa8\x50\x68\x97\xf0\x0e\xc5\x8c\x5e\x67\x17\x23\x5c\x2f\xda\x72\x92\x69\x99\x02\xb6\x90\x57\xe6\x2a\xa2\xa0\x11\x5c\x5a\x9c\xa1\xed\x5a\x38\x91\xbd\x32\xcf\xef\x31\x6f\xfc\x20\x2e\xea\xcb\x6d\xab\x4b\xd1\xcf\x0d\x2e\x1e\x20\x90\x5f\x71\x91\x2a\x9a\x70\xb2\x1b\x5c\x04\x63\xe0\xa6\xce\x86\x44\x5d\x2b\x89\xa1\x68\xdf\x26\x99\x1b\x5c\x38\x46\x3d\x34\xfe\x26\xcc\x8e\xd4\x7f\xd4\x59\x49\x02\x9f\xcf\xa9\x6e\x74\xff\x11\xec\x35\x37\xd5\x54\xea\xb0\x58\x98\x3a\xa9\x82\x67\x4f\x02\xd5\x05\xff\xca\xcb\x7c\x09\x71\xa5\x4d\x3d\x40\x66\xaf\xd3\x39\x3a\x46\x04\x04\xed\xe8\xd0\x81\x45\x15\x3c\x7e\x2e\xeb\x44\x34\xf1\xd6\x33\x78\x4f\xe9\xb1\xa3\xc7\xd9\x36\x82\x04\xf8\x54\xcf\x3f\x37\x42\x65\xf0\x2c\x44\x45\x3e\x7d\x6c\x8a\x9d\x48\x90\x9f\x1b\x79\x2b\x14\x55\x35\xde\x50\xca\x2a\x72\x61\x0b\xce\x06\x91\xbd\x72\x26\x68\x4f\xb4\x80\x23\x79\x7b\xa7\x23\xc7\xcc\x19\xd4\xc2\x7a\x99\x37\x4a\xd8\xc4\xc8\x2f\xbe\x88\x44\x3b\xa3\xb9\xc2\xdc\xe8\x62\xab\x07\x0f\x46\xd7\x38\xb6\x2f\x63\x86\x51\x68\xa5\x29\xb8\x70\x93\x15\xae\x1a\xe9\xd1\x72\x71\x63\x66\xc9\xab\x5b\x17\x1b\x05\x54\x73\x27\x5d\x24\xb7\x5a\x02\x41\x06\x82\xe1\xb8\x17\x1e\x5b\xaf\xc8\xe0\xe7\x45\xca\x57\x23\x90\x3e\x20\x72\xc6\x7f\x09\xc3\x24\x93\x8d\xc2\xee\x1c\x6a\x66\x2c\x52\xd1\x7f\x54\x18\x1e\x83\xb7\x32\xf7\xc7\x19\xfc\x83\x20\x3e\x29\x5e\x63\x29\xbc\xbc\x6d\x31\x64\x42\x22\xde\xa2\x20\x4c\x2c\x1c\x3c\x85\x23\x1e\x06\xb2\xaa\xb0\x90\xc2\xa3\x5a\x1c\xc3\x74\xc1\xcb\xb8\x85\xf3\x58\xed\xa3\x3a\xa9\x3d\x96\x4b\xec\xf8\xfa\xcf\x2c\x12\x37\x52\xfb\x6f\xff\xb6\xa5\x27\x6f\xf6\x01\x9a\x7d\xcf\x90\x72\x29\xd4\x04\x94\xb9\xa2\xc2\x36\x07\x99\x36\x8a\xb4\x71\x43\xba\xe8\x0b\xa3\xce\xaf\x7a\xd8\x2f\x85\x99\x56\xc1\xbf\x93\x1d\x08\xb0\xc8\x17\x3c\xd1\x72\xff\x84\x8d\xcb\x7c\x1b\x61\x32\x98\xd1\x86\xf9\x3c\x60\x84\x42\xf0\xff\xdb\xbf\x0d\x10\x25\x81\x8d\x27\x9d\xaf\x73\x7e\xb0\x47\xa2\xec\x26\x1f\x52\xd6\x4e\xb7\x6e\x97\x7f\xd4\x0c\x0c\xf5\x77\x92\x38\x2d\x81\x42\x25\x52\xd4\xf7\x38\xf1\x64\xd0\x56\x78\x61\x36\x0a\x7e\x52\x3b\x2f\xb4\x97\x1c\xd9\x5a\x46\x2d\x31\x6c\x04\xbf\x1f\x42\xe2\xb0\xad\xc5\x40\x13\x8c\x2b\x72\xa6\x6b\xf1\xe1\xc1\x64\x5b\x2a\xf3\x77\xb3\xaf\x97\x89\x10\x08\x6b\x0a\xe7\x64\x49\x28\x13\xee\x90\xab\xe1\x98\x4e\x96\xd1\x66\xa8\x0a\x78\xa0\xfc\x83\xbd\xa9\x6a\x93\x80\xf4\x09\xf7\xe7\x46\xbb\xa6\xc2\x22\xc5\x8c\x02\x6b\xd4\x05\xea\x7c\xc1\x5c\xbf\xba\x45\x9b\xc1\x3b\x47\x9a\x82\xff\x94\x25\xd5\x7d\x71\xd1\x3e\x54\x62\x54\x40\xa9\x7a\x79\x07\xd2\x91\xe8\x66\x68\x2d\x16\xcc\xb6\x01\x61\xa0\x34\x03\x16\x2b\xfd\x1d\x14\x0d\xdf\x40\xac\x6e\xa2\x21\x39\x04\xba\xc0\x52\x51\x93\xe8\xb9\x96\x28\x09\x0e\x4f\x47\x2a\x4d\xb8\x6b\xe0\xfb\x30\x8a\x9d\xde\x74\x71\x54\x06\x82\xb8\x9d\x43\x6a\xff\xcd\xd7\x61\xde\xe5\x42\x98\x09\xec\x95\xc3\x70\xe1\xd6\xe8\x20\x7c\xec\xb3\x34\x29\xcc\x3c\x0d\x53\x6d\x1a\xc7\xe1\x58\x54\xab\x5b\xee\x62\xba\x15\xfa\x06\x0b\x50\x78\x2f\x73\x53\x5a\x51\xcf\x65\x2e\x94\x5a\xb0\x9b\x32\x49\x26\xbd\xe3\xaa\x7f\x0b\x99\x3d\x14\xc6\xdb\x8b\xd1\x07\x93\xba\x0e\x73\x8b\x7e\xf7\x05\xc1\x55\xe8\xd7\x25\x65\x2e\x97\xcd\x2c\x4d\x10\x6c\x24\xda\x5c\x62\xc1\x45\x9e\x93\x23\xb1\xe9\x52\xd5\x1e\x01\x48\xcf\x94\x33\xb8\xe0\x94\x3a\x45\xc7\x56\x7e\x83\x58\x07\x4b\x53\xd2\x79\x70\x15\x73\x2a\x4e\xea\x1c\x01\x45\x3e\x0f\xe2\xd4\x88\x89\x66\xf4\x56\x62\x80\x41\x94\x6a\x17\xad\x6e\x50\xfb\xcd\xa0\x66\x7b\xdd\xb5\xa5\xe6\xda\x2e\xc6\x36\xa6\xec\x96\x64\x17\x8b\x52\x4e\x8c\x37\xf1\xae\x7b\xf4\xf0\x80\xa5\xc3\xed\xd9\x95\x27\xf0\x51\xee\x8e\x35\xef\x96\xba\xb7\xb7\xaf\x73\x73\x97\xee\xe1\xd6\x9c\x9c\x19\x9b\xa4\xdb\x42\xba\x9c\x3c\x1d\x0b\x38\x37\xda\x31\x3e\x0d\xd7\xb1\x7c\x9d\x7a\x2b\x54\x30\x85\x34\x71\x6d\x94\x62\x97\x6f\x52\x39\x41\x38\x5e\x03\x56\x53\x2c\x0a\x2c\xe8\x58\x61\x2b\x03\x69\xee\x4f\x12\xe8\x29\x3f\x5c\x1a\xa5\xb6\x67\xb1\xad\x75\xe9\x3e\x55\x69\x12\xc0\x36\x6c\xb4\x9c\xfa\x92\xc4\x22\x17\x47\x36\x5d\xa0\x47\x5b\x49\x1d\xe1\x11\x41\xdd\x56\xb0\x53\xf4\x77\x88\x1a\xf2\x39\xe6\x37\xad\x2b\xc5\xdb\xec\x15\xad\x45\xfe\x69\x39\x62\x75\x0f\x05\x8c\x52\x5c\x68\x38\x44\x90\x54\x13\x68\xbc\xeb\x73\x56\x1b\xd2\x0d\xa5\xe8\x5b\x21\x95\x98\x2a\xe4\xac\xd9\xfe\x36\x5a\xba\x55\x4f\xf9\xbc\x6e\x94\x22\x10\xab\x0b\x28\xdf\x5c\x9e\x83\xb7\x62\x36\x93\x39\x7d\x2a\xa4\x0d\xac\xef\xf2\x85\xfc\xf2\x82\xdb\xe0\xda\xa0\x47\x38\x2f\x7c\xb3\xa6\xa3\x2d\x0a\xde\xa6\x58\xaa\x43\xe4\x20\x41\xb4\xa4\xca\x37\xcb\xc5\x0a\x6d\x03\x43\xb1\xb5\xc4\x7f\x67\xf0\xca\x70\x8d\x20\x3c\xbc\x44\x47\x69\x97\x05\xf4\x06\x85\x33\xba\x17\x5d\x19\xfd\x5a\x59\x4a\x2d\x54\x3c\x54\x9f\xdf\x6b\x6b\x0f\xc1\x94\x72\x25\x4b\x2b\x7c\x1b\x14\xbb\x7d\xc7\xec\x12\xf3\x62\x60\x42\x33\x38\xd3\x0b\xd6\xf7\x0c\x05\x35\xd0\xcc\xde\x9a\xa2\xc9\x99\x87\x57\x8a\xaf\x7b\xbb\x49\xbe\x68\x18\x5d\xbe\x5e\x38\x4f\x8b\x24\xa0\xe7\xc8\x01\x84\x8c\x57\x4a\x46\x23\x08\x57\x53\x1d\x97\x6c\x32\x50\xe1\x9d\x80\x39\x59\x9c\x5d\x5e\x40\x7a\x30\x97\xc1\x78\x3c\x86\xb7\xd4\xec\xbc\x6d\x72\xce\x2f\xe4\x42\xba\x88\x99\x22\x58\x1f\x1f\x52\x30\xec\xe4\x63\x40\x64\x3e\x02\x04\xab\x85\x9f\x43\x16\x04\x9f\xf5\x44\x01\xf0\x82\x72\xcd\xbd\xa8\x6a\xb2\xfb\x6b\x1d\xa2\xf7\x0b\x63\xae\x82\x92\xc2\x9a\xff\x84\x93\x93\x55\x9b\x30\x53\x82\xa8\x91\x40\x64\xd3\x98\x19\x73\xe8\x96\x8f\x94\xd1\xc0\x5f\xb5\xb9\xd3\x9b\x56\xe7\xb5\x84\xc5\x09\x5c\x1f\x9c\x25\xef\xbb\x3e\x18\xc1\xf5\xc1\xa5\x35\x25\xc1\x56\xa9\x4b\x6a\x20\xa3\xba\x3e\x78\x86\xa5\x15\x05\x16\xd7\x07\x34\xed\xbf\xd5\x54\x61\xbd\x44\x5b\xe2\xaf\xb8\xf8\x81\x27\x6b\x9b\x53\x46\xf8\xa1\xa2\xef\xdc\x4e\x29\x98\xf2\xd4\x0f\x95\xa8\xdb\x86\x97\xa2\x6e\x07\x9f\x77\x76\xf6\xe1\x63\x85\x5e\xdc\x9e\x66\x9d\x46\x3f\xfd\xee\x8c\x9e\x5c\x1f\x74\xfb\x1f\x99\x8a\x2c\xa3\xf6\x8b\xeb\x03\x58\x5a\x75\x72\x7d\xc0\xeb\xa6\xf6\xb4\xc9\xc9\xf5\x01\xad\x44\xcd\xd6\x78\x33\x6d\x66\x93\xeb\x83\xe9\xc2\xa3\x1b\x9d\x8e\x2c\xd6\x23\x02\x4c\x3f\x74\x2b\x5c\x1f\x7c\x22\x9d\x9c\x9c\xc4\x2b\x0c\x56\xa6\x83\x7f\x6d\x26\xab\x77\xc6\xfd\xed\xf5\x1b\x93\xd0\xc2\xf9\xb7\x56\x68\x27\xd3\xfb\xb1\xc1\xae\x55\xf0\xf7\xc1\xef\x96\x63\xc0\xe0\xe7\x60\x0d\x83\x9f\x07\xb2\xe7\x3e\x99\x6b\xfd\x0c\x7b\xb2\xce\xeb\x03\x13\xa4\xa1\x2f\x1d\x4f\xd3\xea\x87\x72\x40\xec\x4d\xbe\x48\x38\x9e\x5c\x3c\xc6\x37\x42\x8c\x9a\xf5\x96\x45\xff\x6d\x0b\xfc\xf6\xed\x47\xa3\x0b\xb4\x8a\x2f\xab\xba\x59\xc3\x4d\x48\x91\x41\xe0\x0d\x44\xcb\xd2\xdc\x90\x23\x71\x76\xd2\x3d\xf2\x9a\xf7\xd5\xce\x48\xb1\x23\xf8\x7c\x9c\x86\x13\x5d\x9e\x63\xed\x39\xd3\x3d\xfe\x8a\x19\x7a\xa4\x0a\x21\xab\xb1\x1f\x36\x8f\x68\x1c\x7b\x0a\x3e\xf6\x8e\xaf\x75\x9a\x4a\x50\xea\x10\x05\xed\xb7\xfb\x16\xca\xb7\x50\x6e\x85\x90\x1a\x2e\x85\x02\xc7\x9f\xf4\x10\x45\x1d\x13\x09\x03\xb3\xda\x2f\x76\x32\x26\x7b\x1d\xbe\x12\xf7\xbf\xa1\x2e\xfd\x7c\x02\xdf\x7c\xfd\xef\xdf\xfe\x7d\xa0\x63\x08\x8c\x58\xfc\x82\x3a\x72\x41\x7b\x8a\x61\x7d\xe0\x2a\x69\xd8\x3d\xf1\x2c\xbb\x3e\x2d\xc9\xdd\x59\xd0\x9d\xe0\x07\x1c\x31\x5d\x36\x35\xc9\x85\x02\x7d\xe0\x1a\x72\x1c\x11\x48\xda\x38\x99\x6c\x03\xb8\x5a\xc0\xe9\xd7\x23\x98\x46\x11\xaf\x87\xef\x0f\xf7\x1f\xb3\x0d\x5b\x96\x0e\xbe\x1b\xad\xec\x47\x3a\x20\x55\x99\x19\x1b\x4e\x28\x31\x2d\x86\x4c\x98\xc8\x80\xf5\x4c\x88\xed\x7e\x77\x29\x6e\x17\x1f\xb8\x1f\x17\x58\x49\x2d\xab\xa6\x9a\xc0\xd3\x81\x2e\x21\xa4\xed\xa9\xcd\xd0\xb9\x03\x02\x82\x42\x57\x69\x45\x45\x90\x27\x07\x59\xa0\xf6\x72\x26\xf9\xd1\x40\x6b\xda\x5c\xee\x87\x81\xe9\x0d\x4a\x2b\x45\x7e\x9e\x42\x71\xa8\x67\xec\x97\x01\xe7\x58\xce\xc0\xf1\xf6\x26\xef\x07\xa8\x45\x8d\xc1\x1b\x42\x01\x03\x78\x5f\x07\xa8\xda\xbb\x86\xa8\x50\x68\xa9\xcb\xf4\xec\x25\x71\xc9\x21\xeb\xde\xcd\x31\xde\x9e\x63\xff\x2e\x28\xa7\x62\xa9\xe0\xba\x49\x40\xd9\x08\x2b\xb4\xa7\x32\xf6\xec\xf2\x22\x60\xf4\x55\x4e\x53\x74\x6f\x21\x93\x37\x06\x57\x0d\xc1\x8a\xb6\x18\xef\xcd\xd9\x63\xbf\x9c\xab\x9e\x3e\xfd\x7a\xab\xca\xdb\x7e\xc3\x57\x78\xc2\x7b\xb4\x7a\x02\xff\xf3\xe1\x6c\xfc\x0f\x31\xfe\xe3\xe3\x51\xfc\xcf\xd3\xf1\x77\xff\x3b\x9a\x7c\xfc\xaa\xf7\xeb\xc7\xe3\x9f\xfe\xff\xc0\x4c\x9b\xc1\xfc\x80\xf9\xc4\x24\x92\x70\x62\xd2\xe8\x28\xbd\x52\x79\x6b\x1b\x1c\xc1\x0b\xa1\x1c\x8e\xe0\x9d\xe6\xd4\xf0\x27\x85\xb6\xfd\x86\x9a\xb2\xf2\x01\xad\x3a\x74\x53\x1e\xbb\xf0\x96\xb6\xf7\x89\xdb\xdd\x56\xbe\xee\x27\xa4\x44\x35\xf4\x22\x4d\xef\xcd\x2d\x3f\xd2\x24\x47\x32\x59\x44\xb8\x59\x6e\xaa\x93\xde\x9b\x5c\x82\xd6\x2f\x85\x5e\x40\x17\xd6\x02\x28\x5d\xb5\x74\xe7\x29\x36\x89\xdc\x1a\xe7\xda\x47\xc5\x0e\x94\xbc\x41\x38\xeb\xea\x46\x0a\x96\x53\xcc\x05\x63\x71\x3b\x95\xde\x8a\x40\xfa\x26\x5c\xd9\x31\x4a\xb3\x46\xc1\x11\x95\xab\x19\x3f\x24\x5b\x8b\xae\xc7\x91\xbd\x9d\x4a\x25\xfd\x22\x94\xd2\xb9\xd1\x33\x25\x63\x09\x50\xd5\xc6\x7a\xa1\x7d\xe4\x19\xb1\xc4\x7b\x90\xdd\xd5\xb7\x74\x70\x54\x68\x77\x7a\xfa\xf5\x37\x57\xcd\xb4\x30\x95\x90\xfa\x45\xe5\x4f\x8e\x7f\x3a\xfa\xdc\x08\xc5\xb7\xbc\xaf\x44\x85\x2f\x2a\x7f\xfc\xe5\xd2\xe2\xe9\xb7\x7b\x78\xd1\xd1\x87\xe0\x2b\x1f\x8f\x3e\x8c\xe3\xff\xbe\x4a\x4d\xc7\x3f\x1d\x5d\x67\x5b\xbf\x1f\x7f\x45\x67\xe8\x79\xe0\xc7\x0f\xe3\xce\xfd\xb2\x8f\x5f\x1d\xff\xd4\xfb\x76\xbc\xc9\x19\xef\xc7\xdd\x53\x91\x31\x55\x01\xe3\x4a\xd4\xe3\x1b\x5c\x0c\x38\xe7\x20\x1c\x5d\x9f\x28\x48\xac\x12\xf5\xa6\xea\x3b\xbc\xad\x7d\x83\xfc\x9e\x33\xdf\x68\xe4\x7f\xf2\x06\x46\x8b\x01\x48\x36\xee\x5e\x60\x3d\x82\x75\xa2\xbc\x13\x98\xb6\x6d\x70\x7a\x0f\x6b\xd9\x0f\x3f\xea\x2d\xef\x17\x77\x2e\xd2\x9e\xf3\xd1\x33\x24\xff\x1e\xf8\xd3\x8f\xbd\xe7\x69\xe4\x60\xa5\xb5\xcc\x61\x5e\x3c\x0b\xd0\x97\x43\x0f\xc3\xb9\xb9\xa1\x3a\xaf\xd1\xf2\x73\x83\x70\xf1\x2c\xc6\xa3\x11\x48\x9d\xab\xa6\x20\xa4\xf0\xee\xdd\xc5\x33\xaa\xdf\x7f\x8e\xe1\xe6\x0e\xa1\x30\xfa\xd0\xc3\xeb\x57\xbf\xfd\x37\x93\x01\xdc\x63\x14\x12\x7a\xb8\x8f\x12\x4a\x86\xbf\x1a\x49\x09\x18\x7e\xc6\xf0\x4e\x8e\x57\xce\x45\xdd\xf2\x27\x1c\xee\xf8\x85\x95\xaa\x09\x40\xdc\x20\xb8\xc6\xc6\xdd\xd1\xc4\xe1\xc6\x97\x64\x0d\xf1\x3e\xb8\x44\xcf\x46\xae\xf8\xaf\x1f\x1e\x23\xb4\xf8\x1e\x5f\x1a\x7d\x45\x28\xf0\x2f\xf0\x0f\x32\xe4\xd7\x11\xb3\xf2\x1a\x8f\x70\x86\x2d\x7f\x84\xb0\xf3\x84\x10\x9d\xe9\x3c\x9c\xf4\x2f\xf7\xa4\xb5\xf3\x3e\x6a\xc5\xc0\x67\xf2\xcd\xe6\x9b\x1d\xfc\xf3\xda\x33\xae\xe5\xd2\x79\xe5\x6f\xc1\x98\x5b\x6d\x2f\x47\xe7\xc2\xc1\x14\x51\x33\x9d\x1b\xd8\x3f\xd4\xd1\xea\xb0\x23\x62\x9b\x7a\xec\xcd\xb8\xd8\xac\xbc\x1d\x92\xdb\x2d\xb5\x2d\x95\xeb\xd2\xd9\xce\x1e\x5c\xa8\xde\xcd\x17\x9b\x64\xe0\x02\x9d\xc9\x0f\x87\x12\x06\x79\xe8\xc1\x86\x0b\x93\x15\x56\x97\x2b\x8b\x48\x6a\xc4\x3a\x63\x7d\x4b\x54\x3d\x2e\x31\x1b\xde\xf0\x6d\xde\x32\xb3\xf7\xf0\x3d\x06\x35\x5f\xa1\xbd\x95\x8f\x4a\x7e\xbb\x1c\x33\x0f\xef\x4c\xce\xfe\x7a\xb7\x22\xe8\xf5\xe8\x45\x98\xfa\xcb\xcd\x8e\xeb\x9b\xad\xef\xdf\x59\x82\xdb\x5e\xf9\x3f\x64\x8e\x87\x26\xcb\x10\x4d\x26\xfc\x17\x17\xa9\xc9\x1b\xcb\x57\xee\xfd\xb6\x66\xda\x02\xe5\x6e\xf6\x58\x03\xc1\x3f\xff\xf5\xe4\xff\x02\x00\x00\xff\xff\x4a\xcc\x94\x67\x43\x3e\x00\x00") +var _operatorsCoreosCom_catalogsourcesYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7b\x6b\x73\xdc\xb6\x92\xf6\x77\xff\x8a\x2e\xbd\x6f\x95\xa4\xec\x0c\x65\x39\xa7\xb2\x27\xb3\x71\x52\x8a\x6c\x67\x55\x89\x6d\x95\x65\x7b\x6b\x8f\xe5\x5d\x63\xc8\x1e\x0e\x22\x10\xa0\x01\x50\xd2\xe4\xd4\xf9\xef\x5b\xdd\x00\x48\xce\x8d\x33\x72\x1c\x7d\xb1\x05\xe2\xd2\xf7\x7e\xba\x01\x89\x5a\xbe\x47\xeb\xa4\xd1\x13\x10\xb5\xc4\x7b\x8f\x9a\x7e\x73\xd9\xcd\xdf\x5d\x26\xcd\xc9\xed\xe9\xa3\x1b\xa9\x8b\x09\x9c\x37\xce\x9b\xea\x0d\x3a\xd3\xd8\x1c\x9f\xe1\x4c\x6a\xe9\xa5\xd1\x8f\x2a\xf4\xa2\x10\x5e\x4c\x1e\x01\x08\xad\x8d\x17\x34\xec\xe8\x57\x80\xdc\x68\x6f\x8d\x52\x68\xc7\x25\xea\xec\xa6\x99\xe2\xb4\x91\xaa\x40\xcb\x9b\xa7\xa3\x6f\x1f\x67\xdf\x67\x8f\x1f\x01\xe4\x16\x79\xf9\x5b\x59\xa1\xf3\xa2\xaa\x27\xa0\x1b\xa5\x1e\x01\x68\x51\xe1\x04\x72\xe1\x85\x32\x65\x20\xc2\x65\xa6\x46\x2b\xbc\xb1\x2e\xcb\x8d\x45\x43\xff\x54\x8f\x5c\x8d\x39\x9d\x5e\x5a\xd3\xd4\x13\xd8\x38\x27\xec\x97\x88\x14\x1e\x4b\x63\x65\xfa\x1d\x60\x0c\x46\x55\xfc\xff\xc8\x7c\x38\xf6\x8a\x8f\xe5\x71\x25\x9d\xff\x75\xfd\xdb\x6f\xd2\x79\xfe\x5e\xab\xc6\x0a\xb5\x4a\x30\x7f\x72\x73\x63\xfd\xab\xee\x78\x3a\x2e\x17\xde\xd9\x3c\x7c\x96\xba\x6c\x94\xb0\x2b\x6b\x1f\x01\xb8\xdc\xd4\x38\x01\x5e\x5a\x8b\x1c\x8b\x47\x00\x51\x84\x71\xab\x31\x88\xa2\x60\xb5\x08\x75\x69\xa5\xf6\x68\xcf\x8d\x6a\x2a\xdd\x1e\x45\x73\x0a\x74\xb9\x95\xb5\x67\xd1\xbf\x9d\x23\xd4\x16\xbd\x5f\xb0\x48\xc0\xcc\xc0\xcf\x31\x9d\xdd\xae\x02\xf8\xdd\x19\x7d\x29\xfc\x7c\x02\x19\x49\x38\x2b\xa4\xab\x95\x58\x10\x35\xbd\x59\x41\x4d\xcf\xc2\xb7\xde\xb8\x5f\x10\xe9\xce\x5b\xa9\xcb\x21\x52\x68\xde\xfe\x34\x04\xd1\xbc\x5d\xd4\xeb\x24\xac\x0c\xee\x7b\x7e\xdd\x4c\x95\x74\x73\xb4\xfb\x13\xd1\x2e\x59\xa3\xe1\x72\xc3\x97\x2d\x84\xf4\x36\x4d\x0e\x95\xad\x39\xc3\xda\x01\x67\xe5\x3a\x8f\x85\xf0\x69\x30\x4c\xba\x3d\x15\xaa\x9e\x8b\xd3\x38\xe8\xf2\x39\x56\xa2\xb3\x07\x53\xa3\x3e\xbb\xbc\x78\xff\xed\xd5\xca\x07\x58\x96\xce\x92\x9d\x83\x74\x20\xc0\x62\x6d\x9c\xf4\xc6\x2e\x48\x5a\xe7\x57\xef\xdd\x08\xce\xdf\x3c\x73\x23\x10\xba\x68\x1d\x0f\x6a\x91\xdf\x88\x12\x5d\xb6\x46\xab\x99\xfe\x8e\xb9\xef\x0d\x5b\xfc\xdc\x48\x8b\x45\x9f\x0a\x12\x4f\x92\xc9\xca\x30\xc9\xbf\x37\x54\x5b\x3a\xd3\xf7\x1c\x39\xfc\xf4\xa2\xdc\xd2\xf8\x0a\x87\x87\x24\x86\x30\x0f\x0a\x0a\x70\xe8\xd8\x04\xa2\x8f\x61\x11\x65\x17\x4c\x43\x3a\xe2\xdf\xa2\x43\x1d\x42\x1e\x0d\x0b\x1d\x79\xca\xe0\x0a\x2d\x2d\x24\x77\x6f\x54\x41\x91\xf0\x16\xad\x07\x8b\xb9\x29\xb5\xfc\xa3\xdd\xcd\x81\x37\x7c\x8c\x12\x1e\x9d\x07\xf6\x5a\x2d\x14\xdc\x0a\xd5\x60\x10\x65\x25\x16\x60\x91\xf6\x85\x46\xf7\x76\xe0\x29\x2e\x83\x97\xc6\x22\x48\x3d\x33\x13\x98\x7b\x5f\xbb\xc9\xc9\x49\x29\x7d\x8a\xe1\xb9\xa9\xaa\x46\x4b\xbf\x38\xe1\x70\x2c\xa7\x0d\x85\xc3\x93\x02\x6f\x51\x9d\x38\x59\x8e\x85\xcd\xe7\xd2\x63\xee\x1b\x8b\x27\xa2\x96\x63\x26\x56\x73\x1c\xcf\xaa\xe2\xff\xd9\x18\xf5\xdd\xe1\x8a\xf8\x36\x1a\x33\xa4\xb0\x39\x28\x6b\x0a\x9e\xc1\x8a\xc2\xf2\xc0\x4b\x27\x52\x1a\x22\xa9\xbc\x79\x7e\xf5\x16\x12\x01\x41\xec\x41\xc2\xdd\x54\xd7\x09\x9b\x04\x25\xf5\x0c\x6d\x98\x39\xb3\xa6\xe2\x5d\x50\x17\xb5\x91\xda\x07\x97\x56\x12\xb5\x07\xd7\x4c\x2b\xe9\x1d\xdb\x1c\x3a\x4f\x7a\xc8\xe0\x9c\x53\x18\x4c\x11\x9a\x9a\x3c\xa9\xc8\xe0\x42\xc3\xb9\xa8\x50\x9d\x0b\x87\x7f\xb9\xa8\x49\xa2\x6e\x4c\xe2\xdb\x5f\xd8\xfd\x0c\xbc\xbe\x60\xcd\xc7\x00\x52\x86\xdc\x6b\xf2\x36\xa7\x84\xe0\x81\x9b\x22\x30\x0c\xf8\x22\xfd\x88\xa2\xb0\xe8\x36\x7c\x58\x73\xc8\x30\x31\xd8\xc9\xdc\x38\xd2\x9f\xf0\xf0\xfa\xb7\x97\x90\x0b\x0d\x8d\x43\x72\x9e\xdc\x68\x4d\x06\xe1\x0d\x08\xca\x65\x63\xbc\x97\x8e\x0d\xc8\x62\x29\x9d\xb7\x8b\x0c\x5e\x18\x5b\x09\x3f\x81\x1f\xd2\xd0\x98\xb7\x33\x16\x64\xfd\xe3\xe4\x87\xda\x58\xff\x23\xbc\xd6\x6a\x41\x9b\x16\x70\x37\x47\x0d\x57\x2d\x6f\xf0\xb4\xf7\xcb\x2f\xb6\xce\x33\xb8\x28\xb5\xb1\x69\x26\x59\xd5\x45\x25\x4a\x84\x99\x44\xc5\x76\xed\xd0\x67\xab\x1a\x1c\xd4\x22\x04\xb8\x34\x93\xe5\x4b\x51\xef\x14\xcd\x79\x9a\x49\x67\xd1\xf1\xfd\xe4\xdd\x7d\xf4\x86\x4d\x99\x58\xa2\xff\x8a\xfc\x06\x44\x3c\xa5\x12\xf5\xd8\xb1\xdb\xf4\xc4\xb4\x9f\x04\xce\xd3\x06\x24\xbf\x6e\xf8\x22\x46\xae\xec\xa1\x6c\xf7\x39\x7b\xf0\xda\x0e\x86\xec\x14\xda\xcb\x4d\x59\x64\x8f\x33\x4a\x5b\xe7\x97\xa6\x08\x6c\xef\x3c\xe5\x97\xfe\x6c\xc0\xfb\xda\x38\x74\x50\xc8\xd9\x0c\x2d\xc5\x1d\x73\x8b\xd6\xca\x02\x1d\xcc\x8c\x65\x7d\xd5\xa6\x60\x9f\x6c\xf5\xb7\x94\x6a\x2f\x4d\xb1\xaf\x62\xe8\x68\x4e\x18\xc1\x18\xa3\x19\x6e\x65\x77\xa3\xb7\xc3\x0e\xe7\xa5\x1f\x6d\x0a\xbc\x42\x85\xb9\x37\x76\xf3\x8c\x15\x99\xbc\xea\x2d\x88\x51\x3f\xfd\x76\x37\x97\xf9\x1c\xaa\xc6\x71\xd4\xf5\xb6\xc1\x25\xb9\x78\x03\x33\xe9\xc1\x68\x10\x7c\x2c\xc5\xfa\xf5\x95\x95\xf0\xf9\x3c\xce\x38\x74\xa0\xc4\x14\x95\x5b\xdd\x67\x8a\x9c\x72\x8b\x46\x61\x41\x1b\x72\x2c\xe1\x3d\xb7\xb0\xb0\x43\x4a\x10\x42\x59\x8b\xb7\x87\x65\x06\xbb\xac\x2c\x08\x5e\x1a\x2b\xfd\xe2\x5c\x09\xe7\xb6\xd9\xf4\x9a\x74\x2f\x66\x6c\x3e\x72\x26\xb1\x18\x81\xd4\x85\xa4\x92\xc6\x25\xde\x0f\x5d\xbb\x6f\x46\x73\x29\xc1\xf5\xe6\x27\x09\xa5\x39\x70\x27\x95\x22\x61\x15\x38\x13\x8d\xe2\x20\xf9\x07\x5a\x03\x92\xad\xd3\xb2\x5d\x69\x93\x3e\x0f\x0b\x6f\x80\x57\x87\x79\xc3\xbc\x1a\xed\xf1\xde\x6f\xf7\xae\x35\x7e\x0f\xaf\x36\x2d\xe5\x94\x30\x45\x30\x9a\x03\xe1\x27\x85\xa5\xc8\x17\x9f\x88\xfc\x4f\x16\x89\x90\xdc\x63\xf1\x29\x63\x9c\xbf\xe4\x62\x87\x24\x21\xc3\x61\x1b\x25\xb1\x08\x52\x93\xce\xc9\xdb\xa4\x9f\xb3\x84\xac\x2c\xe7\x9e\x66\xc5\xca\x63\x99\x02\x76\xba\xf6\x23\xe5\x7e\x21\x35\xda\x0f\xdf\x7c\x5c\x9b\x19\x30\x1b\x27\x2b\xa5\xcc\x5d\xdf\x40\x6d\xa3\x41\x6a\x72\x78\x48\x1c\xc2\x59\x51\x49\x47\xf0\xf3\xe8\xf2\xea\xec\xb8\x57\x50\x13\xd1\x7d\xbe\xa0\x32\x05\x8e\x88\xdb\xc2\xa0\xd3\x87\x87\x9e\x9c\x9f\xb6\x77\x98\x0e\x15\x9e\x0e\x25\x13\x89\xce\x93\x0b\x4a\xa1\x91\x02\x92\x9f\xa1\x38\x33\xc5\x96\x94\xab\x33\xf8\x34\x15\x0e\x95\xd4\x18\x44\x59\x5b\x79\x2b\x15\x96\x74\xa4\x4e\xa5\xa8\xcb\xe0\xe7\x45\xb2\x88\x11\x6c\xd6\x4f\x08\x47\xc4\xe8\xb2\x3e\x2e\x42\xd4\x0b\x00\x50\x3a\x68\xf4\x8a\x75\x26\x43\x0c\x33\x48\xb7\x7d\xbe\x69\x85\x23\xa0\x06\x57\xbc\x6c\x41\x99\x5f\xe8\x05\x18\x56\x65\x58\xc4\x36\x6d\xd1\xd1\x36\x92\x62\xc9\xad\x50\xb2\x08\xb8\x1d\xad\x35\x36\x83\xff\xa2\xc0\xda\x50\xf9\x0d\x46\x15\x68\x53\xe9\x07\x92\x82\xa9\x1b\x25\x91\x31\x9c\x8f\x20\x31\x8a\x69\x83\x1e\x88\xee\xcd\x62\x88\x05\x01\x45\xa3\x28\x8d\x68\xa9\x3d\x70\x49\x60\x85\x48\x13\x53\xd3\x78\xd6\x42\x34\xee\x99\x69\x74\x01\xe4\x85\x1d\xfe\xbc\x69\xa6\x68\x35\x7a\x64\x08\x5a\x98\xdc\x11\xfa\xcc\xb1\xf6\xee\x24\x59\xdf\x49\x6d\x8a\x71\xfa\x65\x2c\x92\x51\x9d\x1c\x1e\x6e\x02\x29\x7b\xf9\x2f\x24\xbd\x4c\xa0\x63\x7f\xcb\x4c\xd4\x4d\xb5\x3d\x2c\x8e\x21\x48\x60\x60\xc2\x8e\x13\xbc\x51\x54\x6c\x76\x9d\x90\x4d\xc4\xf6\x4b\xfd\x6e\x3e\x08\x8b\xfd\x4a\x3f\x42\xda\x10\x12\x0e\x5d\x7f\xeb\xe1\x50\x27\xac\x15\xdb\x58\x90\x1e\xab\x81\xbc\xb0\xde\x86\xa0\x80\x40\x15\x4c\x47\x28\xa7\x4d\xef\x05\x65\x30\x2e\x19\xc3\x17\xf2\x6a\xbd\x00\x8a\x37\x11\x1d\x73\x2e\x8c\xd1\xdf\x5b\x59\x2b\x84\x1f\x6e\x70\x31\x0a\xf5\x24\xce\x66\x98\xfb\x1f\xa3\xa1\xd3\x1c\x9e\xcf\x56\x9f\x0a\xf6\x1f\xd2\xff\x7e\xdc\xc6\xf1\x5e\xb9\x71\x37\x8e\x08\x3f\x81\xa4\xa1\x19\x2b\x12\x7a\xce\x0b\x56\x12\x5d\x90\x40\xd8\x8b\xe4\xc3\x6c\x65\xf0\xbc\xaa\xfd\x02\x2a\x14\xda\x25\x94\xa0\xd4\xd2\x64\x17\x5d\xbf\x17\x74\x38\x32\xb7\xf5\x35\x5b\xc8\x2b\x73\x15\xb1\xc3\x08\x2e\x2d\xce\xd0\x76\x23\x1c\xfd\x5f\x99\xe7\xf7\x98\x37\x7e\x2b\x9a\xe8\xcb\x6d\xd0\xad\xe8\xe7\x06\x17\x0f\x10\xc8\xaf\xb8\x48\x75\x40\xe0\xec\x06\x17\xc1\x18\x78\xa8\xb3\x21\x51\xd7\x4a\x62\x28\x75\x87\x24\x73\x83\x0b\xd7\x06\xe6\x9b\xb0\x3b\xd2\xfc\x51\x67\x25\x09\xb2\x3d\xa7\x6a\xcb\xfd\x47\xb0\xd7\xdc\x54\x53\xa9\xc3\x61\x61\xeb\xa4\x0a\xde\x3d\x09\x54\x17\xfc\x2b\x1f\xf3\x35\xc4\x95\x88\x7a\x80\xcc\x5e\x27\x3e\xba\x3e\x02\x08\xa2\xe8\xd0\x81\x45\x15\x3c\x7e\x2e\xeb\xd4\x9e\x61\xd2\x33\x78\x4f\x79\xa3\x6b\x2a\xb3\x6d\x04\x09\x30\x57\xcf\x3f\x37\x42\x65\xf0\x2c\x44\x46\xe6\x3e\x0e\xc5\x49\x24\xc8\xcf\x8d\xbc\x15\x8a\x6a\x01\x6f\x28\x33\x15\xb9\xb0\x05\xa3\xd5\xd8\xf3\x71\x26\x68\x4f\xb4\x79\x39\x79\x7b\xa7\x23\xc7\xfd\x26\xa8\x85\xf5\x32\x6f\x94\xb0\xa9\x8f\xbd\xf8\x2a\x12\xed\x8c\xe6\x0a\x73\xa3\x8b\x41\x0f\xde\x1a\x5d\xe3\xda\xbe\x8c\x19\x6d\xa0\x95\xa6\xe0\x72\x47\x56\xb8\x6a\xa4\x47\xcb\x25\x81\x99\x25\xaf\x6e\x5d\x6c\x14\x72\xfb\x9d\x74\xb1\x25\xd4\x96\xdd\x32\x94\xe5\xc7\xbd\xf0\xd8\x7a\xc5\x32\x46\x91\x3e\xe0\x58\x86\x49\x29\xb9\x27\x93\x8d\xc2\xee\x1c\x6a\x66\x2c\x52\xa9\x7c\x54\x18\x5e\x83\xb7\x32\xf7\xc7\x19\xfc\x83\x80\x31\x29\x5e\x63\x29\xbc\xbc\x6d\xa1\x56\x02\xd1\xde\xa2\x20\x20\x29\x1c\x3c\x86\x23\x5e\x06\xb2\xaa\xb0\x90\xc2\xa3\x5a\x1c\xc3\x74\xc1\xc7\xb8\x85\xf3\x58\xed\xa3\x3a\xa9\x3d\x96\x4b\x3d\xe5\xf5\x9f\x59\x6c\x77\x48\xed\xbf\xfb\xdb\xc0\x4c\x26\xf6\x01\x9a\x7d\x9f\x30\x5a\x27\x99\x80\xaf\x56\x54\xd8\xe6\x20\xd3\x46\x91\x36\x6e\x48\x17\x7d\x61\xd4\x83\x7d\x1d\x28\x4a\x61\xa6\x55\xf0\xef\x64\x07\x02\x2c\xf2\xb5\x48\xb4\xdc\x3f\x61\xe3\x32\x1f\x6a\x33\x6c\xcd\x68\xdb\xbb\x60\xc0\x08\x85\x50\xf2\x77\x7f\xdb\xd2\x5e\x08\x3d\x6c\xd2\xf9\x7a\xa7\x0c\xf6\x48\x94\xdd\xe6\xdb\x94\xb5\xd3\xad\xdb\xe3\xbf\x68\x07\xc6\xc0\x3b\x5b\x1f\x6d\xdb\x81\x2a\x89\xa8\xef\x71\xea\x2e\x41\x5b\x16\x85\xdd\x28\xf8\x49\xed\xbc\xd0\x5e\x72\x64\x6b\xfb\x50\xa9\x2f\x45\xc5\xd7\x43\x5a\x1f\x6c\x6b\x31\xd0\x04\xe3\x8a\x9d\xc6\xb5\xf8\xf0\xe0\x16\x55\x2a\x8e\x77\xf7\x2c\x2f\x53\x19\x1d\xce\x14\xce\xc9\x92\x50\x26\xdc\x21\x97\x90\x31\x9d\x2c\xa3\x4d\x1a\x8d\x47\xc8\x3f\xd8\x9b\xaa\x36\x09\x48\x9f\xc0\x7f\x6e\xb4\x6b\x2a\x2c\x52\xcc\x28\xb0\x46\x5d\xa0\xce\x17\xdc\x21\x57\xb7\x68\x33\x78\xe7\x48\x53\xf0\x9f\xb2\xa4\xea\x27\x1e\xda\x87\x4a\x8c\x0a\x28\x55\x2f\x53\x20\x1d\x89\x6e\x86\xd6\x62\xc1\x3d\x2a\x20\x0c\x94\x76\xc0\x62\x65\xbe\x83\xa2\xe1\xbe\xfd\x2a\x11\x0d\xc9\x21\x14\xd9\x56\xe8\xb2\x6d\x4a\xb6\xed\x85\xe0\xf0\xc4\x52\x69\x42\x87\x9e\x6f\x91\x28\x76\x7a\xd3\xc5\x51\x19\xda\xaa\xed\x1e\x52\xfb\x6f\x9f\x84\x7d\x97\xeb\x41\x6e\xfb\xae\x30\xc3\x65\x7b\xa3\x83\xf0\xb1\xdf\xdb\x48\x61\xe6\x71\xd8\x6a\xd3\x3a\x0e\xc7\xa2\x5a\x25\xb9\x8b\xe9\x56\xe8\x1b\x2c\x40\xe1\xbd\xcc\x4d\x69\x45\x3d\x97\xb9\x50\x54\x38\x0b\x17\x5a\x4b\xd2\x3b\x2e\x8e\x07\x5a\xc0\xdb\xc2\x78\x7b\x9d\xf8\xe0\x56\xa8\xc3\xdc\xa2\xdf\xdd\x56\xbf\x0a\xf3\xba\xa4\xcc\x85\xa8\x99\xa5\x0d\x82\x8d\x44\x9b\x4b\xbd\x63\x91\xe7\xe4\x48\x6c\xba\x54\xce\x46\x00\xd2\x33\xe5\x0c\x2e\x38\xa5\x4e\xd1\xb1\x95\xdf\x20\xd6\xc1\xd2\x94\x74\x1e\x5c\xc5\xad\x07\x27\x75\x8e\x80\x22\x9f\x07\x71\x6a\xc4\xd4\x9c\xf3\x56\x62\x80\x41\x94\x6a\x17\xad\x6e\x50\xfb\xcd\xa0\x66\xb8\xee\x1a\xa8\xb9\x86\xc5\xd8\xc6\x94\xdd\x92\xec\x62\x51\xca\x89\xf1\xfe\xda\x75\x4f\x05\x1e\x70\x74\xb8\x73\xba\xf2\x04\x3e\xca\xdd\xb1\xe6\xdd\xd2\xf4\xf6\xce\x72\x6e\xee\xd2\xed\xd5\x9a\x93\x73\x2b\x23\xe9\xb6\x90\x2e\x27\x4f\xc7\x02\xce\x8d\x76\x8c\x4f\xc3\x25\x26\x5f\x42\xde\x0a\x15\x4c\x21\x6d\x5c\x1b\xa5\xd8\xe5\x9b\x54\x4e\x10\x8e\xd7\x80\xd5\x14\x8b\x02\x0b\x62\x2b\x90\xb2\x25\xcd\xfd\xc9\xb6\x73\xca\x0f\x97\x46\xa9\xe1\x2c\x36\x58\x97\xee\x53\x95\x26\x01\x0c\x61\xa3\xe5\xd4\x97\x24\x16\xdb\x51\x64\xd3\x05\x7a\xb4\x95\xd4\x11\x1e\x11\xd4\x6d\x05\x3b\x45\x7f\x87\xa8\x21\x9f\x63\x7e\xd3\xba\x52\xbc\x03\x5e\xd1\x5a\xbc\x80\x5e\x8e\x58\xdd\xf5\xba\x51\x8a\x0b\x0d\x87\x08\x92\x6a\x02\x8d\x77\x69\xcd\x8a\x8f\xf6\x82\xbd\xb8\x15\x52\x89\xa9\x42\xce\x9a\xed\x6f\xa3\xa5\xbb\xe8\x94\xcf\xeb\x46\x29\x02\xb1\xba\x80\xf2\xcd\xe5\x39\x78\x2b\x66\x33\x99\xd3\xa7\x42\xda\xd0\x2a\x5d\xbe\xc6\x5e\x3e\x70\x08\xae\x6d\xf5\x08\xe7\x85\x6f\xd6\x74\x34\xa0\xe0\x21\xc5\x52\x1d\x22\xb7\x36\x88\x96\x54\xf9\x66\xb9\x58\x21\x32\x30\x14\x5b\x4b\x5d\xe3\x0c\x5e\x19\xae\x11\x84\x87\x97\xe8\x28\xed\xb2\x80\xde\xa0\x70\x46\xf7\xa2\x2b\xa3\x5f\x2b\x4b\xa9\x85\x8a\x4c\xf5\x9b\x7c\x6d\xed\x21\xb8\xf3\x5a\xc9\xd2\x0a\xdf\x06\xc5\x8e\xee\x98\x5d\x62\x5e\x9c\x35\xbe\xb1\x98\xc1\x99\x5e\xb0\xbe\x67\x28\x68\x80\x76\xf6\xd6\x14\x4d\xce\xcd\x6b\xa5\xf8\x92\xb4\xdb\xe4\xab\x86\xd1\x25\xa9\x1d\x9c\xa7\x43\x12\xd0\x73\xe4\x00\x42\xc6\x8b\x18\xa3\x11\x84\xab\xa9\x8e\x4b\x36\xd9\x58\xbe\x10\x6b\x05\xcc\xc9\xe2\xec\xf2\x02\xd2\x33\xb3\x0c\xc6\xe3\x31\xbc\xa5\x61\xe7\x6d\x93\x73\x7e\x21\x17\xd2\x45\xcc\x14\xc1\xfa\x98\x49\xc1\xb0\x93\xd9\x80\xd8\xf9\x08\x10\xac\x16\x7e\x0e\x59\x10\x7c\xd6\x13\x05\xc0\x0b\xca\x35\xf7\xa2\xaa\xc9\xee\xaf\x75\x88\xde\x2f\x8c\xb9\x0a\x4a\x0a\x67\xfe\x13\x4e\x4e\x56\x6d\xc2\x4c\x09\xa2\xc6\x06\x22\x9b\xc6\xcc\x98\x43\xb7\xcc\x52\x46\x0b\x7f\xd5\xe6\x4e\x6f\x3a\x9d\xcf\x12\x16\x27\x70\x7d\x70\x96\xbc\xef\xfa\x60\x04\xd7\x07\x97\xd6\x94\x04\x5b\xa5\x2e\x69\x80\x8c\xea\xfa\xe0\x19\x96\x56\x14\x58\x5c\x1f\xd0\xb6\xff\x56\x53\x85\xf5\x12\x6d\x89\xbf\xe2\xe2\x29\x6f\xd6\x0e\xa7\x8c\xf0\xb4\xa2\xef\x3c\x4e\x29\x98\xf2\xd4\xd3\x4a\xd4\xed\xc0\x4b\x51\xb7\x8b\xcf\x3b\x3b\xfb\xf0\xb1\x42\x2f\x6e\x4f\xb3\x4e\xa3\x9f\x7e\x77\x46\x4f\xae\x0f\x3a\xfa\x47\xa6\x22\xcb\xa8\xfd\xe2\xfa\x00\x96\x4e\x9d\x5c\x1f\xf0\xb9\x69\x3c\x11\x39\xb9\x3e\xa0\x93\x68\xd8\x1a\x6f\xa6\xcd\x6c\x72\x7d\x30\x5d\x78\x74\xa3\xd3\x91\xc5\x7a\x44\x80\xe9\x69\x77\xc2\xf5\xc1\x27\xd2\xc9\xc9\x49\x6c\xe4\xb3\x32\x1d\xfc\xeb\x60\x20\xa5\x0f\xc4\xfd\xe1\xfa\x8d\x9b\xd0\xc2\xf9\xb7\x56\x68\x27\xd3\xab\xab\xad\x53\xab\xe0\xef\x5b\xbf\x5b\x8e\x01\x5b\x3f\x07\x6b\xd8\xfa\x79\x4b\xf6\xdc\x27\x73\xad\xf3\xb0\x67\xd7\x79\x7d\x61\x82\x34\xf4\xa5\xeb\xd3\xb4\xfa\xa1\x1c\x10\x67\x93\x2f\x12\x8e\x27\x17\x8f\xf1\x8d\x10\xa3\x66\xbd\x65\xd1\x7f\xdb\x02\xbf\x7d\x31\xd1\xe8\x02\xad\xe2\xeb\x9a\x6e\xd7\x7c\x4e\x80\xbf\xc8\x20\xf4\x0d\x44\xdb\xa5\xb9\x21\x47\xe2\xec\xa4\x7b\xcd\x6b\xa6\xab\xdd\x91\x62\x47\xf0\xf9\xb8\x0d\x27\xba\x3c\xc7\xda\x73\xa6\xfb\xf2\x8b\x59\xe8\x35\x55\x08\x59\x8d\xfd\x76\xf3\x88\xc6\xb1\xa7\xe0\xe3\xec\xf8\xc6\xa5\xa9\x04\xa5\x0e\x51\x10\xbd\xdd\xb7\x50\xbe\x85\x72\x2b\x84\xd4\x70\x33\x14\x7a\xfc\x49\x0f\x51\xd4\x31\x91\x30\x30\xab\xfd\x62\x67\xc7\x64\x2f\xe6\x2b\x71\xff\x1b\xea\xd2\xcf\x27\xf0\xed\x93\x7f\xff\xee\xef\x5b\x26\x86\xc0\x88\xc5\x2f\xa8\x63\x2f\x68\x4f\x31\xac\x2f\x5c\x6d\x1a\x76\x0f\x23\xcb\x6e\x4e\xdb\xe4\xee\x2c\xe8\x4e\x84\x7b\xc6\x90\x2e\x9b\x9a\xe4\x42\x81\x3e\xf4\x1a\x72\x1c\x11\x48\xda\xb8\x99\x6c\x03\xb8\x5a\xc0\xe9\x93\x11\x4c\xa3\x88\xd7\xc3\xf7\x87\xfb\x8f\xd9\x06\x92\xa5\x83\xef\x47\x2b\xf4\x48\x07\xa4\x2a\x33\x63\xc3\x09\x25\xa6\xc5\x90\x09\x53\x33\x60\x3d\x13\x62\x4b\xef\x2e\xc5\xed\xea\x07\xee\xd7\x0b\xac\xa4\x96\x55\x53\x4d\xe0\xf1\x96\x29\x21\xa4\xed\xa9\xcd\x30\xb9\x03\x02\x82\x42\x57\x69\x45\x45\x90\x27\x07\x59\xa0\xf6\x72\x26\xf9\xa6\xbd\x35\x6d\x2e\xf7\xc3\xc2\xf4\x72\xa3\x95\x22\x3f\xea\xa0\x38\xd4\x33\xf6\xcb\x80\x73\x2c\x67\xe0\x78\x7b\x93\xf7\x03\xd4\xa2\xc6\xe0\x0d\xa1\x80\x01\xbc\xaf\x03\x54\xed\x5d\x43\x54\x28\xb4\xd4\x65\x7a\x2c\x92\x7a\xc9\x21\xeb\xde\xcd\x91\x53\x4f\xdb\xa7\x0c\xfd\xfe\x9c\x8a\xa5\x82\xeb\x26\x01\x65\x23\xac\xd0\x9e\xca\xd8\xb3\xcb\x8b\x80\xd1\x57\x7b\x9a\xa2\x7b\x41\x98\xbc\x31\xb8\x6a\x08\x56\x44\x62\xbc\x50\x66\x8f\xfd\x7a\xae\x7a\xfa\xf8\xc9\xa0\xca\xdb\x79\xdb\xaf\xf0\x84\xf7\x68\xf5\x04\xfe\xe7\xc3\xd9\xf8\x1f\x62\xfc\xc7\xc7\xa3\xf8\x9f\xc7\xe3\xef\xff\x77\x34\xf9\xf8\x4d\xef\xd7\x8f\xc7\x3f\xfd\xff\x2d\x3b\x6d\x06\xf3\x5b\xcc\x27\x26\x91\x84\x13\x93\x46\x47\xe9\x6d\xc7\x5b\xdb\xe0\x08\x5e\x08\xe5\x70\x04\xef\x34\xa7\x86\x3f\x29\xb4\xe1\x1b\x6a\xca\xca\x07\x74\xea\x66\xf0\xd1\x4e\x61\x92\x86\xe7\x44\x72\x87\xca\xd7\xfd\x84\x94\x5a\x0d\xbd\x48\xd3\x7b\xa9\xca\x4f\x1b\xc9\x91\x4c\x16\x11\x6e\x96\x9b\xea\xa4\xf7\x92\x95\xa0\xf5\x4b\xa1\x17\xd0\x85\xb5\x00\x4a\x57\x2d\xdd\x79\x8a\x4d\x22\xb7\xc6\xb9\xf6\x29\xae\x03\x25\x6f\x10\xce\xba\xba\x91\x82\xe5\x14\x73\xc1\x58\xdc\x4e\xa5\xb7\x22\x34\x7d\x13\xae\xec\x3a\x4a\xb3\x46\xc1\x11\x95\xab\x19\x3f\xbf\x5a\x8b\xae\xc7\xb1\x7b\x3b\x95\x4a\xfa\x45\x28\xa5\x73\xa3\x67\x4a\xc6\x12\xa0\xaa\x8d\xf5\x42\xfb\xd8\x67\xc4\x12\xef\x41\x76\x57\xdf\xd2\xc1\x51\xa1\xdd\xe9\xe9\x93\x6f\xaf\x9a\x69\x61\x2a\x21\xf5\x8b\xca\x9f\x1c\xff\x74\xf4\xb9\x11\x8a\x6f\x79\x5f\x89\x0a\x5f\x54\xfe\xf8\xeb\xa5\xc5\xd3\xef\xf6\xf0\xa2\xa3\x0f\xc1\x57\x3e\x1e\x7d\x18\xc7\xff\x7d\x93\x86\x8e\x7f\x3a\xba\xce\x06\xbf\x1f\x7f\x43\x3c\xf4\x3c\xf0\xe3\x87\x71\xe7\x7e\xd9\xc7\x6f\x8e\x7f\xea\x7d\x3b\xde\xe4\x8c\xf7\xe3\xee\xbd\xc8\x98\xaa\x80\x71\x25\xea\xf1\x0d\x2e\xb6\x38\xe7\x56\x38\xba\xbe\x51\x90\x58\x25\xea\x4d\xd5\x77\x78\x91\xfa\x06\xf9\x15\x64\xbe\xd1\xc8\xff\xe4\x0d\x8c\x16\x5b\x20\xd9\xb8\x7b\xa8\xf4\x05\x5d\x27\xca\x3b\xa1\xd3\x36\x04\xa7\xf7\xb0\x96\xfd\xf0\xa3\x1e\x78\xf5\xb7\xf3\x90\x96\xcf\x2f\xde\x21\xf9\xf7\x96\x3f\x98\xd8\x7b\x9f\x46\x6e\xad\xb4\x96\x7b\x98\x17\xcf\x02\xf4\xe5\xd0\xc3\x70\x6e\x6e\xa8\xce\x6b\xb4\xfc\xdc\x20\x5c\x3c\x8b\xf1\x68\x04\x52\xe7\xaa\x29\x08\x29\xbc\x7b\x77\xf1\x8c\xea\xf7\x9f\x63\xb8\xb9\x43\x28\x8c\x3e\xf4\xf0\xfa\xd5\x6f\xff\xcd\xcd\x00\x9e\x31\x0a\x09\x3d\xdc\x47\x09\x25\xc3\xdf\x5a\xa4\x04\x0c\x3f\x23\xbf\x14\x0b\x27\xe7\xa2\x6e\xfb\x27\x1c\xee\xf8\x99\x95\xaa\x09\x40\xdc\x20\xb8\xc6\x46\xea\x68\xe3\x70\xe3\x4b\xb2\x86\x78\x1f\x5c\xa2\x67\x23\x57\xfc\x37\x03\x5f\x22\xb4\xf8\x8a\x5d\x1a\x7d\x45\x28\xf0\x2f\xf0\x0f\x32\xe4\xd7\x11\xb3\xf2\x19\x5f\xe0\x0c\x03\x4f\xf7\x77\x72\x08\xd1\x99\xce\x03\xa7\x7f\xb9\x27\xad\xf1\xfb\x45\x27\x86\x7e\x26\xdf\x6c\xbe\xd9\xd1\x7f\x5e\x7b\xc6\xb5\x5c\x3a\xaf\xfc\x05\x15\xf7\x56\xdb\xcb\xd1\xb9\x70\x30\x45\xd4\xdc\xce\x0d\xdd\x3f\xd4\xd1\xea\xb0\x6b\xc4\x36\xf5\xd8\x9b\x71\xb1\x59\x79\x3b\x24\xb7\x5b\x6a\x03\x95\xeb\x12\x6f\x67\x0f\x2e\x54\xef\xe6\x8b\x4d\x32\x70\xa1\x9d\xc9\x0f\x87\x12\x06\x79\x28\x63\xdb\x0b\x93\x95\xae\x2e\x57\x16\xb1\xa9\x11\xeb\x8c\x75\x92\xa8\x7a\x5c\xea\x6c\x78\xc3\xb7\x79\xcb\x9d\xbd\x87\xd3\x18\xd4\x7c\x85\xf6\x56\x7e\x51\xf2\xdb\xe5\x98\x79\x78\x67\x72\xf6\xd7\xbb\x15\x41\xaf\x2f\x3e\x84\x5b\x7f\xb9\xd9\x71\x7d\x33\xf8\x6a\x9c\x25\x38\xf4\x36\xfe\x21\x7b\x3c\x34\x59\x86\x68\x32\xe1\xbf\x53\x48\x43\xde\x58\xbe\x72\xef\x8f\x35\xd3\x16\x28\x77\xbb\xc7\x1a\x08\xfe\xf9\xaf\x47\xff\x17\x00\x00\xff\xff\xc0\x4e\x52\xf2\x79\x3d\x00\x00") func operatorsCoreosCom_catalogsourcesYamlBytes() ([]byte, error) { return bindataRead( @@ -105,7 +105,7 @@ func operatorsCoreosCom_catalogsourcesYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_clusterserviceversionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x77\xe3\xb6\xb5\x30\x8c\xff\xdf\x4f\x81\xe5\xe4\x3c\xb2\x1b\x49\x9e\x69\x7b\xfa\x6b\xe7\xd7\xf7\x64\xf9\xd8\x4e\xe2\x37\x33\x1e\x2d\xdb\x99\x3c\x5d\x49\x4e\x0a\x91\x5b\x12\x6a\x12\x60\x01\x50\xb6\xfa\xe4\xf9\xee\xef\xc2\x06\xc0\x8b\x2e\xb6\x44\x72\xc6\xb2\x07\xe8\x5a\xcd\x58\x24\x41\x70\x63\x63\xdf\x2f\x34\x63\x1f\x40\x2a\x26\xf8\x1b\x42\x33\x06\xf7\x1a\xb8\xf9\x4b\x0d\x6f\xff\xa2\x86\x4c\x1c\xcf\x5f\xff\xee\x96\xf1\xf8\x0d\x39\xcd\x95\x16\xe9\x15\x28\x91\xcb\x08\xce\x60\xc2\x38\xd3\x4c\xf0\xdf\xa5\xa0\x69\x4c\x35\x7d\xf3\x3b\x42\x28\xe7\x42\x53\xf3\xb3\x32\x7f\x12\x12\x09\xae\xa5\x48\x12\x90\x83\x29\xf0\xe1\x6d\x3e\x86\x71\xce\x92\x18\x24\x4e\xee\x5f\x3d\x7f\x35\xfc\xcb\xf0\xd5\xef\x08\x89\x24\xe0\xe3\x37\x2c\x05\xa5\x69\x9a\xbd\x21\x3c\x4f\x92\xdf\x11\xc2\x69\x0a\x6f\x48\x94\xe4\x4a\x83\x54\x20\xe7\x2c\x02\xf7\xbc\x1a\x8a\x0c\x24\xd5\x42\xaa\x61\x24\x24\x08\xf3\x9f\xf4\x77\x2a\x83\xc8\xac\x62\x2a\x45\x9e\xbd\x21\x6b\xef\xb1\xf3\xfa\xc5\x52\x0d\x53\x21\x99\xff\x9b\x90\x01\x11\x49\x8a\xff\x76\x40\xb0\xaf\xbf\xb6\xaf\x77\x90\xc3\xeb\x09\x53\xfa\xfb\xcd\xf7\xbc\x65\x4a\xe3\x7d\x59\x92\x4b\x9a\x6c\xfa\x10\xbc\x45\xcd\x84\xd4\x97\xe5\xb2\xcc\x32\x22\x35\xaf\xfe\xdb\xdd\xc8\xf8\x34\x4f\xa8\xdc\x30\xdb\xef\x08\x51\x91\xc8\xe0\x0d\xc1\xc9\x32\x1a\x41\xfc\x3b\x42\xfc\xbb\xec\xe4\x03\x42\xe3\x18\x37\x92\x26\x23\xc9\xb8\x06\x79\x2a\x92\x3c\xe5\xc5\xcb\xcd\x3d\x31\xa8\x48\xb2\x4c\xe3\x66\xdd\xcc\x00\xa1\x46\xc4\x84\xe8\x19\x90\xd3\xeb\x0f\xc5\xad\x84\xfc\x53\x09\x3e\xa2\x7a\xf6\x86\x0c\xcd\x06\x0c\x63\xa6\xb2\x84\x2e\xcc\x12\x2a\x77\xd9\xdd\x3c\xb3\xd7\x2a\xbf\xeb\x85\x59\xaf\xd2\x92\xf1\xe9\x43\xef\x77\x1f\xb1\xdd\x12\xe6\x95\x7d\xaa\xbe\xfe\xc3\xca\xef\xdb\xbe\xde\x7f\x3e\x35\x6f\x26\x7a\x46\x35\xd1\x33\xa6\x88\xe0\x40\x24\x64\x09\x8d\x40\x3d\xb0\xa0\x35\xb7\xd8\x15\x5d\xad\x5e\xd8\xb0\xa4\xea\x94\x9a\xea\x5c\x0d\xb3\x19\x55\xab\x20\x1e\x2d\xfd\xba\x66\x3a\x7b\xe3\xfc\x35\x4d\xb2\x19\x7d\xed\x7e\x54\xd1\x0c\x52\x5a\xe2\x80\xc8\x80\x9f\x8c\x2e\x3e\xfc\xf1\x7a\xe9\x02\xa9\x43\x67\x2d\xf6\x13\xa6\x0c\xa8\x90\x82\x10\x4f\x42\x70\xef\x16\x19\x90\x7f\xac\x7d\xe6\x3a\x83\xe8\x1f\xc3\x95\x95\x8b\xf1\x3f\x21\xd2\x95\x9f\x25\xfc\x2b\x67\x12\xe2\xea\x8a\x0c\x80\x3c\x59\x5a\xfa\xd9\xc0\xbf\xf2\x53\x26\x0d\x59\xd0\x95\x23\x6f\x47\x85\x2e\xd6\x7e\x5f\xfa\xda\x9e\x01\x89\xfb\xc6\xd8\x90\x44\x50\x88\x8f\x0e\xe3\x20\x76\x70\xb4\x78\xca\x94\x41\x0e\x09\x0a\xb8\x25\x92\x88\x42\xdc\x7d\xd3\x90\x18\x00\x80\x54\x86\x00\xe4\x49\x6c\x68\xe7\x1c\xa4\x26\x12\x22\x31\xe5\xec\xdf\xc5\x6c\x8a\x68\x81\xaf\x49\xa8\x06\xa5\x09\x9e\x5a\x4e\x13\x32\xa7\x49\x0e\x7d\x42\x79\x4c\x52\xba\x20\x12\xcc\xbc\x24\xe7\x95\x19\xf0\x16\x35\x24\xef\x84\x04\xc2\xf8\x44\xbc\x21\x33\xad\x33\xf5\xe6\xf8\x78\xca\xb4\xa7\xfa\x91\x48\xd3\x9c\x33\xbd\x38\x46\x02\xce\xc6\xb9\x21\x9c\xc7\x31\xcc\x21\x39\x56\x6c\x3a\xa0\x32\x9a\x31\x0d\x91\xce\x25\x1c\xd3\x8c\x0d\x70\xb1\x1c\x29\xff\x30\x8d\xbf\x90\x6e\x93\x55\x6f\x09\x7c\x6b\xd1\x99\x78\x02\xfb\x20\xac\x0d\x79\xb5\x98\x64\x1f\xb7\xdf\x52\x82\xd4\xfc\x64\xa0\x72\x75\x7e\x7d\x43\xfc\x02\xdc\xb9\x44\x08\x97\xb7\xaa\x12\xd8\x06\x50\x8c\x4f\x40\xda\x3b\x27\x52\xa4\x38\x0b\xf0\x38\x13\x8c\x6b\xfc\x23\x4a\x18\x70\x4d\x54\x3e\x4e\x99\x56\x88\x73\xa0\xb4\xd9\x87\x21\x39\x45\xa6\x47\xc6\x40\xf2\x2c\xa6\x1a\xe2\x21\xb9\xe0\xe4\x94\xa6\x90\x9c\x52\x05\x1f\x1d\xd4\x06\xa2\x6a\x60\xc0\xb7\x3d\xb0\xab\x3c\x7b\xf5\x81\x95\x33\x46\x88\xe7\xa5\x1b\x77\x67\xe3\x19\x26\x31\x44\x09\x95\x56\x28\x20\x1a\x92\x84\xbc\x7f\xfb\x8e\xcc\xc4\x9d\xc1\x62\xc6\x95\xa6\x49\x82\xa7\xc0\xf1\x67\x4b\x4e\x23\xca\x49\x4a\x39\x9d\x02\xa1\x59\xa6\xc8\x44\x48\x42\xc9\x94\xcd\x81\xfb\xd3\x35\xdc\x76\xf1\x9b\x88\x04\xb1\xc4\x7d\x2d\x83\xf2\x57\xdd\x02\x97\xae\x6c\x22\x1b\x66\xac\xc8\x40\x0f\x40\xed\xa4\xbc\x17\x31\x9b\x93\x9c\x2b\x2d\x73\xdc\xec\x98\xdc\xc2\xc2\x21\x79\x4a\x33\xa2\xb4\x30\x3f\xde\x31\x3d\x23\xb4\x8a\xe0\x54\x23\x16\x8f\x81\x28\xd0\x64\xbc\x20\x46\x8c\x43\x82\xa0\x85\x48\x90\x5a\xe0\xb3\x48\x18\x24\x68\xc9\x60\x0e\x84\xca\x31\xd3\x92\xca\x45\x81\x0d\xcb\x00\x7d\x04\xa8\xf8\xb1\x15\xe1\x61\x33\x48\xc8\x43\xb8\x48\x2c\xb9\x75\xb2\x4b\x5c\x08\x96\x5b\x40\x6f\x74\xe1\xf0\xad\x14\x47\x95\xc3\x37\x50\xc4\xe0\x95\x93\x0f\x0a\xb9\x16\xdf\xe4\x10\x2b\x26\x42\x16\x98\x61\xc0\x56\x45\xc2\x31\x18\x72\x22\x29\x37\x17\xd6\x22\x77\x03\x68\x3d\x84\x36\x66\x88\x3b\xbe\x0e\x47\xab\x73\x53\x29\x6b\x02\x53\x75\x30\x0d\xe9\x86\x99\x1f\x84\x5d\xf1\xb3\x59\xe0\x9c\xc5\x60\x80\xa8\x29\xb3\xa8\x63\x4e\x2b\x1d\x8b\x5c\x5b\xd8\xb9\x5b\x62\x32\x67\x94\xd0\xe9\x54\xc2\x14\x11\x78\xe3\x6b\x1f\x81\x89\x1d\x9b\x0f\x68\x39\x06\x56\x92\x7f\xf0\x0e\x43\x06\x1f\xbc\x81\xaf\x3b\xe6\xd5\x1b\x56\x85\xc5\xfa\x78\x6c\x0f\xed\xa0\x91\x81\x89\x07\xad\x90\x0f\xde\xbc\xcd\xde\xda\xf1\xc8\x0e\xdb\x51\xdf\xe7\xa5\x85\xb8\xab\x63\x73\x3e\x4a\xd2\x6c\xc8\x01\xde\x58\x12\xdf\x31\x90\x0c\xe4\x44\xc8\xd4\x1c\x14\x4e\x28\x89\xac\xfc\x56\x10\x1e\x24\x8d\x3c\x7a\x08\x9c\x64\xdb\xfd\xb7\x63\x1b\x2c\xb0\x63\x40\x32\xaa\x67\x8f\xdc\xb6\xdd\x56\xd9\x51\x05\xda\xa3\x37\x3f\x42\xcd\x56\xe6\x2e\x39\x4c\xe7\x73\x1b\x30\x74\x3e\x29\xf2\x9c\x6d\x66\xad\xa1\xda\x15\xbd\x7b\x07\x4a\x19\x96\x8d\x52\x9a\xa4\x77\x04\x78\x24\x0c\xb1\xf8\x7f\xaf\xdf\x5f\xda\x69\x87\xe4\x42\x13\x96\x66\x09\xa4\x46\x10\x23\xef\xa8\x54\x33\x9a\x80\x44\xee\xf4\x03\x4f\x6b\x7f\x3b\x4c\xcc\x15\xc4\x86\x16\xc5\x90\xd0\x85\x9d\x2c\x86\x48\xc4\x86\x46\x0b\x49\x32\x23\xe0\xa6\x59\xae\x81\x50\x7b\x15\xdf\xcb\xf8\x74\x1d\x91\x6e\x05\x1a\x62\x24\x91\x94\xea\x37\x64\xbc\xd0\x8f\xa1\x3e\x21\xf7\x83\x78\x5b\x1a\x50\x5d\xcc\xe3\x94\xc0\x8e\xad\xe8\x41\x75\xe2\x47\xbf\xd2\x08\xa1\x94\x71\x90\x23\x21\xf5\x36\x44\xcb\x28\x1f\x53\x90\x0f\xde\xe9\x41\xc6\xb8\xfe\xe3\x1f\x1e\xb8\x33\x86\x2c\x11\x0b\x83\x17\x8f\x9f\x95\x2d\xbf\x67\xeb\x73\xbd\xed\x7c\xdb\x9e\xe5\x2d\xe7\xb3\xc6\xa9\x2e\x66\x5a\xa7\x40\x35\x9a\x88\x77\xf5\x6d\x85\x12\xf8\x64\xcc\x6f\x74\xe1\xad\x0d\x57\x30\x01\x09\x3c\x72\xb4\xe9\xfb\x7c\x0c\x92\x83\x06\x55\x11\xa4\x17\x99\xa3\x34\x46\x16\x5c\x66\x77\x4f\xc3\xe5\x1e\x91\x67\xfc\x6d\x8f\x48\x35\xfe\xb6\xc7\x64\x1b\x3b\x76\x61\x9b\x8f\x23\x9d\x1d\x3b\xd1\xd8\xc7\x11\xb0\xc1\xa4\xf3\xf5\xe6\x9c\x16\xf3\x1a\x9d\x78\x0f\x24\xbc\xeb\xda\x32\x6a\xf2\xdd\x84\x41\x12\x13\x66\x84\x37\xb3\x58\x32\x4e\x44\x74\xeb\xec\x96\x57\x67\x44\x09\x2b\xee\x19\x09\xdf\x30\xda\x48\x70\x95\xa7\x40\xd8\x63\x18\x1c\x44\xba\x20\xd2\x05\x91\xee\xb9\x88\x74\xd6\x3f\xb0\x0f\x94\x6a\x69\x21\x1b\x69\x15\xde\x17\xa8\xd5\x43\x23\x50\x2b\x1c\x81\x5a\x3d\x32\x9e\x1d\xb5\xda\x4a\x4e\x7b\x74\xae\xc7\x0e\x72\x30\xa6\x06\x63\x6a\x30\xa6\xba\x11\x78\x99\x1b\x81\x97\x05\x5e\x16\x8c\xa9\x0f\x4d\x19\x8c\xa9\x3b\x4e\x14\x8c\xa9\xc1\x98\x1a\x8c\xa9\xc1\x98\xfa\xd8\xc7\x04\x91\x2e\x88\x74\x41\xa4\xdb\x76\x31\xc1\x98\x1a\x8c\xa9\x0f\x8d\x40\xad\x2a\x23\x50\xab\x07\xc6\xcb\xa6\x56\xed\x8d\xa9\x51\x02\x94\xaf\x57\xaa\x96\xe2\xbf\xf1\x3e\x14\x8d\xd8\x84\xb9\x3c\x08\xf7\x34\x19\xc3\x8c\xce\x99\xc8\x25\xb9\x9b\x01\xf7\x29\x3b\x64\x0a\x5a\x19\x2c\x00\x0d\xeb\x04\xf3\x47\x68\xcd\xc3\xf4\x65\x40\x80\xd3\x71\xb2\x76\xe2\xc7\x48\x89\x7b\xf2\x61\xe3\xf1\x58\x08\xf3\x75\xab\x10\x43\x55\xc7\x6b\x3a\xbb\xc4\x33\x1f\x6c\xca\xb1\x5b\x1f\xd4\x7c\x7a\x75\xd6\x55\x28\x33\xf9\x99\x93\x8b\x62\x56\x82\x96\x69\x4c\x94\x30\x3c\xc4\xfc\xfa\xfe\x8e\x43\x8c\x49\x6e\x7d\xc2\xb4\xb9\xc1\x1c\x7a\x16\x31\x9d\x2c\x8a\x17\x0f\x0f\x76\xdf\xc4\x3d\x0a\x89\x3e\xbd\x3a\xdb\xde\x7c\xef\x37\xe0\x53\x58\xea\x83\x1d\x3e\xd8\xe1\x8b\x11\xc4\xa0\x86\x93\x06\x31\xe8\x81\xf1\xb2\xc5\xa0\x7d\xb7\x5b\x07\x6b\x33\x09\xd6\xe6\x87\x6f\x0b\xd6\xe6\x60\x6d\x0e\xf6\x9b\x0d\x23\x08\x2e\x38\x82\xe0\xf2\xc8\x78\x76\x82\x4b\xb0\x36\x07\x6a\x15\xa8\x55\xa0\x56\xcf\x83\x5a\x3d\xc7\xd0\xdd\x60\xf4\x0b\x46\xbf\x60\xf4\x0b\xdc\x28\x70\xa3\x47\xc6\xb3\xe3\x46\xc1\xe8\xb7\xeb\x44\xc1\xe8\xb7\x76\x04\xa3\xdf\x23\x23\x18\xfd\x82\xd1\x6f\xc3\x08\x82\x4b\xc3\x49\x83\xe0\xf2\xc0\x78\xd9\x82\x4b\x30\xfa\x05\x6a\x15\xa8\x55\xa0\x56\xcf\x83\x5a\xb5\x37\xfa\x3d\x72\x92\x1e\x7e\xf6\xe1\x93\xf2\xe0\xb3\x2c\x7a\xe8\x85\x9b\x20\xfa\x00\x04\x1f\x25\x5c\x8f\x91\xab\x01\x19\x53\x05\x7f\xfe\xd3\x4a\xdd\xf2\xea\x2d\x29\xc4\x8c\x9a\x57\xad\xbd\xe3\x71\x12\x56\xbe\x62\xf3\x9e\x6d\xb1\xf7\xc5\x32\x1a\xce\xe2\x0a\x2b\x3f\x1a\x14\x6b\xb6\x36\xbe\xb0\x37\x5f\x6b\x49\x35\x4c\x17\x95\x42\xde\x68\x93\x2d\x39\x0f\xdf\x50\x80\xbe\x50\x1a\xef\x66\x20\x01\x1f\xf2\xa5\xa7\x95\x9f\x94\xa9\x22\x7a\x39\x6e\x50\xdc\xf7\xb1\x70\x64\xff\x9e\x35\x97\x1f\xdb\xb4\x75\xd5\xb7\xd7\x02\xcb\x03\xe8\xcc\x5a\xaf\xcf\x8a\x14\xe0\x65\x88\x65\x54\x1a\x0a\xe9\xad\xdc\xc8\xb4\x2b\x77\x2f\xc1\x7b\x13\x51\xdc\x82\x53\x3f\xce\xa1\x07\x95\x4c\xe5\x4d\x96\xf5\x6d\x18\xb3\xeb\x81\x31\x02\x99\x32\xa5\x36\x05\x5c\xd7\x97\xfe\x18\xd9\xdc\x82\x5c\x6e\x80\xbf\xff\xa2\xca\x72\x0a\xf1\x09\x77\x40\x8e\x69\x44\x64\x9e\x18\x61\x8a\xc7\xc4\x95\xbf\x26\x34\x8a\x44\xce\x35\xe1\x00\xb1\xb5\x6c\xac\xc3\xd5\x2d\x88\xed\x16\xf2\xd3\xb6\xd2\xd3\xc0\xae\xf3\xd1\xbb\xdc\x37\x9c\xd8\x4f\x58\x5b\x50\xbd\x3a\xb6\x97\xb6\xf0\xf5\x8f\x73\xad\x5d\x58\xe1\xd6\x8c\xb0\xb6\xbf\x23\x91\xb0\x68\x71\x95\x27\x40\x66\x22\x89\x15\x96\xf5\x37\xdc\xbd\x70\x38\x54\x45\xe4\x0c\xef\xc6\xd5\xf7\xc9\x38\xd7\x24\x16\xa0\x08\x17\xda\x17\x06\xa8\x3d\x6e\x5d\x4c\x77\x33\xdb\xda\xc1\x3c\x44\x68\x96\x25\x98\x4a\x21\x8c\xd0\x72\x37\x63\xd1\xcc\xf6\xab\xc9\x68\x04\xeb\x6e\xdb\x5e\x7a\xd9\x4a\xbc\x26\x3b\x89\xd8\xc4\xdb\xac\xc6\x8f\xa1\x0a\xd9\x51\xd6\x26\xb6\x44\xfc\xb7\x52\xe4\xd9\x96\xb7\xaf\x5a\x16\xed\xd3\x86\xca\xeb\xa5\x06\x36\xfe\xa2\x73\x19\xd9\xbd\xb1\xb7\x15\x26\xd1\x21\x21\x17\x13\x92\xe6\x89\x66\x59\x82\x8f\xd8\x6a\x03\x8a\x50\x09\x25\xdf\xe8\x13\xca\x17\xde\x03\xe5\xda\x44\x40\x4c\xe8\xd4\xcc\xa8\xb1\x3f\x8c\x2f\x49\xcf\xf3\x14\xcc\x69\x8e\xcb\x97\xa0\x3a\xc5\x17\xe5\xec\xe4\x8e\x25\x89\x91\x67\x69\x92\x88\xbb\xf5\x6c\x69\xdd\xd8\x4d\x28\x24\xbb\x09\x86\x64\x77\x11\x98\x10\x2e\xb8\x37\xed\xfe\x70\xf5\xb6\xd9\x26\x5e\xd6\xe7\x70\xbd\x40\x40\x1b\x90\x66\x54\x6a\x46\x13\x92\xcb\x44\xd9\x7d\xa4\x46\x09\x90\xbe\x99\xca\x8c\xa2\x67\x30\x02\x65\xbb\x76\x90\xdf\xdb\x9d\x73\x80\xb5\xe7\x53\xf0\x64\x41\xa8\xdd\xf9\x49\x9e\x24\x7d\x32\x61\x9c\x1a\xb2\x0b\x99\xcf\x84\x31\xfa\x13\xb9\x66\x3c\x02\xf3\x4d\x83\x42\xb0\xc0\x15\x99\x19\xcd\xf9\x2e\x0e\x69\xdc\x77\x6d\x45\xac\xb6\xac\xdc\x2b\xcc\x81\x8d\xe8\x38\x01\xec\x6b\xe1\x44\x96\x2b\x91\xa0\x79\xdb\x19\xbe\x63\xdb\x8b\x84\x56\x2f\xff\x37\xe3\xa8\xa4\x90\x2b\x64\x1c\x46\xd9\x01\xa6\x67\x46\xf7\xc9\xb2\x64\x61\x08\x85\xc1\x9d\x12\xa1\x0e\x55\x1e\xcd\xcc\x27\x1d\x64\x22\x56\x07\x86\x8c\x1c\x28\x88\x24\x68\x75\x70\x64\xfe\x5a\xfe\x06\xfc\xbe\xea\x73\xc7\x34\x63\x07\x47\x7d\x82\x00\xc2\x46\x27\x42\xcf\x9e\x2f\x1e\xfa\x6f\xad\xf5\xd7\x7a\x6c\xd4\xb5\xd6\xea\x0c\xae\x6b\x87\xc8\x6c\x13\x0c\x43\xa3\x35\x60\x9e\x94\x41\x4a\x44\x03\xdf\x1e\x6a\x95\x58\x13\x72\xc2\x09\xa4\x99\x5e\x20\x16\xa7\x40\xb9\xbb\x1b\xe6\x20\x17\x7a\x66\xb4\x55\xa6\x9e\xff\xe1\xdf\xd2\xb1\x54\x8e\xb5\x00\x77\x07\xde\x03\xb7\x44\x72\xdb\x59\x69\x19\xb8\xbd\xdf\xf7\xaa\x52\xaf\x11\x9f\x4a\x6a\xfe\x6c\x41\x89\xec\xb5\x11\x18\x3f\x98\x27\xeb\x20\xb4\x3f\x59\x6a\x59\xd0\x8f\xb7\x6f\x6d\x17\x25\x07\xab\xef\x19\x8f\x55\x51\xc9\x28\xb6\x64\xd0\xc1\x7b\x2d\x90\x71\x85\xcf\x11\xc0\xab\xe2\xeb\xb6\x22\xe7\x23\xd3\x57\xf4\x9b\x7d\x50\x49\xb0\x2b\x53\x4d\xca\x31\x74\xaa\x6f\x5d\x4e\x46\x17\x49\xe8\x18\x12\xdb\x72\xc9\x5c\x2d\x97\x4f\x4e\xde\xbe\x2b\xba\x93\x49\xa0\x8f\xd8\xb3\x3e\x82\x22\xb2\x85\xe3\x74\xa5\xc7\xdb\xea\xd8\x5e\xf6\x44\x50\xec\x66\x0c\x26\xd7\xa0\xed\x31\x4b\x69\x66\x4e\x99\x9d\x63\xad\x2d\xf3\x2d\x42\xfa\xf1\xc3\xb2\x93\xcc\xbe\x7d\x4f\xa6\x75\x2f\xd9\xea\xa8\x6c\xe7\xf1\xdd\xe5\xec\x3d\x60\xe1\x28\x47\x0d\xcc\x4b\x08\xed\xe4\x7a\x27\x89\x47\x45\x7f\x3d\x8b\xc1\xca\x26\x46\xdb\x34\x74\xe9\x7f\x2f\xa7\xe8\x78\x0b\x76\x51\x9a\x8c\xde\x9c\x40\xa4\xc5\xc3\x65\xdf\xfc\xcd\x1a\xd2\x2c\x79\xec\xe4\x91\x9d\x15\xac\x94\xf1\x2b\xa0\xf1\xe2\x1a\x22\xc1\xe3\x2d\x09\x6c\x6d\x3f\xde\x31\xce\xd2\x3c\x25\x3c\x4f\xc7\x80\x20\x56\x76\x2e\x24\x24\x56\x79\xa5\x84\xc3\x5d\xb2\x70\xc4\x23\x26\x99\x88\x3d\x3d\x19\x1b\x65\x8b\xc6\x0b\xec\x6f\x86\x05\x52\xf9\xc2\x4c\xc2\x74\xc9\x7d\x24\x89\x24\x55\x46\x2c\xea\xe3\xa4\x4c\x1b\x8e\x35\x06\xf4\x2d\xb1\x18\xcc\x1e\xd3\x39\x65\x89\x11\xad\x87\xe4\x0c\x26\x34\x4f\xb0\x4d\x1f\x79\x45\x0e\xcd\xcb\xbc\x3e\xb5\xee\x01\x23\xee\x2a\x61\x34\x71\xe5\x72\xdc\x71\x41\x47\x3b\x58\xcb\xb7\xa9\xdf\xe7\xc7\xb6\x75\xfc\xfc\xc8\x68\xae\xb6\x55\xc3\x6b\x1b\x73\xc1\x63\x73\x1e\xaa\x92\x68\x85\xa4\x33\xe5\x66\xde\x8e\x65\x3f\x5c\xfb\x60\xcd\xaa\xa5\x98\x4a\x50\xea\x0c\x68\x9c\x30\x0e\xcd\xf1\xeb\x66\x06\x24\xa5\xf7\x88\x63\x9a\xa5\x60\x24\x91\x2a\x86\xd1\xea\x57\x69\x41\x52\x7a\x0b\xc5\xeb\xc9\x18\x26\xd8\x86\x11\x3f\xb8\xb2\xfb\x16\x7f\x26\x94\x25\x10\x0f\xf1\x1d\x95\x59\xca\xee\xc5\x16\x71\xcc\xdf\x8c\xe7\x60\x9e\xca\xa4\x40\x65\xd2\x3e\x5a\xe5\xf1\xc8\x43\xa9\xb9\xd9\xd2\x61\xdf\xb1\x6f\xb4\x04\x8a\xf3\xfb\xc8\x1a\xf9\x24\x50\x85\xb7\x59\xdc\x54\xb9\x9c\x18\xd5\xd1\x6b\x9c\x95\x05\xb9\x56\xaf\xe4\x52\x68\xd7\xf8\xaf\xf8\x40\x7c\xda\x35\xa2\x04\xa5\x59\x8a\x07\x2c\xce\xa5\x6f\x8b\x89\x30\xa3\xeb\xb7\xbe\x76\x54\xfe\xfc\xea\xd5\x96\xf2\xdb\xc7\x47\x7a\x09\xa8\x29\x37\xc1\x97\xcb\x82\x0e\x79\xf2\x6f\x54\x60\xb3\xc7\xcc\x89\xc1\xd8\xdf\x13\x24\xfa\x09\x99\xd2\x8c\x4f\x73\xa6\x66\x64\x0c\xfa\x0e\x80\x13\xb8\xb7\x15\x2e\xc8\xbf\x41\x0a\xdc\x54\x03\xde\xd2\x45\x50\x03\xda\xeb\xfd\x81\xd8\x9c\x29\x26\xf8\x77\x4c\x69\x21\x17\x6f\x59\xca\x1e\x29\x3d\xea\xc7\x6a\x97\xe3\x02\x82\x22\x89\xb1\x37\x31\x8b\xe8\x35\xd8\x0f\x96\x80\x16\x4c\x2d\xac\x7a\x4a\xcc\x39\x19\xd3\xe8\xf6\xa3\x01\xf8\xd5\xbe\x40\xd8\xb3\xeb\x06\x50\x45\x79\xaf\x98\x00\xc9\x96\x45\xca\xf3\x7b\x0b\x9f\x1a\x94\xef\x66\x42\x01\xde\x60\x8d\x8c\xf8\x98\x77\x0a\x30\x55\x10\x0c\x73\xba\x05\x07\x45\xe8\x64\x52\xbf\xa3\x3c\xec\x28\x79\xa6\xb9\xd2\x24\xa5\x3a\x9a\x59\x53\x96\x88\x0b\x71\xa2\xa7\x9c\xd8\xbf\x0b\x94\xb7\x36\x22\xef\x6e\xee\x25\x76\x9d\xe7\xf7\x46\xb7\x7c\xd4\x9b\x53\x1f\x35\x90\x2f\x4f\x53\xd7\x80\x93\xfa\x86\x38\xb9\x2d\xb5\x2d\x82\x6f\xd0\x00\x5c\xfe\x82\xbb\x70\x72\x79\xb6\xbd\x29\xa6\x89\x82\xbb\xb3\x8a\xbb\x6c\xea\x7e\xe0\xa3\xbc\xc9\xd4\x5d\xa9\xdb\xbb\x6d\x6b\xe8\x3e\xa1\xe4\x16\x16\xb6\x8b\xf4\x4a\x5b\x5e\x09\x89\x93\x24\x00\xbb\xd3\x9a\x9b\x5c\x4b\xe9\x1d\xd6\xbb\x33\xf6\xd8\xb1\x9b\x2b\xc2\x8f\x81\x59\xe8\x8e\x4f\xf8\x8f\xde\xe1\xb1\xdd\x11\xdc\x8e\x5b\x58\xec\xf6\xc0\xd2\x76\x9b\x5d\x70\xba\x8f\xdd\x77\xf3\x43\x21\xe8\x15\x5b\xbd\x9b\x8f\xa8\x3a\x76\x36\x51\xf9\xe1\x81\xd8\xea\xf3\x0a\xf4\xab\x5a\x99\xcc\x37\xf6\x94\x45\x46\x73\xa6\x67\x2c\x43\x46\xe4\x9d\x01\xbe\xc9\xf9\x07\x9a\xb0\xb8\x98\xc2\x9e\xdf\x0b\xde\x37\xe2\x93\xf9\x0f\x12\x5d\x2b\xae\x9d\x09\x50\x97\x42\xe3\x2f\x9f\x0c\x40\x76\x99\xad\xc0\x63\xa7\x70\x56\x68\xa4\x32\xa8\x78\x55\xfa\xa3\xab\xa1\xaf\xec\x55\x80\x92\x29\x72\xc1\x89\x90\x1e\x0e\xd8\xb1\xde\x4e\x64\xa7\x40\x3e\x31\xb6\x0e\x0e\xb4\x4f\xaf\x9d\xc3\x81\x4f\xc8\x1a\xf4\x1e\x98\xce\x4d\x85\xf2\x81\xbd\x62\x3b\xe2\x27\x28\xed\x3a\x51\x95\x7a\x27\x37\x8b\x48\x0a\x72\x8a\x1e\x97\x68\x6b\x8f\x43\x7d\x53\x76\xa3\xbb\x76\xec\x4c\x7d\xab\x2f\xdc\x09\x0b\x90\x35\x59\x13\x50\x1b\xe6\x66\x67\xa8\x99\x9c\xfe\x8f\xa1\xe0\xb8\x07\xff\x97\x64\x94\x49\x35\x24\x27\x44\x31\x3e\x4d\xa0\x76\xcd\x69\x18\xd5\x69\xcc\x0c\x4c\x11\x43\x6a\xe7\x34\x71\xba\x14\xe5\x04\xac\xcd\xca\xcc\xbe\xcc\x52\xfb\x4e\x52\x31\x94\xa7\x70\x74\x1d\xdc\xc2\xe2\xa0\xbf\x82\x34\x07\x17\xfc\xc0\xf2\x96\x15\x34\x29\x18\x11\xfa\xc8\x0e\xf0\xda\x41\x97\x5c\x78\x47\x86\xd3\xd4\x8e\x56\x7f\xe9\xd6\x18\xe1\x63\x3b\x1a\x0a\xeb\x35\x2d\xd1\x45\x34\x69\x41\x72\x05\x56\x5a\xc7\x53\x46\xc0\xcb\x99\x28\x55\xa2\x62\xca\xe1\x0e\xa5\xc7\xbd\x11\xfc\x8c\x26\xc1\xf8\xf4\x87\x2c\xa6\x7a\xab\xa0\x52\x3b\x6a\x10\xe9\x5d\xd9\x49\x48\x8e\xb3\x18\xdc\x9a\xb0\x29\xc9\xa8\xa4\xa9\x1a\x92\x91\xab\x6e\x88\x98\xc6\x26\x55\x5b\xa2\x83\xdd\xcd\x22\x03\xf2\xff\x90\xab\xea\x5a\x86\x64\x30\x18\x90\x9b\xf7\x67\xef\xdf\x10\xfb\x8b\x95\xb2\xb5\x20\x13\x81\x4a\x90\xc8\xa5\x79\xd5\x1c\x38\x2a\xfe\x46\xbe\x17\x1c\xde\x4f\xcc\x09\xa1\x1a\xe6\x20\xc9\x9d\xd9\xaa\x88\xc5\x50\x58\xaf\x86\xbd\x8f\x8b\xc7\xcd\x24\x93\x94\xde\x5f\xe7\x72\xba\xc3\x06\x90\x95\x4d\xa8\x9a\x6c\x4a\x65\x12\x51\xaf\x9a\x9d\xab\xa2\x19\xc4\x79\x02\x31\xa1\x63\x31\x87\x9a\xc9\xb6\xfe\x18\xb2\xf4\x1c\xfc\x83\x86\xe7\x8d\x95\x48\x72\x5d\x28\xab\x87\x70\xff\x86\xfc\x27\xba\xb6\x29\xc9\x40\x46\xc0\x35\x9d\xc2\xb2\x19\xc0\xde\xf7\xfa\xd5\x7f\x1c\x39\x7e\x64\x66\x74\xd6\x93\x57\x06\x23\xde\xd1\xfb\x1f\x78\x69\x1a\x64\x8a\xbc\x1a\x92\x93\xa5\x97\xe1\x73\x49\x94\x27\x68\x6b\x41\x77\x7d\xe5\x95\xe3\x05\x91\x22\x47\x87\x3d\xc9\xb3\xba\x36\xfb\x87\xff\xfc\x0f\xa3\xf4\xd1\x34\x4b\xe0\x8d\x2f\x8a\x6a\xd5\x66\x23\xc3\x68\x41\xfe\xf8\xea\x3f\x2c\xf5\x34\xe7\xb3\xd4\x0a\x4b\x98\x51\x03\xb0\x3c\x23\x2c\xb5\xa1\x98\x90\x2c\xca\xea\xaa\xb2\x8e\xfe\x4a\x53\xa9\x55\x9f\xa0\x57\xbf\x10\x0e\xb5\xd0\x34\x59\xd2\xf2\x51\x0b\x87\x3b\x0b\xa4\x58\x20\x4c\x00\x0d\x55\xe4\xf5\x1f\x5f\xfd\xc7\xaa\x39\xe5\x3d\x8f\x00\x9f\xc4\x27\x30\xcc\x62\x6c\x94\xfb\x5b\x96\x24\x10\xf7\x1f\x5d\xfe\x24\x97\x7a\x06\xb2\x4f\x80\x2b\x6f\xac\x32\xeb\x5b\x5a\x1b\xce\x2e\x73\xce\x51\x46\xb0\xd6\x61\xb4\x68\x55\x2c\x5c\xee\x63\x0d\x23\xd4\x24\x15\x4a\xaf\x5f\xf2\xf6\xc7\xcd\x0c\xca\x17\xef\x27\xbb\x8a\x03\x83\x06\x66\x88\xd5\xa7\x1b\x88\x94\xf7\x83\xdb\x22\x53\x72\xc0\xb8\x1e\x08\x39\xb0\xd3\xbc\x21\x5a\xe6\x8f\x7b\x0d\xca\x91\xd6\x4e\xc0\x27\x20\x03\x79\xe5\xbc\xad\xec\xea\x47\x39\xf9\xcd\xcf\x73\x2c\xee\xf8\x66\xca\x81\x84\xd3\xd1\x8c\x86\xa7\xbe\x6e\x71\x5b\x3a\x36\xe6\xed\xe6\xee\xff\xdf\x2a\x76\xef\x40\x0e\xdc\xd9\x2d\x4e\xbb\x91\xab\xd0\xe3\xd1\xdf\xe2\xed\xc5\xb1\xb5\x9c\xcf\xda\x9c\xcc\x0d\xf6\x35\x6b\x28\xd7\xca\x09\x5f\x43\x81\xec\x3a\x4a\x87\x8c\xc6\x88\x02\x73\xce\xd5\xc6\x83\x9e\x00\x55\x7a\x1d\x28\xc2\x41\x7f\x7c\x3c\x1c\xc0\xbf\x3c\xea\x42\xa7\x91\x90\x10\xe4\xa5\x8d\xf1\xd4\x22\xca\xc1\x15\x58\x0f\x9f\x0d\x38\xab\x09\x51\x07\xc5\x91\x30\xfb\x57\x97\xaf\x3e\x56\xd8\x8c\x37\x72\x36\x11\xad\xdd\xa3\x95\xc0\x5e\x67\x3a\x75\xc4\xab\xf0\x28\x5a\x97\xe6\xde\x48\xd1\x29\x68\xfa\x70\x92\xc7\xf2\xa8\x13\xed\x6b\x4d\x79\x4c\x65\xec\x56\xd9\xeb\xa9\x62\xca\x21\x79\x87\xbe\x34\x3e\x11\x6f\xc8\x4c\xeb\x4c\xbd\x39\x3e\x9e\x32\x3d\xbc\xfd\x8b\x1a\x32\x71\x1c\x89\x34\xcd\x39\xd3\x8b\x63\x74\xa0\xb1\x71\xae\x85\x54\xc7\x31\xcc\x21\x39\x56\x6c\x3a\xa0\x32\x9a\x31\x0d\x91\xce\x25\x1c\xd3\x8c\x0d\x4a\x99\x59\x0d\xd3\xf8\x0b\xff\xa2\x8f\x2c\x18\xd7\xce\x10\x5a\x97\xe4\x1c\x06\x39\xbf\xe5\xe2\x8e\x0f\x50\x93\x55\x3b\x9d\xa6\xed\xa2\x18\xfc\x58\x82\xf7\x2e\x81\x0b\x99\x88\x3f\xfa\x26\x98\x8f\x19\x50\x1e\x0f\xac\xd3\xf1\x23\xef\x45\x13\xdb\xee\xa0\x0c\x0c\xd8\x26\xe2\xdc\x8e\x66\xda\x10\x8d\x34\x9b\x43\x23\x27\xb6\x1f\xb5\xed\x7e\xef\x03\x46\xe3\x5c\xda\x1d\xaf\x78\xb3\xbd\x6f\x26\xa5\x0b\x94\x75\xf0\xdd\x44\x58\x56\xce\x45\x0c\xce\xf2\x39\x47\xd5\xfe\xda\x30\xf3\x1b\x23\x0a\x3b\x1f\x37\xda\x7d\x17\x4a\x43\x6a\x89\x93\x7d\x3e\x59\x10\x2d\x17\xd6\x31\x2e\x6f\x8d\xf2\xe9\x3c\xd7\x46\xe2\xbf\xc5\xfb\x94\x12\x11\x43\xd1\xa7\x84\xab\x97\xbb\xbc\x0d\x8f\x92\x4c\x28\x86\xef\x76\x3c\x6f\x37\xcb\x5c\x73\x76\x59\x71\xd3\xfd\xf9\x4f\xbb\x6c\xdd\x04\xdb\x28\xec\x68\x65\xaf\x47\x50\x4c\xaa\x11\xfe\x6e\x7b\x7a\xca\x2b\xae\x46\x2c\x89\x04\x57\x5a\x52\xb6\x39\x87\x69\xfd\x68\xe8\x0a\x69\xee\x6f\x20\x88\x41\x27\x8d\x80\x42\x56\x63\xb0\x3c\x53\x44\xb4\xf4\xa0\xae\x02\xc6\xa6\x38\xf9\x58\x42\x43\xb8\x1a\x9a\x56\x1b\xc0\x88\xb4\x82\x93\x7d\x1a\x26\x20\x25\xc4\x67\x28\x7d\x5e\x17\xdf\x75\x31\xe5\xa2\xf8\xf9\xfc\x1e\xa2\x7c\xdb\x4c\xf0\xd5\xb1\x62\xcb\xf3\x06\x11\x17\x76\x62\x17\x61\x8e\xae\xbf\xe0\xe4\x0f\x81\x60\x77\x82\x88\xa2\x9a\xa9\x89\xcd\x17\x2b\x36\x02\x2a\x8e\xcf\x02\x85\x0b\xf7\x30\xb2\x38\x9b\xfa\xc0\x34\x92\x9b\x68\x26\x84\x32\xa7\x1c\xf7\x13\xe7\x9d\x33\x61\x7d\x7e\x98\xbc\x22\x49\x6a\x68\x8c\x4f\x62\x29\xa7\xb7\x86\xda\xf2\x31\xa6\xac\x0a\x5e\x40\xd0\x7b\xa9\xcc\x34\x68\x78\x34\x7f\x4c\x51\x6a\x52\x9a\xa8\x3c\x35\x93\xde\x01\x9b\xce\xb4\xea\x13\x36\x84\x21\x62\x0d\xd0\x68\x56\x99\x36\x05\xd0\xb5\x2e\x28\x55\x54\xab\x5a\x89\x0f\x8b\xac\x06\x97\x86\xd3\x2f\x78\xcc\xf2\x5e\xae\x05\x57\x9f\x80\x8e\x86\x47\x7d\x52\x26\x8a\x9b\x35\x8e\x17\x84\x69\x30\x34\x1b\x75\x11\x29\xf2\xa9\xfd\x12\xf0\x31\x9d\xb8\xae\x22\xe5\x03\xbd\xa8\x31\xea\x8c\x07\xf6\xe3\x0e\xcc\xbe\xe1\xca\xf3\xd4\xe8\x8b\x05\x51\x47\xb3\xba\x6f\x9c\x23\xa4\x04\x95\x09\xab\x6d\x2e\x1b\xdc\xff\xff\xc5\x43\x87\xea\xa8\x04\xe6\x8c\x4d\x67\x1e\x96\xd4\x31\x82\xfa\x1e\xec\x7e\xf6\x48\x2b\x5f\x8a\x1d\x0d\x3d\x2a\x76\xd4\x7d\xdb\x3e\x5f\xa2\xc4\xaa\xca\xfe\x6b\x90\x69\x01\x45\x44\x11\x24\x19\xce\xce\xed\x1b\xd6\x38\x1c\x23\xaf\xc8\x21\x22\x19\xd3\x3d\x85\x08\x3f\x10\xd9\xd1\x90\x9c\x10\x9e\x17\x67\xee\xa1\x17\x70\x51\xcc\xef\x26\x32\x2f\x55\xa2\x9c\xab\xe1\x17\xb7\x22\x77\x76\x34\xf3\x94\x57\xc7\xc0\x41\x00\x1e\x2f\x8b\xf8\xd0\x24\x16\xd6\x0d\x27\x68\x47\xba\xfd\x1c\xfe\x2b\x9a\xcf\xb1\x12\x60\x81\xc7\xb5\x8c\xa2\x00\x99\xf6\xab\xd2\x53\x71\x20\xeb\xa7\xd8\xc2\xa2\x29\x56\x90\x6e\x30\x83\x74\x04\x57\xd2\x2a\x42\x67\xfd\x58\x0e\x63\xf1\x59\x54\x35\x68\xd7\x88\xfc\x78\x81\x57\x77\x0c\x5e\xda\x3c\xda\x52\xba\x72\xb4\xa2\x79\xe5\x78\x10\xf1\xf6\x2f\xb0\x67\xfd\xe8\x08\x6d\xed\x68\x4f\xda\xca\xb1\x7b\x68\xd0\xa6\x79\x1a\x04\x0c\xad\x1f\x5d\x9d\x4d\x3b\x1a\x04\x17\xad\x1f\x2b\x22\xea\xc7\x89\x35\x5a\x3f\x1a\x1b\x49\xd7\x8f\xa6\x71\x49\xeb\xc7\x52\xaa\xe2\x47\x0a\x52\xea\xd7\x23\x94\xc8\xb7\xda\x9e\xe3\xb7\xad\xf8\x49\x39\x3a\x06\x71\xb3\xc8\xa6\xf5\x63\x59\x00\x7c\x26\x51\x4e\x6b\xa6\xfa\x56\x9b\x69\xde\x6e\x7c\xd8\xe6\xa8\xfb\x38\x1d\xa7\x50\xf4\x5d\xea\x8c\xb7\x33\x63\x44\x75\x26\x01\xcb\x0a\x60\xd8\x97\xb7\xc3\x7c\x9a\xc0\xaa\xf5\xa3\x3b\xc6\x69\x47\x47\xec\xd3\x8e\xce\x90\x1b\x05\x9e\x6f\xac\x5d\xf8\x09\x65\x1d\x6b\x99\x0e\xb2\x4e\x90\x75\x76\x18\x41\xd6\xd9\x76\x04\x59\x67\xd3\x08\xb2\xce\x9a\x11\x64\x9d\x20\xeb\xb4\x1a\xfb\x27\xeb\x58\x4b\x55\x67\x06\xb3\x1f\xad\xc1\x75\xd9\x42\x86\xd2\x94\x0f\xe9\xa9\x9b\xca\x0c\xef\xbf\x76\x24\xf6\x06\xcd\x6b\x2e\x52\x5d\x52\x3e\x05\xf2\x7a\xf0\xfa\xd5\x96\xe9\x80\xeb\x47\x9b\xa0\x9d\xea\xd8\x35\x75\x70\x79\x6c\xf2\x48\x7c\x34\xef\x92\x3b\xa9\x85\xc3\xa3\x26\x61\x6e\x70\x10\x15\x55\xad\x52\xd0\x84\xea\x9a\x41\x9c\xa5\x50\x38\x44\x6b\x29\xc8\x65\x4c\xaf\xe0\xce\xdf\x61\x36\x75\xd8\x6c\x05\x11\x50\x1b\xc7\x3e\x86\x62\x15\x22\x05\x9b\x60\xea\x0f\xbd\x59\x02\x78\x58\x91\x43\x18\x4e\x87\x24\xb6\xc9\xda\x94\xbb\x98\xb1\xa3\x7e\xd5\x3d\x9e\x1a\xe2\x2a\xf1\x3f\x66\xd9\xce\x3f\x0e\x73\xe0\x3a\xa7\x49\xb2\x20\x30\x67\x91\x2e\xbe\x0f\x03\x02\x99\xb6\xce\xce\x36\xae\x94\x16\xe2\x61\x5b\x91\x70\xb0\x72\xb6\x76\xf3\x57\xfb\xd1\x5e\x76\x5b\x59\x47\x73\x7a\xb3\x24\x97\x58\x08\x0d\x37\xaa\x55\xda\xbc\xcd\xfa\x2b\xf1\x9f\x88\xe0\xef\xaf\x9a\xba\xc7\x48\x47\x3c\xa1\x35\x1f\x58\x56\xa0\xf2\x24\x31\xe8\x6d\x3d\x66\xab\x20\x58\xe3\xc9\x5a\x93\x6d\x63\xdd\xac\x69\x25\xeb\x06\xef\xb9\x11\x99\x48\xc4\x74\x51\xdd\x41\xdb\x91\xa5\x52\xde\x86\x12\x95\x8f\x9d\x08\x68\x0e\xd1\xe5\xd2\x96\x07\x5f\xc8\xc6\x11\x7c\x21\x2b\x23\xd8\x07\x96\x47\xb0\x0f\xec\x30\x82\x7d\x60\xcd\x08\xf6\x81\xd5\x11\xec\x03\xc1\x3e\xd0\x66\xbc\x7c\xfb\x00\x09\xbe\x90\x4d\x23\xc8\x3a\xe5\x08\xb2\xce\xf6\x23\xc8\x3a\xab\x23\xc8\x3a\x41\xd6\x09\xb2\x4e\x90\x75\x9a\x8e\x16\xc8\x9d\x89\xb8\xf3\x14\x99\x4c\xc4\x0f\x64\xc8\x58\x7b\x75\x24\x06\x89\x88\x8a\xca\x22\xe6\x11\xe7\xf9\x50\x34\xb5\x26\xf4\x3e\xf9\xb7\xe0\x60\xd3\x13\x6c\xc9\xda\x14\x88\xc0\x26\x10\x99\x88\x0f\xd5\x51\x83\xc0\xf3\x90\x61\x13\x32\x6c\x3e\x83\x0c\x9b\x19\x55\xae\xf0\x11\x92\xd6\xcd\x09\x37\x95\xe3\x7f\x03\x32\xfd\x6c\xf3\x6d\x0c\xc2\x39\x84\xc1\x1e\x71\x25\x52\x58\xd8\xc5\xce\xb7\x0b\xf1\xa8\x0e\x31\xa7\x97\xd9\x16\x3b\x71\x0c\x31\xc9\x40\x0e\x2c\x92\x09\x32\x61\xae\xfe\xd7\x12\xfe\x3a\x08\x3f\xf3\xbc\x99\x3a\x24\x9e\x75\xf2\x4c\xfd\x53\x3a\xf3\x4d\x55\x5d\x74\x35\xae\xf8\xec\x52\x69\xba\xd1\x4a\x07\x44\x3b\x77\xda\xf7\xad\xf4\xd2\xae\x94\x48\x54\xf2\xae\x77\x2a\x73\xbc\x79\xac\x2d\x4e\xfb\xaf\x1c\xe4\x82\x88\x39\xc8\x52\x31\x2a\xba\xf3\xf4\x8b\x26\x33\x11\x75\x05\x90\xbb\x31\xf0\x74\x62\x8a\xe8\x52\x53\xef\xda\x6b\x48\xf6\xac\xfa\xf1\xe6\xd1\xad\xe2\xd0\xa1\xda\xf0\xdc\x6a\x29\x6f\x1e\x9d\x9a\xdf\x48\xc7\x26\x38\xd2\xa1\x19\x8e\x74\x6b\x8a\x23\x9d\x9b\xe3\x48\x97\x26\x39\xf2\xc9\x2b\x40\x6f\x1e\x1d\x9b\x8f\x48\xe7\x56\x3a\xf2\x0c\xeb\x49\x6f\x1e\x1f\x01\xdc\x5d\x5a\xec\x48\xa8\x4e\xdd\x7a\x74\x6d\x50\x23\x5d\x1b\xd5\x48\xd7\x78\xd8\xa8\x0a\xf6\xe6\x11\xea\x63\x7f\x04\x39\xad\x33\x21\xa2\x6d\x4d\xed\xc7\x16\xda\x01\x4e\x16\xbd\x7b\x3f\x95\x02\x64\xb9\x74\xd9\x30\xd6\xbc\xbb\xd2\xab\x0b\x43\x35\xab\x8d\x4d\x7d\xdc\x2a\x62\x34\xfe\x1e\x7b\x83\x57\xce\x2b\xc5\xe3\x2a\x93\xad\xb4\x8e\x29\x4d\x67\x45\xf3\x18\xa3\x14\x94\x4d\xa7\x2a\x0f\xe3\xbd\x43\x1b\x4e\x5a\x4a\x13\x3c\x5e\x0e\x30\x2d\x9f\x40\xfd\xc2\xb6\xb3\x3d\xf0\x76\xec\x9e\x2a\xef\x38\x18\x56\x3b\xdf\xba\x19\x0f\xff\xcf\xff\x3d\xaa\x55\x6f\x29\x27\x0c\xda\xdf\xd6\x23\x68\x7f\xad\x46\xd0\xfe\x36\x8e\xa0\xfd\xb5\x18\x41\xfb\xdb\x6e\x04\xed\x6f\xf3\x08\xda\x5f\xd0\xfe\x1a\x8c\xa0\xfd\x05\xed\xaf\xe9\xf8\x8c\xb5\xbf\x6e\xa3\x9a\xab\xba\x98\x0b\x12\x41\xf9\x51\x53\xcd\xa2\x32\xe2\xd9\xdf\x65\xff\xd5\xad\x0e\x58\xd5\xef\xd6\x6b\x80\x55\x2d\x71\x45\x0b\x1e\x3e\xa2\xee\x15\x0a\xe1\xca\x93\x0f\x6b\x82\x2f\x2d\x72\xbb\x33\x4c\xac\xb8\x84\x3b\x45\xc5\x1b\x1f\x58\x56\x36\x5e\x2f\xa2\xce\x62\x72\xe8\x7d\xf1\xd8\x48\x85\x0b\x5d\xbf\xc8\x35\x1b\x94\x77\x14\xde\x79\x0c\xaa\xa9\xe5\xf3\xd7\x5c\xc8\x45\x0c\x5b\x11\x1f\x55\x62\x8f\x21\x8f\x20\x6b\x6b\xc0\xc6\xb5\x13\xc6\x6d\xa4\xa3\x6f\xfa\x23\xb8\x0f\x9a\xb2\xf4\x14\x29\xa0\xc7\x73\x2b\xfa\xe2\x7a\x50\xfe\x2d\x61\x57\x89\xf2\xa1\x78\xc8\x28\x77\xc9\xb0\x82\xfb\xae\xf4\xb6\xd3\x7c\x29\x2f\x17\xbd\x54\x8a\xb7\x0f\xc9\x39\x62\x7d\x75\x62\xa6\x10\x3e\xd4\xf6\x3f\xe9\x06\x91\xf7\xab\x70\xc3\xdd\xce\x85\x1b\x96\x22\x46\x42\xdd\x86\x50\xb7\xa1\x55\xdd\x06\xbc\x68\x0f\x77\xe7\x05\x1c\xc8\x8f\xae\x3d\x92\x04\x04\x55\x9a\x27\x9a\x65\x65\x04\xb6\xb2\xaf\x4a\xac\x26\x31\x71\x91\xa0\x75\x7c\x37\x6f\xa3\xd1\x6c\x19\xef\x71\x3e\x8c\xd8\x56\x48\x4e\x5c\xb4\x25\x36\x33\xc2\x8a\x03\x5e\xed\xb0\x21\xa5\xec\xf9\x47\x0a\x9e\x21\xc1\x56\xa5\xd6\x6c\x7b\x6d\x19\x3a\x9f\x18\x94\x30\x14\xfb\x01\x06\x51\x6d\x68\x81\x51\xab\x6c\x0e\xbc\xe4\x12\x87\xea\xe8\xc8\x4b\x43\x9d\x72\xaf\x8f\xc2\x7d\xfe\x56\xe1\x12\xff\xb5\x0d\xff\xc1\x0f\x2a\x38\x50\x09\xbe\x92\xff\x3c\xef\x90\xc8\xf6\xd1\x6d\x5d\x58\xe4\x3a\x8b\x6a\x7b\xf2\x88\xb6\xcf\xa9\xf6\xc5\x5e\xfa\x30\xf6\x4e\xeb\x78\x19\x7e\x8b\x90\x30\xba\xfd\x78\x0e\x09\xa3\x4f\xe4\x9b\x78\x3e\x79\xa3\xcf\xd6\x1f\xf1\x5c\xf2\x46\x83\x0f\x62\xa7\xf1\x52\xd3\x39\xeb\xa3\x43\x9f\x43\xf0\x37\x74\x2c\x53\x75\xc2\xfc\x3f\x8e\x9f\xa1\x13\xfc\xeb\x34\xba\x2c\x44\x96\x3d\x65\x64\x59\xd0\xc2\x82\x16\x56\x1f\x41\x0b\x5b\x19\x41\x0b\xdb\x61\x04\x2d\x6c\xf3\x08\x5a\xd8\xea\x08\x5a\x58\xd0\xc2\xb6\x18\x41\x0b\x0b\x5a\xd8\xb6\xe3\x33\xd3\xc2\xba\xab\xb7\x1e\x22\xbc\x3e\x42\x84\x57\x37\x94\xb0\x03\xfa\xd7\x09\xd6\x75\x14\xd1\x15\xa2\xb9\xf6\x3b\x9a\xab\x65\xd9\x39\xae\xd9\xc7\x29\x3d\x57\xdd\xed\x4d\xf5\xe7\xe8\x5c\xb0\x98\x64\xb9\x76\xd5\xb7\x42\x0d\xba\x7d\xae\x41\x57\xdb\xd1\x50\x88\x6e\xab\x42\x74\x9b\x60\x16\xaa\xd1\x6d\x18\xfb\x13\x63\x16\xaa\xd1\xed\x3a\x42\x35\xba\xf5\x23\x54\xa3\x7b\x60\x84\x6a\x74\xa1\x1a\x5d\xa8\x47\xd0\x62\x84\x7a\x04\x6b\x46\xa8\x47\xd0\x7c\x84\x7a\x04\x5b\x8d\x50\x8f\x20\xd4\x23\xa8\x8f\xe0\x85\x6a\x37\x42\x3d\x82\x96\x23\x78\xa6\x42\x3d\x82\x56\x13\x86\x6a\x74\x2f\x2a\x66\x90\x04\xed\x2f\x68\x7f\x5b\x8f\xa0\xfd\x6d\x1c\x41\xfb\x6b\x31\x82\xf6\xb7\xdd\x08\xda\xdf\xe6\x11\xb4\xbf\xa0\xfd\x35\x18\x41\xfb\x0b\xda\x5f\xd3\xf1\x19\x6b\x7f\xa1\x1a\xdd\xde\xc7\x2a\x92\x7d\xcc\x48\x0a\xd5\xe8\x42\xfc\x62\xa3\xed\x0e\xd5\xe8\x1e\x1f\x9f\x7d\x35\xba\x5a\x2c\xdd\xd3\x95\xa4\xdb\x7d\x19\xa1\x2e\x5d\xa8\x4b\x17\xea\xd2\x85\xba\x74\xa1\x2e\x5d\xa8\x4b\xb7\xfd\xd8\x7f\x6f\xc6\xde\xe9\x1f\x2f\xc3\x83\x11\x2a\x22\x6c\x3f\x42\x45\x84\x8d\x23\x54\x44\x08\x15\x11\x82\x37\xa2\xc9\x08\x15\x11\x76\x1c\xc1\xf3\x10\x2a\x22\xec\x34\x42\x5d\xba\x17\x13\x63\x16\xb4\xb0\xa0\x85\xd5\x47\xd0\xc2\x56\x46\xd0\xc2\x76\x18\x41\x0b\xdb\x3c\x82\x16\xb6\x3a\x82\x16\x16\xb4\xb0\x2d\x46\xd0\xc2\x82\x16\xb6\xed\xf8\xcc\xb4\xb0\x50\x97\x6e\xaf\x63\xbd\x42\x5d\xba\x35\x23\xc4\x75\xed\x77\x5c\x57\x43\x5c\xa1\xb9\x16\xa9\xc8\xb9\xbe\x06\x39\x67\x11\x9c\x44\x91\xf9\xeb\x46\xdc\xc2\x8e\xb1\x44\x75\x35\xf4\x81\x69\x09\xe3\x31\x8b\x50\x91\xbc\x9b\x01\x96\x95\x33\xf2\x2d\xde\x47\xa8\xbd\x91\x68\xbc\xb3\x44\x2f\x5c\xa7\x21\x6a\x18\x60\x83\x53\xef\x0a\x2f\x0b\xa1\xb1\x10\x09\x50\xbe\xc3\x93\x8e\x1b\x82\xdc\xf1\x34\xd7\x00\xf2\xd6\x91\xe2\x72\x32\x32\x86\x44\xf0\xa9\x8b\xe7\x71\x27\x60\x48\x4e\xcb\x1b\x22\xca\xf1\xf0\xe4\x52\x02\xd7\xc9\x02\xe1\x80\x05\xae\x50\x6b\x48\xc5\x1c\x62\x24\xd9\x18\x46\x64\xe5\x48\xaa\x49\x02\xd4\xbc\x8b\x43\xf9\x32\x73\x78\x28\x19\xe1\xfc\x76\xd2\x31\xb8\xd0\xa6\x46\x40\xdc\x9d\x36\x36\xa2\x86\x4b\x96\x0d\x27\x36\x21\x5f\x8a\x50\x3f\xaa\x7c\x21\x1e\xcd\x85\xc8\xc9\x1d\xb5\x92\x92\xcc\x39\x1e\x66\xfc\x74\x03\xda\x1d\x5f\xde\x42\x26\x69\x6e\x7e\x18\x20\x55\xdb\xf1\xb1\x36\xe6\x00\x2a\xa7\x8d\x98\x54\x6d\x6b\x7a\x27\x72\x9a\x5b\x91\xd0\xa1\x32\x70\x2d\x17\x18\x6f\x67\x65\x8a\x0a\x26\xa6\x74\x0a\xbd\x9e\x22\xa7\xef\xce\x0c\xf9\xcb\x95\xa1\xd6\xae\xca\x9e\x23\x87\x99\x14\x73\x16\x1b\xe4\xfe\x40\x25\xa3\xe3\xc4\xc8\x9d\x13\x90\xc0\x8d\x58\xf0\xe5\xe1\x87\x93\xab\x5f\x2f\x4f\xde\x9d\x1f\xa1\x04\x0a\xf7\x19\xe5\xe6\x54\xe4\xaa\x0c\x14\x75\xaf\x33\x2f\x02\x3e\x67\x52\x70\xb3\x3e\xd4\xd5\x28\x99\xfb\x59\xa3\xe2\x30\x48\x50\x22\x99\x43\x6c\xe5\xe4\xe2\x6d\x9e\xeb\x30\x9e\xe5\xda\xeb\x8e\x18\xbe\x68\x0e\x10\x8f\x66\x94\x4f\xcd\x3a\xcf\x44\x6e\xe6\xfb\xf2\x4b\x5c\x91\x84\x38\x8f\xac\xe4\x44\x3d\xd6\x7e\xd9\xf7\x9c\xc2\xd0\x7a\x65\x4b\x22\xaa\x88\x66\x7e\xcd\xd5\xcf\x52\x0b\xae\xe9\xfd\x1b\x1b\xbf\x77\xf0\x65\xe5\xd2\x81\x2f\x27\x29\xcc\x2b\x2c\xbf\xb1\xab\x4a\xb0\x92\x61\x42\x0e\xaa\x77\x0f\xc9\xb9\x79\x07\xc4\x55\x00\xda\xf0\x4b\x98\x83\x44\xcd\xd3\x81\xaf\x4f\x24\x4c\xa9\x8c\x13\x50\x18\x78\xe8\x69\xb3\xd5\x0e\x1c\xc0\xa0\xd0\x6b\xb9\xd0\xeb\x88\x09\x79\x27\x30\x08\x71\x22\xde\x90\x99\xd6\x99\x7a\x73\x7c\x7c\x9b\x8f\x41\x72\xd0\xa0\x86\x4c\x1c\xc7\x22\x52\xc7\x9a\xaa\x5b\x75\xcc\xb8\x39\x5c\x83\x98\x6a\x3a\xa8\x9c\xea\x63\xcb\xb9\x07\x91\x48\x53\xca\xe3\x01\x75\xd8\x35\x28\xb6\xf5\xf8\x0b\xc7\x53\x07\xb4\xb8\x8b\xf1\x01\x1d\xa8\x19\x24\x49\xaf\x01\x3e\xb7\x93\xf9\x5a\xc8\x7a\xad\x64\x3c\xf7\xed\xed\x0f\xf0\x79\x71\x5e\x2d\x0c\x86\xe4\x52\x68\x17\x1f\xeb\x42\xb1\x91\x8e\x22\x7c\x37\x1e\xe9\xf3\xcb\x9b\xab\xbf\x8f\xde\x5f\x5c\xde\x84\x93\x1d\x4e\x76\x38\xd9\x2d\x4e\x36\xf0\x79\xeb\x53\xed\x65\xce\xca\x31\x29\xf6\x1b\x39\xb5\x02\xed\x8f\x41\xb1\x01\xad\x25\x44\x3b\x9e\x0c\xea\x35\x08\x9c\xf3\xf9\x07\x5a\xb7\xb0\xf3\xb5\xe0\x20\xee\x06\x2b\x28\x17\x32\x78\x9b\xf8\xf8\x16\xd6\xac\xb6\xee\xab\x46\x52\xa4\x1d\xed\x5d\x4b\xe6\xd5\xcd\x0d\x0d\xb5\xed\xbb\xa4\x69\x59\xa1\x7a\xcd\xae\x0d\xc9\x3b\xaf\xf6\x90\xd3\x5f\x2f\xce\xce\x2f\x6f\x2e\xbe\xb9\x38\xbf\x6a\xae\x47\x77\x60\x71\x41\x9b\x42\x47\x00\xe8\x35\xe4\x92\x99\x84\x39\x13\xb9\x4a\x16\x85\x15\x64\x3d\x11\x58\x3e\xfd\xce\xef\xbb\x28\xf4\xf1\xb5\x8f\x05\x66\xdb\x2d\xb3\x3d\x83\x09\xcd\x13\xab\x3d\x1d\x1c\x0c\x9b\x70\x39\x3b\xba\x42\xdf\x6f\xa4\x68\x51\x81\xb9\x86\xc2\xd7\xb6\x76\xfb\x44\xc8\x8d\xc7\xb8\xe7\xa2\x0f\x6a\xac\xc7\x09\x8f\xd6\x42\xe7\xa4\x47\xeb\x24\x6b\x09\x9d\x96\x5e\x86\x6e\x7c\xef\x91\xe0\x13\x36\x7d\x47\xb3\xef\x61\x71\x05\x93\x76\x66\xe2\x3a\xbc\xd1\xfa\xe8\x5c\xc9\x68\xab\x34\xec\xcc\xbe\xac\x9d\x9b\xa6\x33\x27\x4d\x57\xd1\x19\xed\x23\x33\xba\x0b\xa4\xe8\x24\x88\x62\xa5\x1e\xbe\xb5\x43\x3b\x8b\x72\x57\x31\x36\x9d\x78\xee\xdb\x71\x79\x3f\xea\xcc\xae\xca\xee\x1d\x9d\xd5\xdb\xaa\x1d\x91\xe0\x11\x64\x5a\x1d\x8b\xb9\xe1\x5c\x70\x77\x7c\x27\xe4\xad\xd1\x23\x8c\xee\x3a\xb0\x58\xab\x8e\xd1\x67\x70\xfc\x85\x75\x83\xdd\xbc\x3f\x7b\xff\x86\x9c\xc4\xb1\x6b\x6e\x92\x2b\x98\xe4\x89\x6b\x27\x30\x24\x34\x63\x1f\x40\x2a\x26\x78\x9f\xdc\x32\x1e\xf7\x49\xce\xe2\xaf\x9b\x13\x67\x3f\x3a\xdc\x05\x91\x59\x57\x67\xc7\x3b\x71\x8d\x3e\x96\x45\x8d\x77\x15\x44\xc4\x70\x2d\xa6\x15\xe2\xa6\xb7\x3a\x3b\x21\xa3\x23\xd0\xec\x6e\xa2\x5f\x1e\xb8\x85\xdd\xd2\xd5\x5e\x49\x58\xad\x8b\xd3\x21\x6a\x26\xe2\x37\x44\xe5\x59\x26\xa4\x56\x24\x05\x4d\x8d\xd2\x3b\x34\x18\xd6\xaf\xff\x89\xbe\xaa\x3e\xf9\x47\xf1\x23\x3a\x9c\xd4\x4f\xbd\xde\xdf\xbe\x3f\xff\xfb\x7f\xf5\x7a\xbf\xfc\xa3\x7a\x15\x59\xa1\x8d\x02\xaa\xdf\xa2\x32\x88\x86\x5c\xc4\x70\x89\xef\xc0\x3f\x55\xcd\xcd\xe2\x2e\x68\xaa\x73\x35\x9c\x09\xa5\x2f\x46\xc5\x9f\x99\x88\x97\xff\x52\x2d\x24\x0e\xb2\x9f\x8c\x01\xb7\x68\x44\xf5\x6c\x4f\xd8\x43\x49\x4b\x3a\x3e\xaa\x6e\xd6\x6a\x13\x9d\x94\xe2\x3f\xbf\xf1\x20\x30\xd2\xd3\x9d\x64\x5a\xa3\xeb\xcd\xa5\x82\x8b\x49\xdf\x9c\xda\x52\xec\x9c\xbf\x6e\x5d\x1f\xa5\x53\xd2\x56\xec\x60\xc7\x00\x43\x88\x38\x68\xd9\x83\x5c\x30\xd8\x55\x17\xf3\xc9\xe8\x82\xcc\x2d\x84\xf7\x06\x38\x3e\xbd\xf7\x9b\x8f\x4a\xe3\x8a\xa6\x4b\x0e\x54\x85\x86\xf8\xc6\x06\x05\x15\x49\xc6\x24\x61\x29\x73\xb1\x86\xae\x41\x93\x22\x87\xf6\xc7\x61\x94\xe5\x7d\x77\xc3\x30\x85\x54\xc8\x45\xf1\x27\x64\x33\x48\x8d\xa6\x35\x50\x5a\x48\x3a\x85\x7e\xf1\xb8\x7d\xac\xf8\xcb\x3e\x58\x7b\xc1\xea\xd3\x56\x15\x2e\x5d\xa5\x8e\x22\x43\xfc\xf2\x68\x9b\x07\xfd\x9e\x90\xb6\x02\x33\x2e\x3f\x82\x48\x58\x58\xe2\xac\xc0\x59\x40\x11\xf5\xc9\xb9\x48\xf2\x14\x54\xbf\x10\x83\xac\x35\x80\xcf\x8d\x66\xa9\xf6\x4a\x50\x8b\xd9\x9c\xa9\x2e\xc2\x88\xd7\xc8\x69\xcc\x45\xe4\x8b\x5c\x67\xb9\x76\xf5\x66\x2a\x8d\xdd\x84\x42\xbb\x45\x51\x14\xa0\x46\xf6\x5f\x1f\xb4\x8f\x46\xa7\x5a\x83\xe4\x6f\xc8\xff\x1c\xfe\xfc\xd5\x6f\x83\xa3\xaf\x0f\x0f\x7f\x7a\x35\xf8\xeb\x2f\x5f\x1d\xfe\x3c\xc4\x7f\xfc\xfe\xe8\xeb\xa3\xdf\xfc\x1f\x5f\x1d\x1d\x1d\x1e\xfe\xf4\xfd\xbb\x6f\x6f\x46\xe7\xbf\xb0\xa3\xdf\x7e\xe2\x79\x7a\x6b\xff\xfa\xed\xf0\x27\x38\xff\x65\xcb\x49\x8e\x8e\xbe\xfe\xb2\xf5\xd2\x29\x5f\xbc\x6f\x49\x40\xed\x18\x74\x56\x2e\x68\x79\xc6\x8e\xe2\xac\xef\x07\xa5\xd2\x34\x60\x5c\x0f\x84\x1c\xd8\xa9\xdf\x10\x2d\xf3\x76\xc4\xa4\x64\x4a\x5d\x9f\x7f\xdf\xbd\xeb\x4d\xc9\x90\x0a\x76\xbd\x37\x07\x5c\x41\x24\x41\x7f\x0a\x4b\x8e\x7d\x93\x97\x53\x96\x62\x1e\x5f\x1a\x9f\xfb\x1c\x8c\x3b\x45\xc8\x20\xee\x6b\x29\x89\x4e\xa4\x48\x87\xa4\xe2\xde\x98\x63\xc2\x87\xbb\xef\x16\x5a\x58\x41\xfd\x08\xc6\xa0\x60\x0c\xda\x30\x1e\x35\x06\x5d\x5b\x3c\xdc\x5b\x4b\x10\xf0\x79\x53\x17\xc6\x5a\x0f\xba\xd7\x75\xb4\x20\x99\xc8\xf2\x84\xea\x0d\x9e\xb1\x35\xee\x74\x77\xd4\xcb\x78\xe4\x32\x98\xc6\x32\xb4\x74\xbd\x0f\x93\x9c\x24\x09\x61\xdc\x1e\x7c\x9c\xc0\x3b\xcc\x24\x58\xd5\x86\x50\xeb\xcf\x9e\x9b\x25\xdc\xb9\xb2\x72\xd5\xb8\x1c\x45\x94\xa6\x52\x63\xec\x31\x96\x9d\xb3\xac\xc4\x79\x9f\x18\x2f\x8b\xcf\x15\xc2\x61\x91\x0b\xb2\xb6\x33\x66\x42\x95\xf6\xcb\xc6\xd5\x68\x7a\x8b\xde\xc6\x08\x62\xe0\x11\x60\x62\x5a\x0e\xe5\xb7\x8e\x8d\xde\x46\xce\xf9\xdc\xce\x41\x49\x9c\xdb\x60\x10\x4b\xfe\xd6\xcf\xf1\xb2\x02\x10\x0c\x22\x5e\xfb\x06\xc6\x45\x1c\x02\x52\xfd\x42\xc3\x2e\xf2\xfb\x0a\x2b\xab\x7a\x9a\xc8\x83\xf6\x3c\xb3\xf0\x6c\xb5\x12\x86\x56\x98\x65\x69\x7e\xae\x33\xc9\x97\xe0\x0c\x6c\xcf\x3e\x3f\x3b\xd6\xd9\x11\xdb\xec\x86\x65\xee\xe0\x3b\xe9\x92\x4d\x76\xe1\x2c\xc9\x24\x4c\xd8\x7d\x47\xe7\xf4\x84\x97\x96\x18\x16\x03\xd7\x6c\xc2\x6c\xcf\xfb\x4c\x42\x06\x3c\x2e\x0a\x97\x62\x72\x38\xaf\xc3\x66\x2f\x83\x79\xac\xc0\xdd\x2d\x29\xbb\x5e\x27\xec\x07\x3a\x46\x02\x1d\x6b\x3c\x3e\x11\x1d\x73\x98\xbb\x3f\x44\x0c\x23\xcf\xdb\x47\xbf\x9f\xd6\x43\xd9\x11\x91\x77\x46\xb4\x32\xb3\xeb\x18\x67\x51\x36\x4b\xb2\x48\xc3\x2e\x48\xa3\x16\x36\x78\x8d\xcc\xd8\xd4\x40\x36\x81\x39\x24\x4e\x6e\x22\x29\xe5\x74\x6a\xf3\xbb\xb5\xf0\xa6\x5a\xa3\x68\x19\x3c\x96\x2c\x5e\x89\xbb\x47\x39\xde\xe0\x76\x22\x68\x8c\x17\xa5\x48\x12\x90\x8a\x24\xec\x16\xc8\x19\x64\x89\x58\xb8\x74\x6d\x1e\x93\x6b\x4d\xb5\xc1\xea\x6b\xd0\xcd\xdc\xbe\xad\x30\x16\x57\x3c\xca\x93\x64\x24\x12\x16\x35\x32\xaa\xd4\x77\xee\x02\xf7\x2b\xcb\x93\x84\x64\x38\xe5\x90\xbc\xe7\x48\x34\x4e\x92\x3b\xba\x50\x7d\x72\x09\x73\x90\x7d\x72\x31\xb9\x14\x7a\x64\xa5\xef\x7a\xc0\x9d\xbd\x91\xb0\x09\x79\x83\xd5\x6d\x34\xd1\x74\x8a\xba\x93\x77\x03\xf6\x0d\xfc\xab\x13\x58\xfa\x70\xc7\xd4\x5a\x65\xa5\x35\xe2\x7c\x81\x33\x19\x5a\x65\xff\xfe\xe4\xdb\x94\xb0\x09\x44\x8b\x28\x69\x7f\xb4\x4e\x22\x0c\x60\x28\x33\xce\x2b\xf8\xed\xaa\xa9\xbb\x1c\x4f\xd4\x02\x19\x27\xb6\xcc\xb9\xad\xdf\x5e\xa2\x7a\xb1\x22\xab\xed\xaa\x4e\x95\xc4\xc6\xcc\xb3\x2d\xdb\xcc\x84\xd2\xd7\x46\x43\xef\xa4\x18\x7a\x6f\xe4\xa7\x23\x58\xf2\x39\x49\x20\x26\x2c\x4d\x21\x36\x5a\x7c\xb2\x20\x74\xa2\x31\xd7\xb6\x66\x21\x88\x24\x58\xac\x75\x55\x4c\x66\x94\xc7\x09\x48\x32\xa1\x2c\x71\xf6\x80\xda\xfd\x1a\x64\xca\x38\x9a\x05\xac\x47\x16\x4d\x0c\xe6\xaf\x28\x12\xd2\x97\xa7\x67\x5a\xf9\x4b\xe5\xc1\x44\x3e\x52\x41\x80\x65\xd7\x32\x19\x27\x22\xba\x55\x24\xe7\x9a\x25\x76\x31\x42\xdc\x92\x48\xa4\x59\x82\x47\xa7\xc5\xc9\x2a\xfe\x39\x28\x50\x69\x60\x66\x57\xc7\x5f\x94\x97\xf0\x87\xa6\x0c\xbd\x03\x41\xac\x0b\x31\x0c\xee\x21\xea\x2c\xcf\xff\xfc\x1e\xa2\x4a\x61\x09\xec\xc7\x80\x27\x1a\xf3\x3c\xe9\x2d\xbc\xa0\x4a\x76\x2d\x72\xe9\xaa\xa3\x06\xbf\x53\x3b\xa7\x2f\x84\xe5\x5e\x41\x12\xc6\x91\xbe\xb9\xfc\x3a\xc2\xb8\x32\x9c\xbd\x76\x18\xec\xd1\x73\x42\x2b\x89\x99\xc4\x2a\x08\x8b\x22\x90\xda\xcf\x85\x05\x06\x84\xd0\xe4\xb0\x77\xdc\x3b\x5a\xb1\x3f\xf6\x8c\x04\x92\x80\xa5\xb5\x3e\x71\xaf\x58\x94\x62\x69\x96\x2c\x70\x1d\xbd\xb8\x4f\x98\xf6\x91\xd6\x32\xe7\x7e\x55\x2e\xe9\xaf\x4f\x94\x20\x5a\x52\x5f\x5d\xc5\xfe\x6a\x6e\xd2\x32\x77\x54\xfe\xb0\xf7\x5b\xaf\x4f\x40\x47\x47\xe4\x4e\xf0\x9e\xc6\xe5\x0f\xc9\x8d\x30\xa2\x74\x39\xd1\x42\xe4\x84\x83\x0d\xec\x87\xfb\x2c\x61\x11\xd3\xc9\x02\x29\x16\x11\xb9\xb6\x39\xc4\x54\xfb\x64\xc3\xf3\x7b\xa6\x5d\xbc\x9a\x21\x19\xaf\x10\x9a\x96\x6a\x11\x6a\xc4\x9c\x39\x1c\xcf\x80\x26\x7a\x66\x83\x44\xb8\xe0\x83\x7f\x83\x14\x98\x83\xc8\xdd\x95\x17\x57\xf5\xaf\x13\xcd\xc1\x10\xd1\x6f\xa1\xbb\x26\x3e\xdf\xdd\xdc\x8c\xbe\x05\xbd\x44\x32\xcc\x5b\x7c\xe8\x0e\x5a\x03\x40\x4e\x84\x4c\xf7\x80\x76\x74\xe3\xac\x1c\x90\x4c\xc8\x7d\x20\x61\x33\xa1\x5a\xed\x25\x59\xd9\x4f\xa1\x34\x6a\x43\x4e\x1a\xe3\x10\x99\x1d\xac\xc7\x90\xf8\x3e\x37\x17\xa3\x21\xf9\xbb\xc8\xcd\xd7\x8c\xe9\x38\x59\x14\x95\x18\x14\x68\x72\x60\xa6\x3a\x30\xe4\xc9\x60\xc3\x77\x40\x63\xa3\xa2\x18\xea\x01\x74\x3f\xfa\x59\x11\x77\x1e\xdc\xda\xba\xe5\x03\xb9\xd2\x22\x25\x33\xf7\xd9\xf5\xd4\x4b\x77\x32\x86\x78\x7a\x7c\x5e\x93\x84\xcc\x52\x38\xf7\xcc\x8b\xa3\x5f\x2b\x74\xc3\xc2\xdd\xfd\x3e\xc6\x32\x56\x51\x15\x6c\xae\xa1\x93\x4d\x0c\xe2\x16\x58\x06\xd5\xa0\x99\xab\xa4\x3a\xf6\xb8\xf6\x68\xe3\x44\xce\xe5\x89\xd0\xa9\xd7\x3e\xd6\xab\xd3\xca\xa3\xdd\xc4\x0d\x90\x75\x46\x56\x87\x33\xd6\xfa\xd2\x11\x10\x3f\x4e\xe9\xcb\x4f\x01\x80\x6e\x36\x9f\x74\x09\x81\xac\x83\xd0\xee\xd5\xc0\x6e\x2d\x8c\x1e\x8a\xa9\x97\x96\xb8\x22\x99\x50\x20\xe7\x4d\x93\xb9\xcb\xd1\xdd\xa7\x8b\xe6\x1a\xbf\x1f\x6b\xf2\xa4\x25\xe1\x79\x3a\x06\x59\x66\xa6\x48\xbd\x0a\x90\x4a\x64\xc2\xa5\xbd\xdd\x9b\x73\xeb\xed\x13\xcd\x93\x7f\xfe\xcf\xff\xfc\xe3\x7f\x0e\xed\xf4\x45\x94\x02\x27\x17\x27\x97\x27\xbf\x5e\x7f\x38\xc5\xe4\xd8\xb6\x50\xed\x28\x04\xb3\xeb\x00\xcc\x4e\xc3\x2f\x3f\x6a\xf0\x25\xa6\x7c\xb4\xa6\x22\x75\xdb\x3f\x4e\x69\x30\xc0\xe8\x6d\x46\xe3\x74\xb2\x5f\xa5\x58\x99\x91\x35\xeb\x86\x54\x73\xd4\xf6\xe2\x8c\xe9\x28\xbb\x16\xd1\x6d\x87\x7a\xcd\x19\x64\x12\x22\x6b\x27\xbb\x39\x1d\xd9\xd9\x8d\x7e\x79\xf9\xfe\xa6\x4c\x35\xc0\x78\x1c\xf2\xd6\xdb\x97\xbe\x73\x96\x34\xa3\x93\xde\x42\xa6\x0b\xd5\x7d\x4c\xa3\xdb\x3b\x2a\x63\xb4\x6c\x51\xcd\xc6\x2c\x61\xb6\xf8\xaf\x6f\x0a\xc9\x85\x0d\xf8\xb3\x45\xce\xc4\x64\xb9\xb4\x66\x69\x0e\x45\x93\x95\x8d\xa3\x99\x50\x96\xa0\x05\x35\xe7\x9a\xa5\xe0\x22\x82\xa2\xac\x30\xe9\x55\x6d\xda\x41\xf9\xf2\x63\x6f\x95\xaf\xde\x7b\xef\xd5\xdb\x59\x0f\x6b\x1b\x97\xb8\xc7\xac\xce\xb1\x38\x9b\x10\x12\x58\xdd\x67\xc1\xea\x32\x09\xd7\x5a\x64\x1d\x79\x49\xec\x64\x1b\x7c\x24\x63\x98\x08\x43\x84\x37\x3a\x3d\x7c\x8f\x60\x8e\xc9\x81\xde\xaa\x25\x6a\x8e\x0d\x1b\x91\xa9\xf2\x68\xe6\x0d\x94\x1c\x94\x3a\x46\x77\x48\x9e\x59\xad\x15\xc9\x75\x2e\xa1\x6f\xbe\x0e\x52\x5c\x5d\xbf\xcc\x72\x30\xaf\x07\x6e\x7f\x04\x1d\x59\xcb\x6d\x85\x90\x63\x61\x50\xb7\xfc\x65\x37\x4a\x24\xa9\x9a\x01\x96\x17\x81\x7b\xe6\xbb\xa1\x8c\x44\xdc\xeb\x95\x9f\x62\x18\xcb\x54\xd2\x08\x48\x06\x92\x09\xc3\x8c\x72\xae\x63\x71\xc7\xc9\x18\xa6\x8c\x2b\x0f\x0a\x33\xb7\x87\x19\xfa\x63\x98\x2a\x0a\xc3\x0d\xc9\x55\xad\xd8\x89\x4b\x43\x8a\x44\x79\x34\xdd\x9a\x97\x3d\x49\xc8\xb1\x2a\x2d\x93\x0b\x08\xfb\xf0\x58\xbd\xc5\x92\x0f\x73\x8e\x6f\x8e\x21\xa1\x0b\x1b\x6d\x3a\x61\x9c\x26\xec\xdf\x20\xd5\x51\x07\x1e\x27\x03\xc2\xf2\xda\xc6\x75\x60\xa9\x7e\x1a\xcd\xda\x39\x7f\x83\x8b\x6a\xcb\x11\x5c\x54\x6d\x26\x09\x2e\xaa\xe0\xa2\x7a\x64\x04\x17\x55\x70\x51\x2d\x8d\xbd\xd5\x92\x82\x8b\xaa\xf1\x08\x2e\xaa\x87\x47\x70\x51\x6d\x31\x82\x8b\x6a\xcb\x11\x5c\x54\xc1\x45\x15\x5c\x54\xc1\x45\xf5\x19\xd9\xed\xfc\x08\x2e\xaa\x95\x49\x82\x8b\x2a\xb8\xa8\xb6\x1e\x7b\xab\x7c\x05\x17\x95\x1d\xc1\x45\x55\x1f\x9f\x17\xab\xf3\x0e\x9e\x91\x51\xf5\xda\xe7\xb4\x8d\xd0\xa9\xc0\x22\xe7\x27\xaa\x36\x8d\x2b\x5e\x55\xe9\x13\x57\x29\x0b\xe2\x53\x71\x9c\x47\xa8\xf4\x33\xad\xcd\x97\xda\xd5\x55\xe1\x93\x0c\xd5\x71\x26\xec\xff\x95\x8e\x8a\x8a\x87\xc2\x2a\xbc\xcd\x73\xd6\x9e\x2c\x1b\xab\x8d\x5b\xe2\xd3\xb8\x24\xf6\xc4\x7f\xd3\x81\x1b\x22\xb8\x20\x5e\x9c\x0b\xe2\xe5\x74\xcd\x75\x9e\xf9\x9b\x99\x04\x35\x13\x49\x63\x44\xaf\x21\xf9\x3b\xc6\x59\x9a\xa7\x06\xe7\x94\xc1\x67\x36\x2f\x42\x00\x54\x81\xae\x96\x62\x5b\x2b\xa2\xb9\x91\xc5\x80\xc5\x4e\x29\x4b\xcc\x36\x62\xfe\xe6\x8c\xce\x0d\xae\xab\x3c\x8a\x00\xb0\x95\x5a\x55\xc3\xf9\xe3\xb0\x78\x53\xd1\x3a\xe3\x75\x3b\x7a\xd3\x8e\x89\xdb\x72\xa4\x38\xcb\x1f\xff\xd0\x68\x8e\xa9\xcc\xba\xa1\xcb\xdf\x5e\x8d\x4e\xab\x6d\xb2\xb9\x27\xcb\x8c\xcf\x45\x32\xb7\x1d\xf6\xf1\x26\x23\xac\xb9\x66\xfc\xd8\xcc\x7d\x0c\x9a\x56\x74\x1b\xa7\x16\x28\x02\x9c\x8e\x13\xf3\x9c\x79\xaa\xe0\xc8\x23\xcb\x77\x81\xea\x5c\x02\x99\x52\xfd\x94\x04\xbf\xbd\x0a\xd3\x4a\x7d\xe9\x82\xdf\xb4\x95\xd0\xeb\x36\x38\x23\x87\xd7\xad\x50\x53\xc4\x0b\x5b\x41\x7f\x6b\x39\xbc\x35\xa5\x6c\x2f\x1b\xb7\x3f\x5a\x04\x4b\xdc\xe0\x87\x77\x06\xe0\x03\xd7\xf2\xd9\xb3\xf3\xaa\x12\xe4\xbb\x4a\x69\x41\xb2\x84\x96\x7d\xa1\x70\x07\xbe\x43\x1e\x74\x3a\x83\xe8\xf6\xca\x79\x62\x0f\x15\x40\x21\x9b\x4e\x99\x9e\xe5\xe3\x61\x24\xd2\x63\x43\x12\xec\xff\x8d\x13\x31\x3e\x4e\xa9\xd2\x20\x8d\xb8\xea\x58\xdc\x20\x32\xb3\x30\x3e\x1d\xa6\xf1\xd1\x90\xfc\xcc\x6d\x76\x7b\xd9\x87\xb2\x52\xdb\xc1\xbc\xdf\xd7\xd9\x18\x83\xa1\xae\x42\x56\xdb\x87\x8f\x17\xb8\xbc\x61\x9b\x42\xc9\xad\x59\x52\x4b\x2f\xf8\xa7\xf7\x80\x07\xca\x45\x3a\x30\xb8\x3c\x37\x4f\x77\x67\x11\x1f\x1d\x78\xb8\xf7\xc8\xbb\xbd\x37\xa2\xf1\xbe\x78\xb4\xf7\xb0\xda\x74\x07\x0e\xd8\x2e\x3c\xd8\xdd\x79\xaf\x3f\x42\x51\xe6\x8f\xe3\xb5\xee\xd0\xb4\xd7\x91\xb7\xfa\x53\x78\xaa\x3b\xf9\xea\xb6\x1e\xea\x4f\xe7\x9d\xee\xe6\x73\xbb\x54\x04\x9e\xab\x47\xba\x03\x13\x7d\x97\xe6\xf9\xce\x4c\xf3\x1f\xcd\x03\xdd\xde\xfb\xbc\x07\x9e\xe7\xd6\x40\x66\x9c\x69\x46\x93\x33\x48\xe8\xe2\x1a\x22\xc1\xe3\xc6\x1c\x66\xa9\x4a\x67\x71\x7e\x94\x9d\xd6\xd9\xa9\xea\x89\x16\x33\xea\x8a\x91\x1b\x8d\xca\x26\x96\x78\x5f\x86\x13\x28\xd0\xab\x6c\x57\xb9\x97\xde\x09\xb2\x37\x06\x31\x9b\x75\xd2\xe5\x26\x7e\x27\xee\x88\x98\x68\xe0\xe4\x90\x71\xbf\x8f\x47\x15\x35\xb0\xb4\x4e\x16\x68\x6d\xae\xbe\x7e\xe5\x6f\x7e\x79\x66\x47\x34\xb0\x2a\xf5\xf1\xad\xc0\xee\x45\x8f\x9b\x81\xdd\x8d\x93\x3c\xa9\x9b\x82\xad\x79\xb8\x4e\x6f\x5e\x97\xe5\x94\x5f\xe3\xbc\xc5\x69\xa3\x3c\x26\x2e\x13\xed\xe5\x6d\x5a\xeb\xb8\x9a\xba\xe8\x57\xc4\xd1\x3c\x66\x35\xbe\x39\x1d\x59\xa3\x71\x30\x97\xec\x8b\xb9\xe4\x89\x62\x53\xf6\x50\xd0\x7d\xa6\xf1\x28\x41\xd0\xdd\x61\x54\x72\x53\xbf\x95\x34\x82\x51\xe7\x32\x82\x3f\x4e\x24\xce\x25\x75\x04\xb0\x10\xf9\xfc\xe1\xe1\x00\xb1\x3d\x4d\x45\x3e\x2f\x66\xca\x4e\xf2\x24\x59\x90\x3c\x13\xbc\x9e\xfd\x6c\x7d\xed\xcb\xc9\xb4\x68\x92\x5f\xf3\x96\x52\xb0\xcc\xa4\x70\x3c\x53\xe6\x9c\x1b\x1a\x5c\xf6\x44\x43\x41\x12\xcb\x34\xd3\x5a\xca\xae\x62\x53\xb3\x7c\xc3\xff\x30\x9b\xb7\x0c\x40\xac\x4d\x68\x9e\x9e\x08\x19\xb1\x71\xb2\x20\x33\x9a\x14\x0d\x70\x28\xb9\x65\x49\xe2\xa6\x19\x92\x6b\xd0\xd6\xa5\x60\x79\x67\x22\xf8\x14\x17\x47\xb9\x6f\xbc\x08\x91\x79\x36\x4a\x80\xf2\x3c\xb3\xef\x33\x9c\x78\x21\x72\xe9\xdf\x37\x2c\x1c\x13\x05\x07\xe6\x2c\xe9\x57\xda\xbb\x3d\xb8\xb1\x45\xec\x4f\xae\x8c\x00\xf0\xde\x97\xa5\xee\x57\xe7\xf4\x95\xc3\x55\xa5\xb9\x4f\x26\xc5\x9c\xc5\xd6\xbb\xe1\xc1\x86\x8d\xa4\x6d\x03\x9f\xe2\x3c\x73\xc1\x07\x1c\xa6\x14\x05\x15\x77\x8a\xec\x9e\xd9\x79\x6c\x04\x01\x8f\xb1\xa5\x8f\x91\xf0\x45\x56\x4b\xa7\x9f\x33\xdb\x8c\xb8\x02\x39\x72\xc8\x05\x11\x18\x8f\x9a\x73\xa6\x6d\x83\xfb\x59\xae\x49\x2c\xee\xf8\xd1\x4e\x5e\x57\x74\xb4\xde\xac\x05\x50\xdd\xfd\xba\x4e\xce\xb1\xdf\xfb\x30\x78\x99\x72\xa6\xcf\x09\xc9\xb9\x82\x96\xec\xbd\x33\xe1\xe8\xcf\x7f\x6a\x46\x23\x58\x0a\x22\xd7\x9f\x44\xfb\xbb\x9b\xb1\x68\x56\x15\x66\x59\x0a\x8a\x88\x7c\x49\x2d\x7e\xed\x1e\x5b\xbf\x43\x41\x05\x5c\x37\x9a\x1a\x76\xd7\x58\xbf\x96\xcb\x21\x94\x9d\xaf\x31\x4e\xfc\xec\xf2\xfa\xd7\xb7\x27\xff\x7d\xfe\x76\x48\xce\x69\x34\xab\xd6\xc4\xe0\x84\x22\xd1\x40\x42\x31\xa3\x73\x20\x94\xe4\x9c\xfd\x2b\x77\x0e\xdf\xc3\xe2\xd9\xa3\x4e\x6b\xb5\x37\xe4\xbe\xd8\x9d\xbf\xb3\x76\x70\xb6\xd7\xbf\x8d\xcb\x12\x0a\xb0\x81\xcb\xb2\xf8\x74\x6e\x2e\x59\xe5\x00\x45\x2d\x0c\x9c\x9f\xb2\xb9\x23\xc3\xae\xf8\x3d\x8d\x8b\x48\x31\x83\xe7\x06\x2d\x0c\xab\xa2\x63\x8c\xf0\x9a\x01\xe1\xa0\x0d\x5a\x17\x36\x26\xc1\x55\xad\x38\x49\xae\x40\xf5\xc9\x38\xc7\x98\xb4\x4c\xb2\x94\x4a\x96\x2c\xaa\x93\x19\x5e\x75\x59\xb8\xbc\x17\xcb\x4b\x3a\x7b\x7f\x7e\x8d\x39\x02\x99\xb4\x65\x4b\x30\xa8\x0c\xaf\xe3\x67\x8d\xc1\x3c\xe1\xda\x08\x0f\xc9\x09\x5f\xd8\x8b\xf6\x80\x33\x45\x12\xa6\x34\x20\x0b\x76\x32\xa4\x77\xa6\x1f\xbc\x1a\xe2\xff\x0e\xcc\x57\x4a\x23\x64\x16\xb1\x72\xd1\x4a\xf0\xaa\x15\x43\xd9\x38\xa9\x40\xd3\x7d\xfb\x8b\x6a\x08\x57\x06\x09\x19\x20\x56\x1a\xc2\xd1\x62\xab\x11\xbc\xb6\x41\x20\xe3\xd3\xa4\x8a\x55\xcd\xc8\x7e\x5b\xdd\xb2\xad\x66\x39\x28\xbf\x60\xd4\x54\xc1\xec\xa4\x31\x5d\xb9\x86\x8e\xda\x39\x95\xdc\xcf\xab\x53\x8e\x22\x88\x6a\x87\xde\x8b\x91\x3f\x01\x4e\xba\x49\x97\xda\xba\x66\x65\x4c\x52\x9f\xbc\x22\x7f\x23\xf7\xe4\x6f\xa8\x5e\xfd\xb9\x6d\xf3\xab\xb6\x8a\x4f\x17\x21\x46\x46\xab\xbf\x18\x75\x04\xf1\x1f\x0d\x75\x32\x33\x1a\xa8\x6a\x41\xc6\xcc\x89\xf3\x70\xaf\x41\x1a\x3a\xea\x76\xe2\x49\xdb\x86\x99\x05\x7e\x42\x34\xb3\xee\x86\x8b\x49\x3d\xac\x69\x37\x44\x33\x8f\x7f\x27\x94\xbe\x74\x54\xa8\xde\x00\xa7\x9c\x2d\xa5\x3a\x9a\xd5\xc9\x98\x11\xd4\x94\x2e\x0f\x98\x22\xb1\xc0\x28\x2b\x1b\xbe\x3c\x63\x2d\x82\x27\xf6\x07\x8d\xdb\xf9\xd3\x6b\xfb\xf9\xd0\x4e\x2d\x19\x50\x50\xf3\x71\x82\x55\xa5\x32\x56\x26\x62\x27\x93\x99\x65\xc5\x15\x9e\xf1\x80\x50\xe6\x6c\x35\x85\x95\x19\x71\xc9\x9c\xa7\x88\x72\x9b\x40\x32\x01\x29\x6d\xc4\xf9\x78\xe1\x83\xf5\x5a\x6f\x5e\xab\x93\x94\x49\xa1\x45\x24\x5a\x74\x36\xab\xfb\xb8\xdd\x74\x08\x04\x1b\xe5\xeb\xcd\xe4\x3f\x9c\x8d\xfa\xe4\xe6\x74\x84\xdd\x9e\xae\x4f\x6f\x46\x75\x4d\xe5\xe0\xe6\x74\x74\xf0\xa4\xa0\x20\x5e\xb2\x42\xc3\x74\x83\x49\x6a\x86\x27\x23\xb6\x0d\x52\x9a\x0d\x6e\x61\xd1\x90\xa7\x76\xc1\xd7\x07\xc5\x0e\x77\xf2\x41\x16\xcc\x29\xcd\x76\x9e\x4d\x02\x8d\xd9\x27\xca\xe2\xf2\x61\xb0\xc5\x3b\xd7\xa7\x73\xa5\x62\x0e\xb1\x15\x87\xfd\x13\xc0\xe3\x4c\x30\x23\x2f\x86\x1c\xaf\xdd\x9f\x0e\x39\x5e\x5b\x8f\x90\xe3\x15\x72\xbc\x56\xc7\xde\x04\xb2\x86\x1c\xaf\x97\xe5\xb7\x0f\x39\x5e\x9f\xb9\xeb\x3f\xe4\x78\xad\x1f\x21\xc7\x2b\xe4\x78\x6d\x37\x42\x8e\xd7\xee\x63\xef\x82\x96\x42\x8e\xd7\x4e\x23\xe4\x78\xad\x8e\x90\xe3\xb5\x61\x84\x1c\xaf\x0d\x23\xe4\x78\x85\x1c\xaf\x90\xe3\x15\x42\x5f\x1f\x9d\x6b\x3f\x43\x5f\x49\xc8\xf1\x72\x23\xe4\x78\xbd\x88\x00\x3f\x12\x72\xbc\xb6\x1a\x21\xc7\x2b\xe4\x78\x35\x19\x21\xc7\xeb\xa5\x98\x4b\x42\x8e\x57\xc8\xf1\xfa\x7c\x04\xdd\x90\xe3\x15\x72\xbc\x42\x8e\x57\xc8\xf1\x7a\x70\x15\x21\xc7\xeb\x25\xa8\x80\xbe\x0f\x70\xfb\x9c\xa5\xde\xa9\x48\xb3\x5c\x03\xb9\xf2\x53\x16\x52\xa4\x25\x0c\x4c\x55\x25\x82\xf6\x21\x84\x91\xe0\x13\x36\x75\x94\xfd\xd8\x36\xdf\x1d\x14\xdf\x33\xa8\x34\xbc\x7d\x86\xf1\x83\x09\x4b\x59\xb3\x44\x32\xb2\xb2\x31\x6f\x71\xae\x8a\x5f\xc6\x9c\xa4\x94\xde\xe3\x11\xa1\xa9\xc8\x6d\xc3\xe2\xc8\xed\x5f\x01\x42\xeb\xbd\xda\xbb\x9d\x21\xdd\xa8\x38\x65\x46\xdc\xa8\x8b\xb0\x12\xaa\x35\x48\xfe\x86\xfc\xcf\xe1\xcf\x5f\xfd\x36\x38\xfa\xfa\xf0\xf0\xa7\x57\x83\xbf\xfe\xf2\xd5\xe1\xcf\x43\xfc\xc7\xef\x8f\xbe\x3e\xfa\xcd\xff\xf1\xd5\xd1\xd1\xe1\xe1\x4f\xdf\xbf\xfb\xf6\x66\x74\xfe\x0b\x3b\xfa\xed\x27\x9e\xa7\xb7\xf6\xaf\xdf\x0e\x7f\x82\xf3\x5f\xb6\x9c\xe4\xe8\xe8\xeb\x2f\x1b\x2f\xb9\xb5\x48\xdc\x9d\x40\xdc\x91\x38\xfc\x51\x84\x61\xe7\xd0\xed\xe8\x2c\xba\x60\x94\x95\xd3\xe8\x18\xd6\x43\xa7\xd1\x53\x53\x14\xf3\x8a\x79\x98\x22\x22\x65\xda\x08\x87\x46\x1e\xa4\xd5\x70\x56\xa6\x6b\x4a\xa9\xa3\x03\x18\xd0\x4d\xb5\x6d\xaf\x5e\x84\x82\x56\x82\x58\x84\x97\xfc\x5c\xff\x79\x96\x66\x09\xb6\x35\xc7\xf3\x3c\xf0\xb1\x2c\xc8\x5c\x03\x6d\x78\x7c\x04\xda\xf0\x12\x69\x83\x82\x28\x97\x4c\x2f\x4e\x05\xd7\x70\xdf\xc8\xc2\x52\x27\x0d\xd7\xf5\x09\x5d\xcc\x98\xcb\xe2\x76\xd7\x88\xc8\x6c\xdc\xf7\x52\x3a\xfd\x4c\xe4\x49\x8c\xc9\x1c\x39\x47\x05\xd3\x66\xe9\x81\xb6\xda\x1f\xea\x3d\x18\xca\xbd\xfc\x12\xaf\xcf\x59\x35\xf3\x5f\x39\x9b\xd3\xc4\x68\xbb\xe5\x13\x23\xd4\x60\xaa\x0f\x6d\x7b\xe6\x35\x55\xb7\xe5\x81\x87\x81\x91\xa1\x8b\x35\x1f\xfb\x4f\xc2\x9f\xe0\x5e\x3f\x47\x29\x0d\x05\xa4\x91\x64\x73\x96\xc0\x14\xce\x55\x44\x13\xa4\x6b\xdd\xf0\x8a\x93\x0d\xb3\xe3\xc6\x4b\x91\x28\x72\x37\x03\x43\xab\x09\xf5\x26\x00\xcc\xb0\x9b\x52\xc6\x49\x6a\xb6\x28\xf3\x0f\x2b\x6b\x4b\x30\xe4\x3f\xa3\xd2\x6c\x70\x61\x33\x40\x15\x79\x2c\x44\xe2\x32\x1e\x92\x45\x39\xbf\xcb\xfd\xe1\xe2\x57\x0e\x77\xbf\x9a\xd9\x14\x99\x24\x74\x5a\x98\x0a\x14\xe8\x15\x6b\x5f\x39\xf5\xc6\x0f\xc0\x74\x82\x1c\x08\x4d\xee\xe8\x42\x95\x86\x93\x4a\xdd\x07\xf5\x86\xbc\x3e\x42\x74\xa6\x8a\x14\x73\xc4\xe4\x0f\x47\xe8\xfe\x3b\x3d\x19\xfd\x7a\xfd\xf7\xeb\x5f\x4f\xce\xde\x5d\x5c\x92\x4b\xa1\xc1\x32\xb5\x4a\x73\xc0\xa8\xd0\x30\xcc\x2a\xf1\x1d\xa8\xa5\x0b\x35\x44\xdb\x25\x53\xe4\x8e\xf1\x58\xdc\xa9\xc6\x36\x5a\x8b\x7e\x06\x78\x40\x79\xa3\x39\x22\x9a\x51\xec\x79\xd8\x82\xc3\xac\x44\x98\x54\x27\x45\x1e\x1e\xc7\xc7\xb1\x14\x99\x05\x82\x37\x72\x95\xac\xb6\xae\x46\x57\x63\x58\x71\x7f\x27\xf5\x09\xa7\x92\x72\x5d\x5a\x7b\xca\x3d\x73\xcd\x16\x87\xad\xb7\xe3\x79\x67\x34\xd1\xb8\xbb\x6c\xa6\x93\x38\x86\xb8\x06\xfe\x17\x17\x39\x78\xea\x3f\x6e\x51\x56\xa9\x20\xa3\xf7\xd7\x17\xff\x7b\x09\x8f\x17\x59\xbb\x40\xa9\x6e\x32\x63\xa5\xc8\x3a\xdb\xdd\x2b\x97\x79\x19\xf6\x77\x2f\xf6\xb7\xe0\x96\xdd\xb8\xe7\xaf\x72\x5e\x2f\x64\x54\xce\x4f\x52\x11\xc3\x90\x8c\x0a\x3f\x41\xfd\x6a\xa5\xc0\x01\x95\x40\xcc\x2d\x5c\x33\x9a\x24\x8b\xaa\x88\xa6\x85\xcd\x42\xac\xd5\x66\xa8\x12\xf2\x09\x4d\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x3e\xdc\xc9\x76\x14\xb3\x91\x18\xb8\xd0\x4e\xb0\x36\xab\xc4\x7a\x17\x52\x44\xc4\x2a\xdf\x95\x60\xac\x1a\x7f\x53\xd6\x57\xe1\x59\x23\x53\x1e\xd8\xa3\x62\x66\x6b\xa8\xce\x15\x2c\x0b\xe8\xbe\x0f\x71\xa1\x8e\x9b\xd9\x25\xd0\x58\xf0\x64\x81\x91\x97\x36\x96\x22\xa5\xea\x16\x62\xfb\x83\x13\xcd\x0a\x4f\x85\x99\xb1\x78\xd5\x8d\x59\xb7\x77\x4b\xa0\x48\x66\x23\x3c\xd0\x9d\x01\xf1\x13\xef\x7a\x8b\x43\x68\x80\xf2\x9e\x27\x8b\x2b\x21\xf4\x37\x45\x1a\x6d\x27\x18\xf0\xa3\x93\x96\xeb\xa6\x68\x14\x27\x29\xbe\x77\x80\xbb\x81\x87\xaa\x9a\xc1\x7b\x56\xee\xf8\x73\x3f\x52\x32\xe7\x27\xea\x5b\x29\xf2\xc6\x4c\x6c\x45\xd8\xfc\xf6\xe2\x0c\x49\x51\xee\x5c\x95\x5c\xcb\x05\x96\x0e\x58\xad\xfa\x56\x28\x06\x3f\x38\x67\x6b\xf5\x4c\x94\x7e\x31\xf2\x8e\x2e\x08\x4d\x94\xf0\xb0\x64\x7c\xad\x16\xea\x54\x5c\x73\x79\x2c\xf4\x6c\x45\xb7\x35\x07\x6a\xf5\xb9\x7e\xc5\x73\x59\x96\xa1\x63\x7c\xe5\x71\x4d\x6f\x41\x91\x4c\x42\x04\x31\xf0\xe8\xa9\xb7\xfd\xa9\x1d\x7e\x88\x3a\x97\x82\x9b\x83\xd9\x09\xf2\x5c\x14\x9e\x5e\x07\xd2\x2a\xaa\xa0\xcf\xd8\x69\x7f\x14\x3d\xc7\x78\x2c\x73\x05\xd2\xba\xb9\x65\x0e\x76\x27\xbf\xcf\xc7\x90\x18\xc8\x1b\x95\xd4\x75\x8a\xb7\xe6\x0c\x96\xd2\x29\x10\xaa\x0b\x4c\xd3\x82\x00\x57\x86\x62\x5a\x03\xa8\x26\xb1\x80\x32\xfb\x9e\x2a\xf2\xc3\xc5\x19\x79\x45\x0e\xcd\xbb\x8e\x10\x7f\xb0\x91\xbc\x16\x36\xc8\x6d\x59\x47\x9d\xf8\x29\x70\x49\x88\xbc\x44\x48\x4b\x24\xfa\x84\x0b\xa2\xf2\x68\x56\xed\x5e\xef\xd5\x66\x17\x08\x89\xae\x95\xfd\xc4\xf5\xa7\xa5\x50\x3f\x28\x90\x9d\x11\xa8\x1f\x1a\x10\xa8\xaa\x18\x65\x70\xae\x0e\x3d\x8b\x58\x29\x68\x1a\x53\x4d\x1d\xe1\xf2\x37\xec\xed\x96\x7e\xde\xe4\x4b\xc1\x5b\xc6\xf3\x7b\x1b\x78\xd4\x9d\xa9\xe5\xfa\x1c\xa7\x25\x91\x87\x3a\xee\x3a\xcd\xb2\x84\xd9\x6a\x1b\x4b\x81\x70\x17\x35\x5c\xe9\x6f\x10\x13\x91\x4e\xd0\x24\x11\x86\x3e\x1a\xe1\x84\xf2\x58\xa4\x2b\x2f\x33\x42\x24\xd4\xea\xa5\x0e\x49\xc0\xbe\xfa\xd8\x13\xa3\x50\x02\x73\x68\x51\x5b\x6c\xb9\x3e\xac\x99\xcd\x00\xc7\x63\x04\x4e\x4f\x12\x3a\x86\xc4\xc2\xd8\x62\xa0\x5a\xc5\xc0\xa7\x8e\x46\x95\x22\xe9\x2e\x7d\xe6\x4a\x24\x60\xc3\xbb\x3c\x20\xcc\xf4\xcf\x02\x0e\x38\x49\x57\x70\x40\x6d\xb0\x06\x07\xd4\x6b\x9f\x03\x1c\xf2\x16\xac\x9e\x2c\xc3\xc1\xc8\x0d\x75\x38\x20\xf3\xde\x77\x38\x28\x88\x22\x91\x66\x23\x29\x8c\xda\xd9\x19\x6f\x72\xd3\x96\x3e\x43\x6b\xd8\x58\x13\x8c\x85\xbc\xa0\x7e\x33\x95\x95\xc0\x4e\xaa\x2d\x93\xf0\xd1\x9d\xff\xab\xc2\xb3\x90\xf4\x2c\x33\x32\x3f\x4b\xcd\xbd\x68\x9e\x74\x17\x9e\x33\x3b\xe8\x22\x37\xa2\x85\xb1\xb3\x13\x6e\x24\x22\x9a\x60\xed\xd8\x76\x28\x47\x96\xd1\x6e\x79\xe2\x4a\x38\x2f\xfa\x28\xf1\x37\x1f\x40\x82\x65\x44\xf1\x17\x67\xc2\xe4\x22\x86\x8a\x2f\xdb\xc6\x21\xdf\xd8\xb0\x4f\xbc\xcf\x47\x12\x1b\xb9\xc2\xbb\x95\xe3\xda\xd3\x5a\xb8\x0a\x68\xef\x8a\x8a\xb4\x66\x81\xc0\x63\xc6\xa7\x68\x57\xeb\x13\x09\x89\x8d\x41\x76\x44\xe0\xd6\x6a\x90\x3d\x3c\x12\x7e\x52\x7f\x1e\xfc\xab\x51\x16\x63\x82\xbb\x99\xd1\x52\xe4\x25\xac\x89\x25\xb7\x4c\x91\x83\xb7\x1e\x00\x2d\x4a\x78\xee\x23\x87\x39\xb0\x5f\x58\xec\xa6\xb5\x74\xde\x32\x1e\xbb\x70\xdd\x1a\xb0\x8a\x62\xeb\x56\x0e\xc6\x40\x70\x16\x57\x69\xcb\x1b\xf2\x33\x27\x05\xb0\xc8\xa0\x31\x7a\x5c\x59\x91\xd9\xdb\xe8\x06\x0f\x1b\x5e\x8b\x97\x2c\x4f\xf3\x03\xc7\xbd\x37\xef\x1d\x18\xcd\x7d\xf5\x3e\xff\x2d\x4f\x5a\xba\xc7\x51\xbf\xae\xb5\x98\x1f\xed\xb4\x5e\xa4\x8f\x0c\x5a\x6b\xc6\xa7\xaa\xaa\xc9\xd0\x24\xa9\x19\xc3\xd7\xa9\x32\x7e\x87\x8b\xd2\xfa\xab\x2a\xc4\x52\x9a\xc1\x73\x51\x43\x12\x23\x4e\x3c\x73\x25\x64\x9a\x2a\x7a\x2a\x0d\x24\x34\xa3\xc9\x75\xd6\xbc\x44\x29\x59\x29\x87\xf7\xee\xfa\xa4\x3e\x35\x32\x6b\xec\xfc\x60\xf6\xca\x5c\x27\x34\x4e\x99\x52\x68\x08\x83\xf1\x4c\x88\x5b\x72\xb8\xa6\x1e\x57\x25\x4e\x4b\xb1\xa9\x3a\x76\x38\x3f\x30\xab\x3f\x22\x8c\x27\x45\x54\x14\xea\xc1\x5c\x2b\x6f\xc8\xc1\x97\x44\xc5\x2a\x70\x0f\x5d\xdd\x6a\x17\xac\xb0\xba\x4c\x5b\xa9\xda\x60\xc1\x93\x13\xec\xd5\xed\xb9\x6c\x59\x76\xe5\x91\x2d\xba\x74\xb8\xbd\x5c\x59\x6d\x2d\x1c\xad\xf4\xf8\xe4\x40\x72\xc2\x45\x04\xaa\xbb\x82\x4e\xdf\x95\x73\x92\x18\x6c\x16\x0f\x60\xf4\x13\xdd\x18\x64\x87\x76\xe9\x1e\x26\x83\xba\x47\x7b\x55\x89\xfa\xa6\x24\x2e\x46\x1f\x49\xb2\x19\x1d\x58\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x09\x2e\x5c\x92\x84\x61\xa2\x82\x23\x4a\x23\x89\xb2\xde\x3c\xdc\x13\x47\xa2\x2b\x4b\x3d\x2d\xbd\xc4\x55\x47\x20\x26\x93\xd9\xfa\x11\xe5\x1a\xee\x98\x9e\xf9\x4e\x2f\x35\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\xbf\x7a\xaa\xea\xa8\x2e\x4b\xc1\x63\xbc\xa2\xc1\x26\x98\x4c\x20\x42\x41\xab\x0a\x60\x4b\xb5\x0f\xcb\xc2\xb7\x2e\xcb\xc0\x20\x98\x2b\x25\x9f\xb2\x7b\xf3\x96\xea\x53\x55\x97\xb8\x2b\x38\xbb\xfe\xf2\xd1\x90\x90\x0b\x5e\x44\xf0\xf6\xcd\x2e\x56\xef\xf4\xa1\x67\xda\x7c\x62\xb5\x0f\x01\x7e\x40\xd5\x70\x66\xa4\x43\x99\x77\x80\xf1\x6d\xcc\xe1\xa4\x6a\x12\xef\x94\x1c\xa0\x69\xdc\x4d\x6a\xb6\xde\xcb\x00\x6d\x4c\xe5\xe6\x96\x8f\x65\x2e\x7f\x1e\x0e\x10\xd2\x96\xce\xb9\x6a\x0a\x1d\x15\x87\xbf\xae\xcc\x56\x91\xde\x0b\x87\xdb\x48\xc4\xb6\x9a\x4a\x51\x0d\x02\x7b\x3a\x61\x75\x17\xf6\x6f\x2f\x9f\x95\x32\x1e\x17\x36\x3b\xa0\x5a\x66\xc5\x95\xd4\x8e\x89\x11\xb5\x13\x6f\x5b\x48\xb3\x04\x30\x8b\xb3\x32\x73\x99\xa0\x5a\xa9\x26\xdf\x2f\x16\x52\x16\xa4\x77\xc5\x5d\xfa\xe4\x9f\x78\x28\x8b\x40\x54\x5f\x77\x62\x54\x3c\x6e\x35\x44\xa6\x7c\x6b\x09\xcc\xb0\xd4\xc2\x9b\x2e\x48\xcc\x26\x13\xf0\x01\xaf\x46\x73\xa4\x92\xa6\x86\xc4\x2b\xe2\x40\x30\x86\x29\xb3\x01\x91\x05\x61\xeb\x19\x71\xcf\xe5\xfa\xf5\x2d\x31\x64\x9a\xa4\x6c\x3a\xb3\x88\x42\x28\x66\xe8\x12\xef\x54\x4c\x04\x8d\x09\xe2\xb6\x90\xe4\x8e\xca\xd4\xf0\x0d\x1a\xcd\xd0\x43\x49\x39\x89\x73\x89\x55\x96\x35\xd0\x78\x31\x50\x9a\x6a\x23\x29\x83\x74\x0a\xa5\x5f\x7f\x28\xa9\xff\xe0\x08\x25\xf5\xb7\x1c\xa1\xa4\x7e\x28\xa9\xbf\x3a\xf6\x26\x3a\x34\x94\xd4\x7f\x59\x65\x92\x42\x49\xfd\xa7\xf6\x26\x84\x92\xfa\xa1\xa4\xfe\x43\x23\x94\xd4\x7f\x64\x84\x92\xfa\x0d\xc6\x0b\xa0\x5c\xa1\xa4\x7e\x83\x11\x4a\xea\xaf\x1f\xa1\xa4\xfe\xea\x08\x25\xf5\x37\x8e\x50\x52\xbf\xf1\x08\x25\xf5\x43\x49\xfd\x50\x69\x74\xb7\xb9\xf6\xb3\xd2\x28\x09\x25\xf5\xdd\x08\x25\xf5\x5f\x44\x3d\x45\x12\x4a\xea\x6f\x35\x42\x49\xfd\x50\x52\xbf\xc9\x08\x25\xf5\x5f\x8a\xb9\x24\x94\xd4\x0f\x25\xf5\x3f\x1f\x41\x37\x94\xd4\x0f\x25\xf5\x43\x49\xfd\x50\x52\xff\xc1\x55\x84\x92\xfa\x2f\x41\x05\x54\x3a\x66\x8d\x2a\x80\x6e\x53\xac\xc8\x05\xa1\x57\x6a\x03\x8c\xf3\xc9\x04\x24\x52\x2e\x7c\xf3\x4a\xf0\x54\x59\x97\x71\xd9\xc9\x0a\xba\x8f\x75\x8f\x5c\xbe\xce\x86\xc7\x5d\x31\x02\xac\xd4\x59\x46\x8a\x9f\xbf\xff\x66\x4d\x65\xa4\xc6\x51\x85\x4d\x63\xa4\x71\xcd\xef\x79\x33\xff\xf8\x06\x80\xaf\xcb\x1f\x73\x70\x8f\x12\xa1\x5c\x84\x3b\x02\x2b\x9a\x51\xce\xc1\xeb\x7b\x4c\xa3\x1d\x65\x0c\xc0\x89\xc8\xc0\x79\xa7\x29\x51\x8c\x4f\x13\x20\x54\x6b\x1a\xcd\x86\xe6\x4d\xdc\x03\xbb\x8c\x46\x77\xbf\x28\x2d\x81\xa6\x3e\x2e\x3f\xa5\xcc\x4e\x45\x68\x24\x85\x52\x24\xcd\x13\xcd\xb2\x62\x32\xa2\x00\x13\x6a\x2c\xa3\x2a\x80\x81\x51\x71\x65\x08\x7b\xbf\x7c\x9b\x5b\x96\xa8\x96\xa6\x43\x6d\xb3\x8f\xf5\xc0\xd3\x4c\x2f\x8a\x38\x5e\x20\x13\x26\x95\x26\x51\xc2\x90\x5b\xe3\x1b\x6d\xee\x34\xce\xd7\xf7\xbc\x9a\xbb\x95\x2a\xb7\x54\x1e\xa3\xd8\x9a\x69\x65\xa3\x62\xcb\x09\xdd\x54\x31\x53\x4e\xcc\x57\x7d\x42\x7d\xdd\x34\x0b\x68\xbf\x52\x04\xb5\xe7\x2c\x76\x76\xf7\x53\x65\xba\x4a\xbd\xd8\x32\x6c\xb8\x44\x74\x4c\x71\xf0\xc8\xd9\xaf\x65\x73\x94\x02\x05\x46\xe9\xad\x1c\x03\xdc\x00\x0e\x73\x83\x03\x10\x81\xe1\xaf\x74\x03\xd6\x7f\x72\xa4\xaf\x30\xc5\x77\xa0\x14\x9d\xc2\xa8\xa1\xa3\x61\x93\x46\x86\xbe\x86\x72\x63\x10\x15\x12\x9b\x5d\x5b\xfc\x52\x46\x67\xd6\xc5\x20\x92\xda\x35\x15\xc2\xcf\x9d\x64\x5a\x03\x6e\x2a\x56\xd8\x43\x5f\xe5\x72\x02\x7e\x6f\x29\xc6\xf3\x9d\x9f\xa4\x7c\xd8\x10\x75\x1e\xdb\x88\xcb\x31\x90\xb1\x64\x30\x21\x13\x86\x61\x9c\x18\x58\xd9\xb7\x05\x97\xa8\xb5\x02\x28\x65\xf4\x5d\xc1\xbd\x2c\xeb\xd7\x35\x24\x3f\xba\x85\x69\x99\xf3\x88\x56\x6a\xd9\x62\x86\x29\x9b\x90\x29\x06\x66\x3a\x69\xf1\x4f\xaf\xfe\xfa\x67\x32\x5e\x18\x96\x86\x92\x95\x16\x9a\x26\xc5\x47\x26\xc0\xa7\x06\x56\xf6\x78\xd6\x73\x24\x0b\x08\x60\x37\x0f\xbb\xf0\xd7\x7f\xb8\x1d\xd7\x79\xec\x71\x0c\xf3\xe3\x0a\xfc\x06\x89\x98\xae\xeb\x8f\xd2\x3c\x64\xbb\xa1\x4a\xb4\x06\xcd\x44\xc2\xa2\x45\x6b\x44\xf3\x95\xbf\xc8\x4c\xdc\x59\x59\x7f\x0d\xf6\x94\xe9\x56\x99\xc8\xf2\xc4\x1a\x9d\xbf\x29\xb2\x8b\x73\x05\xab\x39\x80\x6b\xcf\x05\x9a\x49\xdd\x14\xcb\x75\xd3\x6d\x3c\xae\x7f\xa5\x70\xb9\x25\xce\x90\x57\x14\x00\x43\x45\xe8\x1b\x9a\x24\x63\x1a\xdd\xde\x88\xb7\x62\xaa\xde\xf3\x73\x29\x85\xac\xaf\x25\xa1\x86\x5a\xce\x72\x7e\x6b\x3b\x38\x14\x25\x12\xc4\xd4\x88\x56\x59\xae\x7d\x22\xc3\xba\x0f\xb6\xf9\xf2\x9e\x08\x7b\x35\xa8\x9c\x05\xee\x59\xa9\xeb\xb8\x54\x2d\x8b\x91\xd5\xf9\x55\x15\xd9\xfe\xf0\xea\x4f\x7f\xb1\xa8\x4b\x84\x24\x7f\x79\x85\x31\xdb\xaa\x6f\x0f\x31\xd2\x36\xc3\x28\x52\x9a\x24\x46\x6d\xa8\x22\xa5\x01\xf4\x3a\x24\xfc\xe4\x38\xa8\xdb\xa3\xdb\xd6\xa2\xd4\xcd\xcd\xdf\x51\x8e\x62\x5a\x41\x32\xe9\xdb\xac\xa4\x42\xad\xe9\x21\x63\xe8\x39\xea\x83\xa9\x61\x7b\x20\x00\xcd\x45\x92\xa7\x70\x06\x73\xd6\x45\x13\xa7\xda\x6c\x5e\xd5\x4f\x98\xc2\x04\xb0\x71\x22\xa2\x5b\x12\xbb\x8b\x95\xc8\x93\xe5\x4a\xe0\xcd\xa1\xd0\x34\x06\xa7\x45\xec\xcd\xc6\xef\xaf\x45\xdd\xa4\x34\xcb\x8a\x1c\x21\x49\xef\x6a\xc0\xc0\x33\x89\xe5\x0a\x5a\xd6\x93\x69\x6d\x66\x6e\x6b\x64\x1e\xb8\x2f\x32\x74\xb3\xf1\x14\x8d\xa3\x4e\xda\xdb\xa8\xcb\xd5\x37\x37\x4c\xd6\x10\xa2\x9c\xd0\x9f\x86\x0c\xff\x6d\xb3\x4a\x56\xb2\x22\x8b\xc4\xba\x02\x31\xac\x00\x60\xd0\x07\x49\x72\x73\x83\x6b\x07\xd6\xcd\x76\x21\x47\x35\xb8\xf0\xc2\xaa\x9c\x52\xed\x04\x42\x6f\xbe\xa6\x24\x03\xa9\x98\x32\x7c\xf9\x03\x1e\xa8\xd3\x84\xb2\xb4\x62\x02\x7c\x1a\x20\xd8\xc3\x8d\xe5\x93\xdb\x53\xca\x91\x88\xdd\x84\x48\x0a\x6d\xe9\xe8\x35\x62\x6d\x5d\xaa\xed\x90\xa1\x3e\x35\xa9\xfc\x50\x42\xb3\x4e\x29\xcd\x2f\x05\xa9\xb4\x77\xbd\x24\x02\x89\xdf\xf7\x5c\xe9\x63\xb1\xf8\x8e\xc8\x00\x12\x46\xb7\xb9\x75\x4a\x58\x53\x1e\xed\x41\xa9\x88\xf4\x4e\x0f\x1c\x12\xeb\x05\x37\x67\xc2\x3d\x4a\x7a\x6f\x7a\x4f\x4a\x24\x2d\x88\xa4\xc8\xe8\xb4\x55\x2f\x9f\x25\x48\x2d\x4f\x5b\x2d\x34\x61\xd4\x20\xbc\x5e\x94\x5d\xc3\xbb\x20\x2e\xeb\xe8\x60\x95\x24\xeb\x1d\xf5\x00\x76\x0a\x82\xcd\xc7\xbe\xa3\x0b\x42\xa5\xc8\x79\xec\xec\x4b\x85\x81\xef\xdd\xd2\x8b\x2f\x05\x07\x6f\x38\x5f\xae\x53\x81\x16\x7d\xc6\xc9\xeb\xe1\xeb\x57\x2f\x85\x53\xe1\x17\x2e\x71\xaa\xcb\x82\x53\x59\xfa\xf4\xa4\xdf\xea\x2b\xde\x77\xf4\xbd\xef\x9c\x89\xa5\x2c\x68\xcf\x7c\xb9\x6c\xfc\xe9\x4e\x32\x0d\x95\x1e\x7f\x87\xa8\xb8\x18\xfd\xb0\x52\x95\xe1\x68\x5d\x27\x89\x96\x40\x6a\x57\x06\x43\xe5\xe3\x8f\x48\xb7\x1c\x81\xc2\xe3\xb6\xce\xc2\xa5\x1e\x20\x61\x55\x40\x1d\x1c\x90\x43\x7b\x67\xcf\x26\x34\x1f\x3d\x29\x6a\x39\xa0\x9d\xdf\x67\x2d\x6a\x6c\x2e\xe5\xce\x67\x14\x6d\x70\x59\x87\x10\xfc\x6f\x98\xd1\x39\x60\x22\x37\x4b\xa8\x4c\xd0\xe7\x78\x6d\xd7\x4e\xc6\xb9\x26\xc0\xe7\x4c\x0a\x9e\x02\xd7\x64\x4e\x25\xc3\xaa\x38\x12\xb0\xb2\x83\xd1\x45\xbf\x3c\xfc\x70\x72\x85\x01\x0d\x47\xae\x24\x85\x5b\x65\xae\x7c\xf9\x9a\xea\x4a\x2a\xd3\x3d\xba\x7d\x7e\x1d\x06\x86\x48\x73\xfd\xba\xcc\x7b\xd2\x5c\xe7\xb6\x2d\xcb\x7d\x94\xe4\x8a\xcd\x9f\x8a\x92\xb8\x0c\xfb\x33\xd6\x68\x9f\x97\xb2\xfd\x4b\x40\xad\x24\xee\xa3\x69\x7d\x4d\x82\xde\x8a\xc3\xa4\xa7\x8a\xa4\xbd\xaa\x0f\xdc\x99\x9e\x5c\x2d\x0d\x1b\x3e\xe7\x2b\x2e\xae\x88\x10\x58\x37\xe6\x69\x8d\x50\x31\x57\xa7\xb8\xc2\xdd\xc0\x5a\x0f\x48\xae\xe5\xf1\x9d\x5d\x5e\x57\x8b\x90\x58\x75\x49\xc4\x43\x32\x2a\x7f\x2c\x2b\xd5\x60\xfd\xb4\x42\x89\x04\x39\x2d\x8b\x8a\x4f\x81\x83\x44\x21\xc1\x4c\x59\x6b\xab\x4a\xc6\x54\x59\x27\xcf\xd9\xe5\xb5\xb5\xd9\xee\x06\xb3\xc6\x62\x76\x73\x09\xd5\x70\x7c\x9b\xc6\xd0\x40\xb8\xad\xf7\x4c\x2b\x0c\x56\x06\x30\xa8\x94\xda\x89\xc9\xc5\x88\xd0\x38\x96\xe8\xf6\x71\xa2\x4f\xa5\x52\x65\xe1\x5b\xc0\xaa\x30\x54\x41\x75\x4d\x15\x70\x23\x89\x2b\x01\x4b\xce\xf2\x2c\x61\xd6\x8d\x50\x7d\xa0\xac\x66\x83\x4d\xbe\x76\x47\xda\x36\x6a\x5e\x63\x25\xaf\x05\x15\x12\x4d\x8b\x52\x3e\xb0\x7b\x12\x94\x48\xe6\x65\x41\xe1\xa5\x5d\x73\x27\x02\x4d\xe2\xc5\xae\xf9\x1a\x94\x5b\xed\x18\x70\x2d\xcd\xd1\x5c\xde\x2d\xec\x62\x9f\xe4\x78\x9a\x8a\x09\xd9\x1c\xd0\x3f\xee\xca\x6f\xba\x32\x6e\x65\x89\x63\xeb\x1b\xb6\x55\xa6\x81\x4a\x4f\xd1\x70\x55\x0d\x4f\x22\x79\x2a\x44\x58\x36\x76\x9c\x5d\x5e\x5b\x4a\x68\x3f\xbe\xe8\x4e\xbb\x6e\x97\x4a\xaa\xd6\x18\x03\x9f\xac\xca\x50\x1b\xcd\x63\xa9\xb9\x9f\x6b\xd7\xdd\x2a\x90\xa5\x85\xf8\xd7\x2a\xd9\xae\xc5\xdb\x15\x50\x19\xcd\x9a\xc0\xff\x01\x42\x60\x27\x25\xb1\xb0\x91\x00\x13\x21\x51\x25\x1e\x20\x79\x4f\x84\xb8\xcd\xb3\x6d\x28\xba\x9b\xc6\x36\x5c\xdb\x8a\x40\xd4\x9e\xf8\xac\x68\x7a\xcc\x55\x13\x7f\x6f\x5d\xf6\x01\x6d\x25\x1e\x9c\xa8\x4c\xa0\x10\xcb\x7a\xd3\x69\x92\x2b\x0d\xf2\x1b\x26\x95\x3e\xf0\xf5\xa2\x11\x83\xad\x4d\xa4\x57\xbd\xe1\x47\xa6\x67\xae\x74\x63\xaf\x5f\xbf\x64\xfe\x76\x13\xf7\x8c\x4e\xdb\xbb\x14\x1c\x7a\xc3\x65\xb1\xab\x20\xe5\x05\x59\xdb\xc8\x53\xdc\xd2\x15\x24\x36\x5e\x14\x2f\x54\x70\xe5\xc6\x95\xad\x34\x6f\xf0\xf4\x4f\x81\x26\x14\x4b\xc4\xe1\xdd\xb3\xb2\xcc\xa4\xad\x1b\x65\xeb\x64\x0a\x27\xe8\x2d\xaa\x20\xaa\x94\x92\xd2\x62\xf3\x67\x37\x91\xe7\x76\xc6\x00\x5b\x7e\xd4\xd5\x0b\x79\xcb\xf8\xed\x8e\xe8\x57\x8f\x2e\x39\x5f\x99\xad\x56\x4f\xdc\xfa\x68\x19\xb7\xc1\x77\x86\xc5\xd0\xb1\xc8\xb5\xaf\x49\xa2\x2a\x8a\x23\xe3\xff\xb4\x7b\x81\xf6\xf6\xcc\x56\xec\x5b\xa7\x23\xaa\xbe\x35\xfa\x78\x25\x50\x2d\xb8\xa6\x58\x5b\xf4\x4c\x44\xb7\x20\x49\x62\x96\x31\x24\x65\xe0\x4b\xad\x9a\xa5\xcc\x61\xc7\xa8\x8b\xa6\x96\x0e\xc8\x66\x90\x82\xa4\x49\x59\xd4\xb5\x05\xa8\xdf\x3a\xc2\x59\xcc\x5a\x8d\x49\xb1\x45\xd1\x5c\x19\x46\x73\x0e\xcf\xd7\xdd\x95\xd2\x85\xaf\x74\xcb\x38\x86\x1b\xdc\x33\x85\x66\xfd\x4c\xc4\xd5\xc4\xb3\x5c\x81\x1c\x14\x69\x81\x2e\xf7\x46\x15\x81\x38\x31\x8c\xf3\xe9\x94\xf1\xa9\xa3\xce\x48\xd3\x2b\xe5\xb6\x0b\x4d\x07\x23\xbd\x23\x09\xb6\xe0\x2c\x4a\x0f\x36\xbe\x8c\x55\xef\x4f\x45\x6c\x6f\x1f\x2f\xac\x36\xe8\x77\xb6\x0c\x90\xbe\xe0\x44\x48\x57\x1a\x81\xc6\x31\xae\x7d\xf5\x0b\xf1\x6a\xfd\xab\xfa\x45\x1c\x87\x8d\xec\x2e\x9e\xaa\x80\x45\xe5\x63\x23\xec\xe4\x32\x82\x75\xb6\xd3\x4a\x89\x5f\x3a\xa7\x2c\x41\x3b\x85\xe0\x24\xb2\xa7\xd8\xc5\x9a\x99\xd3\xcf\x7b\x18\x05\x87\xcd\x3a\xf1\x9d\xe7\xab\x18\xd0\xa2\x44\x55\x53\x3e\xd3\x88\xc7\xd4\xcb\x0b\x9d\xf0\x35\xdf\x62\x03\xc6\x35\xa4\x99\x90\x54\x2e\x96\x3d\xa6\x86\x26\x1a\x8c\x33\xfb\xb5\xb4\x31\x23\x11\x23\xdb\x58\x83\x67\x73\xdb\x38\x78\x0d\xaa\xad\x45\x69\x24\xba\x5c\x10\xbf\x81\x86\x3d\xa8\x68\x06\x71\x8e\xc1\xea\xd3\x9c\x62\x63\x73\x43\x34\x9c\x6d\x7d\xe1\xa2\x00\x2d\xee\x15\xf1\x85\x45\x56\xc2\x02\x63\x72\xb0\xe8\xa7\xf9\x05\x8b\x87\xda\x48\x44\xdb\xd7\x19\x7b\xbc\x16\x41\x89\x37\x65\xab\x09\xfc\x58\x98\xb3\x48\xfb\x87\x26\x9b\xf0\x34\xa2\x45\x3b\xd9\x91\x70\xc5\x06\x23\x30\xb4\x4f\xab\xf2\x53\x5c\x10\x0b\x96\x13\xfd\x99\x1b\x9e\xb4\x19\xf5\x4b\x3c\x7f\x04\xc3\x51\x8c\xaf\x6f\xc5\x03\xd4\xa2\x80\xd2\xba\x6f\x37\x6b\x5a\xca\x1b\x70\xb8\xdd\xf9\x39\xd9\xb5\x0e\x54\x0b\x7d\xa3\xb9\x33\xb1\x91\x13\xb0\x8d\x6a\x43\xe5\xb4\xbd\x1a\xd8\x3b\x91\xd3\x3c\xb5\xe5\xc9\xc5\x52\x85\x68\x8b\xdf\x68\xb2\x33\xdc\xf8\xf4\xdd\x59\x35\x3b\xa3\x1a\x76\xee\x73\x5b\x8c\x94\xd7\xd2\x94\xbb\x6c\xcb\xbd\x30\x7a\x67\x61\x20\x2e\xd9\x86\x53\x50\x9d\xb1\xb2\x78\x9b\x57\xd0\x19\xcf\x8c\xa0\x81\xe2\x51\x69\xae\xe4\xd1\x8c\xf2\x29\x5a\xf8\x45\x6e\xe6\xfb\xf2\x4b\x5c\x91\x84\x38\x8f\x5c\x4b\x0c\x1f\xda\xfd\xa5\x37\x6c\xba\xea\x44\xd8\x99\x4f\x45\x34\xf3\x6b\xae\x7e\x96\x95\x42\xde\x10\x36\x84\x21\x39\xf8\xb2\x72\xe9\xc0\xbe\x3d\x93\xc2\xbc\xc2\x45\x85\xe3\xaa\x12\xa6\xf1\xd0\x1d\x54\xef\x1e\x92\x73\xf3\x0e\x74\xf6\x14\x00\xac\x04\x2e\x8f\x4b\xf0\xf5\x89\x84\x29\x95\x71\x82\xc9\x84\x93\x42\xde\xb2\x29\x47\x0e\x60\x78\xd2\x31\x54\x90\x0b\xbd\xce\xf0\xba\x65\xc6\x87\xa6\xea\x56\x1d\x5b\x29\x6d\x10\x53\x4d\x07\xd8\x46\xc4\x12\xa8\x63\x6b\x39\x18\xb8\x02\xae\x03\xea\x70\x6a\x50\x6c\xeb\xf1\x17\x2e\x69\x6c\x40\x8b\xbb\x18\x1f\xd0\x01\x96\x52\x6d\x1e\x06\xfb\x04\x11\x13\xad\x94\xf8\x16\x75\x7c\x97\x25\xef\xa2\x8e\x3b\xc2\x00\xbb\xa0\x94\x75\xbb\x8b\xe0\x0c\x57\xaa\xb6\x76\x90\xcf\x2f\x6f\xae\xfe\x3e\x7a\x7f\x71\x79\x13\xce\x73\x38\xcf\xe1\x3c\xb7\x38\xcf\xc0\xe7\xad\xcf\x72\xa1\xda\xad\xd3\x76\x97\xea\xe6\x55\x92\xc5\x5f\x50\xdc\xd9\x39\x9f\x7f\xa0\x46\xb8\xcc\x24\x28\x94\x45\x8c\x8c\xba\xce\x41\xec\x6e\xb0\x8d\xc4\x4e\x9f\x7d\xe0\xd9\x13\x86\x8d\x75\x18\x8e\x73\x59\xa9\x71\xb0\x6e\xd7\xaa\x9d\xfb\x4e\x7f\xbd\x38\x3b\xbf\xbc\xb9\xf8\xe6\xe2\xfc\xea\x49\xe3\x28\x5a\xd6\xad\xab\x73\xe3\x86\x5c\x32\x93\x30\x67\x22\x57\xc9\xa2\x28\x7d\xbb\x9e\x08\xac\x86\xe2\x71\xa3\x0a\x2e\x8a\xea\xbe\x6b\x1f\x0b\xcc\xb6\x5b\x66\x5b\x0f\x2b\x69\x51\xb2\xa4\x2b\xf4\xfd\x46\x8a\xb4\x23\x14\xbe\xb6\xe6\x01\x6f\xcd\x5f\x87\x4f\x3d\x57\xdd\xa0\xc6\x7a\x9c\xf0\x58\x96\x52\x30\x52\x68\x9a\xe9\x16\x7d\x0d\x3a\xa9\x54\xda\x4d\x51\x4f\x1b\x82\xf1\x8e\x66\xdf\xc3\xe2\x0a\x5a\x56\x46\x59\xf2\xa2\x24\x10\x19\x46\x47\x6e\x61\x61\x9d\xab\xa7\xfe\x65\x6d\x2a\xb8\xec\x65\xa1\xd7\x5b\x68\x53\x84\xb7\xcb\x0a\xad\xb7\xd0\x22\x26\xd3\x8f\x95\x5a\xa5\x66\x0b\x51\x4e\x33\x7b\xda\x6e\xf7\x48\xb7\xd5\x59\x3f\x42\x45\xda\x5e\x95\xdd\x3b\x3a\xab\x77\x2e\x1c\x21\xe6\x86\x73\xc1\xdd\xb1\x8b\x47\x1b\x18\x8d\x75\x60\xb1\x56\x1d\x63\xd0\xcd\xf1\x17\xf8\x1f\x72\xf3\xfe\xec\xfd\x1b\x72\x12\xc7\x2e\x2e\x3a\x57\x30\xc9\x13\x6b\xa5\x57\x43\x42\x33\xf6\x01\xa4\xc2\xc6\x70\xb7\x8c\xc7\x7d\x92\xb3\xf8\xeb\x36\xf5\xa4\xec\xe8\x70\x17\x84\xf7\x45\x75\xbb\x13\xd7\xce\xd5\x58\xe5\x5d\x05\x11\x21\x36\xe9\x11\x71\xd3\x97\x96\x71\x42\x46\x47\xa0\x69\xdb\x03\x8f\xd8\x2d\xec\x96\xae\xf6\x4a\xc2\x6a\xdd\x38\x45\xed\xad\xf8\x0d\x51\x39\xd6\xc0\x51\x45\xe3\x3a\x6c\x05\xdb\xaf\xff\xa9\x32\x1a\x41\x9f\xfc\xa3\xf8\x11\x5b\xcd\xab\x9f\x7a\xbd\xbf\x7d\x7f\xfe\xf7\xff\xea\xf5\x7e\xf9\x47\xf5\x2a\xb2\x42\xd4\x9a\x97\x6e\x41\xd7\x15\x17\x31\x5c\xe2\x3b\xf0\x4f\x27\xae\x9d\x44\x91\xc8\xb9\x76\x17\x30\x61\x79\x38\x13\x4a\x5f\x8c\x8a\x3f\x33\x11\x2f\xff\xa5\x5a\x15\x49\xdb\x4b\xc6\x80\x5b\xd4\x22\xf1\xc6\x8e\xee\xd8\x43\x49\x4b\x3a\x3e\xaa\x6e\xd6\xa2\x29\x47\x34\x83\xd4\x96\x69\xfa\xc6\x83\x00\x9b\xeb\xfa\xca\x08\x1c\xd3\xc9\x8d\x64\x5a\xaf\x98\x77\x30\x7f\xdd\xaa\x0b\xb9\x1d\x1d\x92\xb6\x62\x07\x3b\x06\x18\x42\xc4\x41\xcb\x1e\xe4\x82\xc1\x7a\x2d\xa5\x74\x34\x9f\x8c\x2e\xc8\xdc\x42\x78\x6f\x80\xe3\x3d\x6e\xdf\x7c\x54\x1a\x57\xf5\xeb\xd5\x34\xc4\x37\xb6\x17\xad\xbf\xee\x4a\x08\xa8\xa2\xaa\x17\x18\xc5\xe6\xd0\xfe\x38\x8c\xb2\xbc\xef\x6e\x18\xa6\x90\x0a\xb9\x28\xfe\x2c\xfc\x89\x03\xa5\x85\xa4\x53\x4c\x39\xb1\x8f\xdb\xc7\x8a\xbf\xec\x83\xb5\x17\xac\x3e\x6d\x55\xe1\x28\x97\x46\x68\x48\x16\x9e\x22\x37\x2c\x85\x51\x8e\x3d\xa4\x6d\x1e\xf4\x7b\x42\xda\x0a\xcc\x68\xdb\x71\xd6\x8e\x3a\x42\x96\x41\x01\x28\x70\x16\x50\x44\x7d\xd2\xa5\xd4\xf6\x0b\x31\xc8\x5a\x03\xf8\xdc\x68\x96\x8d\x8b\x82\x95\xa3\x43\x6a\x16\xb3\x39\x53\xa2\x45\x62\x4d\x31\xd1\xe6\x6c\x01\x57\xd5\xc3\xc6\x44\x15\x66\xb3\xfb\x0c\xeb\x20\x15\xe7\x75\x89\xec\xbf\x6e\xd3\x0a\xc9\x8e\x8c\x6a\x0d\x92\xbf\x21\xff\x73\xf8\xf3\x57\xbf\x0d\x8e\xbe\x3e\x3c\xfc\xe9\xd5\xe0\xaf\xbf\x7c\x75\xf8\xf3\x10\xff\xf1\xfb\xa3\xaf\x8f\x7e\xf3\x7f\x7c\x75\x74\x74\x78\xf8\xd3\xf7\xef\xbe\xbd\x19\x9d\xff\xc2\x8e\x7e\xfb\x89\xe7\xe9\xad\xfd\xeb\xb7\xc3\x9f\xe0\xfc\x97\x2d\x27\x39\x3a\xfa\xfa\xcb\xd6\x4b\xef\xa0\x2c\xa9\x1d\x5d\x16\x27\xad\xcf\xd8\x09\xfa\x7d\xc4\x8a\xfc\x76\x78\xf4\xea\xfa\xfc\xfb\xc0\xe8\x37\x25\x43\x2a\xd8\xf5\xde\x1c\x70\x05\x91\x04\xfd\x29\x2c\x39\xf6\x4d\x95\xe2\x08\x3d\x45\x0a\xd5\xe2\xa5\xf1\xb9\xcf\xc1\xb8\x53\xf4\xd2\xc3\x7d\x2d\x25\xd1\x89\x14\xa9\x4f\x78\x47\xf7\x06\x36\xd8\xf7\xf7\xdd\x42\xab\xee\xae\x76\x04\x63\x50\x30\x06\x6d\x18\x8f\x1a\x83\xae\x2d\x1e\xee\xad\x25\x08\xf8\xbc\xa9\x0b\x63\xad\x07\xdd\xeb\x3a\xd5\xea\x70\xdb\x39\xd4\x86\xfe\xa8\x97\x4d\x28\xcb\x10\x1a\xcb\xd0\xd2\xf5\x3e\x4c\x72\x82\xcd\xa6\xed\xc1\xc7\x09\xca\x8c\x12\xab\xda\xb8\xe2\x85\x30\x37\x4b\x28\xaa\x5f\xd7\xea\x5c\x62\x50\x25\x86\xb9\xfe\x68\xa3\x4e\x6f\x6d\x20\xaa\x51\xd2\x18\x2f\x2b\x84\x16\xc2\x61\x59\x56\x9a\x2a\x25\x22\x1b\x40\x5b\xe4\x37\x60\xd1\x3a\xb7\x6c\x5c\x0d\x76\xb8\xcf\x24\x44\x10\x03\x8f\xc0\x95\x9c\xae\x35\xdc\xa4\x9c\x9c\xf3\xb9\x2f\xbb\x1d\xfb\x6c\x19\x5c\xc9\xfa\x39\x5e\x56\x00\x82\x41\x44\xe7\x04\xab\xc4\x21\x20\xd5\x2f\x23\x67\x31\x14\x43\x4c\x4a\x2b\x6b\xb3\x9e\x7c\xad\xb9\x78\x7b\x9e\x59\x78\xb6\x5a\x09\x43\x2b\xcc\xb2\x34\x3f\xd7\x99\xe4\x4b\x70\x06\xb6\x67\x9f\x9f\x1d\xeb\xec\x88\x6d\x76\xc3\x32\x77\xf0\x9d\x74\xc9\x26\xbb\x70\x96\x64\x12\x26\xec\xbe\xa3\x73\x7a\xc2\x4b\x4b\x0c\x8b\x81\x6b\x36\x61\x36\x7b\x26\x93\x90\x01\xb7\x19\x09\x34\x9a\x21\xed\x77\x9c\xb2\x74\x4e\xef\x63\x30\x8f\x15\xb8\xbb\x25\x65\xd7\xeb\x84\xfd\x40\xc7\x48\xa0\x63\x8d\xc7\x27\xa2\x63\x0e\x73\xf7\x87\x88\x61\xe4\x79\xfb\x98\xf7\xd3\x7a\x19\x19\x44\xe4\x9d\x11\xad\x4c\x71\x3a\xc6\x59\x1a\x19\xa0\x5b\xe1\x03\xbe\x76\x94\x27\x49\x47\xa5\xb7\x7b\x17\x08\x8d\x2c\x4f\x12\x97\x71\x3c\x24\xef\x39\x1e\xc9\x13\x6c\xf1\xd0\x27\x97\x30\x07\xd9\x27\x17\x93\x4b\xa1\x47\x56\xb6\xad\x87\xb3\xd9\x1b\x09\x9b\x90\x37\x46\x6b\x52\x9a\x68\x5b\x66\xbf\x52\x14\x48\xc8\xda\x04\x65\xbd\xb1\x16\x61\xe8\x9b\xb7\xe5\x0b\x9f\x0b\x3a\x78\xa2\x6d\x2a\xfa\x98\x74\xa0\x9e\xba\x99\x7c\x80\x1c\x06\x45\x3a\xef\xc8\xba\x84\xde\x67\x58\x63\x23\x13\x4a\x5f\x1b\x2d\xb6\x9b\x1e\x37\x23\x3f\x1d\xb6\x8d\xa0\x49\x02\x71\xad\xc9\x91\x6d\xce\x41\xeb\x5a\x34\xa6\x1a\x17\xbd\x22\x80\xcc\x28\x8f\x13\x90\x58\xef\x5d\x2d\x17\xb5\x62\x65\x83\x83\xa2\x25\x85\x4f\x06\xa5\x51\x24\x64\xec\x9a\xcb\xba\xa4\x4c\x5c\x4c\x71\xbc\x90\xd6\xa6\x94\xd3\x29\xa0\x65\x61\xa5\x6a\x30\xd6\x92\x56\x95\xbe\x16\x33\x21\x6e\x49\x24\xd2\x2c\xc1\x03\xd0\xe2\x7c\x94\x6d\x75\x0a\x14\x1d\x98\xd9\xd5\x71\xa5\xe3\x0e\xfe\xd0\xae\xe1\x4e\x2b\x61\xa5\x0b\x51\x05\xee\x21\xea\xac\x25\xdf\xf9\x3d\x44\x95\x9e\x92\x66\x4b\x5c\x53\x49\x2d\xd0\xb6\xd1\xbe\x55\x70\x6b\xb3\x7c\x57\xa6\xf0\x16\x59\x66\xd5\xb1\x54\x43\x0e\xe7\xf4\x25\xb3\xdd\x2b\xb0\xfb\x80\xcd\x60\xc6\xcc\x33\x5f\x45\xbb\x76\x18\xec\xd1\x5b\x29\x3c\x57\x04\x1b\xfb\xb9\x30\xcf\x5a\x08\x4d\x0e\x7b\xc7\xbd\xa3\x15\x1b\xdd\x52\xdd\xe5\x9b\xca\x93\x0c\x0b\x0d\x66\x58\xb5\x0f\xa2\x5e\xdc\x27\x4c\x7b\x62\x6b\xeb\x1d\xe0\xaa\x5c\x3a\x5c\x9f\x28\x41\xb4\xa4\x31\x73\x5a\x10\xfe\x6a\x6e\xd2\x32\x77\xc5\x0e\x0e\x7b\xbf\xf5\xfa\x04\x74\x74\x44\xee\x04\xef\x69\x5c\x3e\x56\x06\xc9\x55\x65\xa2\x85\xc8\xb1\x01\x9f\x05\x41\x51\xe6\xc3\x50\x2c\x22\x72\xdb\xad\x67\x46\xb5\x4f\xc3\x3b\xbf\x67\xda\x77\xa8\x10\x13\xf2\xca\x36\x0b\x02\xea\xac\x84\x09\x9b\xc3\xf1\x0c\x68\xa2\x67\x36\x90\x82\x0b\x3e\xb0\xfd\xde\x0c\x29\x71\x57\xda\xfa\x14\xda\x99\xdc\xaa\xa3\x85\xf9\x6d\x75\x41\x2d\xa5\x6b\x43\x44\xbf\x6d\xde\x84\x96\xac\xf4\x67\xbe\xb9\x19\x7d\x5b\x6b\x43\x8b\x54\x5c\xeb\xcc\x87\xb7\x54\x4a\x66\xec\x01\xed\xe8\xc6\xa1\xd7\xaa\x1f\x2d\xe9\x90\x84\xb5\xed\x4b\x4b\x56\xfb\x6d\xef\xd6\x90\x96\xfc\x5d\xe4\xd8\x48\x8f\x8e\x93\x05\xb9\xa3\x5c\xfb\x54\xbc\x03\x33\xd5\x81\x21\x4f\x06\x1b\xbe\x03\x1a\x83\x54\x48\x3d\x80\x36\x2e\x0d\xe6\x47\x67\x8e\xa6\xca\xda\xba\xe5\x03\xb9\xd2\x22\x25\x33\xf7\xd9\xf5\xf4\x44\x77\x32\x86\x78\x7a\x7c\xee\x8f\x84\xcc\x52\x38\xf7\xcc\x8b\xa3\x5f\x2b\x74\xc3\xc2\xbd\x56\x42\x3f\xaa\x82\xad\xda\x68\x85\x71\x0b\x2c\xdb\x22\xb1\x23\x5a\xda\x41\x80\x00\xe9\x30\x48\x80\xb4\x4b\x76\x5c\x9e\x08\x1d\x5f\xed\xe3\xa1\x3a\x8b\x3b\x20\x9d\xf9\xd6\xc9\x3a\x43\xa4\xc3\x19\x1b\x05\xdb\x11\x10\x3b\xf5\x68\x93\xf6\xe9\x94\xd5\xf1\x30\x00\xba\xd9\x7c\xd2\x25\x04\xb2\x0e\xc2\x9f\x57\x83\x9f\x57\x1a\x85\x23\x99\xb0\xa5\x68\xf7\x86\xcb\xb4\xed\x9a\x4e\xd6\xe7\x12\x4b\xc2\x8b\x26\xb7\xfa\x59\x74\x4e\x27\xdd\x85\x29\x76\x1d\xa4\xd8\x69\x88\xe2\x47\x0d\x50\xc4\xb4\x88\xd6\x54\xa4\x6e\x1f\xc7\x29\x0d\x06\x18\xbd\xcd\x68\x9c\x4e\xf6\x73\xd6\x1d\xdf\x88\xa3\x6e\x0e\x35\x47\x6d\x2f\xce\x98\x8e\xb2\x6b\x11\xdd\x76\xa8\xd7\x9c\x41\x26\x21\xb2\x76\xb2\x9b\xd3\x91\x9d\xdd\xe8\x97\x97\xef\x6f\xca\x70\x7c\x8c\x59\x29\x0d\x97\xdf\x39\x4b\x9a\xd1\x49\x6f\x21\xd3\x85\xea\x3e\xa6\xd1\xed\x1d\x95\x31\x5a\xb6\xa8\x66\x63\x96\x30\xbd\x40\xe5\x5c\x02\xc6\xfa\x73\x61\x83\xe2\x6c\xfd\x47\xe1\xbb\xb8\x16\x2d\xc6\x0b\x1b\x16\x5a\xc8\x5c\xf4\xcc\x84\x32\xa3\x8f\x17\xad\x7a\x6d\xd4\x4c\x94\x15\x26\xbd\xaa\x65\x3a\x28\x5f\x7e\xec\xad\xf2\x55\x69\x43\xbb\xab\x1e\xd6\x36\x76\x6f\x8f\x59\x9d\x63\x71\xb2\xe8\xb2\x16\x58\x5d\x47\xf3\xed\x2f\xab\xcb\x24\x5c\x6b\x91\x75\xe4\x25\xb1\x93\x6d\xf0\x91\x8c\x61\x22\x0c\x11\xde\xe8\xf4\x88\x73\x70\xa5\x39\x4f\x46\x17\x85\x55\x4b\xd4\x1c\x1b\x36\x6a\xd1\xd7\xe3\x4c\xd8\x1c\x38\x28\x75\x8c\xee\x90\x3c\xb3\x5a\xab\x6f\xa8\xdb\x37\x5f\x07\x29\xae\xae\x5f\x66\x02\xb8\x76\xbe\xf8\x23\xe8\xc8\x5a\x6e\x2b\x84\x1c\x3b\x85\xb9\xe5\x2f\xbb\x51\x22\x49\xd5\xcc\xb6\xba\x85\x7b\xa6\x5d\xbb\xe6\x91\x2d\x0f\x5c\xed\xb8\x3b\x95\x34\x02\x92\x81\x64\xc2\x30\xa3\x9c\xeb\x58\xdc\x71\x32\x86\x29\xe3\xca\x83\x02\x2b\x6e\x3a\x98\xa1\x3f\x86\xa9\xa2\x64\xda\x90\x5c\xd5\x0a\x82\xb8\x54\x9d\x48\x94\x47\xd3\xad\x79\xd9\x93\x84\x1c\x0b\xe1\x64\x1b\xc7\x14\x10\xae\xf6\xd2\x79\x6c\xc9\x87\x39\xc7\x37\xc7\x90\xd0\x85\x8d\xc8\xc4\x36\xd8\xec\xdf\x20\xd5\x51\x07\x1e\x27\xdb\x0d\xca\x5f\xdb\xb8\x0e\x2c\x75\x4a\xa3\x59\x3b\x17\x6e\x70\x51\x6d\x39\x82\x8b\xaa\xcd\x24\xc1\x45\x15\x5c\x54\x8f\x8c\xe0\xa2\x0a\x2e\xaa\xa5\xb1\xb7\x5a\x52\x70\x51\x35\x1e\xc1\x45\xf5\xf0\x08\x2e\xaa\x2d\x46\x70\x51\x6d\x39\x82\x8b\x2a\xb8\xa8\x82\x8b\x2a\xb8\xa8\x3e\x23\xbb\x9d\x1f\xc1\x45\xb5\x32\x49\x70\x51\x05\x17\xd5\xd6\x63\x6f\x95\xaf\xe0\xa2\xb2\x23\xb8\xa8\xea\xe3\xf3\x62\x75\xde\xc1\x33\x32\xaa\x5e\xfb\x1e\xc3\xa8\x30\x3a\x1a\xfb\x22\xd3\x9e\xda\xd8\xff\x3f\x8d\xed\x7f\x4f\x1c\x25\x1d\xd8\xfb\x83\xad\xff\xc5\xd9\xfa\xbb\xb1\x93\x75\x60\x23\x6b\x4d\x93\x9d\x0b\xfc\x66\x26\x41\xcd\x44\xd2\x18\xd1\x6b\x48\xfe\x8e\x71\x96\xe6\xa9\xc1\x39\x65\xf0\x99\xcd\x0b\x5f\xbb\x2a\x1b\x2f\xa3\x0b\xde\x9a\xeb\xcc\x8d\x2c\x06\xac\xbc\x49\x59\x62\xb6\x11\x13\x25\x67\x74\x6e\x70\x5d\xe5\x51\x04\x80\x7d\xbd\xaa\xaa\xc4\x1f\x87\xc5\x9b\x8a\x3e\x0e\xaf\xdb\xd1\x9b\x76\xdc\xd2\xd6\xc6\xc4\x59\xfe\xf8\x87\x46\x73\x4c\x65\xd6\x0d\x5d\xfe\xf6\x6a\x74\x5a\xa1\xcb\x94\x7b\xb2\xcc\xf8\x5c\x24\x73\xdb\xd8\x16\x6f\x32\x52\xd1\x70\xa5\x25\x66\xa1\x44\x38\xf9\x5b\xd9\x0e\xcc\xe6\x39\xf3\x54\x91\xd2\x3e\xb2\x81\x14\x8d\xbb\xc3\x96\xa3\x03\x82\xdf\x5e\x57\x68\xa5\x27\x74\xc1\x6f\xda\x8a\xc2\x75\x39\xc6\x08\xbc\x75\x73\xcf\x14\xf1\xc2\x96\x73\xdf\x5a\xe0\x6d\x4d\x29\xdb\x0b\xa1\xed\x8f\x16\xc1\x7a\x2b\xf8\xe1\x9d\x01\xf8\xc0\xb5\x10\xf7\xec\xbc\xaa\x6d\xf8\x16\x47\x5a\x90\x2c\xa1\x65\x93\x22\xdc\x81\xef\x90\x07\x9d\xce\x20\xba\xbd\x72\x2e\xcf\x43\x05\x50\xc4\xab\x4c\x99\x9e\xe5\xe3\x61\x24\xd2\x63\x43\x12\xec\xff\x8d\x13\x31\x3e\x4e\xa9\xd2\x20\x8f\x63\x11\x39\x16\x37\x88\xcc\x2c\x8c\x4f\x87\x69\x7c\x84\xed\x6d\x2f\xea\x4d\x11\x2b\xa5\x10\xcc\xfb\x9d\x32\x48\xc6\x60\xa8\xab\x40\x85\xbf\x52\x4f\xcd\x2c\x6f\xe7\xc6\xb5\xd5\xd1\x9a\x25\xb5\x74\x37\x7f\x7a\x57\x73\xa0\x5c\xa4\x03\xcb\xc6\x73\x73\x29\x77\x16\x5a\xd1\x81\x2b\x79\x8f\xdc\xc8\x7b\x23\x1a\xef\x8b\xeb\x78\x0f\x4b\x1f\x77\xe0\xe9\xec\xc2\x55\xdc\x9d\x9b\xf8\x23\x54\x08\xfe\x38\xee\xe1\x0e\x6d\x68\x1d\xb9\x85\x3f\x85\x4b\xb8\x93\xaf\x6e\xeb\x0a\xfe\x74\x6e\xe0\x6e\x3e\xb7\x4b\x45\xe0\xb9\xba\x7e\x3b\xb0\x85\x77\x69\x07\xef\xcc\x06\xfe\xd1\x5c\xbd\xed\xdd\xbc\x7b\xe0\xe2\x6d\x0d\x64\xc6\x99\x66\x34\x39\x83\x84\x2e\xae\x21\x12\x3c\x6e\xcc\x61\x96\x4a\x46\x16\xe7\x47\xd9\x69\x9d\x9d\xaa\x9e\xd1\x30\xa3\xae\x32\xb6\xd1\xa8\x6c\x06\x87\xf7\x4f\x38\x81\x02\x5d\x0b\x76\x95\x4d\x8a\xce\xdd\x09\x79\x9b\x08\x1a\xab\xe3\x4c\xd8\xff\x2b\xf3\x15\x2a\x89\x0a\xf6\x5d\xed\x32\x15\x9e\xda\x20\x66\xd3\x3b\xba\xdc\xc4\xef\xc4\x1d\x11\x13\x0d\x9c\x1c\x32\xee\xf7\xf1\xa8\xa2\x06\x96\xd6\xc9\x02\xad\xcd\xd5\xd7\xaf\xfc\xcd\x2f\xcf\xec\x88\x06\x56\xa5\x3e\xbe\x15\xd8\xbd\xe8\x71\x33\xb0\xbb\x71\x92\x27\x75\x53\xb0\x35\x0f\xd7\xe9\xcd\xeb\xb2\xb6\xef\x6b\x9c\xb7\x38\x6d\x94\xc7\xc4\xa5\x7c\xbd\xbc\x4d\x6b\x1d\xc0\x52\x17\xfd\x8a\x80\x95\xc7\xac\xc6\x37\xa7\x23\x6b\x34\x0e\xe6\x92\x7d\x31\x97\x3c\x51\x10\xc8\x1e\x0a\xba\xcf\x34\xf0\x23\x08\xba\x3b\x8c\x4a\x12\xe8\xb7\x92\x46\x30\xea\x5c\x46\xf0\xc7\x89\xc4\xb9\xa4\x8e\x00\x16\x22\x9f\x3f\x3c\x1c\x20\xb6\xa7\xa9\x48\x9c\xc5\x94\xd4\x49\x9e\x24\x0b\x92\x67\x82\xd7\xd3\x8c\xad\xaf\x7d\x39\x6b\x15\x4d\xf2\x6b\xde\x52\x0a\x96\x99\x14\x8e\x67\xca\x9c\x73\x43\x83\xcb\x06\x5d\x28\x48\x62\x55\x63\x5a\xcb\x8d\x55\x6c\x6a\x96\x6f\xf8\x1f\xa6\xcd\x96\x91\x7e\xb5\x09\xcd\xd3\x13\x21\x23\x36\x4e\x16\x64\x46\x93\xa2\x1b\x0b\x25\xb7\x2c\x49\xdc\x34\x43\x72\x0d\xda\xba\x14\x2c\xef\x4c\x04\x9f\xe2\xe2\x28\xf7\x5d\x00\x21\x32\xcf\x46\x09\x50\x9e\x67\xf6\x7d\x86\x13\x2f\x44\x2e\xfd\xfb\x86\x85\x63\xa2\xec\xba\xcf\x92\x7e\xa5\xd7\xd8\x83\x1b\x5b\xf4\xa7\xc9\x95\x11\x00\xde\xfb\x2a\xce\xfd\xea\x9c\x62\x0e\x52\xb2\xd8\xd9\xf9\xed\x6f\x99\x14\x73\x16\x5b\xef\x86\x07\x1b\x76\x35\xb6\xdd\x64\x8a\xf3\xcc\x05\x1f\x70\x98\x52\x14\x54\xdc\x29\xb2\x7b\x66\xe7\xb1\x11\x04\x3c\xc6\xfe\x32\x46\xc2\x17\x59\x2d\x6f\x7d\xce\x6c\x67\xdc\x0a\xe4\xc8\x21\x17\x44\x60\xe0\x67\xce\x99\xb6\xdd\xd6\x67\xb9\x26\xb1\xb8\xe3\x47\x3b\x79\x5d\xd1\xd1\x7a\xb3\x16\x40\x75\xf7\xeb\x3a\x39\xc7\x7e\xef\xc3\xe0\x65\xca\x99\x3e\x27\x24\xe7\x0a\x5a\xb2\xf7\xce\x84\xa3\x3f\xff\xa9\x19\x8d\x60\x29\x88\x5c\x7f\x12\xed\xef\x6e\xc6\xa2\x59\x55\x98\x65\x29\x28\x22\xf2\x25\xb5\xf8\xb5\x7b\x6c\xfd\x0e\x05\x15\x70\xdd\x68\x6a\xd8\x5d\x63\xfd\x72\x0d\x4b\x57\xe3\xf7\x2a\x0d\x99\x31\x34\xfb\xec\xf2\xfa\xd7\xb7\x27\xff\x7d\xfe\xd6\x9d\x4f\x5e\x65\xfa\x39\x67\xff\xca\x81\xd0\x54\x18\x59\x38\xa9\x86\x01\xf6\x51\xa3\xaf\xfc\x80\x27\xb9\xdb\x80\xc1\x86\x0c\x19\xbb\xc7\xb7\x0f\x8b\xc4\x1e\xf4\x1f\x3f\x2a\xf2\xa9\xbb\x6a\x95\xc1\x2d\x46\x6e\xac\x74\xd5\xa2\x84\x83\x36\x27\xcf\x4a\x94\xb6\xcb\x1a\xe3\xd3\xa4\x2a\x4c\x36\x23\x57\x6d\x75\xa2\xb6\x1a\xd1\xa0\xfc\x82\x51\x53\xc5\xa8\x93\xee\x5e\xe5\x1a\x3a\xea\x89\x53\x52\x6d\xaf\x06\xd8\xa6\xc5\x5e\x0d\xb0\xa2\xc7\xc5\x88\xd0\x38\x96\x28\xa6\xe0\xa9\x4f\x97\x7a\x63\x66\x65\x2c\x4d\x9f\xbc\x22\x7f\x23\xf7\xe4\x6f\xa8\x16\xfc\xb9\x6d\x07\xa1\xb6\x02\x7b\x17\xa1\x31\x46\x1b\xbd\x18\x75\x04\xf1\x1f\x67\x54\xe3\x8c\x06\xaa\x5a\x90\x31\x73\x62\x28\xdc\x6b\x90\x46\x2c\x72\x3b\xf1\xa4\xbd\x97\xcc\x02\x3f\x21\x9a\x59\x33\xf9\xc5\xa4\x1e\x8e\xb3\x1b\xa2\x99\xc7\x8d\x7e\x7f\xe9\xa8\x50\xbd\xcf\x49\x39\x5b\x4a\x75\x34\xab\x93\x31\x23\x60\xa8\x1a\x73\x8a\x05\x92\x71\x1b\x76\x3b\x63\x2d\x9c\xfe\xfb\x83\xc6\xed\xfc\xc0\xb5\xfd\x7c\x68\xa7\x96\x14\x7f\xe4\xf3\x4e\x30\xa8\x94\x4e\xca\x44\x3c\x24\xe7\x34\x9a\xe1\xb2\xe2\x0a\xcf\x30\x1a\x08\x4e\x36\xa3\x73\xb3\xf1\xee\x59\xdb\x17\x08\xa5\x95\xc2\x3a\x8a\xb8\x64\xce\x53\x44\xb9\x6d\xce\x39\x01\x29\x6d\xa4\xf4\x78\xe1\x83\xcc\x5a\x6f\x5e\xab\x93\x94\x49\xa1\x45\x24\x5a\xb4\x87\x5a\xce\xbe\xc0\xe9\x10\x08\x36\x3a\xd5\x9b\x77\x7f\x38\x1b\xf5\xc9\xcd\xe9\x08\x9b\xfa\x5c\x9f\xde\x8c\xea\x12\xf6\xc1\xcd\xe9\xe8\xe0\x49\x41\x41\xbc\x99\x0d\x0d\xaa\x0d\x26\xa9\x19\x4c\x12\xa6\xf4\x20\xa5\xd9\xe0\x16\x16\x0d\x79\x6a\x17\x7c\x7d\x50\xec\x70\x27\x1f\x64\xc1\x9c\xd2\x6c\xe7\xd9\x24\xd0\x98\x85\x34\x9f\xed\x47\x48\xf3\xd9\x72\x84\x34\x9f\x90\xe6\xb3\x3a\xf6\x26\x96\x31\xa4\xf9\xbc\x2c\xd7\x6d\x48\xf3\xf9\xcc\xbd\xbf\x21\xcd\x67\xfd\x08\x69\x3e\x21\xcd\x67\xbb\x11\xd2\x7c\x76\x1f\x7b\x17\xb7\x12\xd2\x7c\x76\x1a\x21\xcd\x67\x75\x84\x34\x9f\x0d\x23\xa4\xf9\x6c\x18\x21\xcd\x27\xa4\xf9\x84\x34\x9f\x10\xfd\xf8\xe8\x5c\xfb\x19\xfd\x48\x42\x9a\x8f\x1b\x21\xcd\xe7\x45\xc4\x78\x91\x90\xe6\xb3\xd5\x08\x69\x3e\x21\xcd\xa7\xc9\x08\x69\x3e\x2f\xc5\x5c\x12\xd2\x7c\x42\x9a\xcf\xe7\x23\xe8\x86\x34\x9f\x90\xe6\x13\xd2\x7c\x42\x9a\xcf\x83\xab\x08\x69\x3e\x2f\x41\x05\xf4\x3d\x57\xdb\xe7\xa8\x5c\xf9\x99\xb6\x0f\xeb\x23\xe7\x6b\x7e\x45\x4b\x88\xca\xcc\x24\xb2\x9c\x32\x91\x40\xe3\x05\x4e\x89\x7d\x1e\x2a\x42\xd6\x33\x8c\x0e\x4c\x58\xca\x9a\xa5\x05\x91\x95\x43\xf3\x16\xe7\xaa\x78\x5d\x0c\x58\x52\x7a\x8f\x07\x80\xa6\x22\xb7\xad\x5f\x23\x91\x66\xb9\xae\xc3\x14\xb7\xa7\x49\xd7\xd6\x09\x9b\x3a\x8e\x7a\x6c\x1b\xcc\x0e\x8a\x69\x07\x95\xa6\xae\x4f\xd8\xaa\x95\xc6\x3e\x6a\x6e\xd4\x45\xd0\x08\xd5\x1a\x24\x7f\x43\xfe\xe7\xf0\xe7\xaf\x7e\x1b\x1c\x7d\x7d\x78\xf8\xd3\xab\xc1\x5f\x7f\xf9\xea\xf0\xe7\x21\xfe\xe3\xf7\x47\x5f\x1f\xfd\xe6\xff\xf8\xea\xe8\xe8\xf0\xf0\xa7\xef\xdf\x7d\x7b\x33\x3a\xff\x85\x1d\xfd\xf6\x13\xcf\xd3\x5b\xfb\xd7\x6f\x87\x3f\xc1\xf9\x2f\x5b\x4e\x72\x74\xf4\xf5\x97\x8d\x97\xdc\x5a\xe0\xed\x4e\xdc\xed\x48\xd8\xfd\x28\xa2\xae\x73\xd7\x76\x74\x16\x5d\xa8\xc9\xca\x69\x74\xec\xe8\xa1\xd3\xe8\x35\x6e\x14\xe2\x8a\x79\x98\x22\x22\x65\x5a\x3b\x2a\x4a\xab\xc1\xaa\x4c\xd7\x54\x4e\x47\x07\xb0\x21\x36\xd5\xb6\x51\x75\x11\xe8\x59\x09\x51\x11\x5e\xae\x73\x9d\xbc\x59\x9a\x25\xd8\x20\x1a\xcf\xf3\xc0\x47\xaa\x20\xeb\x0c\xb4\xe1\xf1\x11\x68\xc3\x4b\xa4\x0d\x0a\xa2\x5c\x32\xbd\x38\x15\x5c\xc3\x7d\x23\xfb\xc9\x26\x03\xd2\x75\x7d\x6a\x17\x1b\xa6\x5c\x4c\x9b\xbd\x46\x44\x66\xe3\xbb\x37\x66\x4e\xcf\x44\x9e\xc4\x98\x97\x94\x73\x54\x29\x6d\x8a\x1b\x68\xab\xef\xa1\xa6\x83\xc1\xdb\xcb\xaf\xf3\x1a\x9c\x9d\xfa\x5f\x39\x9b\xd3\xc4\xe8\xb7\xe5\x13\x23\xd4\x59\xaa\x0f\x35\x32\x62\x3d\xb1\x8c\x85\xe2\xcd\x48\xb2\x39\x4b\x60\x0a\xe7\x2a\xa2\x09\x52\xa5\x6e\x28\xfd\xc9\x86\xd9\x71\x8b\xa4\x48\x14\xb9\x9b\x01\x76\xe0\xa7\x5e\x3d\xc7\x44\xb2\x29\x65\x9c\xa4\x86\xa8\x66\xfe\x61\x65\xf5\x7c\x43\xbc\x8d\xd4\xcb\x75\xa9\xcf\xa3\xfa\x3a\x16\x22\x71\xd9\x08\xc9\xa2\x9c\x9f\x59\xd3\x1b\x17\xbf\x72\xb8\xfb\xd5\xcc\xa6\xc8\x24\xa1\xd3\x42\x8d\x57\xa0\x57\x2c\x71\xe5\xd4\x1b\x3f\x00\x43\xfd\x73\x20\x34\xb9\xa3\x0b\x55\x1a\x35\xca\x39\x98\x7a\x43\x5e\x1f\x21\xe2\x51\x45\x8a\x39\x62\xf2\x87\x23\x74\xcd\x9d\x9e\x8c\x7e\xbd\xfe\xfb\xf5\xaf\x27\x67\xef\x2e\x2e\xc9\xa5\xd0\x60\x59\x52\xa5\x49\x5a\x44\xb9\xd1\x10\xdc\x2a\xf1\x1d\xa8\x41\x0b\x35\x44\xbb\x22\x53\xe4\x8e\xf1\x58\xdc\xa9\xc6\xf6\x53\x8b\x7e\x06\x78\x40\x79\xa3\x39\x22\x9a\x51\xec\xfd\xd6\x82\x3f\xac\x44\x7f\x54\x27\x45\x0e\x1c\xc7\xc7\xb1\x14\x99\x05\x82\x37\x40\x55\x95\xa4\xb3\x25\xbb\xb2\x8f\x2f\xc5\xfd\x9d\xd4\x27\x9c\x4a\xca\x75\x69\x89\x29\xf7\xcc\x35\x9d\x1b\xb6\xde\x8e\xe7\x9d\x6d\x44\xe3\xee\x32\x8d\x4e\xe2\x18\xe2\x1a\xf8\x5f\x5c\x54\xdf\xa9\xff\xb8\x45\x59\x8c\x81\x8c\xde\x5f\x5f\xfc\xef\x25\x3c\x5e\x64\xed\x82\x98\xba\x49\x00\x95\x22\xeb\x6c\x77\xaf\x20\x15\xf3\xb0\xbf\xfb\xb2\xbf\x05\xb7\xec\xc6\x75\x7e\x95\xf3\x2a\x43\xe3\x95\xf9\x49\x2a\x62\x18\x92\x51\x61\xc3\xaf\x5f\xad\x16\x99\x91\x40\xcc\x2d\x5c\x33\x9a\x24\x8b\xaa\x30\xa5\x85\xcd\x10\xac\x95\x20\xa8\x12\xf2\x09\x4d\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x36\xdb\xc9\x76\x14\xb3\x91\x18\xb8\xd0\x4e\x18\x36\xab\xc4\xb2\x0e\x52\x44\xc4\xaa\xce\x95\x40\xa9\x1a\x7f\x53\xd6\x8f\xe0\x59\x23\x53\x1e\xd8\xa3\x62\x66\x6b\x44\xce\x15\xa8\xf5\xac\xb1\x54\xa6\xcd\xec\x12\x68\x2c\x78\xb2\xc0\xa8\x48\x1b\xe7\x90\x52\x75\x0b\xb1\xfd\xc1\x89\x66\x85\x17\xc1\xcc\x58\xbc\xea\xc6\xac\xdb\xbb\x0c\x50\x24\xb3\xd1\x17\xe8\x6a\x30\x1a\xfe\x93\xee\x7a\x8b\x43\x68\x80\xf2\x9e\x27\x8b\x2b\x21\xf4\x37\x45\x8a\x6b\x27\x18\xf0\xa3\x93\x96\x11\x20\xf5\x48\x2f\x8a\xef\x1d\xe0\x6e\xe0\xa1\xaa\x66\xd7\x9e\x95\x3b\xfe\xdc\x8f\x94\xcc\xf9\x89\xfa\x56\x8a\xbc\x31\x13\x5b\x11\x36\xbf\xbd\x38\x43\x52\x94\x3b\x37\x22\xd7\x72\x91\x09\x66\x6d\x50\x1b\x14\x83\x1f\x9c\x23\xb4\x7a\x26\x4a\x9f\x15\x79\x47\x17\x84\x26\x4a\x78\x58\x32\xbe\x4e\x5f\x24\x4e\x19\x35\x97\xc7\x42\xcf\x56\xb4\x50\x73\xa0\x56\x9f\xeb\x57\xbc\x8a\x65\x6d\x30\xc6\x57\x1e\xd7\xf4\x16\x14\xc9\x24\x44\x10\x03\x8f\x9e\x7a\xdb\x9f\xda\x19\x87\xa8\x73\x29\xb8\x39\x98\x9d\x20\xcf\x45\xe1\x85\x75\x20\xad\xa2\x0a\xfa\x73\x9d\xf6\x47\xd1\xab\x8b\xc7\x32\x57\x20\xad\x0b\x5a\xe6\x60\x77\xf2\xfb\x7c\x0c\x89\x81\xbc\x51\x49\x5d\xc7\x6c\x6b\x78\x60\x29\x9d\x02\xa1\xba\xc0\x34\x2d\x08\x70\x65\x28\xa6\x35\x5f\x6a\x12\x0b\x28\x33\xe3\xa9\x22\x3f\x5c\x9c\x91\x57\xe4\xd0\xbc\xeb\x08\xf1\x07\x1b\x6a\x6b\x61\x03\xd0\x96\x75\xd4\x89\x9f\x02\x97\x84\xc8\x4b\x84\xb4\x44\xa2\x4f\xb8\x20\x2a\x8f\x66\xd5\x2e\xde\x5e\x6d\x76\x41\x8a\xe8\x18\xd9\x4f\x5c\x7f\x5a\x0a\xf5\x83\x02\xd9\x19\x81\xfa\xa1\x01\x81\xaa\x8a\x51\x06\xe7\xea\xd0\xb3\x88\x95\x82\xa6\x31\xd5\xd4\x11\xae\xa2\xab\xfa\xbe\x6e\xe9\xe7\x4d\xbe\x14\xbc\x65\x3c\xbf\xb7\x26\xd2\xee\x4c\x2d\xd7\xe7\x38\x2d\xe2\x10\x42\x1d\x77\x9d\x66\x59\xc2\x4a\x07\x72\x25\x48\xed\xa2\x86\x2b\xfd\x0d\x62\x22\xd2\x09\xef\x87\x36\xc2\x09\xe5\xb1\x48\x57\x5e\x86\x4e\x6f\x1a\xcd\xaa\x2f\x08\xd8\x57\x1f\x7b\x62\x14\x4a\x60\x0e\x2d\x4a\x68\x2d\x61\xde\x5b\x33\x9b\x01\x8e\xc7\x08\x9c\x9e\x24\x74\x0c\x89\x85\xb1\xc5\x40\xb5\x8a\x81\x4f\x1d\x29\x2a\x45\xd2\x5d\x6a\xcb\x95\x48\xc0\x86\x5e\x79\x40\x98\xe9\x9f\x05\x1c\x70\x92\xae\xe0\x80\xda\x60\x0d\x0e\xa8\xd7\x3e\x07\x38\xe4\x2d\x58\x3d\x59\x86\x83\x91\x1b\xea\x70\x40\xe6\xbd\xef\x70\x50\x10\x45\x22\xcd\x46\x52\x18\xb5\xb3\x33\xde\xe4\xa6\x2d\xfd\x7c\xd6\xb0\x81\x76\xfb\xaa\x06\xec\xbc\x7a\xf5\x9b\xa9\xac\x04\x5d\x52\x6d\x99\x84\x8f\xbc\xfc\x5f\x15\x9e\x85\xa4\x67\x99\x91\xf9\x59\x6a\x8e\x40\xf3\xa4\xbb\xf0\x9c\xd9\x41\x17\x79\x0b\x2d\x8c\x9d\x9d\x70\x23\x11\xd1\x04\x4b\xa4\xb6\x43\x39\xb2\x8c\x76\xcb\x13\x57\x42\x6d\xd1\x47\x89\xbf\xf9\xf0\x0f\xac\x96\x89\xbf\x38\x13\x26\x17\x31\x54\xbc\xce\x36\x46\xf8\xc6\x86\x64\xe2\x7d\x3e\xca\xd7\xc8\x15\x2e\x0a\x04\xe2\xda\xd3\x5a\xb8\xea\x64\xef\x8a\xc2\xab\x66\x81\xc0\x63\xc6\xa7\x68\x57\xeb\x13\x09\x89\x8d\x0f\x76\x44\xe0\xd6\x6a\x90\x3d\x3c\x12\x7e\x52\x7f\x1e\xfc\xab\x51\x16\x63\x82\xbb\x99\xd1\x52\xe4\x25\xac\x89\x25\xb7\x4c\x91\x83\xb7\x1e\x00\x2d\x2a\x55\xee\x23\x87\x39\xb0\x5f\x58\xec\xa6\xb5\x74\xde\x32\x1e\xbb\x50\xda\x1a\xb0\xbc\x9e\xeb\xe4\x60\x0c\xd2\x66\x71\x95\xb6\xbc\x21\x3f\x73\x52\x00\x8b\x0c\x1a\xa3\xc7\x95\x15\x99\xbd\x8d\x6e\xf0\xb0\xe1\xb5\x78\xc9\xf2\x34\x3f\x70\xdc\x7b\xf3\xde\x81\xd1\xdc\x57\xef\xf3\xdf\xf2\xa4\x65\x75\x1c\xf5\xeb\x5a\x8b\xf9\xd1\x4e\xeb\x45\xfa\xc8\xa0\xb5\x66\x7c\xaa\xaa\x9a\x4c\xbd\x1e\xfe\x7a\x55\xc6\xef\xf0\x44\x0a\x9b\x82\xb9\xaa\x42\x2c\xa5\x00\x3c\x17\x35\x24\x31\xe2\xc4\x33\x57\x42\xa6\xa9\xa2\xa7\xd2\x40\x42\x33\x9a\x5c\x67\xcd\xcb\x87\x92\x95\x52\x75\xef\xae\x4f\xea\x53\x23\xb3\x9e\x81\xb4\xbc\xdf\x5c\x27\x34\x4e\x99\x52\x68\x08\x83\xf1\x4c\x88\x5b\x72\xb8\xa6\x56\x56\x25\xca\x4a\xb1\xa9\x3a\x76\x38\x3f\x30\xab\x3f\x22\x8c\x27\x45\x24\x13\xea\xc1\x5c\x2b\x6f\xc8\xc1\x97\x44\xc5\x2a\x70\x0f\x5d\x79\x66\x17\xac\xb0\xba\x4c\x5b\x90\xd9\x60\xc1\x93\x13\xec\xd5\xed\xb9\x6c\x59\x12\xe5\x91\x2d\xba\x74\xb8\xbd\x5c\xf5\x6c\x2d\x1c\xad\xf4\xf8\xe4\x40\x72\xc2\x45\x04\xaa\xbb\x62\x4b\xdf\x95\x73\x92\x18\x6c\x86\x0d\x60\xf4\x13\xdd\x18\x0e\x87\x76\xe9\x1e\x26\x6a\xba\x47\x7b\x55\x89\xfa\xa6\x24\x2e\x46\x1f\x49\xb2\x19\x1d\x58\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x09\x2e\xa4\x45\x51\xc3\x44\x05\x47\x94\x46\x12\x65\xbd\x79\xb8\x27\x8e\x44\x57\x96\x7a\x5a\x7a\x89\xab\x8e\x40\x4c\xf4\xb2\xb5\x1d\xca\x35\xdc\x31\x3d\xc3\x1a\xac\xb3\x25\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\xbf\x7a\xaa\xea\xa8\x2e\x2b\x9e\x63\x8c\xa1\xc1\x26\x98\x4c\x20\x42\x41\xab\x0a\x60\x4b\xb5\x0f\xcb\xa2\xb4\x3e\x85\x43\x0b\x5f\x31\x3d\x65\xf7\xe6\x2d\xd5\xa7\x96\xfa\xae\x70\xc1\x07\xeb\x2f\x1f\x0d\x09\xb9\xe0\x45\xfc\x6d\xdf\xec\x62\xf5\x4e\x1f\x7a\xa6\xcd\x27\x56\xcb\xed\xe3\x07\x54\x0d\x67\x46\x3a\x94\x79\x07\x18\xdf\xc6\x1c\x4e\xaa\x26\xf1\x4e\xc9\x01\x9a\xc6\xdd\xa4\x66\xeb\xbd\x0c\xd0\xc6\x54\x6e\x6e\xf9\x58\xe6\xf2\xe7\xe1\x00\x21\x6d\xe9\x9c\xab\x74\x10\x6a\xa0\x6f\x37\x42\x0d\xf4\x2d\x47\xa8\x81\x1e\x6a\xa0\xaf\x8e\xbd\x09\x19\x0c\x35\xd0\x5f\x56\x5d\x9b\x50\x03\xfd\xa9\x4d\xcc\xa1\x06\x7a\xa8\x81\xfe\xd0\x08\x35\xd0\x1f\x19\xa1\x06\x7a\x83\xf1\x02\x28\x57\xa8\x81\xde\x60\x84\x1a\xe8\xeb\x47\xa8\x81\xbe\x3a\x42\x0d\xf4\x8d\x23\xd4\x40\x6f\x3c\x42\x0d\xf4\x50\x03\x3d\x94\x86\xdc\x6d\xae\xfd\x2c\x0d\x49\x42\x0d\x74\x37\x42\x0d\xf4\x17\x51\x00\x8f\x84\x1a\xe8\x5b\x8d\x50\x03\x3d\xd4\x40\x6f\x32\x42\x0d\xf4\x97\x62\x2e\x09\x35\xd0\x43\x0d\xf4\xcf\x47\xd0\x0d\x35\xd0\x43\x0d\xf4\x50\x03\x3d\xd4\x40\x7f\x70\x15\xa1\x06\xfa\x4b\x50\x01\x95\x8e\x59\xa3\xb2\x90\xdb\x54\xb0\x71\x91\xc9\x95\x84\xf1\x71\x3e\x99\x80\x44\xca\x85\x6f\x5e\x09\x9e\x2a\x8b\xf5\x2d\x3b\x59\x41\xf7\xb1\x18\x8e\x4b\xe2\xd8\xf0\xb8\xcb\x50\xc7\xf2\x8d\x65\xf8\xf0\xf9\xfb\x6f\xd6\x94\xcb\x69\x1c\x55\xd8\x34\x70\x16\xd7\xfc\x9e\x37\xf3\x8f\x6f\x00\xf8\xba\xa4\x22\x07\xf7\x28\x11\xca\x85\x3d\x23\xb0\xa2\x19\xe5\x1c\xbc\xbe\xc7\x34\xda\x51\xc6\x00\x9c\x88\x0c\x9c\x77\x9a\x12\xc5\xf8\x34\x01\x42\xb5\xa6\xd1\x6c\x68\xde\xc4\x3d\xb0\xcb\x10\x65\xf7\x8b\xd2\x12\x68\xea\x83\xb5\x53\xca\xec\x54\x84\x46\x52\x28\x45\xd2\x3c\xd1\x2c\x2b\x26\x23\x0a\x30\xcb\xc2\x32\xaa\x02\x18\x18\x15\x57\xc6\x35\xf7\xcb\xb7\xb9\x65\x89\x6a\xbd\x32\xd4\x36\xfb\x58\xe2\x39\xcd\xf4\x82\x98\x4f\x4e\x5c\xd9\x57\xa9\x34\x89\x12\x86\xdc\x1a\xdf\x68\x13\x6a\x71\xbe\xbe\xe7\xd5\xdc\xad\x54\xb9\xa5\xf2\x18\xc5\xd6\x4c\x2b\x82\x61\xc0\xe5\x84\x6e\xaa\x98\x29\x27\xe6\xab\x3e\xa1\xbe\x98\x96\x05\xb4\x5f\x29\x82\xda\x73\x16\x3b\xbb\xfb\xa9\x32\x5d\xa5\x88\xa8\xc1\x4d\x6b\xc0\x2a\x11\x1d\xe3\xde\x3d\x72\xf6\x6b\x21\xfe\xa5\x40\x81\x51\x7a\x2b\xc7\x00\x37\x80\xc3\xdc\xe0\x00\x44\x60\xf8\x2b\xdd\x80\xf5\x9f\x1c\xe9\x35\x95\x53\xd0\x45\x3c\x53\xd3\x58\xf1\x7a\x58\x48\xb5\xdc\x6f\x55\x11\x29\x41\x86\xd0\x19\x89\x18\x53\x7e\xca\xbc\xaa\x75\xf5\x84\xed\x0a\x5d\x19\xb5\x75\x37\x78\xc1\xc8\x86\x68\x16\x2f\x55\x19\x8d\x40\x91\xc3\x8b\xd1\x69\x9f\x8c\x2e\xce\x5c\x1c\xa6\x98\xac\xcb\x63\x76\x34\xcc\x62\xe0\xa6\xca\xc6\x45\x85\xb6\xca\xf4\x95\xdc\x4f\xf7\xee\x51\x21\x5f\xfd\xcc\x5d\x78\xe9\x32\x05\x40\x91\xab\xa8\x6e\x4e\x54\x8e\x22\x92\xb3\x09\xb1\x22\x31\xc3\x21\x1f\x94\xe9\x88\xbe\xee\x90\x7f\xa2\x58\x88\x83\x92\xcb\xba\xf0\xbe\x6e\x24\xb0\xc8\xaf\x57\x52\x3b\x30\x14\xd4\xc5\xbd\x34\x8a\x77\x69\xa5\x21\x55\x44\xb1\x77\xa0\x14\x9d\xc2\xa8\xa1\x7b\x6b\x93\x1d\x00\x3d\x5c\x25\x39\x40\x02\x94\xd8\x44\xdf\xe2\x97\x32\x26\xb8\x2e\x7c\x93\xd4\xae\xa9\xc0\xac\x3b\xc9\xb4\x06\x24\x25\x58\xec\x0f\x37\x7b\xb9\x16\x40\x6f\x29\xb2\xf8\x9d\x9f\xa4\x7c\xd8\x88\x12\x3c\xb6\x71\xbe\x63\x20\x63\xc9\x60\x42\x26\x0c\x83\x87\x31\x9c\xb7\x6f\x6b\x3f\x51\x6b\x7b\x52\x0a\x24\xae\xc7\x69\x50\x7e\x5d\x43\xf2\xa3\x5b\x98\x96\x39\xb7\x4d\x47\x9c\x70\x8f\xc9\xae\x6c\x42\xa6\x18\x0e\xec\x74\x94\x3f\xbd\xfa\xeb\x9f\xc9\x78\x61\x04\x29\x44\x48\x2d\x34\x4d\x8a\x8f\x4c\x80\x4f\x0d\xac\x2c\x53\xa8\xa7\x6b\x16\x10\xc0\xb6\x20\x76\xe1\xaf\xff\x70\x3b\xae\x4b\x76\xc7\x31\xcc\x8f\x2b\xf0\x1b\x24\x62\x3a\x24\xa7\x45\x76\x64\x9e\xc5\x68\xe7\x6f\x5e\xaa\xbb\x3b\x34\x13\x09\x8b\x16\xad\x11\xcd\x17\x21\x23\x33\x71\x67\x35\xcc\x35\xd8\x53\x66\x7e\x65\x22\xcb\x13\xeb\xea\xf8\xa6\x48\x74\xce\x15\xac\xa6\x23\xae\x3d\x17\x68\x9c\x77\x53\x2c\xd1\x51\x17\x05\xee\x5f\x29\x5c\x9a\x8b\x33\x1f\x17\xb5\xc8\x90\x98\x7c\x43\x93\x64\x4c\xa3\xdb\x1b\xf1\x56\x4c\xd5\x7b\x7e\x2e\xa5\x90\xf5\xb5\x24\xd4\xf0\xe8\x59\xce\x6f\x6d\x2b\x88\xa2\x5a\x83\x98\x1a\x81\x3e\xcb\xb5\x2f\xee\xbd\xee\x83\x6d\xea\xbe\x67\xfd\x5e\xf9\x2e\x67\x81\x7b\x56\x6a\xd8\x2e\x6b\xcc\x62\x64\x75\x7e\x55\x45\xb6\x3f\xbc\xfa\xd3\x5f\x2c\xea\x12\x21\xc9\x5f\x5e\x61\xa6\x80\xea\xdb\x43\x8c\x1c\xd5\x88\x27\x29\x4d\x12\x43\xc8\xab\x48\x69\x00\xbd\x0e\x09\x3f\x39\x0e\xea\xf6\xe8\xb6\xb5\x00\x7f\x73\xf3\x77\xe4\x22\x4c\x2b\x48\x26\x7d\x9b\x20\x55\x28\xd3\x3d\x14\x47\x7a\x8e\xfa\x60\x96\xda\x1e\x88\xdd\x73\x91\xe4\x29\x9c\xc1\x9c\x75\xd1\xeb\xa9\x36\x9b\x37\x30\x25\x4c\x21\x1f\x1c\x27\x22\xba\x25\xb1\xbb\x58\x89\x77\x5a\x2e\x4a\xde\x1c\x0a\x4d\x23\xbf\x5a\x44\x7c\x6d\xfc\xfe\x5a\xac\x57\x4a\xb3\xcc\xc8\x00\x98\x87\x29\xe9\x5d\x0d\x18\x78\x26\xb1\x72\x42\xcb\xd2\x36\xad\x9d\x1b\x6d\x5d\x1b\x03\xf7\x45\x86\x6e\x36\x9e\xa2\x71\xac\x53\x7b\xcf\x48\xb9\xfa\xe6\xe6\xf0\x1a\x42\x94\x13\xfa\xd3\x90\xe1\xbf\x6d\x2e\xd3\x8a\x60\x5e\x14\xd5\x2c\x10\xc3\x0a\x00\x06\x7d\x90\x24\x37\x37\xf3\x77\x60\x53\x6f\x17\xe8\x56\x83\x0b\x2f\x7c\x19\x29\xd5\x4e\x20\xf4\xba\x0a\x25\x19\x48\xc5\x94\xe1\xcb\x1f\xf0\x40\x9d\x26\x94\xa5\x15\xc3\xf3\xd3\x00\xc1\x1e\x6e\xac\xe4\xdc\x9e\x52\x1a\x3d\xc5\x4e\x88\xa4\xd0\x56\xb1\x5e\x23\xd6\xd6\xa5\xda\xeb\x7c\x8c\xf8\x83\xb7\xef\xd2\x50\xaf\x43\x4e\xfc\xd4\x34\xf6\x43\xb9\x0d\x75\x12\x6b\x7e\x29\x68\xac\xbd\xeb\x25\x51\x56\xfc\xbe\xe7\x4a\x58\x8b\xc5\x77\x44\x3f\x90\xa2\xba\xcd\xad\x93\xd0\x9a\xd6\x69\x4f\x58\x45\x17\x70\x0a\xe4\x90\xd8\xa0\x0d\x73\x26\xdc\xa3\xa4\xf7\xa6\xf7\xa4\xd4\xd5\x82\x48\x8a\x8c\x4e\x5b\xf5\x23\x5a\x82\xd4\xf2\xb4\xd5\x62\x19\x46\x7f\xaa\x90\x92\xcc\xdd\x65\x28\x89\xaf\x05\x84\x95\x9e\xac\x33\xdf\x03\xd8\x69\x16\xd8\x2f\x8e\xdc\xd1\x05\xa1\x52\xe4\x3c\x76\xe6\xd0\xc2\x1e\xfd\x6e\xe9\xc5\x97\x82\x83\xf7\xf3\x2c\xd7\xda\x40\x07\x14\xe3\xe4\xf5\xf0\xf5\xab\x97\xc2\xe2\xf0\x0b\x97\x58\xdc\x65\xc1\xe2\x2c\x7d\x7a\xd2\x6f\xf5\x55\xfb\x3b\xfa\xde\x77\xce\x36\x53\x16\xe5\x67\xbe\xe4\x37\xfe\x74\x27\x99\x86\x4a\x97\xc1\x43\xd4\x78\x8c\x62\x59\xa9\x2c\x71\xb4\xae\x1b\x46\x4b\x20\xb5\x2b\xe5\xa1\xf2\xf1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x67\x1a\x53\x0f\x90\xb0\x2a\xa0\x0e\x0e\xc8\xa1\xbd\xb3\x67\xf3\xef\x8f\x9e\x14\xb5\x1c\xd0\xce\xef\xb3\x16\x75\x42\x97\x4a\x3d\x64\x14\x8d\x77\x59\x87\x10\xfc\x6f\x98\xd1\x39\x60\xdd\x01\x96\x50\x99\xa0\x8b\xfc\xda\xae\x9d\x8c\x73\x4d\x80\xcf\x99\x14\x1c\xed\xc4\x73\x2a\x19\x56\xf6\x91\x30\x01\x09\xdc\x28\xb1\x5f\x1e\x7e\x38\xb9\xc2\xf8\x9b\x23\xdb\xf5\xc5\xaf\x32\x57\xbe\x04\x4f\x75\x25\x95\xe9\x1e\xdd\x3e\xbf\x0e\x03\x43\xa4\xb9\x7e\x5d\xe6\x3d\x69\xae\x73\xdb\x5a\xe6\x3e\x4a\x72\xc5\xe6\x4f\x45\x49\x5c\x41\x88\x33\xd6\x68\x9f\x97\x8a\x53\x94\x80\x5a\xa9\x33\x51\xba\x09\x1e\x29\xc3\xdd\x53\x45\x8e\x69\x35\x64\xc3\xd9\xac\x48\xca\xa6\x33\xed\xa2\x3d\x97\x3c\x07\x15\x17\x54\x8a\x66\xde\xa7\xb4\x5e\x19\xb6\x7b\x92\x30\xaa\x76\x15\xb9\x56\x12\x19\xdd\x2c\x18\xe8\xc1\x5d\xad\x3f\x9a\x14\x46\x19\xf3\x22\x6b\xa9\xbc\x18\x39\x0f\x9a\x87\x1b\xe3\xff\xb4\x81\x35\x85\x5a\x62\x03\x65\xec\x23\xd6\xdc\x38\x21\x95\xa2\x40\x3e\xa0\x04\x89\x3f\x56\xa2\x42\x8d\x84\x0b\x3e\x98\x55\x8a\x36\x65\x22\xde\x31\xc9\xaf\xa9\xe2\xd1\x48\xe5\x58\x0f\x41\x32\x13\x49\xec\x7b\x68\x5b\x5b\xce\x18\xf4\x1d\x00\x27\x17\x23\x84\x9f\xf9\x44\xf4\x08\x6d\x80\xa2\x75\x2b\x60\x79\xa6\x8a\x2a\x5b\x83\xe7\xae\x08\xd6\x42\x2b\x69\x23\xd2\x17\x5f\xda\xfa\xcc\x7f\x57\xc0\xcc\x47\x64\xd3\xb1\x98\x03\x82\x34\x8e\x25\xa8\x16\xe5\x8d\x9e\x40\x4f\x6d\x45\x4a\x59\xa3\xf6\x3e\x75\xc7\x48\x01\x36\x6f\x5a\x42\xf1\x1d\x8f\x2a\x22\xde\x27\xa6\x60\x17\xa3\xd3\x16\xd4\xab\xf7\x83\xf3\x8b\x98\xa9\x7a\x3d\x45\x58\x16\x95\x3e\xd7\x21\x29\xdd\x8d\x95\x44\x09\x2b\x31\xee\xe6\xeb\x6a\x2a\x26\x56\x88\x5a\x4b\x22\x4d\xb8\x9d\xc6\x90\x15\x97\x24\xed\xcc\x39\xe8\x74\xc8\x44\x8c\xfd\x97\x4a\x68\x28\xff\x44\x15\x20\x3e\x58\xc2\x12\x79\x17\x3a\xd2\x2f\x82\x90\x97\x08\x13\x9a\xde\x7d\xf8\x61\x85\x8a\xaf\x00\xf3\x93\xc1\x72\x74\x71\xd6\x25\xba\x64\x2c\xde\x3b\x74\xd9\x5d\xbf\xac\xa7\xc4\xd5\x2b\x49\xb8\x09\xfd\x61\x1f\x89\x78\x83\x98\x54\x32\x1a\xbc\xbf\xda\x09\x58\x0b\x42\x89\xb5\x2f\x2e\xf5\x78\x6f\x00\x94\x9d\xa9\x04\x8a\x5a\xa3\x3c\x49\xae\x21\x92\xb0\xab\x5d\xb5\xbe\xff\x17\x4b\x73\x6d\x12\x79\x2a\xf2\x3b\x96\x27\x70\x37\xf3\xb2\x08\x66\x25\xb0\xa3\x4c\x3e\xcc\xf2\x04\x63\x61\x29\x5f\x78\x80\xe3\xea\x55\xc5\x89\xc5\x94\x0f\xab\xb1\x61\x5c\xb5\x5d\x50\x50\xbc\xac\xe8\x29\x45\x95\xb2\xae\x56\xc6\x63\x36\x67\x71\x4e\x13\x7c\x11\x4a\xa1\xd5\xfe\xfb\x05\x87\x4c\x7d\x51\xd7\x06\x2d\xf8\x7d\x8f\x7d\xbb\xee\x2f\xec\xf2\x16\x8c\x4f\x07\xf8\x8b\x79\xb1\x5b\xe1\x40\xf0\x01\x1d\x18\xb4\x79\x26\x82\x1a\x96\x25\x7f\x8f\x92\xd0\x95\xdf\x5f\x2f\xd2\x1b\xc5\x4b\xe4\xd3\x19\x02\x4b\xa6\xd4\x57\x08\x4c\x40\x63\xf1\x37\xe7\xc0\xb5\x51\x3b\xee\xd9\xd8\x89\x55\xd5\x62\x78\x75\xdc\x78\x26\xc2\x5a\x53\x8b\xd6\x52\xf4\x71\x85\xcc\x38\x18\xe9\x9d\x31\x50\xcc\x41\xce\x19\xdc\x1d\x3b\x56\x37\x30\x6a\xfc\xc0\x42\x44\x1d\x23\x60\x8f\xbf\xb0\xe2\xe0\xcd\xfb\xb3\xf7\xd8\x49\xd9\x99\x19\x73\x05\x93\x3c\x71\xbd\xe8\x87\x84\x66\xec\x03\x48\x85\xb5\x62\x6f\x19\x8f\xfb\x24\x67\xf1\xd7\x9f\x30\xc2\x85\x71\x56\x86\xed\xb5\xa2\x5a\x6f\x1d\x55\x72\x69\xc3\xec\xdf\x65\xbb\x78\x17\x05\x34\x86\x44\xf0\x69\x25\xe9\x19\xc5\x81\x0b\xce\xf4\x4a\xd3\x59\x5b\xc0\x11\x55\x5a\x21\x63\x0c\x8e\x64\x42\xd6\xec\xb7\x66\x3e\x2c\x6b\x57\x09\xb1\x34\x24\x8d\xd5\xe6\xc3\xb8\x15\x55\x30\x0f\x62\x23\x1f\x7c\x7e\xa4\xaf\xfa\xeb\xcb\xe5\xd9\xea\x8d\x33\xca\x63\xfc\x33\x8a\x84\x8c\xdd\x7a\x99\x2e\xe2\x39\x6d\xf4\x8f\x0d\x39\x41\x36\x64\x28\x1a\xe5\xcb\x6f\x46\x8d\x51\xa6\xb5\xd8\x3f\x2f\xa6\xe4\x9c\xfd\x2b\x07\x42\x53\x61\x08\xf1\x72\x6d\xfb\x25\x88\xa4\x74\x81\xbc\x10\x97\xfa\xd6\xc7\xa7\xbb\xa4\x42\xd5\x27\x57\x40\x63\x56\xc9\x8b\xee\x93\xb7\xf5\x44\xe9\xbe\x59\xcb\xb5\xcd\xe0\x74\x3f\xd9\xd5\x4b\x50\x22\x97\x11\x5c\x59\xa7\x4e\xea\x03\x88\x56\x3f\xc6\xec\x8a\xa6\xb7\xc0\xad\x12\x6d\x40\x83\x7e\xab\x5c\xe2\x1e\x44\x33\x88\x73\xe4\x2a\xe3\x05\x99\x30\xdb\xf0\x02\x59\x3b\x9b\xce\x40\x69\x2f\x0c\x1e\x63\x50\x4e\xd9\x3b\xcc\x2f\x00\xd1\xb7\x12\xbd\x5b\x9a\x9d\x52\x8a\xe5\x98\xf1\xc8\x52\xed\x13\x54\xac\x8e\xa5\xf2\xd4\x9f\xe5\x65\x48\xab\x21\x79\x6b\x5e\x65\xf1\xa9\xd2\x48\x80\x2d\x01\x17\x9d\x6a\xce\x6e\x46\x26\x54\xcd\xb0\xcd\xc6\xf2\x16\xb8\x1a\xfd\x51\x2e\x0d\xc1\xb0\xa5\xb3\x29\xb6\x47\xc7\x56\xba\xd8\x49\x7b\x9d\xa1\xa5\x65\x42\x82\x59\xec\xa0\xc2\xef\x9e\x0b\x13\x3b\x29\x02\xcc\x0d\xe0\xa3\x25\x4a\x60\x77\xd2\x30\x2c\x5f\x62\x4a\xe6\xbc\xf4\x70\x1a\xaa\xf0\xe9\x58\x52\x73\x7f\x66\x23\x3f\x64\x1b\x0e\x48\xe5\xb4\xbd\xa5\xa2\x77\x22\xa7\xb9\x3d\xe8\x8e\x0a\x97\x85\xb6\x87\x4b\x81\xc6\x28\x4c\x19\x0d\xe4\xf4\xdd\x59\x35\xb3\xa9\x9a\xb2\xe1\xf3\xc2\x86\xe4\x43\x5b\xbb\xf2\xb2\x61\xd9\x10\xf4\xd2\x5a\x5d\xb6\xc9\x30\x44\x23\x99\x7b\x95\xa0\x78\x9b\x97\x7c\x19\xcf\x72\xed\x38\x61\xa9\x24\xf2\x68\x46\xf9\x14\xf5\x42\x91\x9b\xf9\xbe\xfc\x12\x57\x24\x21\xce\x23\xd7\x63\xc4\x63\xed\x97\xde\xca\xea\x2a\x7b\x21\xb9\x52\x11\xcd\xfc\x9a\xab\x9f\xf5\xff\xb1\xf7\x3f\xde\x71\xdb\x46\xbf\x30\xfe\xaf\xe0\xa8\x3d\x5f\x69\x93\xdd\xb5\x9d\xb4\x7d\x52\xdf\x7c\x9b\xa3\x48\x72\xaa\x1b\x5b\xd6\x23\xc9\xc9\xdb\x37\xce\xd3\x62\x49\xec\x2e\x2a\x12\x60\x08\x50\xf2\xf6\xfa\xfe\xef\xef\xc1\x0c\x00\x02\xdc\x95\x2c\x91\x94\x77\xa5\x2c\x7b\x4e\x63\x71\x49\x90\x1c\x0c\x06\xf3\xf3\x33\x6a\x21\x34\xfd\xf0\x92\xf0\x31\x1b\x93\x9d\x3f\x06\x3f\xed\xe0\xd3\x8b\x52\x9a\x47\xd8\x8a\x0a\x78\xab\x8c\x6b\xc8\x6c\xd8\x09\xaf\x1e\x93\x23\xf3\x0c\x88\x3c\x79\x02\x06\x49\xff\x93\x9a\x7c\x43\x52\xb2\x19\x2d\xd3\xcc\x7a\x48\xae\x83\x4a\x11\x4f\x30\xf6\x81\x2b\xad\x70\x1b\xd2\x1d\x84\x93\xa6\xea\xd2\x88\x22\xb3\xb8\x46\x29\xd5\x74\x14\xac\xea\x67\x68\x6a\x8d\x2c\xf8\xf1\x88\x5a\xee\xaa\xa5\xd6\xb3\x3f\xd8\x82\xcb\x11\xf5\x57\x71\xa3\x94\x03\x0c\x71\x7b\x55\xe7\xb1\xb9\xc5\x3a\x60\x60\xc7\x0b\xf8\xa8\x06\xc6\x07\x1a\x40\x5b\x99\x5a\x65\xf2\x72\xd4\xc2\x3c\xdf\xb0\xa4\x8f\x4e\x2e\xce\xfe\x71\xfa\xf6\xf8\xe4\x62\xbb\xb2\xb7\x2b\x7b\xbb\xb2\x3b\xac\x6c\x26\xae\x3a\xaf\x6a\x67\x3d\xad\x0a\xd4\x36\xd1\x27\x83\x9a\xa3\x27\x94\x0e\x77\x24\xae\x7e\xa2\x46\x99\x2e\x4a\xa6\x40\x3f\x81\x28\xd3\x8a\xb8\xb5\xbd\x00\x55\xf7\x83\x47\x9f\x0f\xb7\xc6\x6c\xb6\x1e\xb3\x84\x42\xc7\xca\xaa\x59\x0b\x9b\x22\x1e\xfc\xf3\xf8\xf0\xe8\xe4\xe2\xf8\xd5\xf1\xd1\xd9\x5a\xd3\x3b\x3a\xa2\x3f\xc6\xfb\x72\xcb\x5d\xb2\x28\xd9\x15\x97\x95\xca\x16\x1e\x40\x7a\xb5\x10\x58\xce\x10\x14\x29\x78\x3c\x1c\x46\xf6\xca\xdb\xb6\x9b\x6d\xbf\x9b\x6d\x9c\xed\xd2\x01\xf8\xa7\x2f\xf6\x7d\x55\xca\xbc\x27\x16\x3e\x47\x5f\x8c\x0b\x61\xaf\xe2\xa7\x5d\x8b\x11\x12\x6d\x3d\x56\x79\xac\x01\x49\x8c\x3e\x9a\x17\xba\x43\x77\x90\x5e\xf0\x7e\xfb\x81\xc6\xc5\x0c\x9b\x37\xb4\xf8\x91\x2d\xce\x58\x47\x7c\xa1\x98\xde\x2c\x63\x89\xd9\xe8\xc8\x25\x5b\x60\x3a\xe5\x81\x7b\x58\x17\x1c\xa4\x8d\x84\x4b\xbe\x64\x5d\xa0\xac\xfb\xc4\x39\xbe\x64\x1d\x52\x45\xdd\xb1\x84\xf8\x6b\xa6\x10\xf4\x34\x33\xa7\xdd\x66\x8f\xf4\x8b\x71\xfc\x00\xb8\xce\x4f\x37\x8e\x12\x1f\x3d\xce\x82\x0b\xdf\xf6\x3c\x13\x18\x49\x5f\x44\x7b\x97\x17\x22\x04\x8b\x38\x81\x37\x5d\xe8\xc1\x2a\x19\x3d\x91\xa6\x6b\x7b\x41\x82\x53\xd8\xaf\x5c\xdd\xad\x05\x2b\x66\xe6\x7b\x04\xbb\xf4\xa5\x03\x3d\x50\xbe\x27\x20\x74\xd9\x1d\xc6\x7f\x42\x60\x74\x48\xfe\xe5\x4f\x42\x17\x7f\xf5\xcb\xee\xee\xb7\x3f\x1e\xfd\xe3\x6f\xbb\xbb\xbf\xfe\x2b\xfc\x15\xb6\x42\x0c\x6f\xc7\x97\x00\x82\x83\x90\x29\x3b\x81\x67\xc0\x9f\x56\x5d\xdb\xc7\x10\x8a\xfd\x01\x0a\xb0\xc7\x98\x6b\xe4\xff\x2c\x64\xda\xfc\x4b\x75\x82\x1a\xdc\xc8\x8d\x01\xa6\xa8\x43\x3d\x10\x1e\xfd\x6d\x0f\xb5\x2c\xe9\x79\xa9\xda\x51\x7d\x6b\x9b\x64\xce\x72\x04\x3b\x7b\xe5\x48\x00\x7d\x8b\x1d\xd2\x83\x80\xf2\x78\xa3\x99\xc6\xb8\x93\x3b\x57\x2f\x3a\x35\x78\xc7\xa3\x47\xd1\xe6\x67\xb0\x67\x82\x01\x45\x2c\xb5\x70\x21\xfb\x0d\xd6\xa7\xb9\xf8\xbe\x9a\xfb\xa7\xc7\xe4\x0a\x29\xbc\x31\xc4\x71\xe1\xcd\x57\x0f\x2a\xe3\x7c\x10\xb5\x59\x86\xfb\x12\x33\x98\xdd\xef\x16\x12\x41\x79\x6c\x3c\x66\x0c\x9b\x3d\x3c\x39\x4e\x8a\x6a\x68\x2f\x18\xe7\x2c\x97\xe5\xc2\xff\xe9\x4b\x31\x47\x4a\xcb\x92\xce\xa0\x12\x06\x6f\xc7\xdb\xfc\x5f\x78\x63\xf4\x80\xe5\xbb\xd1\x14\xae\x63\xa9\x56\x22\xb7\x84\xf6\xa8\x8f\x0d\x94\x6d\x8e\xf4\x1b\x22\xda\x92\xae\x00\x4d\xf1\x11\x33\xa4\xf7\xc4\xa1\xc2\xe9\xa9\x08\xf6\xa4\x2d\x11\x1e\xd6\x59\x6c\xe0\x0d\x10\x57\xc6\xb2\x6c\x0d\xad\x57\x1f\x3d\x4a\xb3\x94\x5f\x71\x25\x3b\xd4\xfb\xf8\x81\x6e\xce\x78\xb4\x28\x25\x98\xc5\xe5\xdd\x66\x1f\x0a\x40\x13\xf3\xeb\xb5\x21\xf6\x5f\x74\x69\x28\x86\x47\x41\xb5\x66\xa5\x78\x49\xfe\x67\xef\xfd\x97\x1f\x47\x83\xef\xf6\xf6\x7e\x79\x3e\xfa\xeb\xaf\x5f\xee\xbd\x1f\xc3\x3f\xbe\x18\x7c\x37\xf8\xe8\xfe\xf8\x72\x30\xd8\xdb\xfb\xe5\xc7\x37\x3f\x5c\x9c\x1e\xfd\xca\x07\x1f\x7f\x11\x55\x7e\x89\x7f\x7d\xdc\xfb\x85\x1d\xfd\x7a\xc7\x41\x06\x83\xef\xfe\xd8\xf9\xd5\x7b\x00\xf7\xc5\xa3\x4f\x88\xdf\x78\xc4\x5e\xd8\xef\x01\xfb\x5a\xe0\xe1\xd8\xab\xef\xf5\x7f\xe6\xa4\x66\x90\xd5\xe3\xb6\xeb\x8d\x59\xe0\x98\x16\xfa\x39\x3c\x39\xf8\xa4\xb8\x42\xc6\x9b\x16\x4f\x6d\x9f\xfb\x3d\x38\x77\x7c\x47\x4a\x98\xd7\x5a\x13\x9d\x96\x32\x77\x75\xf8\x10\xde\xc0\x8a\x31\x7b\xdd\x25\xeb\xd4\x23\x19\x8f\xad\x33\x68\xeb\x0c\xba\xe1\xf8\xa4\x33\x08\x8b\x08\x36\xd7\x13\xc4\xc4\x55\xdb\x10\xc6\xca\x08\xba\xb3\x75\x42\xb4\xbb\xbb\x05\xd4\xc6\x6e\xa9\xd7\xad\x5c\xeb\x64\x1a\xdc\xd0\xf2\xd5\x31\x4c\xb2\x0f\x2d\xdb\x71\xe1\xc3\x00\x1e\x4d\x94\xa1\x69\xe3\xaa\x26\xaf\xcc\x2b\x78\x0c\xf9\x08\x2d\x16\x72\x8b\xb9\x98\x59\xfc\x09\xdc\x4a\x6c\xf4\x89\x8b\x1a\x67\xd7\x2b\x87\x35\x38\x3b\x55\x4a\x26\xd0\x05\x09\x61\xf1\x3c\x08\x9f\x7d\x6d\x78\x1b\x4d\x2f\x21\xda\x98\xb0\x94\x89\x84\x59\xe0\xf6\xa8\x6d\x2d\x15\xe4\x48\x5c\x39\xf0\xfa\xb4\xc2\x64\x10\x14\x7f\xab\xc7\x78\x5a\x09\x08\x86\x11\x6d\x10\x2c\xc8\x43\x00\xa9\xef\x2d\x6c\x0a\xa9\x18\x72\x5a\x7b\x59\xdb\x75\xb6\xec\xbc\x8b\x77\xdf\x33\x7d\x64\xab\x93\x32\xb4\xb4\x59\xd6\xee\xe7\x78\x93\x7c\x0a\xc1\xc0\xee\xdb\xe7\xef\x6e\xeb\xec\x69\xdb\xec\x67\xcb\xbc\x47\xec\xa4\xcf\x6d\xb2\x8f\x60\x49\x51\xb2\x29\xff\xd0\xd3\x3a\xdd\x0f\xea\x09\x79\xca\x84\xe6\x53\x8e\xcd\x7b\x8b\x92\x15\x4c\x80\xab\x15\x4a\x34\x8c\xec\xb7\x3b\x65\x1d\x9c\xde\xc4\x64\x1e\x54\xb8\xfb\x15\x65\xe7\xab\x94\xfd\xad\x1c\x23\x5b\x39\xd6\xfa\xf8\x4c\x72\xcc\x72\xee\xe6\x08\x31\xc8\x3c\xef\x9e\xfd\x7e\x10\xa7\xb2\x03\x23\x77\x2f\x21\x6e\xc0\xb8\x79\xd1\xa8\x25\x26\xaf\x61\x1d\x5b\x49\x32\x76\xc5\x32\xab\x37\x91\x9c\x0a\x3a\x43\xec\x7d\x2d\x3d\x5a\x8f\x2c\x7d\xff\xa4\x66\xde\x3d\xe8\xf1\xae\xc4\x0b\x7e\x2c\x65\x96\xb1\x52\x91\x8c\x5f\x32\x72\xc8\x8a\x4c\x2e\x72\x9b\xfb\x9a\x92\x73\x4d\xb5\xe1\xea\x73\xa6\xdb\x85\x7d\xbb\xc1\x78\xb8\x2a\xf4\x9e\xc0\xce\xb1\xac\x1d\x8a\xc2\x49\x61\x2b\x28\xdf\x0a\x10\x1a\xfb\xd0\xca\x65\x48\x4e\xd8\x15\x2b\x87\xe4\x78\x7a\x22\xf5\x29\x6a\xdf\x71\xc2\x1d\x5e\x48\xf8\x94\xbc\x34\x76\x9d\xd2\x44\x63\x3b\x8d\xa0\x40\x5d\x96\xd1\x00\x35\x50\x5b\x1f\xf5\x79\xcb\xb5\xe7\x30\x92\xaf\x3c\x6f\x15\xc9\xe8\x34\x4d\xbe\x5f\x51\xe7\x09\xda\xc7\x7a\xd2\x1a\xbb\x37\xe0\x6f\xc4\x55\x70\xd0\x63\x60\x05\x72\x41\x4a\xa6\x0a\x29\x14\x8b\x71\x15\xfd\x1b\xa1\xb5\xdb\x2f\x68\x6b\xeb\xcd\xb3\xeb\xb6\x59\x48\xa5\xa1\x84\xb6\x9f\x2e\x58\xa7\x6e\x38\xa8\x48\xa6\x59\xc6\xd2\xa8\x0d\x1a\xb6\xef\xa1\xb1\x87\x20\x81\x76\x0c\xa9\x6f\xe8\x81\x85\xca\x51\x8d\x73\x74\xbd\x6f\xa9\xe7\x9a\xd6\xb8\x7e\xca\x37\x55\x36\xd7\x0b\x13\xf6\x91\x80\x01\x96\x10\x9e\x01\xf7\x5b\x05\x9d\x6f\xe6\x52\x5e\x92\x44\xe6\x45\x06\x4b\xa7\xc3\xca\xaa\x1b\x6f\x79\x56\x1a\x99\xd1\xd5\xb3\xa0\x27\x17\x9c\xe8\xd6\x92\xab\x93\x22\xd6\x87\x1a\xc6\x3e\xb0\xa4\xb7\xa6\x9d\x47\x1f\x58\x12\x74\x9d\x05\x0c\xaa\xc4\x21\x44\x98\x15\xdb\xbd\x99\x78\xe7\x90\x43\x5f\x6e\xfe\x0e\xb5\x74\xe1\xd1\x80\xed\x83\x31\x1d\xbc\xb9\x7d\x04\x74\x8a\x00\x5b\x08\xeb\xeb\x42\x18\x0d\xcf\x8c\xb8\xf4\x96\xb0\xfe\x7c\x22\xb5\x1b\x0b\x7a\x42\x49\xa9\xc9\xde\xee\xb3\xdd\xc1\x92\xff\xb1\x81\x91\x7d\x11\xdc\xc9\x01\xdb\xb1\x00\xa0\x44\x96\xec\xa6\x43\xc2\xb5\xcb\xb4\xc6\x86\x45\xf0\x56\xb6\xe8\x6f\x48\x94\x24\xba\xa4\x29\xb7\x6a\x0c\x9c\x35\x17\xe9\xb2\xb2\x52\x7e\x6f\xf7\xe3\xae\xed\x65\x74\x2d\xc5\xae\x86\xd7\x1f\x93\x0b\xc4\x89\xf1\x03\x2d\x64\x05\x2d\x3a\x91\x04\x45\xc6\x13\xae\xb3\x05\x48\x2c\x22\x2b\xec\xe7\x65\xf6\x0b\x5b\x6c\x78\xf4\x81\x6b\xd7\x4d\x44\x4e\xc9\x73\x6c\x27\xc6\xa8\xf5\x80\x66\xfc\x8a\x3d\x9b\x33\x9a\xe9\x39\x26\x89\x08\x29\x46\xd8\x11\xd2\x88\x12\xfb\x4b\xd7\x78\x49\x37\x77\x62\x78\x74\x70\x2d\x2e\xbf\x50\x47\xcb\xc1\x08\xd1\x1f\xda\xb7\xa9\x26\x4b\x70\x5d\x17\x17\xa7\x3f\x44\x8d\xaa\x41\x8a\x6b\x5d\xb8\xd4\x9d\xa0\x9b\xfb\x06\xc8\x8e\x7e\x82\x95\x9d\x3a\x56\x93\x1e\x45\x58\xd7\xce\xd5\x64\x35\xfc\xda\xdd\x5b\x56\x93\x7f\xc8\x0a\xc0\x40\xe8\x24\x5b\x78\x24\x06\xc5\x34\xd9\x31\x43\xed\x18\xf1\x64\xb8\xe1\xef\x8c\xa6\x08\x94\xa1\x34\xa3\xad\x54\xb7\xf0\xe8\x2d\x88\x16\xbc\x5b\xbf\xfb\x40\xa5\xb4\xcc\xc9\xdc\x7e\x76\x5c\x7a\x69\x57\xc6\x18\x56\x8f\xab\x6b\x2a\x59\x81\x12\xce\xde\xf3\xe4\xe4\xd7\x92\xdc\x40\xba\x47\x5d\x0b\x92\x90\x6c\x61\x53\x1c\x2e\x90\x58\x88\x3b\xd3\x93\x2c\xed\x21\xf9\x81\xf4\x98\x00\x41\xba\x15\x72\x36\x07\x82\xa0\x5e\xf7\x5c\xaf\xde\x72\x2a\x48\x6f\x79\x03\x64\x95\x93\xd5\xf2\x0c\x7a\x5f\x7a\x22\x62\xaf\xd1\x7a\xd2\xbd\x54\x34\x3c\x6e\x27\x40\x3f\x93\x4f\xfa\xa4\x40\xd1\x43\x6a\xf7\x72\x62\x37\xc2\x48\x41\xe9\x25\x0a\x57\x10\x13\x8a\x95\x57\x6d\x8b\xb9\xeb\xa3\xbf\x4f\x97\xed\x2d\x7e\x77\xac\xa8\x93\x2e\x89\xf0\x6d\xb0\x1d\xac\xe9\x32\x41\x82\xcc\x04\xdb\x35\xdb\xb9\x73\xdd\x76\x44\xc5\x8c\x91\x17\xe6\xce\xbf\xfc\xf9\xcf\x5f\xff\x79\x8c\xc3\xfb\x2c\x05\x41\x8e\xf7\x4f\xf6\xff\x79\xfe\xd3\x01\x14\xc7\x76\xa5\x6a\x4f\x29\x98\x7d\x27\x60\xf6\x9a\x7e\xf9\xa0\xc9\x97\x50\xf2\xd1\x59\x8a\xc4\xbe\x7f\x18\x32\xc4\xf7\xb4\xba\x5f\x80\xb3\x67\x74\xcd\xd8\x91\x6a\x96\xda\x46\xac\x31\x9d\x14\xe7\x32\xb9\xec\xd1\xae\x39\x64\x45\xc9\x12\xf4\x93\x5d\x1c\x9c\xe2\xe8\xc6\xbe\x3c\x79\x7b\x51\x97\x1a\x40\x3e\x4e\x0d\xa6\xf7\x77\xeb\x49\x33\x36\xe9\x25\x2b\xb4\x37\xdd\x27\x34\xb9\xbc\xa6\x65\x0a\x9e\x2d\xaa\xf9\x84\x67\x5c\x23\xf6\x5f\xc9\x6c\xdf\x2a\x4c\xf8\x43\x90\x33\xd7\x17\x18\x65\x39\x3a\x10\x9c\x3b\x14\x5c\x56\x98\x47\x33\xa5\x3c\x03\x0f\xaa\x6d\xc9\x8b\x19\x41\x49\xe1\x5d\x7a\xa1\x4f\x7b\x6b\x7c\xb9\x63\x63\x8d\xaf\xa0\x65\xf0\x7d\xed\xb0\xae\x79\x89\x1b\xbc\xd5\xd9\x2d\xae\x8c\xba\x77\x6f\xb7\xba\x1e\xc6\xdb\xdc\xad\xae\x28\xd9\xb9\x96\xad\x5a\x00\x90\xe5\x28\x09\x0e\x76\x43\x8c\x64\xc2\xa6\xd2\x08\xe1\x1b\x83\x1e\x69\x05\x8b\x90\x0a\x28\x0e\x74\x5e\x2d\x19\x05\x36\x30\x23\xd3\xf5\xcb\xce\x2c\x70\xea\x33\x15\xa2\xa5\xba\xe6\xc7\x43\xf3\x75\x2c\x87\xb7\x1b\xd6\x55\x0e\xb6\xf5\x32\x9c\x64\x3a\x41\xcf\x6d\x20\xc8\x01\x39\xd4\xbe\x7e\x33\x8c\x92\x94\x54\xcd\xb1\x2d\x31\xfb\xc0\x5d\x7f\xfa\x53\x99\x36\x9b\x89\xcf\x4a\x9a\x30\x52\xb0\x92\x4b\xb3\x19\x55\x42\xa7\xf2\x5a\x90\x09\x9b\x71\xa1\x1c\x29\x00\x3c\xdd\xd2\x0c\xe2\x31\x5c\x79\x60\xb8\x31\x39\x8b\xc0\x4e\x6c\x19\x52\x22\xeb\xa5\x69\xdf\xb9\x19\x49\x82\x1d\x0b\xe8\x84\xbd\x7a\x3c\x85\xc3\xf6\x45\x9f\x7a\xe5\xbd\x4a\xc0\x93\x53\x96\xd1\x05\x66\x9b\x42\xcb\x72\xfe\x1f\x56\xaa\x41\x0f\x11\x27\x6c\xc0\xe5\x7e\xbb\xf1\x3d\xb8\x22\x25\xa3\xc9\xbc\x5b\xf0\x77\x1b\xa2\xba\xe3\xb1\x0d\x51\x75\x19\x64\x1b\xa2\xda\x86\xa8\x3e\x71\x6c\x43\x54\xdb\x10\x55\xe3\xd8\x58\x2b\x69\x1b\xa2\x6a\x7d\x6c\x43\x54\xb7\x1f\xdb\x10\xd5\x1d\x8e\x6d\x88\xea\x8e\xc7\x36\x44\xb5\x0d\x51\x6d\x43\x54\xdb\x10\xd5\xef\xc8\x6f\xe7\x8e\x6d\x88\x6a\x69\x90\x6d\x88\x6a\x1b\xa2\xba\xf3\xb1\xb1\xc6\xd7\x36\x44\x85\xc7\x36\x44\x15\x1f\xbf\xaf\xad\xce\x05\x78\x4e\x8d\xa9\xd7\xbd\xa6\xed\x14\x82\x0a\x3c\xb1\x71\x22\x39\x8d\xea\xa0\xf0\x51\xe3\xba\x47\x45\x00\x0b\xe2\x4a\x71\x6c\x44\xa8\x8e\x33\xad\xac\x97\xea\xd8\x47\xae\x90\x69\x1d\xa8\x08\x22\x14\x68\xf0\xb6\xaf\x59\x5b\x5b\x35\x56\x97\xb0\xc4\xe7\x09\x49\x6c\x48\xfc\xa6\x87\x30\xc4\x36\x04\xf1\xe4\x42\x10\xfd\xb8\xef\x7a\x70\xdd\x75\xde\x2a\x6c\x64\xfe\x62\x5e\x32\x35\x97\x59\x6b\x46\x8f\x98\xfc\x0d\x17\x3c\xaf\x72\xe8\x14\x6b\xf8\x99\x5f\xf9\x14\x00\xdf\xbe\xda\x4a\x6c\xf4\x22\x06\x2d\x65\x5d\x2b\x59\xa8\xdf\x9c\xd3\x2b\x68\x8f\x5a\x25\x09\x63\x69\xd0\x94\x1e\x34\xac\xaf\xc7\xfe\x49\xbe\x75\xc6\x8b\x6e\xf2\xa6\xdb\x26\x8e\x70\xa4\x30\xca\xd7\x5f\xb5\x1a\x63\x56\x16\xfd\xc8\xe5\x1f\xce\x4e\x0f\x02\xb9\x4c\x85\x13\xcb\x5c\x5c\xc9\x0c\xa8\x4a\xf1\x22\xa3\xac\x8d\xb1\x7e\x9f\x1b\x83\x69\xc2\x34\x0d\x6c\x1b\x6b\x16\x28\xc2\x04\x9d\x40\x87\x5a\x73\x97\xdf\x91\x4f\x71\xdf\x65\x54\x57\x25\x23\x33\xaa\xd7\x29\xf0\xbb\x9b\x30\x9d\xcc\x97\x3e\xf6\x9b\xae\x1a\x7a\xec\x83\x33\x7a\x78\xec\x85\x9a\x01\x5f\x20\x82\xfe\x9d\xf5\xf0\xce\x92\xb2\xbb\x6e\xdc\x7d\x69\x11\x80\xb8\x81\x0f\xef\x8d\xc0\x3b\xe7\xb6\x75\x94\xdd\xce\x43\x23\xc8\x75\x95\xd2\x92\x14\x19\xad\xfb\x42\xc1\x0c\xfc\x1d\xf6\xa0\x83\x39\x4b\x2e\xcf\x6c\x24\x76\x4f\x31\xe6\x75\xd3\x19\xd7\xf3\x6a\x32\x4e\x64\xfe\xcc\x88\x04\xfc\xbf\x49\x26\x27\xcf\x72\xaa\x34\x2b\x8d\xba\x6a\xb7\xb8\x51\x62\x46\xe1\x62\x36\xce\xd3\xc1\x98\xbc\x17\x58\xdd\x5e\xf7\xa1\x0c\xb0\x1d\xcc\xf3\x1d\xce\xc6\x84\x19\xe9\x2a\xc1\x0f\x11\x40\xd8\x99\xd7\x1b\x77\x01\x4a\xee\xbc\x25\x75\x8c\x82\x7f\xfe\x08\xf8\x56\x72\x91\x1e\x1c\x2e\x8f\x2d\xd2\xdd\x5b\xc6\x47\x0f\x11\xee\x0d\x8a\x6e\x6f\x8c\x6a\xbc\x29\x11\xed\x0d\x44\x9b\xee\x21\x00\xdb\x47\x04\xbb\xbf\xe8\xf5\x03\x80\x32\x3f\x4c\xd4\xba\x47\xd7\x5e\x4f\xd1\xea\xcf\x11\xa9\xee\xe5\xab\xbb\x46\xa8\x3f\x5f\x74\xba\x9f\xcf\xed\xd3\x10\x78\xac\x11\xe9\x1e\x5c\xf4\x7d\xba\xe7\x7b\x73\xcd\x3f\x58\x04\xba\x7b\xf4\x79\x03\x22\xcf\x9d\x89\xcc\x05\xd7\x9c\x66\x87\x2c\xa3\x8b\x73\x96\x48\x91\xb6\xde\x61\x1a\x28\x9d\x7e\xfd\x28\x1c\xd6\xfa\xa9\xe2\x42\x8b\x39\xb5\x60\xe4\xc6\xa2\xc2\xc2\x12\x17\xcb\xb0\x0a\x05\x44\x95\xf1\x2d\x37\x32\x3a\x41\x36\xc6\x21\x86\x55\x27\x7d\x4e\xe2\xdf\xe5\x35\x91\x53\xcd\x04\xd9\xe3\xc2\xcd\xe3\x20\x30\x03\x6b\xef\xa4\x67\x6b\xf3\xeb\x8b\xe7\xee\xe2\xa7\xe7\x76\x04\x07\xab\x52\x0f\xef\x05\xb6\x0f\xfa\xb4\x1b\xd8\x5e\x38\xad\xb2\xd8\x15\x8c\xee\xe1\x58\xde\xbc\xa8\xe1\x94\x5f\xc0\xb8\x7e\xb5\x51\x91\x12\x5b\x89\xf6\xf4\x26\xad\x73\x5e\x4d\xac\xfa\xf9\x3c\x9a\x4f\x79\x8d\x2f\x0e\x4e\xd1\x69\xbc\x75\x97\x6c\x8a\xbb\x64\x4d\xb9\x29\x1b\xa8\xe8\x3e\xd2\x7c\x94\xad\xa2\x7b\x8f\x23\xa8\x4d\xfd\xa1\xa4\x09\x3b\xed\x5d\x47\x70\xcb\x89\xa4\x55\x49\xad\x00\xf4\x2a\x9f\x5b\x3c\x82\xb1\x14\x57\x93\xaf\xe7\x85\x4a\xd9\x69\x95\x65\x0b\x52\x15\x52\xc4\xd5\xcf\x18\x6b\x6f\x16\xd3\x82\x4b\x7e\xc5\x53\x6a\xc5\xb2\x28\xa5\xdd\x33\xcb\x4a\x08\x23\x83\xeb\x9e\x68\xa0\x48\x02\x4c\x33\x8d\x4a\x76\x15\x9f\x99\xd7\x37\xfb\x1f\x54\xf3\xd6\x09\x88\xd1\x80\xe6\xee\xa9\x2c\x13\x3e\xc9\x16\x64\x4e\x33\xdf\x00\x87\x92\x4b\x9e\x65\x76\x98\x31\x39\x67\x1a\x43\x0a\xb8\x77\x66\x52\xcc\xe0\xe5\xa8\x70\x8d\x17\x59\x62\xee\x4d\x32\x46\x45\x55\xe0\xf3\xcc\x4e\xbc\x90\x55\xe9\x9e\x37\xf6\x81\x09\xbf\x03\x0b\x9e\x0d\x83\xf6\x6e\xb7\x4e\xac\xcf\xfd\xa9\x94\x51\x00\xde\x3a\x58\xea\x61\x38\xa6\x43\x0e\x57\x41\x73\x9f\xa2\x94\x57\x3c\xc5\xe8\x86\x23\x1b\x34\x92\xc6\x06\x3e\x7e\x3d\x0b\x29\x46\x82\xcd\x28\x28\x2a\x76\x15\xe1\x9c\xe1\x38\x98\x41\x20\x52\x68\xe9\x63\x34\x7c\x59\x44\xe5\xf4\x57\x1c\x9b\x11\x07\x94\x23\x7b\x42\x12\x09\xf9\xa8\x95\xe0\x1a\x1b\xdc\xcf\x2b\x4d\x52\x79\x2d\x06\xf7\x8a\xba\x42\xa0\xf5\x62\x25\x81\xe2\xf0\xeb\x2a\x3d\x07\xbf\xf7\x76\xf2\x72\x65\x5d\x9f\x53\x52\x09\xc5\x3a\x6e\xef\xbd\x29\x47\x7f\xf9\x53\x3b\x19\xc1\x73\x26\x2b\xfd\x59\xac\xbf\xeb\x39\x4f\xe6\xa1\x32\xcb\x73\xa6\x88\xac\x1a\x66\xf1\x0b\x7b\xdb\xea\x19\xda\x9a\x80\xab\x8e\xb6\x8e\xdd\x15\xde\xaf\x26\x1c\x42\xdd\xf9\x1a\xf2\xc4\x0f\x4f\xce\xff\xf9\x7a\xff\xfb\xa3\xd7\x63\x72\x44\x93\x79\x88\x89\x21\x08\x05\xa1\x01\x82\x62\x4e\xaf\x18\xa1\xa4\x12\xfc\xb7\xca\x06\x7c\xf7\xfc\xbd\x83\x5e\xb1\xda\x5b\xee\xbe\xd0\x9d\xbf\xb7\x76\x70\xd8\xeb\x1f\xf3\xb2\xa4\x62\xd0\xc0\xa5\xa9\x3e\x1d\x99\x9f\xd0\x38\x00\x55\x0b\x12\xe7\x67\xfc\xca\x8a\x61\x0b\x7e\x4f\x53\x9f\x29\x66\xf8\xdc\xb0\x85\xd9\xaa\xe8\x04\x32\xbc\xe6\x8c\x08\xa6\x0d\x5b\x7b\x1f\x93\x14\x2a\x02\x27\xa9\x14\x53\x43\x32\xa9\x20\x27\xad\x28\x79\x4e\x4b\x9e\x2d\xc2\xc1\xcc\x5e\x75\xe2\x43\xde\x8b\xe6\x2b\x1d\xbe\x3d\x3a\x87\x1a\x81\xa2\x44\xd8\x12\x48\x2a\x83\xdf\xe1\xb3\x26\xcc\xdc\x61\xdb\x08\x8f\xc9\xbe\x58\xe0\x8f\xb8\xc0\xb9\x22\x19\x57\x9a\xc1\x16\x6c\x75\x48\x17\x4c\xdf\x79\x3e\x86\xff\xed\x98\xaf\x2c\x8d\x92\xe9\x73\xe5\x92\xa5\xe4\x55\x54\x43\xf9\x24\x0b\xa8\x69\xbf\xfd\x49\x35\x84\xab\x93\x84\x0c\x11\x83\x86\x70\xd4\x4f\x35\x90\x17\x1b\x04\x72\x31\xcb\x42\xae\x6a\x27\xf6\xbb\xda\x96\x5d\x2d\xcb\x51\xfd\x05\xa7\x6d\x0d\xcc\x5e\x1a\xd3\xd5\xef\xd0\x53\x3b\xa7\x7a\xf7\x73\xe6\x94\x95\x08\x32\xec\xd0\x7b\x7c\xea\x56\x80\xd5\x6e\xf2\x46\x5b\xd7\xa2\xce\x49\x1a\x92\xe7\xe4\x5b\xf2\x81\x7c\x0b\xe6\xd5\x5f\xba\x36\xbf\xea\x6a\xf8\xf4\x91\x62\x64\xac\xfa\xe3\xd3\x9e\x28\xfe\xb3\x91\x4e\x66\x44\x43\x55\x2d\xc9\x84\x5b\x75\x9e\x7d\xd0\xac\x34\x72\xd4\xce\xc4\x5a\xdb\x86\x99\x17\xfc\x8c\x6c\x86\xe1\x86\xe3\x69\x9c\xd6\x74\x3f\x46\x33\xb7\xff\x5d\x2a\x7d\x62\xa5\x50\xdc\x00\xa7\x1e\x2d\xa7\x3a\x99\xc7\x62\xcc\x28\x6a\x4a\xd7\x0b\x4c\x91\x54\x42\x96\x15\xa6\x2f\xcf\x79\x87\xe4\x89\xcd\x61\xe3\x6e\xf1\xf4\x68\x3e\x6f\x9b\xa9\x86\x03\x05\x2c\x1f\xab\x58\x05\xc8\x58\x85\x4c\xad\x4e\x66\x5e\x2b\x0d\xf6\x8c\x5b\x94\x32\xeb\xab\xf1\x5e\x66\xe0\x25\xb3\x9e\x12\x2a\xb0\x80\x64\xca\xca\x12\x33\xce\x27\x0b\x97\xac\xd7\x79\xf2\x3a\xad\xa4\xa2\x94\x5a\x26\xb2\x43\x67\xb3\x38\xc6\x6d\x87\x03\x22\x60\x96\xaf\x73\x93\xbf\x3b\x3c\x1d\x92\x8b\x83\x53\xe8\xf6\x74\x7e\x70\x71\x1a\x5b\x2a\x3b\x17\x07\xa7\x3b\x6b\x25\x05\x71\x9a\x15\x38\xa6\x5b\x0c\x12\x39\x9e\x8c\xda\x36\xca\x69\x31\xba\x64\x8b\x96\x7b\x6a\x1f\xfb\xfa\xc8\xcf\x70\x2f\x1f\x84\x64\xce\x69\x71\xef\xd1\x4a\x46\x53\xfe\x99\xaa\xb8\x5c\x1a\xac\x7f\xe6\xea\x72\xae\x5c\x5e\xb1\x14\xd5\x61\x77\x07\x13\x69\x21\xb9\xd1\x17\xb7\x35\x5e\xf7\xbf\x7b\x5b\xe3\x75\xe7\x63\x5b\xe3\xb5\xad\xf1\x5a\x3e\x36\x26\x91\x75\x5b\xe3\xf5\xb4\xe2\xf6\xdb\x1a\xaf\xdf\x79\xe8\x7f\x5b\xe3\xb5\xfa\xd8\xd6\x78\x6d\x6b\xbc\xee\x76\x6c\x6b\xbc\xee\x7f\x6c\x5c\xd2\xd2\xb6\xc6\xeb\x5e\xc7\xb6\xc6\x6b\xf9\xd8\xd6\x78\xdd\x70\x6c\x6b\xbc\x6e\x38\xb6\x35\x5e\xdb\x1a\xaf\x6d\x8d\xd7\x36\xf5\xf5\x93\x63\x6d\x66\xea\x2b\xd9\xd6\x78\xd9\x63\x5b\xe3\xf5\x24\x12\xfc\xc8\xb6\xc6\xeb\x4e\xc7\xb6\xc6\x6b\x5b\xe3\xd5\xe6\xd8\xd6\x78\x3d\x15\x77\xc9\xb6\xc6\x6b\x5b\xe3\xf5\xfb\x51\x74\xb7\x35\x5e\xdb\x1a\xaf\x6d\x8d\xd7\xb6\xc6\xeb\xd6\xb7\xd8\xd6\x78\x3d\x05\x13\xd0\xf5\x01\xee\x5e\xb3\xb4\x7b\x20\xf3\xa2\xd2\x8c\x9c\xb9\x21\xbd\x16\x89\x82\x81\xab\x50\x23\xe8\x9e\x42\x98\x48\x31\xe5\x33\x2b\xd9\x9f\x61\xf3\xdd\x91\xff\x9e\x51\xd0\xf0\xf6\x11\xe6\x0f\x66\x3c\xe7\xed\x0a\xc9\xc8\xd2\xc4\xbc\x86\xb1\x82\xb8\x8c\x59\x49\x39\xfd\x00\x4b\x84\xe6\xb2\xc2\x86\xc5\x89\x9d\x3f\x4f\x42\x8c\x5e\x6d\xdc\xcc\x90\x7e\x4c\x9c\xba\x22\xee\xb4\x8f\xb4\x12\xaa\x35\x2b\xc5\x4b\xf2\x3f\x7b\xef\xbf\xfc\x38\x1a\x7c\xb7\xb7\xf7\xcb\xf3\xd1\x5f\x7f\xfd\x72\xef\xfd\x18\xfe\xf1\xc5\xe0\xbb\xc1\x47\xf7\xc7\x97\x83\xc1\xde\xde\x2f\x3f\xbe\xf9\xe1\xe2\xf4\xe8\x57\x3e\xf8\xf8\x8b\xa8\xf2\x4b\xfc\xeb\xe3\xde\x2f\xec\xe8\xd7\x3b\x0e\x32\x18\x7c\xf7\xc7\xd6\xaf\xdc\x59\x25\xee\x4f\x21\xee\x49\x1d\x7e\x10\x65\xd8\x06\x74\x7b\x5a\x8b\x36\x19\x65\x69\x35\xda\x0d\xeb\xb6\xd5\xe8\xa4\x29\xa8\x79\x7e\x1c\xae\x88\xcc\xb9\x36\xca\xa1\xd1\x07\x69\x98\xce\xca\x75\x64\x94\x5a\x39\x00\x09\xdd\x54\x63\x7b\x75\x9f\x0a\x1a\x24\xb1\x48\xa7\xf9\xd9\xfe\xf3\x3c\x2f\x32\x68\x6b\x0e\xeb\x79\xe4\x72\x59\x60\x73\xdd\xca\x86\x4f\x1f\x5b\xd9\xf0\x14\x65\x83\x62\x49\x55\x72\xbd\x38\x90\x42\xb3\x0f\xad\x3c\x2c\xb1\x68\x38\x8f\x07\xb4\x39\x63\xb6\x8a\xdb\xfe\x46\x64\x81\x79\xdf\x8d\x72\xfa\xb9\xac\xb2\x14\x8a\x39\x2a\x01\x06\x26\x56\xe9\x31\x8d\xd6\x1f\xd8\x3d\x90\xca\xdd\x7c\x88\xb3\xe7\xd0\xcc\xfc\xad\xe2\x57\x34\x33\xd6\x6e\x7d\xc7\x29\x58\x30\xe1\x4d\x77\x5d\xf3\x9a\xaa\xcb\x7a\xc1\xb3\x91\xd1\xa1\xfd\x3b\x3f\x73\x9f\x04\xa7\xd8\x07\xfd\x18\xb5\x34\x50\x90\x4e\x4b\x7e\xc5\x33\x36\x63\x47\x2a\xa1\x19\xc8\xb5\x7e\xf6\x8a\xfd\x1b\x46\x87\x89\x2f\x65\xa6\xc8\xf5\x9c\x19\x59\x4d\xa8\x73\x01\x40\x85\xdd\x8c\x72\x41\x72\x33\x45\x85\xbb\x59\xa1\x2f\xc1\x88\xff\x82\x96\x66\x82\xbd\xcf\x00\x4c\xe4\x89\x94\x99\xad\x78\xc8\x16\xf5\xf8\xb6\xf6\x47\xc8\x7f\x0a\x76\xfd\x4f\x33\x9a\x22\xd3\x8c\xce\xbc\xab\x40\x31\xbd\xe4\xed\xab\x87\xbe\xf1\x03\xa0\x9c\xa0\x62\x84\x66\xd7\x74\xa1\x6a\xc7\x49\x80\xfb\xa0\x5e\x92\x17\x03\x60\x67\xaa\x88\x1f\x23\x25\x5f\x0d\x20\xfc\x77\xb0\x7f\xfa\xcf\xf3\x7f\x9c\xff\x73\xff\xf0\xcd\xf1\x09\x39\x91\x9a\xe1\xa6\x16\x34\x07\x4c\xbc\x85\x61\xde\x12\x9e\x01\x56\xba\x54\x63\xf0\x5d\x72\x45\xae\xb9\x48\xe5\xb5\x6a\xed\xa3\x45\xf6\x33\xc4\x63\x54\xb4\x1a\x23\xa1\x05\x85\x9e\x87\x1d\x76\x98\xa5\x0c\x93\x70\x50\xd8\xc3\xd3\xf4\x59\x5a\xca\x02\x89\xe0\x9c\x5c\xf5\x56\x1b\x9b\xd1\x61\x0e\x2b\xcc\xef\x34\x1e\x70\x56\x52\xa1\x6b\x6f\x4f\x3d\x67\xb6\xd9\xe2\xb8\xf3\x74\x3c\xee\x8a\x26\x9a\xf6\x57\xcd\xb4\x9f\xa6\x2c\x8d\xc8\xff\xe4\x32\x07\x0f\xdc\xc7\x2d\x6a\x94\x0a\x72\xfa\xf6\xfc\xf8\xff\x69\xf0\xf1\xa2\xe8\x96\x28\xd5\x4f\x65\x6c\x29\x8b\xde\x66\xf7\xcc\x56\x5e\x6e\xe7\x77\x23\xe6\xd7\xef\x96\xfd\x84\xe7\xcf\x2a\x11\x03\x19\xd5\xe3\x93\x5c\xa6\x6c\x4c\x4e\x7d\x9c\x20\xfe\x35\x00\x38\xa0\x25\x23\xe6\x12\xa1\x39\xcd\xb2\x45\xa8\xa2\x69\x89\x55\x88\x11\x36\x43\x28\xc8\xa7\x34\x53\xeb\x96\xc6\x5d\xf6\x46\xa3\x47\xbc\x31\xf6\x70\x2f\xd3\xe1\x47\x23\x29\x13\x52\x5b\xc5\xda\xbc\x25\xe0\x5d\x94\x32\x21\x68\x7c\x07\xc9\x58\xd1\xfe\xa6\x30\x56\xe1\xb6\x46\xae\x1c\xb1\x4f\xfd\xc8\xe8\xa8\xae\x14\x6b\x2a\xe8\xae\x0f\xb1\x37\xc7\xcd\xe8\x25\xa3\xa9\x14\xd9\x02\x32\x2f\x31\x97\x22\xa7\xea\x92\xa5\x78\xc2\xaa\x66\x3e\x52\x61\x46\xf4\x8f\xba\x30\xef\xed\xc2\x12\xa0\x92\x61\x86\x07\x84\x33\x58\xba\xe6\x59\xef\xb0\x08\x0d\x51\xde\x8a\x6c\x71\x26\xa5\x7e\xe5\xcb\x68\x7b\xe1\x80\x9f\xad\xb6\x1c\xbb\xa2\x41\x9d\xa4\xf0\xdc\x11\xcc\x06\x2c\xaa\xb0\x82\xf7\xb0\x9e\xf1\xc7\xbe\xa4\xca\x4a\xec\xab\x1f\x4a\x59\xb5\xde\xc4\x96\x94\xcd\x1f\x8e\x0f\x41\x14\x55\x36\x54\x29\x74\xb9\x00\xe8\x80\x65\xd4\x37\x6f\x18\xbc\xb3\xc1\xd6\x70\x4d\xd4\x71\x31\xf2\x86\x2e\x08\xcd\x94\x74\xb4\xe4\x62\xa5\x15\x6a\x4d\x5c\xf3\xf3\x44\xea\xf9\x92\x6d\x6b\x16\xd4\xf2\x7d\xc3\x20\x72\x59\xc3\xd0\x71\xb1\x74\xbb\xa6\x97\x4c\x91\xa2\x64\x09\x4b\x99\x48\xd6\x3d\xed\xeb\x0e\xf8\x01\xeb\x9c\x48\x61\x16\x66\x2f\xcc\x73\xec\x23\xbd\x96\xa4\x21\xab\x40\xcc\xd8\x5a\x7f\x14\x22\xc7\xb0\x2c\x2b\xc5\x4a\x0c\x73\x97\x15\xc3\x99\xfc\xb1\x9a\xb0\xcc\x50\xde\x98\xa4\xb6\x53\x3c\xba\x33\x78\x4e\x67\x8c\x50\xed\x39\x4d\x4b\xc2\x84\x32\x12\x13\x1d\xa0\x9a\xa4\x92\xd5\xd5\xf7\x54\x91\x77\xc7\x87\xe4\x39\xd9\x33\xcf\x1a\x00\xff\x40\x23\x79\x2d\x31\xc9\xad\x69\xa3\x4e\xdd\x10\xf0\x4a\xc0\xbc\x44\x96\x28\x24\x86\x44\x48\xa2\xaa\x64\x1e\x76\xaf\x77\x66\xb3\x4d\x84\x84\xd0\xca\x66\xf2\xfa\x7a\x25\xd4\x3b\xc5\xca\xde\x04\xd4\xbb\x16\x02\x2a\x54\xa3\x0c\xcf\xc5\xd4\x43\xc6\xca\x99\xa6\x29\xd5\xd4\x0a\x2e\x77\xc1\xc6\x4e\xe9\xef\x5b\x7c\x29\xf6\x9a\x8b\xea\x03\x26\x1e\xf5\xe7\x6a\x39\x3f\x82\x61\x49\xe2\xa8\x0e\xb3\x4e\x8b\x22\xe3\x88\xb6\xd1\x48\x84\x3b\x8e\x78\x65\x78\x83\x9a\x08\x72\x82\x66\x99\x34\xf2\xd1\x28\x27\x54\xa4\x32\x5f\x7a\x98\x51\x22\x59\x84\x97\x3a\x26\x5b\xee\x8b\x8f\x0d\x71\x0a\x65\xec\x8a\x75\xc0\x16\x6b\xe2\xc3\x9a\xd1\x0c\x71\x1c\x47\xc0\xf0\x24\xa3\x13\x96\x21\x8d\x91\x03\xd5\x32\x07\xae\x3b\x1b\xb5\x94\x59\x7f\xe5\x33\x67\x32\x63\x98\xde\xe5\x08\x61\x86\x7f\x14\x74\x80\x41\xfa\xa2\x03\x58\x83\x11\x1d\xc0\xae\x7d\x0c\x74\xa8\x3a\x6c\xf5\xa4\x49\x07\xa3\x37\xc4\x74\x80\xcd\x7b\xd3\xe9\xa0\x58\x92\xc8\xbc\x38\x2d\xa5\x31\x3b\x7b\xdb\x9b\xec\xb0\x75\xcc\x10\x1d\x1b\x2b\x92\xb1\x60\x2f\x88\x2f\xa6\x65\x90\xd8\x49\x35\x6e\x12\x2e\xbb\xf3\xff\x17\xec\x59\x20\x7a\x9a\x1b\x99\x1b\x25\x0a\x2f\x9a\x3b\xed\x0f\x8f\x79\x3b\xe8\xa3\x36\xa2\x83\xb3\xb3\x97\xdd\x48\x26\x34\x03\xec\xd8\x6e\x2c\x47\x9a\x6c\xd7\x1c\x38\x48\xe7\x85\x18\x25\x9c\x73\x09\x24\x00\x23\x0a\x67\xac\x0b\x53\xc8\x94\x05\xb1\x6c\xcc\x43\xbe\xc0\xb4\x4f\xb8\xce\x65\x12\x1b\xbd\xc2\x85\x95\xd3\xe8\x6e\x2d\x2d\x02\xda\x1b\x8f\x48\x6b\x5e\x90\x89\x94\x8b\x19\xf8\xd5\x86\xa4\x64\x19\xe6\x20\x5b\x21\x70\x89\x16\xe4\x2e\x2c\x09\x37\xa8\x5b\x0f\xee\xd1\xa0\x8b\x71\x29\xec\xc8\xe0\x29\x72\x1a\xd6\x14\xc5\x2d\x57\x64\xe7\xb5\x23\x40\x07\x08\xcf\x4d\xdc\x61\x76\xf0\x0b\xfd\x6c\xa2\xa7\xf3\x92\x8b\xd4\xa6\xeb\x46\xc4\xf2\x60\xeb\xa8\x07\x43\x22\x38\x4f\x43\xd9\xf2\x92\xbc\x17\xc4\x13\x8b\x8c\x5a\xb3\xc7\x19\xaa\xcc\xce\x47\x37\xba\xdd\xf1\xea\x1f\xd2\x1c\xe6\x9d\x80\xb9\x37\xcf\x1d\x19\xcb\x7d\xf9\x3a\xf7\x2d\x6b\x85\xee\xb1\xd2\xaf\x6f\x2b\xe6\x67\x1c\xd6\xa9\xf4\x89\x61\x6b\xcd\xc5\x4c\x85\x96\x0c\xcd\xb2\xc8\x19\xbe\xca\x94\x71\x33\xec\xa1\xf5\x97\x4d\x88\x46\x99\xc1\x63\x31\x43\x32\xa3\x4e\x3c\x72\x23\x64\x96\x2b\x7a\x50\x1a\x4a\x68\x4e\xb3\xf3\xa2\x3d\x44\x29\x59\x82\xc3\x7b\x73\xbe\x1f\x0f\x0d\x9b\x35\x74\x7e\x30\x73\x65\x7e\x27\x34\xcd\xb9\x52\xe0\x08\x63\x93\xb9\x94\x97\x64\x6f\x05\x1e\x57\x90\xa7\xa5\xf8\x4c\x3d\xb3\x3c\x3f\x32\x6f\x3f\x20\x5c\x64\x3e\x2b\x0a\xec\x60\xa1\x95\x73\xe4\xc0\x43\x12\xff\x16\x30\x87\x16\xb7\xda\x26\x2b\x2c\xbf\x26\x22\x55\x1b\x2e\x58\xbb\xc0\x5e\x9e\x9e\x93\x8e\xb0\x2b\x9f\x98\xa2\x13\xcb\xdb\x4d\x64\xb5\x95\x74\x44\xed\x71\xed\x44\xb2\xca\x45\xc2\x54\x7f\x80\x4e\x7f\xaf\xc7\x24\x29\xc3\x2a\x1e\x06\xd9\x4f\xf4\xc6\x24\x3b\xf0\x4b\xef\x42\x31\xa8\xbd\x75\x37\xd4\xa8\x2f\x6a\xe1\x62\xec\x91\xac\x98\xd3\x11\x1a\xe9\x46\xa2\x81\x08\x74\x2a\xc4\x5c\x0a\x69\x8b\x24\xcc\x26\x2a\x05\xb0\x34\x88\x28\x8c\xe6\xc1\x9c\x58\x11\x1d\xbc\xea\x41\x1d\x25\x0e\x03\x81\x50\x4c\x86\xf8\x11\xf5\x3b\x5c\x73\x3d\x77\x9d\x5e\xa2\xa8\x21\xbc\x49\xc9\x14\x04\x60\x04\x61\x65\x29\x4b\x9b\x90\xe5\xfc\xd6\x30\x12\x48\x72\xc8\xe8\x32\x4c\x42\xcd\x5f\xbb\x2a\x0c\x54\xd7\x50\xf0\x90\xaf\x68\xb8\x89\x4d\xa7\x2c\x01\x45\x2b\x24\x30\x4a\xed\xbd\x1a\xf8\xd6\x56\x19\x18\x06\xb3\x50\xf2\x39\xff\x60\x9e\x12\xde\x15\x86\xc4\x2d\xe0\xec\xea\x9f\x07\x63\x42\x8e\x85\xcf\xe0\x1d\x9a\x59\x0c\xaf\x74\xa9\x67\xda\x7c\x62\xd8\x87\x00\x3e\x20\x74\x9c\x19\xed\xb0\xac\x7a\xe0\xf8\x2e\xee\x70\x12\xba\xc4\x7b\x15\x07\xe0\x1a\xb7\x83\x9a\xa9\x77\x3a\x40\x17\x57\xb9\xb9\xe4\xa1\xdc\xe5\x8f\x23\x00\x42\xba\xca\x39\x8b\xa6\xd0\x13\x38\xfc\x79\x30\x5a\xa0\xbd\xfb\x80\xdb\xa9\x4c\x11\x4d\xc5\xa3\x41\x40\x4f\x27\x40\x77\xe1\xff\x71\xfa\x59\xad\xe3\x09\x89\xd5\x01\x21\xcc\x8a\x85\xd4\x4e\x89\x51\xb5\x33\xe7\x5b\xc8\x8b\x8c\x41\x15\x67\x30\x72\x5d\xa0\x1a\xa0\xc9\x0f\xfd\x8b\xd4\x80\xf4\x16\xdc\x65\x48\xfe\x0d\x8b\xd2\x27\xa2\x3a\xdc\x89\x53\x7f\x3b\x5a\x88\x5c\xb9\xd6\x12\x50\x61\xa9\xa5\x73\x5d\x90\x94\x4f\xa7\xcc\x25\xbc\x1a\xcb\x91\x96\x34\x37\x22\x5e\x11\x4b\x82\x09\x9b\x71\x4c\x88\xf4\x82\x6d\xd7\xa8\x7b\xb6\xd6\x6f\x88\xc2\x90\x6b\x92\xf3\xd9\x1c\x19\x85\x50\xa8\xd0\x25\x2e\xa8\x98\x49\x9a\x12\xe0\x6d\x59\x92\x6b\x5a\xe6\x66\xdf\xa0\xc9\x1c\x22\x94\x54\x90\xb4\x2a\x01\x65\x59\x33\x9a\x2e\x46\x4a\x53\x6d\x34\x65\x56\x5a\x83\xd2\xbd\xff\x16\x52\xff\xd6\x63\x0b\xa9\x7f\xc7\x63\x0b\xa9\xbf\x85\xd4\x5f\x3e\x36\x26\x3b\x74\x0b\xa9\xff\xb4\x60\x92\xb6\x90\xfa\xeb\x8e\x26\x6c\x21\xf5\xb7\x90\xfa\xb7\x1d\x5b\x48\xfd\x4f\x1c\x5b\x48\xfd\x16\xc7\x13\x90\x5c\x5b\x48\xfd\x16\xc7\x16\x52\x7f\xf5\xb1\x85\xd4\x5f\x3e\xb6\x90\xfa\x37\x1e\x5b\x48\xfd\xd6\xc7\x16\x52\x7f\x0b\xa9\xbf\x45\x1a\xbd\xdf\x58\x9b\x89\x34\x4a\xb6\x90\xfa\xf6\xd8\x42\xea\x3f\x09\x3c\x45\xb2\x85\xd4\xbf\xd3\xb1\x85\xd4\xdf\x42\xea\xb7\x39\xb6\x90\xfa\x4f\xc5\x5d\xb2\x85\xd4\xdf\x42\xea\xff\x7e\x14\xdd\x2d\xa4\xfe\x16\x52\x7f\x0b\xa9\xbf\x85\xd4\xbf\xf5\x2d\xb6\x90\xfa\x4f\xc1\x04\x54\x3a\xe5\xad\x10\x40\xef\x02\x56\x64\x93\xd0\x03\x6c\x80\x49\x35\x9d\xb2\x12\x24\x17\x3c\x79\x29\x79\xaa\xc6\x65\x6c\x06\x59\x99\x1e\x02\xee\x91\xad\xd7\xb9\xe1\x76\x0b\x46\x00\x48\x9d\x75\xa6\xf8\xd1\xdb\x57\x2b\x90\x91\x5a\x67\x15\xb6\xcd\x91\x86\x77\x7e\x2b\xda\xc5\xc7\x6f\x20\xf8\xaa\xfa\x31\x4b\xf7\x24\x93\xca\x66\xb8\x03\xb1\x92\x39\x15\x82\x39\x7b\x8f\x6b\xf0\xa3\x4c\x18\x13\x44\x16\xcc\x46\xa7\x29\x51\x5c\xcc\x32\x46\xa8\xd6\x34\x99\x8f\xcd\x93\x84\x23\x76\x9d\x8d\x6e\xcf\x28\x5d\x32\x9a\xbb\xbc\xfc\x9c\x72\x1c\x8a\xd0\xa4\x94\x4a\x91\xbc\xca\x34\x2f\xfc\x60\x44\x31\x28\xa8\xc1\x8d\xca\x13\x03\xb2\xe2\xea\x14\xf6\x61\xfd\x34\xfb\x5a\x32\x84\xa6\x03\x6b\x73\x08\x78\xe0\x79\xa1\x17\x3e\x8f\x97\x91\x29\x2f\x95\x26\x49\xc6\x61\xb7\x86\x27\x62\xed\x34\x8c\x37\x74\x7b\xb5\xb0\x6f\xaa\xec\xab\x8a\x14\xd4\xd6\x42\x2b\xcc\x8a\xad\x07\xb4\x43\xa5\x5c\x59\x35\x5f\x0d\x09\x75\xb8\x69\x48\x68\xf7\xa6\x40\x6a\xb7\xb3\xe0\xe8\xf6\x54\x30\x5c\x80\x17\x5b\xa7\x0d\xd7\x8c\x0e\x25\x0e\x8e\x39\x87\x51\x35\x47\xad\x50\x40\x96\xde\xd2\x32\x80\x09\x10\xec\xca\xf0\x00\x4b\x98\xd9\x5f\xe9\x0d\x5c\xff\xd9\x99\x3e\xd8\x14\xdf\x30\xa5\xe8\x8c\x9d\xb6\x0c\x34\xdc\x64\x91\x41\xac\xa1\x9e\x18\x60\x85\x0c\xab\x6b\xfd\x99\x3a\x3b\x33\x56\x83\x48\x8e\xef\xe4\x95\x9f\xeb\x92\x6b\xcd\x60\x52\x01\x61\x0f\x62\x95\xcd\x02\xfc\xdd\x46\x8e\xe7\x1b\x37\x48\x7d\xb3\x11\xea\x22\xc5\x8c\xcb\x09\x23\x93\x92\xb3\x29\x99\x72\x48\xe3\x84\xc4\xca\x21\x02\x2e\x51\xf4\x02\x28\x65\xec\x5d\x29\x9c\x2e\xeb\xde\x6b\x4c\x7e\xb6\x2f\xa6\xcb\x4a\x24\x34\xc0\xb2\x85\x0a\x53\x3e\x25\x33\x48\xcc\xb4\xda\xe2\x9f\x9e\xff\xf5\x2f\x64\xb2\x30\x5b\x1a\x68\x56\x5a\x6a\x9a\xf9\x8f\xcc\x98\x98\x19\x5a\xe1\xf2\x8c\x6b\x24\x3d\x05\xa0\x9b\x07\xbe\xf8\x8b\xaf\x2e\x27\xf1\x1e\xfb\x2c\x65\x57\xcf\x02\xfa\x8d\x32\x39\x5b\xd5\x1f\xa5\x7d\xca\x76\x4b\x93\x68\x05\x9b\xc9\x8c\x27\x8b\xce\x8c\xe6\x90\xbf\xc8\x5c\x5e\xa3\xae\xbf\x82\x7b\xea\x72\xab\x42\x16\x55\x86\x4e\xe7\x57\xbe\xba\xb8\x52\x6c\xb9\x06\x70\xe5\xba\x00\x37\xa9\x1d\xa2\x89\x9b\x8e\xf9\xb8\xee\x91\xd2\xd6\x96\x58\x47\x9e\x07\x00\x03\x43\xe8\x15\xcd\xb2\x09\x4d\x2e\x2f\xe4\x6b\x39\x53\x6f\xc5\x51\x59\xca\x32\x7e\x97\x8c\x1a\x69\x39\xaf\xc4\x25\x76\x70\xf0\x10\x09\x72\x66\x54\xab\xa2\xd2\xae\x90\x61\xd5\x07\x63\xbd\xbc\x13\xc2\xce\x0c\xaa\x47\x61\x1f\x78\x6d\xeb\xd8\x52\x2d\xe4\xc8\x70\x7c\x15\x32\xdb\x57\xcf\xff\xf4\x0d\xb2\x2e\x91\x25\xf9\xe6\x39\xe4\x6c\xab\x21\x2e\x62\x90\x6d\x66\xa3\xc8\x69\x96\x19\xb3\x21\x64\x4a\x43\xe8\x55\x4c\xf8\xd9\x79\x50\x77\x67\xb7\x3b\xab\x52\x17\x17\xff\x00\x3d\x8a\x6b\xc5\xb2\xe9\x10\xab\x92\xbc\x59\xb3\x0b\x1b\xc3\xae\x95\x3e\x50\x1a\xb6\x01\x0a\xd0\x95\xcc\xaa\x9c\x1d\xb2\x2b\xde\x47\x13\xa7\x68\x34\x67\xea\x67\x5c\x41\x01\xd8\x24\x93\xc9\x25\x49\xed\x8f\x41\xe6\x49\x13\x09\xbc\x3d\x15\xda\xe6\xe0\x74\xc8\xbd\xb9\xf1\xfb\xa3\xac\x9b\x9c\x16\x85\xaf\x11\x2a\xe9\x75\x44\x0c\x58\x93\x00\x57\xd0\x11\x4f\xa6\xb3\x9b\xb9\xab\x93\x79\x64\xbf\xc8\xc8\xcd\xd6\x43\xb4\xce\x3a\xe9\xee\xa3\xae\xdf\xbe\xbd\x63\x32\x62\x88\x7a\x40\xb7\x1a\x0a\xf8\x37\x56\x95\x2c\x55\x45\xfa\xc2\x3a\xcf\x18\xa8\x00\x18\xf6\x01\x91\xdc\xde\xe1\xda\x83\x77\xb3\x5b\xca\x51\x44\x17\xe1\xbd\xca\x39\xd5\x56\x21\x74\xee\x6b\x4a\x0a\x56\x2a\xae\xcc\xbe\xfc\x13\x2c\xa8\x83\x8c\xf2\x3c\x70\x01\xae\x87\x08\xb8\xb8\x01\x3e\xb9\xbb\xa4\x3c\x95\xa9\x1d\x10\x44\x21\x42\x47\xaf\x50\x6b\x63\xad\xb6\xc7\x0d\x75\xdd\xa2\xf2\xa7\x9a\x9a\xb1\xa4\x34\x67\xbc\xa8\xc4\xab\x9e\x92\x80\x84\xef\x7b\xac\xf2\xd1\xbf\x7c\x4f\x62\x00\x04\xa3\x9d\xdc\x58\x12\x46\xc6\x23\x2e\x94\x40\xa5\xb7\x76\xe0\x98\x60\x14\xdc\xac\x09\x7b\x2b\xd9\x7d\xb9\xbb\x56\x21\x89\x24\x2a\x65\x41\x67\x9d\x7a\xf9\x34\x28\xd5\x1c\x36\x04\x9a\x30\x66\x10\xfc\xee\x61\xd7\xe0\x2a\x96\xd6\x38\x3a\x80\x92\x84\xd1\x51\x47\x60\x6b\x20\x60\x3d\xf6\x35\x5d\x10\x5a\xca\x4a\xa4\xd6\xbf\xe4\x1d\x7c\x6f\x1a\x0f\x3e\x91\x82\x39\xc7\x79\x13\xa7\x02\x3c\xfa\x5c\x90\x17\xe3\x17\xcf\x9f\xca\x4e\x05\x5f\xd8\xd8\xa9\x4e\xfc\x4e\x85\xf2\x69\xad\xdf\xea\x10\xef\x7b\xfa\xde\x37\xd6\xc5\x52\x03\xda\x73\x07\x97\x0d\xa7\xae\x4b\xae\x59\xd0\xe3\x6f\x0f\x0c\x17\x63\x1f\x06\xa8\x0c\x83\x55\x9d\x24\x3a\x12\xa9\x1b\x0c\x86\xaa\x26\x0f\x28\xb7\xac\x80\x82\xe5\xb6\xca\xc3\xa5\x6e\x11\x61\x21\xa1\x76\x76\xc8\x1e\x5e\xb9\x8b\x05\xcd\x83\xb5\xb2\x96\x25\xda\xd1\x87\xa2\x03\xc6\x66\xa3\x76\xbe\xa0\xe0\x83\x2b\x7a\xa4\xe0\xf7\x6c\x4e\xaf\x18\x14\x72\xf3\x8c\x96\x19\xc4\x1c\xcf\xf1\xdd\xc9\xa4\xd2\x84\x89\x2b\x5e\x4a\x91\x33\xa1\xc9\x15\x2d\x39\xa0\xe2\x94\x0c\x90\x1d\x8c\x2d\xfa\xc7\xbd\x9f\xf6\xcf\x20\xa1\x61\x60\x21\x29\xec\x5b\x56\xca\xc1\xd7\x84\x6f\x12\x0c\xf7\xc9\xe9\x73\xef\x61\x68\x08\x32\xd7\xbd\x97\x79\x4e\x5e\xe9\x0a\xdb\xb2\x7c\x48\xb2\x4a\xf1\xab\x75\x49\x12\x5b\x61\x7f\xc8\x5b\xcd\x73\xa3\xda\xbf\x26\xd4\x52\xe1\x3e\xb8\xd6\x57\x14\xe8\x2d\x05\x4c\x76\x95\x2f\xda\x0b\x63\xe0\xd6\xf5\x64\xb1\x34\x30\x7d\xce\x21\x2e\x2e\xa9\x10\x80\x1b\xb3\x5e\x27\x94\x90\x29\xbb\x3f\xea\x4e\x9c\xde\x63\x87\xc0\x98\x79\x50\xc1\xa7\x92\x39\x4b\x2b\x80\x77\xe2\x0a\xc1\x51\x8d\xf9\x40\x6b\x14\x3e\x01\x5d\x82\x8e\xa7\x1e\xd2\x40\x8c\xc0\x39\x88\x34\x77\xf7\x97\x0e\x00\xc1\x9d\x50\x8d\x11\xc1\x28\x35\x63\x0d\x09\x55\xaa\xca\x71\x49\x60\x03\x84\x29\xd7\xca\xf7\x98\x75\xda\xb1\x59\x18\xf7\x2c\xa8\xea\x40\xdf\x73\x96\x01\x73\x75\xa0\xf1\xee\x49\x30\x0e\x12\x5a\xb9\xbf\x2c\xc3\xd9\x84\x09\x88\xb6\xf9\x3c\x4e\x09\x5e\xd2\x29\x87\x26\x4a\xd4\xd2\xfb\x7c\xc5\x9d\xa8\x3a\xe0\x15\x00\x0f\x43\x27\x2c\x53\xcd\x81\x26\xf5\xa4\x58\x54\x52\x4b\xf8\x8e\x5d\x72\xa9\x52\x7c\x26\xa0\x7f\xa6\x19\xed\x9e\x9d\x32\x5b\xdb\x4c\x7d\x74\xc1\x6d\x2d\xd5\xa2\x2c\xac\x9c\x16\x23\x6b\xf5\x6a\x99\xf3\xe4\x1e\x23\xc9\x7b\xbe\x72\xa3\x56\x3a\xaa\xc1\x7d\x7b\xbe\xe4\xf1\x51\x81\x57\x63\x4c\xce\x65\x6e\x53\x9c\x44\xd0\xc5\xcb\x35\x53\x35\x3b\x46\xc9\x0c\x2d\x20\xf1\x88\xd7\xd1\x78\xe8\x7a\xe3\xaa\xa0\xe1\x39\x5e\x25\xb7\x61\x5c\x80\x9f\xb4\xcd\x5c\x65\x96\xc9\x6b\x48\x2c\xc6\x71\x1d\x6f\x43\x0a\xcc\x4b\x32\x6a\x74\xa6\x1d\xc7\xa0\xa1\xb7\x3f\xc7\x5e\x3b\xfc\xf4\x53\x30\x3f\x07\xe0\xf8\x8e\x0f\xc3\x3f\x8f\x4f\x0f\xdc\x9f\xcd\x37\x89\x9b\x30\xdc\x7c\x55\x08\x87\x7d\xd3\x55\x53\xec\x63\xf4\x89\x9f\x0f\xe6\x54\xb8\xb8\xd5\x8d\xcf\x5b\xa8\x44\x67\xf5\xeb\xcc\x69\xc9\x2c\x5c\x9c\x11\xdc\xaa\xa0\xc9\x8d\x6f\xe1\xb1\xd9\x6e\xbd\xe0\xd6\x37\x55\x55\xe1\xfa\x6b\x67\x70\xa1\x7f\x93\x9a\xcb\x7e\xf9\xe2\xd7\x3b\x12\xf3\x53\xf7\xac\x22\xed\xed\xf7\x44\x5d\xfa\xee\x74\xc7\xea\x1e\x5e\x77\xbb\x37\x68\x83\x77\xa7\xeb\x6f\x6a\xc1\x7b\xd7\xa7\xb9\xd6\x6d\x77\xfb\xb0\xe6\x6c\xdf\xe1\x72\x9c\xfb\x4f\x67\xcd\x99\x05\x79\x0c\x88\x9b\xd3\xc5\xa9\x4c\xcd\xda\xc4\x14\xb9\xfb\x01\x1b\xb4\x96\xf6\x6d\x3d\x63\x2d\xfc\x59\xed\xfd\x58\xed\xfc\x02\x0d\x5d\xe1\x06\xd4\x53\x8b\xc8\x26\x66\x24\xc2\x99\xaa\xca\x92\x09\xe8\x90\x5f\x41\x52\xa4\xeb\x7c\x8f\xf2\x1c\xe4\xb2\xc5\xf4\x44\x60\x7a\xb2\xef\xb7\x4d\x9b\x2c\x97\x53\xc0\xf9\x0c\x70\xad\xa7\x15\xe4\x3e\xc2\x2e\x81\xb8\x75\x52\x98\xf7\x78\xb9\x0a\x4c\x43\x16\x4c\x04\x6d\xf1\xad\x82\x3d\x32\xfc\x17\xc1\x6b\xa0\xce\x30\xce\xd3\x3f\x14\x19\xd5\x53\x59\xe6\x23\xa7\x49\x8e\x22\x7d\x82\x1c\x40\x16\x8e\x72\xa6\x18\xa6\xc2\x22\xfe\xa6\x48\x33\x16\x6c\xfc\xfe\x53\x45\x8a\x68\x55\xa4\x12\x25\x4b\xe4\x4c\xf0\xff\xd4\x84\x80\x2d\xd0\xfb\x91\xa8\x32\x9b\x2e\x11\x55\x96\xdd\x3f\x65\xa1\xa5\xbe\x20\xaf\x58\x39\x67\xf4\x9e\xcc\xdb\xc8\x7e\xb1\x63\xd4\x6d\x4a\x95\x85\x1f\xb0\xda\xb1\x7b\x88\xd1\xa2\x65\x02\x65\x70\x18\x8d\x77\x39\xce\x14\xf6\x7e\xa3\x14\x52\x32\xe3\x57\x4c\x38\x74\xf2\x83\x8c\xfa\x56\xdb\x0e\x90\xd5\x22\xa4\x57\x5a\xfa\xfc\x06\x42\x75\x80\x91\x0c\xe9\x50\x36\xb4\x1a\x8e\x13\x5c\x62\x1b\x75\x67\xae\x29\xda\x5d\xae\x84\x14\x03\xec\x12\x39\xac\x3f\x29\x77\x6e\xd8\x08\x84\x93\x24\x90\x08\xe3\xac\x16\x9b\x00\xf3\xe9\x47\xd8\xec\x35\x23\x83\x56\x0d\x63\x35\x6b\x8f\x16\x5b\x13\x36\x33\x5b\xc7\x02\xf5\xa1\xe3\x69\xfc\x24\x1e\xe1\xf3\x43\x99\x14\x68\xea\xb5\xe9\x78\x2a\x53\xa3\xb0\x0d\x89\x9f\xca\xb0\x4f\xb9\x0d\xcd\xe0\x9a\x0c\x16\x23\xea\x73\x65\xc9\x54\x21\xb1\x4d\x40\xf8\xd8\x61\xe0\x2a\xe3\x3a\xca\xcb\xc3\x86\x6f\x7e\x69\x20\x90\xdb\x7f\x58\x29\x57\xaa\xfb\x33\xae\xc7\x97\xdf\x80\xae\xcf\xc4\x9c\x8a\x04\xcd\xac\x67\x97\xac\x50\xcf\x14\x9f\xa1\x6a\xff\x97\x6f\xbe\x01\x3d\xdf\x91\xe4\xd9\xd9\xd1\xfe\xe1\x9b\xa3\x71\x9e\x3e\x22\xa5\xbf\xa0\x5a\xb3\x52\xbc\x24\xff\xb3\xf7\xfe\xcb\x8f\xa3\xc1\x77\x7b\x7b\xbf\x3c\x1f\xfd\xf5\xd7\x2f\xf7\xde\x8f\xe1\x1f\x5f\x0c\xbe\x1b\x7c\x74\x7f\x7c\x39\x18\xec\xed\xfd\xf2\xe3\x9b\x1f\x2e\x4e\x8f\x7e\xe5\x83\x8f\xbf\x88\x2a\xbf\xc4\xbf\x3e\xee\xfd\xc2\x8e\x7e\xbd\xe3\x20\x83\xc1\x77\x7f\xbc\xe7\x8b\xb6\x2c\x61\xe9\x5a\xb6\xd2\xa9\x54\xa5\xc7\xf2\x94\xa2\x64\x2c\x07\xf1\xd7\x26\xb1\x2b\x76\xa8\x36\x86\x72\x1b\xac\xfd\xcb\xc8\x44\xf7\x34\x31\x33\x62\x52\xa1\xe8\xcc\xe4\x35\x24\x63\x72\x69\x14\xa7\x31\x79\x0b\xfb\x20\x39\x61\x57\xac\x1c\xba\x51\x5f\x9b\x8b\x4e\xfd\x35\xa1\xc7\x6e\xd5\x15\x2d\xcb\x01\x5a\xce\x89\x7b\xf7\x0e\xc4\xc3\x16\x27\xf6\xe5\x41\x3e\x8d\xc9\x4f\xb4\xe4\xb2\x52\x56\x17\x09\x91\xc1\x31\xdb\xcc\xef\x24\xe0\xc0\xb0\xb1\x20\x3f\x88\x2f\x22\x73\xe1\x20\x4f\x9b\x7d\x2f\xaf\x0f\x56\x6f\x09\x5c\x9b\x99\xba\x72\x8f\x2a\x5d\x56\xec\x12\xa8\x38\x6e\x06\x2b\xe5\xbf\xdb\xd1\x54\xf8\xa2\x30\x8c\x7b\x0f\x90\xad\x46\x13\xc3\x51\xe6\x7c\xe6\x72\xaf\xe1\xfb\xd1\xd2\x0d\xce\x7a\x0e\x69\x31\xa5\x6d\x96\x69\xdb\x12\x80\xa2\xf9\x7d\x1d\xd8\x22\x86\x5e\x0e\xd1\x9b\x5d\xf1\x51\xbd\x6e\x76\x90\x4f\x60\x13\x19\x25\x25\xd7\x3c\xa1\xd9\x0e\x6c\x4e\xee\xa7\x24\xab\x8c\x9e\x18\xfe\x5a\x32\xa2\xaf\x25\x3e\x85\x66\xe4\x92\x2d\xae\x65\x99\xba\xfd\xd9\x3d\xb1\x9e\x0b\xa5\xdd\x23\x8d\x2d\x08\x0b\x18\x3d\x12\x65\xce\x4a\x32\x61\xce\xd9\xde\xb8\x78\x31\x26\xfb\x62\x61\x23\x95\x22\xac\x47\x0c\x40\xdc\x40\x47\x40\x2d\x2a\x62\x12\xbb\x89\xb9\xa7\x51\xac\x14\xbd\xc9\x11\x6d\x14\x30\xbf\x0a\xdc\xee\xef\x3c\xd1\xb2\xb4\x05\x51\xb0\x3a\x4a\x2c\xe7\x92\xee\xe7\xcf\x22\x2d\x8c\x7e\xc3\x05\x53\xea\x07\x33\x95\x5d\xd4\xd5\x98\x3b\x28\xa8\x25\x76\x6c\x28\xaa\xaa\xb3\x8f\x99\x59\x52\x18\x4e\x36\x62\x58\xa6\xf5\x95\x63\xb2\x0f\x27\x20\x7d\xde\x68\x5e\x50\x70\x67\x06\xe3\x5a\x35\xfb\xd0\xe3\x15\xfb\x27\x87\x2e\xcd\x19\x35\x05\x15\x23\xab\xa3\xca\x1c\xbf\x09\x68\x7a\x36\xd9\x96\xfd\x56\x51\x68\xa9\xbb\x73\x51\x56\x6c\xa7\x9d\xaa\x84\x98\xfd\xcf\xfe\xfc\xcd\x73\xd0\x96\xfc\xf3\x46\xf0\xbc\x36\xaa\xd2\xfd\xd3\x69\x5a\x25\xd2\x34\x73\x88\xce\x42\x7e\x70\x04\x77\x76\x87\x8d\x6f\x41\x19\x30\x4c\x93\xa7\x79\x2b\x2f\x6c\xab\xb4\x99\xf6\x09\x33\xa3\xfa\x75\x2f\xee\xdf\xee\xac\x4b\xae\x4b\xf4\xdc\x3e\x02\x62\xf5\x68\x38\x2b\x0a\xa7\xc4\x3f\x27\x70\x02\x63\x57\x0c\x7b\x1a\x32\x67\x41\x70\x41\x00\x01\xc4\xe3\xa2\xe8\x90\x25\xdc\x42\xde\x40\x51\x4c\x67\xfd\x6e\xf7\x0c\x07\x22\x45\xad\xd0\x2d\x15\x3b\xf8\x60\x30\xe8\x1d\x56\x95\xdb\x87\xca\xb1\x21\x79\x2b\x5e\x61\x2a\xfd\x10\xb5\xbb\x08\xa8\x04\x2f\xea\xb5\xa2\xf0\xd9\x1f\xec\xb7\x8f\xf0\x95\xdb\x08\x85\xfb\x93\x3b\xb0\x1c\x3b\xee\xfe\xbb\x67\x8d\xb1\x22\xd6\x8b\x2c\x63\xbb\x43\xf2\xba\x4d\x9a\x15\x9f\x64\x56\xca\xaa\x70\x41\xd7\xb8\xe7\x59\xdd\xe8\x03\x63\x85\xd8\x12\x58\xc8\x78\x68\xef\xfc\x00\x06\x66\xb5\xd7\x2c\x25\x09\x9a\xc7\x6e\xd7\xc5\x82\x29\xf4\x20\x94\x95\x88\x5b\xa2\x07\x61\xcb\x9d\x8c\xcd\x68\xb2\xd8\x89\x9f\xb3\x2a\x48\xcc\xa1\x8e\x87\xe7\x88\xad\x8e\xcf\xab\xcb\x1f\xa0\x4a\x02\xf4\x07\x5c\x6b\xa0\x1a\x54\xca\xbe\xa2\xdb\xf2\x5d\xfd\x1e\x7a\xb6\xca\x0e\x96\xf9\x9f\xbf\xf9\xf3\xc8\xf9\xde\xe0\x55\x3e\x0b\x43\xf9\x20\x6f\xaf\xba\x64\x34\x67\x46\x41\xe2\xaa\x80\xf9\x05\x4d\xac\xde\xce\xfd\xd3\x6f\x53\xb7\x56\x0f\xe2\x26\xa0\x1e\xe2\xb3\x90\x2b\xf6\xc0\x77\x59\x7e\xcd\x0e\x31\x73\x99\xa5\xb0\x50\x6c\x1f\x27\xf7\x28\x42\xb5\x2e\xf9\xa4\xd2\xd6\x4d\x9a\xc8\x3c\x8f\xcb\x2b\x6d\x2f\xbd\x31\xa9\xeb\xeb\x42\x13\x16\x38\x79\x4c\xc8\x39\x63\xd8\x47\x32\x78\x0f\x90\xb3\x8e\x94\xd6\xdb\x2a\xa7\xd8\xf4\x1b\x8d\xb0\xcf\xe4\x16\x6a\xbf\x1d\xdb\x40\x5c\x47\xaf\xfd\xce\xbe\xb7\x52\xc2\x78\x19\x0a\xb8\xa5\xd6\xbe\x8d\x9d\x09\x32\x8f\xeb\x00\xad\x4d\x44\x32\xb4\x50\x08\x27\x0b\xbc\xfc\x23\xb6\x01\x85\x2c\x4b\x88\x1a\xa2\x6f\xf2\xda\x0c\x31\xe7\x05\xda\xd4\x54\xfb\xdb\x21\xde\x6f\x7e\x0e\x51\x1a\xa0\xaf\xe5\x0b\x34\x6a\xe5\x35\x78\x85\x7f\x38\x3e\xf4\x6b\xc4\x5c\xf5\xea\x1c\x43\x42\x5f\x8d\x6d\x97\x5e\x3d\xe3\x29\x99\x60\x8e\x87\x91\x97\x7b\x82\x5d\x63\xd6\xb8\x75\x9c\x7a\xbd\xfa\xca\x65\x53\xe3\x68\xfe\xe1\x76\xc8\x01\xf9\xda\xf6\x4b\x65\xa5\xb3\xca\x27\xdc\x66\x95\xbe\x3d\xdb\x75\xee\xea\xeb\x51\x79\x3d\x1a\x8d\x46\x36\x14\x0c\x52\x7a\x18\xd1\xc0\x0b\xf3\x5c\xa6\x7c\xba\x68\x50\xc2\xb0\x79\xfd\x08\xe0\x48\x2a\x16\xf6\xed\xba\xb7\xf6\xbd\x3f\x92\x77\x37\x77\x5c\x17\xe4\x86\x15\x61\xe6\xae\xf1\xa9\x55\x91\x6b\xb4\x93\x55\x0d\x80\x2e\xa7\xc8\xa4\x90\x68\x7f\xc3\xc4\x38\x2f\x90\xe5\x1a\x0b\xeb\x87\x56\x3a\xfb\x50\x48\x04\x0d\x86\x42\x16\x68\xee\xd6\x0c\x4f\x40\xf2\xa8\x59\x55\x90\x8f\x17\xad\x1a\xab\x50\x60\x44\xcc\x11\x81\x4c\xa8\x19\xd2\xbf\xce\x5e\x83\x4f\x06\x63\x72\x6c\x59\x0b\x0c\x42\x21\x6d\x8b\x38\x22\x05\x61\xc5\x9c\xe5\xac\xa4\x59\xfc\x20\x5b\xd0\xfb\xd2\x88\xdb\xd2\x70\x29\x86\x00\x72\x5a\xa0\xb4\x05\xe1\x99\xf2\xd2\xb5\x98\x0d\x42\x73\x3b\x6f\xc5\x99\x94\xfa\x0d\x57\xa0\xbb\x58\x67\x08\x6a\x9a\x3b\xab\x36\x34\xf7\x5b\x9d\x1d\xdd\x95\x93\x3f\x5b\xfc\x8b\xb8\x36\x71\x7d\xc8\x5a\x23\x41\x8c\xd0\xba\x6f\x27\xb8\x77\x16\xef\x27\x6a\xb8\xeb\x7d\xb1\xab\xfa\xbc\x2d\x35\x79\xfb\xcc\x5d\xde\x6c\x02\x17\xd5\x11\xb0\xd6\xe7\xee\x4c\xbe\x3e\xe9\x05\x2c\x73\x22\x61\x9d\x74\x64\x9a\xe3\xe5\xe6\x72\x35\x8b\x80\xbb\xcf\x77\xcd\x14\x52\x8c\xa0\xd9\x53\xa5\x5c\xe0\xb2\x74\x2e\xdf\x68\x03\xb2\x1d\x28\x71\xdb\xc4\x2e\x82\xb4\x56\xe9\x8d\xea\x24\x54\x55\x32\x9f\xcc\x98\x4a\x56\x37\x7e\xa2\x8a\xbc\x3b\x3e\x24\xcf\xc9\x1e\x24\xf2\xfa\x62\x6e\x84\xaf\x30\xa6\x6c\x23\xdb\x74\xea\x86\x88\x4d\x17\x8b\x1d\x21\x24\xca\x22\xd7\x15\x53\x0a\xbf\x0d\x5b\x0c\xce\x1b\x7a\x19\xae\x9b\xc7\xdb\xf2\x63\xbb\x74\x7d\x9f\x21\xd3\x83\x0c\x7a\xd7\x42\x06\x85\x8a\x75\x1f\x9d\x28\xd7\x3d\x7b\xbf\x77\x09\x15\x27\xb9\xf5\xc0\x54\xe7\x47\x30\x20\xe2\x46\x7c\xd0\x56\x8d\xbf\x67\x9b\xf3\x65\x7c\x20\x0b\x92\xe4\xa1\x04\x4a\x2a\x52\x99\x2f\x3d\xcd\xcc\x26\x18\x6f\xc1\x6c\x6e\xd9\xee\xa6\xa3\x53\xb5\x67\xb7\x62\x49\xb0\xf1\x7b\xa8\x92\x7d\x0d\xbe\x02\xae\x3c\x27\xa0\xf3\x00\xf2\xc7\x97\xcc\xd6\xce\x20\x0a\x9d\x8b\x86\x4a\x99\xb5\xac\xbb\x8b\xbe\xfa\x4c\x66\xb6\xde\xc1\x7d\xb6\x19\x78\x63\xbf\x5a\xb7\x0c\x13\x34\xc5\xcb\xa2\x68\x7c\x35\xb8\x73\x36\xf5\xab\xab\x56\xbb\x34\x69\x7e\x35\xa4\xc3\x46\x5f\x0d\xfb\xee\x26\x7e\x75\x9c\xfd\xdc\xc3\x66\x62\x07\x24\xd2\xe6\x60\xdb\xa6\x03\x4d\x3c\x94\x3a\x43\x12\x9c\x50\x8f\x4b\x8e\x76\xa9\x98\xc7\x44\xa7\xcf\x2d\xba\x65\x42\xb3\x39\xb6\x7c\x6f\x37\xcf\xa4\x39\xd7\xcd\x21\x83\x64\x0c\x6a\xde\x16\xce\x05\x29\x85\x14\xc1\x9c\x64\x1d\x90\x69\x04\x5f\xac\x9b\xce\xde\xe9\xb2\x21\xcc\xfe\x5b\x67\x38\x86\x77\x6b\x69\xbb\xd0\x3a\xd0\x78\x0a\x2f\xc8\x30\x5f\xb1\xa0\x7a\x3e\x24\x25\xcb\x10\x07\xd6\xae\xb3\x4b\x34\xa5\x76\xa3\xb4\x49\xc7\xb1\xee\xd1\xa0\xb0\x40\x17\x6a\x18\x19\x5c\x3e\x4e\x0d\x99\xa2\xfc\xe2\x8a\xec\xbc\x76\x04\xd8\x79\xcc\x02\x7a\x07\xbf\xc7\xcf\x1d\x7a\xb1\x2e\xb9\x48\x2d\x40\x6a\x44\x1a\x9f\xa2\x8b\xba\xa1\xf3\x30\xb9\xb5\x4e\x4b\x06\xce\x5e\x4f\x1a\x32\x6a\xcd\x0c\x36\x14\xe6\x02\xa2\xa3\x1b\x94\x4c\xe7\x53\x71\x0f\x69\x0e\xf3\x4e\xc0\x4c\x0b\xa8\x9d\x10\x72\xc5\x75\xee\x5b\xda\x35\x4b\xec\x22\x7a\x97\x8a\x5c\x3a\x8a\xdf\x7d\x0f\x4b\x35\xc3\x9a\x99\x40\x85\xaf\xa1\x2b\xad\x5d\x68\x3b\x41\x37\x54\xef\x21\xcc\x8e\xcd\x77\x5d\xda\x9d\x30\xbd\x2a\xa7\xe5\x82\xfc\x70\x7c\x88\x1a\x78\x64\x08\x08\xe9\x1e\xed\x39\x25\xb5\xe8\x84\x54\x2c\x36\x40\x71\x6e\x87\x10\xd3\x1a\x1f\xa6\x2b\xf2\x6e\x27\x33\x11\x4b\xb8\x3a\xf2\xd4\xb9\x2d\x04\x9b\xcb\x2c\x25\xd4\x33\x98\x70\x45\x60\xa9\x7b\x0e\x06\xd0\x83\xea\xcf\xb1\x31\xbe\x6c\x70\xba\x12\x75\xa5\x88\xbb\x7e\xaf\xa9\x12\xb8\x35\x3d\xb0\xa5\xd0\xce\x33\x95\xd1\x4a\x24\xf3\xdf\x0b\xcb\xac\xa0\xbe\x0f\x75\x50\x72\xc9\x4a\xc1\x32\x52\xd0\x92\xe6\x4c\xfb\x66\x87\x8a\xb5\x81\xfe\xe9\x88\x1c\xd4\x0d\x37\xa8\x03\xe6\x4f\xfb\xa6\x85\x5d\xd1\x82\xba\x60\xb0\xac\xe8\xe4\x36\xc5\xdd\xd1\xbc\xd2\xc2\x36\xf8\x6c\x39\x78\x67\x60\x8c\x4e\x6d\x08\x63\x10\x2c\x44\xf0\xdf\x88\x6f\x8b\xcb\x7c\x7b\xb0\x6e\x7e\xc6\x01\x6b\x3c\x02\x97\xc9\x70\x5f\x77\x99\x53\x99\x96\x51\xc0\x76\xd5\x92\x2b\x2a\x6e\x99\xf0\x99\x7d\xe5\xad\xe5\x2e\xd4\x01\x3e\x2a\x0f\xd7\x2c\x57\xf4\xa0\x64\x50\x71\x4a\xb3\xf3\x82\xb5\x6c\xe2\x1f\xb7\xf0\x7f\x73\xbe\x1f\x0f\x0a\x9b\x12\x24\x5b\x9b\x39\x31\xbf\x07\x25\x03\xd7\x6c\x32\x97\xf2\x92\xec\xad\x28\x7b\x0c\xaa\x5c\x14\x9f\xa9\x67\x96\xbd\x47\xe6\xbd\x07\x84\x0b\x80\xb2\x5d\x86\x00\x76\x0f\x49\xfc\x5b\xc0\x5c\xd9\x9c\x35\xbb\x0d\x2f\xbf\x26\xc8\x28\xcc\xa8\x59\x87\x81\xb3\x3c\x19\xf7\xcf\xf7\x72\xc7\x27\x26\xe4\xa6\xf2\xd7\x95\x54\x43\x87\xc6\x5a\x48\x62\xcd\x6d\xa3\xbe\xf7\x40\x87\xbf\xd7\xa3\x85\xc8\x6b\x7c\x1a\x81\xc2\xd7\x86\x92\x0f\x56\xee\x42\x73\x2a\x7b\xeb\x6e\xa8\xd5\xc7\xd0\x69\x34\x2b\xe6\xd4\xa6\x86\x61\x39\xb0\xcb\xa0\x98\x30\x32\x97\x42\x96\xb6\xcc\xa1\x2e\xe4\x01\x31\x83\x75\x37\x30\x03\x56\xde\x06\xaf\x7a\x50\x7b\x90\x5c\xbf\x94\x69\x46\x67\xd0\xdc\xa6\x51\x8d\x03\xc2\x55\x56\x18\xd5\x0c\x2f\x76\x25\x8b\xae\x71\x03\xe0\x46\x2b\x94\x62\x2e\x98\x69\xcb\x36\x20\x0b\x64\xdf\xbc\xb7\x21\xcb\xa9\x4b\x66\x76\xaf\x00\x6e\x0a\x5f\xb4\xa9\x0c\xef\x60\xfe\x06\xbf\x62\x11\x81\x51\xf2\xee\x39\xd4\x1a\x8d\x49\x56\xb8\x5f\xc0\xfd\x94\xe4\xfc\x83\x79\x4a\x78\x57\x58\x6d\x20\x52\x88\x12\xaf\xfe\x79\x60\x8c\xb1\xda\x72\x1b\x9a\x59\x0c\xaf\x0c\x9a\x2a\x08\xf8\xe1\x04\xcb\x05\xf0\x03\xc2\x48\x8b\xed\x8f\xd0\x85\xbf\xdb\xa3\x9a\xf9\x50\x69\x4f\x4b\x1d\x42\xa6\x76\x38\x33\xd1\x6e\xfb\xee\x12\x42\x35\x97\xf4\x11\x46\x5d\xde\xa3\x3f\xfb\xd6\xfe\x39\x65\x98\x62\xe5\x15\x4f\xd8\x7e\x92\xc8\x4a\x74\xca\x42\x3d\x64\xe6\x13\xa8\x66\xe9\x79\x34\x26\x7a\xdc\x53\xf8\x15\x2b\xd1\x69\xc6\x29\x22\x12\xc5\x57\x62\x91\x5d\x3d\x0e\x78\xec\x1b\x6f\x68\x59\x46\x69\x46\xdb\x65\x94\x76\xa4\x50\xd7\x54\xf9\xe5\x2f\x5e\xb5\xc3\x35\x28\x68\x9d\xf5\x4b\x69\xf0\x77\xab\x41\xd0\x54\x5d\xd6\x38\x4d\x0c\xca\x90\xfc\x62\x0a\xce\xdb\x0f\x1d\x51\x7c\x6a\x2b\xec\xa6\x16\xd4\xd5\x46\xee\x99\x8f\xdf\x57\xaf\xfe\xfb\xf0\xa4\x5b\xe6\xb8\x6f\x51\x83\xf5\x2d\x73\x3b\xb4\x57\xd5\xc3\xb2\xfc\xb0\x3c\xd1\x3c\x79\x48\x4a\x6a\xd1\xf7\x6d\xe7\xb5\x8c\x51\xf4\xa9\x90\xbd\x20\x53\x7f\x30\x36\x32\xbd\x8e\x96\xa3\xa8\xb7\x8d\xd2\x72\x46\x85\x0a\x4a\x50\x19\x0c\xed\xb2\x62\xfd\xfb\xe0\x46\x68\x67\xdb\x7a\x0f\xf6\x9c\xd3\x35\xbe\x42\xe9\xb2\x4a\x34\xa9\xb4\x32\xe7\xf1\xe1\x4e\x60\xde\xe1\xf1\x25\x9b\x71\xa5\xcb\x85\x6b\xe1\x36\x0d\x5e\xc2\x7a\x85\xfc\x25\x97\x6c\x41\xfe\xfe\xe3\xd1\x3f\xfe\xf9\xfa\xed\xc1\xfe\xeb\x7f\xbe\xd9\x3f\xf8\xfb\xf1\xc9\xd1\xfb\xf7\xe7\xff\x38\xbf\x38\x7a\xf3\xfe\xfd\x01\x22\x8c\xd8\x72\xdc\x73\xa6\xdf\xbf\xb7\x9c\xaa\xde\xbf\xbf\x48\x0a\x5e\xbc\x7f\x7f\xea\x7c\x20\xd8\x9c\xe1\xbf\x0f\x4f\x40\x7e\x62\x55\x98\x4f\x7b\x82\xbd\x15\x89\x0e\xef\x3d\xa7\xaa\x4e\xb2\x8c\xea\x6d\x5a\x00\x7a\xb6\xdd\xee\x56\xc2\x29\x75\x5a\xec\x66\xc0\xba\xab\x92\x73\xf1\x7a\x2f\x1d\x99\x30\x7d\xcd\x6c\x19\xe3\x4a\xbc\x2e\x1a\x14\x46\x07\x10\x5c\xab\x3a\xb7\xa0\x72\x26\xc9\x15\x67\xd7\x88\x39\x81\x4d\xf2\xea\xf6\x41\x50\xd6\x8c\xa5\xad\xcb\xa8\x60\xa0\x24\x15\x32\xf5\xad\x92\x1a\x7e\xe9\x25\x9f\x74\x54\x46\x83\xb8\x6f\x2c\x25\xa7\xc7\x87\xe4\xc5\x18\x95\x9c\xe3\x43\x84\xa1\x5c\x89\x52\xe5\x2c\x55\xb3\xa1\xe2\xee\xbb\xa2\xea\xa0\x66\x80\x36\xc2\xa8\x05\x07\x54\x93\x54\xe6\xf4\xbe\x4d\xd1\x3e\x51\xbf\x82\x2d\x2b\x7f\xab\x68\x86\x3a\xc0\xa9\x4c\x97\x25\xd3\xce\xb7\xee\xd4\xdf\xc6\xdf\xfa\xf7\xf8\xdb\xf8\x5b\x68\x86\xe9\xc8\xf6\xb7\xb1\xba\x4a\xc6\xdf\xda\x02\x69\x62\x2f\x5a\x99\x23\xbc\x54\xed\x64\xf5\x59\xbc\x07\x9e\x4d\x41\xdf\xfd\x2c\xe5\x2e\x3d\x76\x15\xed\xb9\x97\x28\x6a\x81\x50\x7b\x9d\x94\x8c\x62\xaa\x39\x49\x59\xc6\x6a\x1c\x98\x0d\x68\x66\x79\x73\x77\x4f\x17\x6b\x8b\x7a\x9f\x86\xbe\x29\xaf\x2f\xfd\xee\x5b\xa4\x86\x06\xc3\xd7\x75\xc7\xf9\x16\x0b\xa0\x23\x52\xc3\xbd\xc2\x46\x5a\x66\x0c\xe7\xa7\xcb\x4a\x59\x59\x57\xb7\xab\xc2\xd1\xdb\x10\x62\x1d\xd5\xe8\x17\x0e\xc8\xd4\x70\xc4\x85\x7f\x7f\xb0\x34\xb0\xf5\x1f\x06\x57\xf1\x17\xa8\x76\x5b\x10\xb3\x6b\x69\xf4\x64\x84\x15\xa2\xba\x84\x26\x85\xdf\x5e\xb2\xc5\x10\x01\x3d\x50\x09\xf9\x5b\x80\xc8\xec\x4b\xa2\x11\x78\x4d\x96\xe4\x5b\xf7\xaf\xbf\xdd\xd7\x5a\xeb\xe0\x47\xed\xe2\x45\xc5\x8f\xea\x1c\xf9\x3a\xc2\x2a\x98\x18\xe1\x03\x29\x6b\x0b\x64\xb4\x44\x72\x8d\xc9\x11\xd4\xbd\xa2\x46\x6a\x51\x69\xb3\x2c\xba\x58\xb9\x0e\x93\x11\x3a\x04\xf8\x5f\x82\xea\x98\x13\x79\x6e\x2b\x33\x01\x66\x67\xca\xca\xfa\x0c\x08\x98\x13\x79\xf4\x81\x25\x95\xfe\x9c\xd5\xea\x78\x5c\xb2\xee\x3d\xbf\x7e\x64\x1e\x82\x08\x69\x63\xb4\x70\x5f\x99\x50\xaf\xce\x20\x39\xed\x76\xda\x5e\xb2\x85\xf2\x20\x6b\x97\x38\xba\xad\x6a\xf6\xfc\xeb\x36\xb2\xa3\x0f\x5c\x69\xf5\xbf\x5c\xc3\xb1\x7c\x52\xb7\x7a\xa3\x98\x25\x56\x8f\x1e\x00\xec\x99\x3f\xe1\x31\x9f\x9b\xe0\xee\x03\x3a\x53\xfd\xad\xa3\x44\x00\xa1\x47\xcd\x37\xed\x2a\x9b\x9e\x24\x05\x14\xaa\x85\x58\x6c\x75\x62\x0d\xde\x8c\xfc\x89\x34\x04\xba\x1c\x19\x25\x2f\xde\x66\xec\x29\x7b\x11\x07\x54\x11\x7e\x45\x33\x26\x2c\x8a\x6d\x96\x26\xb4\xc4\x10\xbd\x05\x14\x52\x16\x08\xdb\x22\x69\x98\x3d\xce\x4a\xb2\x7a\x96\x95\x0d\xe5\xd1\x52\xf3\xa4\xca\x68\x49\xcc\x7a\x9c\xc9\xf2\x9e\xb8\x43\x78\x74\x6b\x7c\xe7\x59\xb4\x43\x3f\xe8\x58\xbe\x37\x47\x6c\x02\x1d\x5a\xed\xc5\x98\x4c\x50\x5f\x13\x2f\x94\xbd\x18\x48\x5b\x4e\x9d\x6c\xf2\x82\x22\x84\xca\xd3\x91\x73\x9c\xcf\xc0\xff\x3d\x08\x36\x0f\xbf\x32\xc7\xe4\x7b\x5f\x2d\x3e\x24\xb5\xcf\x18\x6a\x52\xed\x33\xed\xb2\xb1\xd3\x55\x2f\xea\xa9\x2c\xa1\x8b\xe1\x5e\x2a\xe1\x1e\x76\xc5\x13\x3d\x18\x93\xff\xd7\x68\x8a\xe0\x44\x76\xea\xa4\x5d\x66\xbe\x0e\xb7\x06\xec\x7b\x4e\xf6\xe0\xb6\x50\x95\x1c\xb8\x40\x91\x45\x02\x7d\x64\xd9\x30\x1d\x22\xdc\x2b\xa2\xdb\x91\x18\x45\x4d\xb1\xc1\x1a\x7e\xe7\x97\x5e\x42\x7a\x99\xc8\x95\x5d\xa5\x91\xe7\xd6\xc7\x59\x9c\x08\xf5\x8c\xf3\x6f\xf0\xd1\x93\x92\xcd\x60\xfd\xe1\xea\xf9\x8c\xab\x4f\xcb\x42\x66\x72\xb6\x38\x2f\x4a\x46\xd3\x03\x29\x94\x2e\x41\x34\x74\xc1\x77\xbb\x69\xcc\xa0\x71\xd6\x5c\x5e\x13\x6a\xcb\xd9\xe5\x14\x11\xf2\x64\x35\x9b\x63\xab\x00\xb8\xd1\x35\x99\x75\xaf\x68\x8d\x4e\x35\x26\xe7\xbe\x15\x00\x30\xb8\xef\x2c\x00\xa3\x80\xc3\xe3\x9a\x2e\xec\x62\xa2\x13\x9e\x32\x15\xe4\x28\xbb\x97\xc1\xd0\xcf\x8d\xdf\x0f\x52\x79\xff\xe4\xf0\xbe\xfd\x17\xd6\xa8\xd0\xde\xf0\x29\x5e\x33\x42\xaa\xd7\xf4\xf5\x1a\x29\xd0\x8d\xe6\xd2\x6a\xaa\x88\xe5\xea\x28\xf3\x19\x75\xd3\x2e\xe0\x4b\x39\xfd\x70\x7e\xc9\xae\x5b\xdc\xe9\x3e\xf4\x47\x76\xff\x54\xb0\x11\xd8\xa3\xef\x84\xa2\x9a\xab\x29\x34\x6a\xf9\x8c\xfa\x38\x14\x1d\xb4\xeb\x27\x81\x47\x5c\xbb\x13\x8e\xe6\x8a\xc2\x3d\xde\x62\xc4\x2c\x36\xff\xaf\xb6\x83\x70\x03\xc4\x22\x08\xdf\x8a\xc2\xac\xa0\xc4\xb6\x67\xd2\xb2\x8e\x43\x63\xa4\xa2\xca\x27\xac\xf4\x6b\x1f\x9d\x01\xbc\x6c\x40\xd3\x36\xd6\x7e\x7b\xc1\xd8\x3a\x13\xae\x6b\x5a\x19\x90\xe7\xe8\x83\xd1\x3c\x54\xbb\x44\x25\x3c\xe2\xee\x6a\x8d\x41\x31\x3c\xe6\x12\x38\x1b\xd3\x10\x75\x39\x01\xb3\x37\x3c\xd3\x56\xce\xd5\x47\xb7\xfe\x8c\xa4\x5b\x8f\x46\xb2\x22\x51\xfa\xc6\xcf\x6f\xb4\x4a\x09\x0b\xfe\xac\x53\x48\x0d\x51\x81\x47\x07\x36\x15\xf5\xc6\x6e\xdb\xe6\x67\x5e\x9b\x33\x46\x91\xb9\x08\xef\xeb\xda\x08\xa9\x43\x8f\x47\xd2\x43\x9f\x47\x02\xb2\xec\xb2\x85\x04\x0c\xef\x77\xc4\x6a\x3d\x48\xf7\x8e\x8f\xa4\xbd\x41\x5d\x1f\x11\x43\x5d\xd6\xa6\x35\x72\x56\x64\x5a\xd7\xc2\xae\x36\xac\x3b\x3d\xbb\x87\x36\x68\xa4\xa3\x8d\x5b\x1f\x11\x21\xe4\x3d\xac\x5d\x0a\x01\x26\x39\x75\xab\x63\xa5\xcd\x7b\x2c\x86\xe4\x44\x6a\xf3\x9f\xc0\xfc\x3d\x94\x4c\x9d\x48\x0d\x67\x36\x82\x94\xf8\x09\x3d\x12\xd2\xb5\x11\x00\xbc\x37\x90\x9b\x36\x44\x6b\x76\x3c\x47\xb0\x15\x86\xc5\xb1\x20\xb2\x74\x14\xf3\xd6\x85\xb2\x43\x84\x61\x05\x8b\xb1\x75\xa3\x71\x62\xc6\x09\xe9\x7c\xcb\x70\x76\x28\xc8\xfe\xc2\x5f\x00\x3c\xb5\xc8\xa0\x40\x20\xad\x4a\xc4\xb0\x35\xba\xa6\x66\x33\x9e\x90\x9c\x95\x33\x68\x1b\x9d\xcc\xfb\x98\xbe\x2e\xfb\x0a\x1e\x1d\x77\x97\xf0\x65\x3a\xf0\x12\x6c\xd9\xa0\x62\xf5\xa8\x02\xe0\x78\xb8\xad\xe5\x14\x2c\xa9\xff\xe3\x7d\xd0\xff\x97\x14\x94\x97\x80\x79\x6b\x63\xc7\xe1\x6f\x36\xfa\x12\x0e\x63\x46\x58\xf2\x2d\x51\x41\x18\x56\x32\x99\xd1\x9b\x8a\xc7\x90\x5c\xcf\xa5\xc2\xcd\xd0\xbb\x3f\x76\x2e\xd9\x62\x67\xb8\xc4\x7a\x3b\xc7\x62\xa7\x0e\x0c\x47\xcc\xe6\x37\x61\xc8\x20\xdc\x81\xdf\x76\x1e\x4e\x57\xe9\xb4\xd9\xf6\xd1\x31\xa0\xf9\x42\x2d\xf9\xca\xda\x3c\x9d\x35\xff\xdd\x37\x38\x50\x60\x9f\x63\x4c\x70\x56\x32\x2c\xc6\x04\x53\x1a\x14\x75\xdb\xdd\xa5\x12\xec\x8a\x99\xc9\x4a\xb9\xb2\x78\x80\x2e\xc5\xe0\x5f\x4b\x26\xd1\xff\xff\x50\x9e\x48\xed\xac\xf6\x7f\x39\xb7\x17\xf2\xdf\x07\x9e\x57\x39\xe2\x66\x69\x63\x29\xa4\x7c\xea\x80\x80\x5d\x66\x43\x6c\x2f\xc4\x66\xab\xe5\x63\x4d\xcb\x19\x64\x38\x5a\x7b\xc1\xb1\xd9\x2c\x93\x13\x9a\x91\x9c\x0b\xf3\x18\x1b\xbc\x8c\xce\xf9\x37\xb1\x7f\xde\xf2\x20\x58\x0b\x7c\xc6\x27\x19\xb3\x06\x49\x03\x63\x3b\xb8\xb9\x71\x21\x2c\xd2\x8c\x29\x85\xf1\xc6\x37\x5c\x1c\x3a\x6f\xc6\x2b\x59\x12\xf6\x81\xe6\x45\xc6\xb0\x44\x8f\x7c\x3d\xfa\x8f\x14\x8c\xd8\x00\xfd\x90\xb8\xe9\xa9\xfb\x96\xbd\xc0\x85\x54\x37\x16\xf0\xd9\x17\x91\x4d\xe8\x3d\x29\x8a\x7c\xf5\xec\xab\x67\x2f\x5e\x9a\x3d\x04\xdd\xf4\x54\x59\x08\xa2\x65\x6a\xbc\x18\x93\x8f\xc4\xbc\xc1\x0b\xfb\xdf\xaf\xec\x7f\xbf\x26\x1f\xc9\x47\x42\x4e\xc9\x29\x09\xff\x6b\xfe\x43\x3e\x92\x91\x21\x42\xf0\xaa\x2f\xcc\xd7\x24\x32\xb7\x14\x04\x1f\xb4\x2f\xb8\xf5\x7d\x03\xb5\xb4\x43\x43\xb5\x53\x22\x73\x06\xaf\xfa\xd5\xff\x72\xd7\x40\xa8\x58\x63\x6b\x47\x78\xa9\x3d\x78\xa5\x01\xb9\x06\xa7\x5a\x4e\x2f\xd1\xa0\xdc\x4f\x74\x45\x33\xf3\xf0\xbd\xaf\x47\x2f\x06\x44\x8a\xf8\xf2\x2b\x2e\x8d\xf2\xee\xde\x70\xef\xc5\x60\xbc\xf4\xca\x5f\xad\x78\xe5\x46\x97\x43\x5b\xee\x68\x06\xbd\x99\xdf\x1d\xab\xef\x8b\xc5\x35\x5d\x78\x86\x77\x06\xf5\x8c\x5f\x79\xb4\xff\x00\x84\x04\xa2\x8d\xc0\xbf\xdc\xe1\x4a\xe1\xa0\x0b\xc2\xf5\x98\x1c\xeb\xdd\x5d\xd7\x53\xd3\xe8\xfa\xae\x2d\xc1\x61\x88\x97\x09\x84\x07\xde\x78\xde\xc8\x46\x6e\x81\xce\xd6\xab\x5b\xf7\x5e\x7d\x05\xf0\xc8\xfd\x2a\xe9\x2c\xe2\x76\xea\x15\x17\x55\xb3\x2f\xaf\xfa\xe6\xc2\xf5\x89\x53\xb7\xae\xee\x06\xea\xb5\x13\x43\x97\x6c\xd1\x58\xf9\xf5\x37\x0d\x21\x87\xc7\x79\xed\x08\xba\xed\xd0\x55\xaf\xc8\xfb\x9d\x78\x5d\xbe\xdf\x01\xe7\xbd\xdf\x3f\x6d\x1f\x1f\x9a\x25\x95\x6d\x00\x27\xa7\xc4\xb1\x71\x80\xd0\xb5\x2f\xd2\x3a\x65\xa2\xe5\xfb\x03\x84\x3d\xe8\x8c\x33\x88\x23\x94\xcb\x5f\x12\xa4\x55\x44\x59\x78\x66\x15\xd6\xeb\x78\x4c\xf6\x91\x81\x15\x04\x3f\xee\xf2\x5e\x37\xd2\xae\x6e\x07\x7b\x2d\xc5\x6e\x0d\xbc\x4b\x72\x89\x10\x69\xc2\x6d\x8f\xd6\x57\x25\x89\x06\x55\xc5\x4f\xeb\xf1\x74\x45\x1e\x4c\xed\x20\x46\xf0\x49\xc3\x24\x50\x37\x11\xf2\x4f\x80\xea\xff\x62\x05\x12\xa3\x5d\x2e\x2a\x26\xd7\x73\xcb\x48\xf5\x33\xa5\xc6\xe7\xfe\xdc\x94\x1f\x5e\xf9\x8e\xf6\x4d\x68\x99\xd9\x66\xb3\xf8\x6a\xd8\x78\x7b\x7b\xfe\xcf\x6d\xf6\x90\xaf\x5e\xde\x6f\x73\xb0\xff\xbd\x88\xa6\x79\xe5\xec\xfe\x79\xaf\x7e\xcb\x01\x04\x30\x57\x2c\x02\x28\x76\xa8\x83\x59\x63\xbf\xa1\x29\xae\x2b\x8a\xf5\x11\x82\x5d\xdb\xa4\xb5\x9b\x3f\x2a\xa8\x71\x73\xc2\x7d\x68\xf6\x1f\x5a\x29\x06\x45\x2b\x15\xd4\x33\x1b\x42\xba\x20\xda\xd7\x7b\x5f\x93\x11\x79\x3e\x30\xdc\x20\x90\xad\x80\x98\xe1\x56\x66\xb6\x06\x9b\x83\xa9\xe7\x46\x79\x32\x94\x51\x43\xdf\x4a\xab\xb1\x09\xc1\x94\xfa\x5e\x89\x02\xab\x6a\x56\x75\x4b\x84\xb2\x19\xb3\x32\x6b\x12\x1d\x8b\x53\x99\xc6\x3e\x7f\x5f\x08\x33\xa3\x9a\xb5\x02\x3d\x58\xaf\xbc\x0f\x3c\xf1\x3d\x84\x7f\xfd\x58\x4e\xc3\x33\x46\x8a\x9c\x22\x24\x05\x76\x34\x1e\x43\xbb\x6a\xbb\xd7\xda\xd4\x46\x74\xf2\x58\xde\xe1\xca\xfb\xf9\x38\x54\x8a\x25\x41\x93\xc0\x12\xc5\x05\x4f\x59\xc9\x5c\x43\xe4\x30\x11\xd6\x47\x50\xc8\xcf\xf5\x95\x98\x00\x0b\x99\x42\x38\xd0\xdf\xb0\xf0\x6a\x67\x52\x25\x97\x4c\x3b\x0b\xa9\x84\xdc\xbd\xa2\xd2\x64\x42\x33\x2a\x8c\xad\xbd\xe4\x31\xd7\x12\x07\xc3\x3b\xe1\x29\x58\x4d\xee\x13\x34\x71\xe8\x20\xbe\xcf\x85\xd2\x66\x34\x0c\xfc\xd7\x2f\xb8\x9f\x29\x39\x24\xd7\xf5\x00\xcb\x9a\x2e\x0c\x65\xff\x8d\x46\x9f\x00\xda\x39\xff\xbf\xc3\xfa\xb0\x2b\x6c\x4c\xd8\x78\x06\x42\xb6\x31\x13\x3b\x71\x75\x81\x4b\x58\xdd\x19\xe2\xc7\x98\x09\xb1\xd5\x1e\x56\xc3\xb6\x38\xd4\xc1\xcb\x8a\x14\x8a\xa0\x9a\x03\xfb\x2b\xe2\x27\x98\x25\xe8\x46\x07\x51\x79\xfb\xe8\xc7\x7a\x95\x96\xf5\xb9\xf3\x21\x96\x74\xca\xee\x46\xde\xf2\x36\x53\x2b\x42\x36\x30\x98\x32\x9a\xb9\xd4\x49\xe8\x93\xe3\x41\x42\xc5\xee\x6e\xad\x8d\x02\x87\xa3\xc4\xa9\xf7\x4b\xa3\x4d\x47\xfb\x15\xd9\x73\xb5\x0e\x44\xb3\x2c\xc3\x35\x58\x6f\xdb\x46\xfc\x86\x6d\xe1\x39\x8c\x10\x6b\xce\x2b\x6f\x8c\x7b\xc9\x63\x12\x1f\x18\x67\x0b\x0f\xef\x33\x24\x93\x4a\x1b\x35\xdb\x88\xcc\x3b\x29\xda\x68\x4c\xcc\x59\x56\x90\x92\xa5\x55\x62\x8b\xfe\x40\x46\xef\x87\x5a\x01\xb6\x65\x74\x8b\x7e\x27\x22\xe8\x0e\xf6\x09\x11\xb1\x11\xc1\xa7\xb0\xa4\xc1\xf4\xe1\x53\xc2\xae\x58\xb9\x20\x85\x54\x0a\x56\x17\x2c\x1a\xcc\x7c\x07\x27\x8b\x47\x22\x84\x1d\x0c\xde\xca\x6d\x1a\x3b\x76\xd7\xd8\x01\xad\x4a\x46\x12\xe6\xf3\x18\x91\x5f\x3f\x7b\x61\x8c\xc8\xdb\x14\x80\x53\xf8\x5f\x6d\x15\xba\xff\x1e\x4f\x57\xe8\x39\xf5\xbb\x44\x9c\x73\x1f\xc3\xf1\x2b\xb0\xef\xbe\x1e\x04\xf6\xe3\xd7\xc6\xd4\xdd\x33\xef\xfa\xd5\xc0\xbc\x75\x60\x19\x7e\x15\x58\x86\xfe\x4e\xfb\x46\x4c\x45\xb6\xe1\xb1\xb0\x65\x0e\xd0\x23\xcc\x6a\x87\x36\x65\xde\xbc\x91\xd2\x56\x2f\xe0\xb9\x13\xd1\xc8\x76\xb1\x66\xba\xab\xd1\x44\xe5\x9a\x7c\x61\x54\xd3\x2f\x82\xeb\x6f\xb4\xe9\xda\x9b\x6a\x5d\x5b\xcf\x67\x5c\x69\xe8\x3f\x6f\x34\xff\xfb\xf7\x46\x6e\x1f\x4b\xef\x1a\x49\x5f\xfe\x0a\x24\x48\x4e\x8b\x7b\x8c\x83\x60\xec\x9d\x1a\x95\xbd\xb6\x51\x58\x3b\x94\x8d\x32\xa2\x23\x21\xb7\xd1\xf0\xc9\x22\x2c\x9e\x99\xb0\x4c\x22\xb4\xbd\xcd\x13\xbc\x47\x5d\x9e\xef\x0d\xa4\xb4\x2c\xe9\x8c\x3d\xb3\x8f\x7d\x2c\x3d\xc1\x7e\x42\xf4\xfb\x28\xa4\x84\xd8\x05\x16\x17\xdf\xd5\x2f\xb9\x64\x03\x90\x02\x34\x81\xd4\x7f\x20\x64\x04\x3e\x15\x14\x15\x3c\x92\xbc\x95\x16\x48\x39\x5d\xa2\xa4\xf4\x5a\x1d\x65\x54\x69\x9e\x7c\x9f\xc9\xe4\xf2\x5c\xcb\xb2\x07\xd5\x62\xd5\xa8\xd1\x9c\x0a\xb2\xff\xf3\x39\x39\xe4\xea\xb2\x6e\xb1\x84\x30\xe6\x71\xb6\x3d\xf5\x30\x7e\xb6\xf0\x92\xe4\x34\x99\xa3\x46\x6a\xfd\x1e\xae\x95\x43\x7f\x6b\xe5\x0f\xf4\x5a\x31\x7c\xfd\x89\x79\x7d\xf3\x33\x6b\x2f\x82\xd7\x06\xba\x84\x9f\x73\x7c\xb8\x86\x2c\x97\xa9\x6a\xdb\x7b\x8e\xac\x68\x08\xe2\x90\x65\xb1\x80\x30\x63\xb6\x29\x2c\xc0\x19\xc6\x4d\x3e\x80\x87\x16\xb2\x22\xd7\x14\xc3\x55\x20\x61\xc7\xe4\x82\x17\x2f\xc9\x51\x00\x97\xbf\x6a\x28\xa3\x7d\x78\xe8\x32\x9b\x20\x08\x3c\xb7\xdc\x1a\xff\x08\x55\x2b\xf5\x92\xec\xb0\x0f\xfa\x4f\x3b\x43\xb2\xf3\x61\xaa\xcc\x7f\x84\x9e\x42\x7b\x0d\xdb\xb6\xcb\xe8\x78\x62\xca\xca\xda\x22\xc4\x1b\x96\x51\x03\xfa\x67\x59\x72\xf1\xf6\xf0\xed\x4b\xd0\xe5\x53\x69\x8c\x39\xdb\xd8\xd6\x61\x60\x58\xd9\x18\x90\x01\x8a\x39\x13\x99\x17\xa5\xcc\x79\x50\xa9\x02\x4b\xae\xcd\x0a\x20\x7d\x84\x4a\xc1\x5e\x05\x66\xe8\x85\x9f\xfc\x70\x8e\xa5\x82\x13\xe2\x2e\xcc\x74\x3c\x25\x12\x83\x53\x71\xad\x1c\x57\xfe\x22\xc3\x3e\x76\x14\x6c\xd7\x5a\x33\x8c\xd1\xcc\xed\x4f\xcf\x52\x76\xf5\x4c\xa5\xf4\xc5\x10\x1e\x83\xdc\xb0\x68\xbc\x13\x55\x64\xe7\xc5\xce\x98\x9c\xf3\x9c\x67\xb4\xcc\x6c\x1f\x39\x3b\x44\x7d\x9d\x31\x14\xdc\x80\x60\xfe\x3e\xdf\x21\x7b\x58\xac\x06\xea\x46\xc6\x1c\x74\x89\x87\xea\x82\x58\xfe\xa0\x95\x76\x49\x7a\x70\x0e\x91\xce\x0e\x22\x62\x5b\xca\xbe\x15\x59\xeb\x14\x9f\x98\x39\xdc\x68\x2e\xd3\xbb\xac\x6c\x35\xed\x54\x96\xd6\x08\xf4\x97\xb8\x8a\x78\x2e\xac\xda\xf2\xc6\x4c\xfd\xfd\xdb\x38\x3e\xd4\xf6\x43\x7a\x40\x69\x21\x7e\x17\xe9\x87\xbe\x6e\x34\x08\x7f\x09\xfe\x5b\xc5\xc8\xf1\xa1\xef\xd7\xcd\x4a\xc5\x95\x36\x22\x2a\x8d\x54\x03\x8e\xfa\xc2\xde\x7e\x4e\xff\x23\x05\x39\xfa\xfe\xdc\xbe\xd6\x60\x03\x89\xdd\x52\xd2\xd1\xff\x54\x25\x33\x1a\x51\x67\xf5\xcb\x8f\xd4\x54\xb9\xcc\x79\x72\x48\x35\x45\xcd\x0b\x25\x95\xac\x51\x24\x40\xa9\x9a\x40\x76\xaf\x83\x08\x69\xa9\x3c\x93\xf5\x6b\x3f\x86\x83\x4e\xda\xc3\x4e\x9a\xdb\xdf\x9d\x1d\xaf\x41\x77\x4a\x60\xbb\x9d\xbd\x91\x69\x4f\x0a\x54\x30\xa0\xdb\xf2\x00\xd5\xeb\x00\xcf\x93\xdc\x3c\x89\x9c\x48\xc1\x86\xe4\x8c\xd1\x94\x18\xe9\x66\xff\xf9\x73\xc9\xf5\x7d\x81\x12\xea\xa3\xf3\xd6\xef\x26\xb1\x17\x42\xb8\xc1\x1c\x11\x4e\x02\x70\x1c\x40\x72\x02\xa1\x63\x75\x80\x49\x26\x27\xc4\x0a\x8b\x75\x7e\xfd\xbb\xb3\xe3\xde\x3e\xfe\xdd\xd9\xb1\xfb\x76\xf3\x4f\x39\xdd\xcc\xcf\xee\xd1\x78\xa8\x6d\x87\x57\x0d\x65\xbf\x56\xe7\x6a\x4c\xf9\xa6\x41\x70\x77\x6b\x60\xdc\x97\x1d\xb0\x2e\x9a\x5f\x72\xd1\x3a\x59\x3c\x96\x36\x80\x27\xef\xb1\x13\x82\xd8\x18\x40\xb6\xa4\x2f\x49\x5e\x65\x1a\xca\xe3\x81\xd7\x0c\xf3\x41\x86\x82\xe3\x3a\x62\xa1\xa2\x08\x39\x64\x18\x8e\x48\x5f\xba\x84\x45\x7f\xc7\xea\x1b\xde\x50\x41\x67\xe6\x72\xd8\x01\x49\x8e\x7f\x06\x4c\xbe\x87\x4e\x77\xe1\x7f\xa2\x57\x94\x67\x74\xc2\x33\xae\x41\x9f\x1b\x8c\x9d\x36\xaf\x10\x2b\xc3\xbc\xf2\xda\xa4\x5f\xaf\xaa\xad\x57\x5b\xc3\x42\x62\xc0\xc1\x21\x7b\xe6\xb7\x67\xd7\x46\xd4\x0f\xc6\x20\xf7\xe1\x42\x80\x2d\x6d\x28\xbf\x67\x9f\x52\x7e\xd7\xa2\xa7\xc2\x7c\xbf\x6a\xd9\xec\x62\x59\x77\x32\x23\xad\xd4\x9d\xe0\x07\x8b\x4e\xf5\xc4\xd5\x27\x6c\x38\xda\x41\x81\x82\xb5\xd3\xf2\xfe\xae\x2a\xd4\xc3\x2c\x9c\xf4\xe9\x2d\x1c\x82\x6d\x81\xec\x4c\xf7\x42\xae\x7a\x38\xa7\x6b\x78\x14\x42\xfc\xa9\x51\x67\x85\x2b\xeb\xdc\xca\x72\x87\x4e\x08\xf7\x9b\xf5\xd4\xa6\x0a\x13\x8f\xce\xe2\xd7\x73\x70\x3f\x74\x71\xa3\x39\xb2\xe0\x26\x05\xa7\x49\xeb\x75\xd6\xf1\x33\x13\x56\xcc\xa7\xdd\xb3\x29\xcd\x30\xaf\xce\xe3\xa8\xcd\x01\x2b\xe6\xe4\xd5\xf9\x0a\x31\x89\x99\xac\xe6\xbb\x15\xc6\x72\x76\x15\xc9\xf8\x94\x69\xde\x8a\x08\x6b\x16\x94\xb9\x14\x5c\xcb\x52\xad\xa3\x96\xd4\x3e\xba\x1f\xc5\xcd\x8d\x66\xf8\xf3\xcc\x11\x85\xbc\x09\xce\x52\x92\xc8\x2c\x63\x89\xcb\x2f\x85\x29\xf6\xb7\xad\x70\xc4\xd8\x0c\x04\x35\xbe\xfc\x06\x5c\x31\xd6\xe9\xf2\x0c\xd9\xee\xd9\xd9\xd1\xfe\xe1\x9b\xa3\x71\x9e\xfe\x61\x2e\xaf\x47\x5a\x8e\x2a\xc5\x46\x5c\x77\xd3\xb7\xd6\x58\x78\xda\x83\xa7\x5b\xcf\xfb\x72\x72\xeb\xb9\x99\xb2\x1a\xfd\xf0\x9d\xaa\xf1\x49\x5d\xdc\xb9\x94\x52\x2f\x23\x94\x4e\xab\x2c\xc3\xb9\xd5\x25\x63\xc3\xd0\xbf\x7d\x4f\xfc\xd6\xfa\xd8\x2c\x5d\xb8\x76\xf3\x46\x24\x7a\x58\xcd\x78\x53\x16\x48\x77\x5d\xa1\xad\xa6\x4d\x96\xe6\xa1\x1e\x2f\x9e\x89\xf3\xe8\x3c\x06\x44\xf4\xdc\xcc\xcb\x25\x5b\x10\xa8\x31\x9c\xca\x12\xf0\xbe\x63\xfe\x64\x3a\x01\xe2\x3d\x83\xe6\xda\x56\xe1\xd8\x10\xc2\x77\x51\x45\xe0\x43\xce\xd8\xb4\x4f\xb2\x9f\xb1\xe9\x2a\xaa\xdb\xd3\x00\x8a\xe6\xd3\xe3\x8c\xbe\x52\xe9\x39\xa6\xbc\x22\x18\x23\xd2\x76\xe5\x34\xd8\x22\xd1\x0d\xa1\x7b\xa7\xf2\xbe\x3e\x4a\xd0\xbb\xb4\x12\x22\x4b\x93\x17\xba\x2d\xed\x24\xe9\x7b\x87\x41\xe4\x95\xb1\x62\xd9\xf5\xb3\x6b\x59\x5e\x72\x31\x1b\x5d\x73\x3d\x1f\x21\xa5\xd4\x33\x80\x86\x7d\xf6\x07\xf8\x8f\x8d\x22\xef\xa7\xa9\xcd\x7f\xab\x14\x9b\x56\x19\x66\xa6\xa9\x31\xa1\x05\xff\x89\x95\x0a\xb2\x2c\x2f\xb9\x48\x87\xa4\xe2\xe9\x77\x6d\x67\x8c\xf4\xb1\x5a\xda\xb7\x76\x6d\xd2\xba\xb2\xdd\x5d\x65\xb8\x8d\x96\x4e\x26\x95\x34\x95\x0a\x1b\x04\x18\x52\x45\x4b\x80\xa6\x39\x17\x9b\xb2\x02\xda\x5a\x07\x5c\xa4\xed\x28\xd9\x08\x40\xc0\x38\xb1\x79\x60\xcf\xd9\x30\xb6\xcf\xf9\xa1\xce\x7b\x82\x1d\x40\x6d\xf6\x4f\x9c\xfb\x73\x27\xc1\x92\x2f\xd4\x6f\xd9\x08\x9f\x32\x2a\xd2\x9a\xae\xdb\x44\x9e\xfb\x1c\x9f\x2f\x91\xa7\x5f\x87\xfc\x67\x48\xcf\x79\x50\x8e\x23\x1b\xac\x33\x3f\xac\x1f\x6c\x8d\xa4\xee\xae\x19\x3f\x8c\x86\x56\xef\x3e\xd0\xbc\x46\x39\x44\x15\x50\xc0\x50\x2a\x39\x7f\x1a\xf6\x43\xf6\xdd\x12\x5c\x85\x71\x22\x85\xb0\x40\xba\x6f\x0b\x26\xce\x35\x4d\x2e\x3b\x46\x75\xb7\x5a\xd5\xef\x4c\xab\x7a\xa0\x44\x20\xc7\xa2\x58\x4f\x67\xd3\xdf\xea\x64\x6f\x5c\xe4\x8f\x50\x00\x63\x57\x98\x37\xb4\xe8\xee\x5d\x75\x23\x35\x34\x28\x7f\xda\x3a\x54\xa1\x38\xa8\x90\x45\x95\x21\x4c\x2c\x57\x96\x8e\x9f\x5f\xe3\xe9\xba\xbe\xed\x16\xd3\x5f\x0e\x4c\x30\x60\x2c\x51\x73\x73\x66\xc2\x75\x2d\x2b\x15\xd3\x08\x3f\x62\xb1\xf4\xa4\x20\x89\x2d\x31\x06\x7d\xc4\xe8\x1e\x76\xb8\x40\x57\x11\x44\x26\xda\x15\x83\x7a\xa4\x92\xe7\xcf\x9f\x3f\x47\xf4\x85\xff\xfa\xaf\xff\x22\xb2\x84\xa6\x55\x09\xcf\x97\x2f\x84\xab\xfe\xfc\xe2\xc5\x98\xfc\x63\xff\xcd\x6b\xa8\x68\x28\xb4\xc2\x56\x26\x38\xb2\xb9\x20\xba\x59\x0d\xc9\xff\x3e\x7f\x7b\x52\x57\x05\xc7\xbf\x82\x69\xee\x3f\x2f\x06\x90\x7e\xfe\x97\x3f\xfd\x69\x4c\x0e\x79\x09\x15\x5d\x9c\xf9\xe6\xa4\xde\xd5\x42\x4b\x86\x68\x11\x50\xb7\xef\x34\x2e\xee\xfb\x00\x59\x08\x28\x6c\xdf\x8c\x85\xae\x86\x21\x33\x9e\x68\x2c\x1e\x43\xb1\xe6\x7a\x9f\x22\xf6\xb4\x45\x73\xb7\xda\x1f\xbc\xdc\x90\x64\xfc\x92\x91\xa9\x82\xb6\xe8\x35\x1e\x90\xed\xd8\x67\x0b\x65\x70\xb0\x7a\xae\x14\xd3\x8f\x3c\x6d\xb5\x93\xab\x39\xe2\x6d\x18\xa9\xa1\xb0\xda\xf2\xd6\x4b\xb6\x18\x21\x9f\x15\x94\xfb\x62\x18\xc8\x00\x8c\x9a\x45\x79\x5f\x4f\x4a\x0e\xbc\x54\x71\x75\xee\x45\x29\xff\x8d\x2c\x00\x25\xc6\x81\x78\x86\x12\x60\x98\x49\x5b\x00\x1c\x44\xb7\x5c\x99\xb4\xed\x4e\xea\x4e\x5b\xc8\xf3\xe5\xbe\x11\x19\x57\xe6\x11\x00\x30\x71\xcb\x93\xeb\xa6\x77\x86\x4b\x15\xf2\x4b\x25\x96\xee\xb6\xc5\xfc\x56\x5c\xda\x6e\x51\x16\xba\xaf\x1e\x03\x71\x8c\x2c\xf6\x82\xbd\xd6\x51\xc9\x13\x22\xca\xb7\x56\x4c\x57\x96\x34\x90\x45\x6f\x9e\x0d\x9d\x8c\xe0\x0b\x73\x5a\x5e\x1a\xc3\xd5\x4a\x97\x31\x39\x35\x2f\xe9\xe1\x1b\x10\x15\xef\x0a\x03\x9b\x39\x5d\xc0\x63\xad\xe2\x06\x0f\xd9\x1d\x8f\x77\x71\xf9\xc9\x92\x28\x4d\x4b\xbb\x96\xcc\xf9\xa7\x01\xc7\xf9\x86\x16\x0a\xe1\xe1\x8c\xa6\x0a\xd0\x89\x12\x4a\xd2\xf5\xbc\xee\x8f\x8c\xb4\xde\x42\x68\x92\x11\x10\xa6\xf5\x00\x1b\x0e\x9f\x69\x67\xdf\xae\xf2\x8d\xc0\x76\xcc\x3b\x28\x1c\x78\x34\x63\xaa\x69\x23\xb2\x71\x27\x7d\xc3\xb6\x0f\xc8\xd8\xa3\x52\x30\x56\xb7\x0b\xb3\x82\x33\x54\xc0\xe2\x1e\xe7\x8f\x55\x8f\xc0\xa3\x0f\x6d\x02\x8f\xee\x3a\x05\x1e\x5d\x82\xc8\x78\x44\x3c\xec\x22\xc9\x48\x4c\xbb\x81\xe1\x1e\x35\xad\xa7\x00\x9a\xba\x14\xc1\xb2\xc6\x0e\x68\xae\x93\x9f\x20\x74\xa2\x64\x56\x69\xbc\xb5\xfe\x31\xdc\xfd\x60\x50\x07\x2e\x09\x5b\x9e\xbf\x2c\xd8\x0b\x41\x0b\xc0\xed\xa3\xcb\xb6\x88\x47\x67\xb1\xd1\xc5\x09\xf1\x3b\x72\x40\x74\xa6\xb3\x37\xd8\xfa\xa0\xb5\x1b\xcc\x57\xdc\x5d\xcf\x99\x4d\x81\x08\xf4\x3e\x23\x4d\x8d\x8c\x00\xa5\xd2\xa9\x70\x88\x87\x93\xae\xc5\xcd\x98\x28\xde\xdd\x97\xa0\x38\xd9\xf3\x7d\xd5\x7d\xda\xdd\xb1\xd0\xac\x9c\xd2\x84\x0d\x42\x1f\x03\x2b\xe6\x2c\x67\xa5\x21\x94\xbd\xce\xd5\x68\xcf\xa9\x48\x33\x0b\x5c\xc0\x4a\x58\xc1\xec\x83\x66\xa5\x21\xea\xc1\xf9\x31\x49\x4b\x7e\xc5\x4a\x45\xf6\xbe\x67\xc6\xd6\x40\x18\xaa\xc1\x23\x4c\x83\xc5\x0f\x59\x87\x07\x04\x1e\xdc\x4f\xe9\x07\x0c\xb5\xaa\x25\x74\x3d\x55\x0e\xf2\xca\x4c\xab\x0a\x7d\x47\x63\xb3\x20\x60\x0b\x05\xe9\x0b\xad\x0f\x31\xb6\xe9\x3a\xfd\x42\x87\x86\x44\xe3\xc0\x54\xd9\xce\xbf\x00\x87\x63\x05\xbb\x85\x49\x59\x5b\x71\x43\xff\x05\x25\x75\xb0\xea\xb6\xda\x8f\xa9\xb5\x2b\xe5\x15\x4f\x9d\x3a\x04\xa9\x11\x35\xe8\x5f\x41\x55\x00\x5e\x40\x95\x92\xb6\x9f\x79\x30\x35\x68\xa5\x82\xd2\x14\xf7\xcc\x70\xe1\xe6\x30\x4c\x26\x01\x79\xbe\x55\xc3\x2e\xd2\xcb\x86\x28\x53\x76\x5a\x4d\x32\xae\xe6\xe7\xbd\x86\x44\x56\x0d\x8c\x49\x89\x4b\x99\x2a\x37\x46\x46\x14\x13\x8a\xdb\xfe\xaa\xa8\x6e\x71\xa3\x6d\x4b\x98\x06\x77\x77\xb8\x28\x24\x54\xc3\x43\xd7\x56\xf7\xd3\x49\xfd\x1e\x16\xac\x04\xdb\x05\xa6\xec\x9d\x28\xa2\xf3\x09\xcd\x32\x65\xf5\x5b\x0f\x86\xed\xf6\x1e\xd4\x50\x1d\x80\x09\x72\x05\x37\x0c\xe3\xde\x1e\x52\x70\x50\x78\x79\xe4\xf6\x95\x1f\xa6\x02\x88\x4b\x29\xdc\x45\xd0\xf5\xd0\xdd\xe0\x29\x84\x95\x38\xc8\x74\x6b\xc4\xcc\xde\x86\x7f\x1e\x5f\xf8\xe7\x61\x6a\x2a\xea\x5e\x54\x14\x4e\x8e\xa0\x42\xcb\x75\xd4\xa7\x1e\xd9\xa0\xb6\x24\xc7\x9f\x4a\xd3\x5c\x5b\x08\x18\xdf\x6f\x5f\x5b\xfc\xf3\x7e\xbc\xbb\xcd\x41\x41\x15\x33\xa6\x38\x48\xa8\x91\xa5\x5f\x12\x2c\x29\x6b\x23\xfb\x75\xbe\x2c\xd7\xea\x3d\x1d\xb6\x73\x3c\xb9\xab\x48\x2a\x93\xca\x18\x5f\x35\xd9\xeb\x84\x8b\x6e\x6d\x6d\x9e\x16\xce\x7e\x2a\xaf\xc5\x35\x2d\xd3\xfd\xd3\x56\xb5\xb9\xb1\x72\x56\x8f\x15\xaa\xde\xee\x34\x31\xe7\xe9\x44\x56\xda\x63\x1b\x6e\xa3\x7d\x2b\x87\x08\xa5\xf9\x2a\x77\x9b\x96\x46\xc8\xde\x31\x9a\x77\x5f\x87\xdd\x36\x40\xb8\x0d\x10\x46\xc7\x26\x05\x08\x8f\x31\x40\x18\xb6\x84\x8b\xc4\x8b\xf5\xd0\x1a\x8a\x3f\x89\x18\xd3\x61\x2d\x52\x51\x13\x6f\xd6\xf3\x36\x94\x7f\x5c\xbc\x35\xd7\x05\x06\x83\x93\xb9\xa0\x97\x3d\x85\x78\xd4\x06\xc4\x93\x80\x96\x1d\xac\x42\x3c\x62\x81\x5f\xd7\xab\x21\x4a\x2d\x06\xa6\x83\x08\x77\x21\xd3\x97\x08\x1a\x0b\x40\xef\xd8\x9c\x6c\x68\x61\xbf\x87\xd6\x77\x21\x52\xf8\x87\x2a\x68\xc2\x40\xbe\x79\xf5\xa7\x97\x20\x41\x47\x06\x20\x3d\x31\x01\x01\x46\x00\xea\x9c\x76\xe1\x06\xd2\x1b\x47\x98\xa3\xb6\x78\xba\x8e\xd4\x44\x14\xc5\x51\x1d\x23\xa8\x64\xce\x72\x0a\xff\x7c\xe5\x48\x60\x64\xa3\x31\x1e\x34\x43\x08\x38\x56\xe6\x8a\xc8\xe9\x30\xca\x74\xdd\xb9\x7a\xb1\xd3\x2d\xd8\x40\xfa\x8b\x53\x12\xb7\x8e\x4e\x3b\x07\x7b\x48\x93\x60\xa7\x51\x6c\xc7\xac\x21\xd0\x79\xcc\xb2\xf2\x70\xf6\x3e\x83\x02\xf6\x0f\xa4\xf0\xc6\x10\xa7\xef\x20\x6e\xdb\xe0\xed\xd0\x47\x0d\x1e\x81\xf2\xb7\x0d\xde\x3e\xc5\xe0\x6d\xb0\x31\x3a\x41\xb7\x22\x90\x1b\x86\x04\x5c\x34\x77\xc2\x9c\x51\x63\x6d\x18\x17\xca\x75\x71\x5c\x59\xc6\xa9\x4b\xbb\xe3\xf1\xee\xae\x8b\xee\x5a\xbe\xaf\xf4\x74\xf4\x0d\x61\x22\x91\x29\x32\x8b\x19\xbf\x54\x1a\xd4\xbd\xda\xdd\x16\xbe\x4b\xee\x9e\x15\xa6\x3f\xc1\xd8\x7d\x4c\x75\x67\xd9\xe2\x20\x09\x5f\x3d\x80\x12\x53\xab\x2e\x1e\xf8\xd0\x92\xc8\xe3\x59\x5b\x1d\xc6\xfd\xae\x48\xc6\x73\x6e\x1b\xa5\x9a\x85\xce\x94\x56\x64\x0f\x4f\x8e\x93\xa2\x1a\xda\x0b\xc6\x39\xcb\x65\xb9\x18\xfa\x8b\xcc\x8f\xd1\x5d\xf6\x8a\x01\xb6\x31\xa9\xca\x92\x09\x9d\x2d\x9e\xb2\x06\xe4\x88\xb8\x21\x0a\x90\x9f\xe3\x2e\x88\x23\xf5\x11\xb3\x56\x1d\xf1\x05\xb7\x79\xd0\x5f\xc0\xa3\xd1\xaa\x61\x1d\x17\x37\x67\x99\xb8\x22\x57\xb4\xbc\x27\x72\xfc\xaa\xa3\x47\x9d\x27\xe5\x57\x5c\x75\xed\x62\x4c\x9a\xe4\x39\xf7\x4e\x68\xb3\xd8\x64\xa5\x8b\x4a\x5b\x89\xee\x56\xa0\x43\x19\xf7\x2b\xaf\xa1\x1c\xbe\x68\xd3\x5d\x29\x3e\x0a\xaa\x35\x2b\xc5\x4b\xf2\x3f\x7b\xef\xbf\xfc\x38\x1a\x7c\xb7\xb7\xf7\xcb\xf3\xd1\x5f\x7f\xfd\x72\xef\xfd\x18\xfe\xf1\xc5\xe0\xbb\xc1\x47\xf7\xc7\x97\x83\xc1\xde\xde\x2f\x3f\xbe\xf9\xe1\xe2\xf4\xe8\x57\x3e\xf8\xf8\x8b\xa8\xf2\x4b\xfc\xeb\xe3\xde\x2f\xec\xe8\xd7\x3b\x0e\x32\x18\x7c\xf7\xc7\xce\xaf\x4e\xc5\xe2\x6d\x47\x51\x88\xc7\xa8\xc7\x2d\x39\x1e\xb1\x17\xf6\x6b\xb4\x95\xe0\x42\x8f\x64\x39\xc2\xa1\x5f\x02\x58\x70\xc7\x07\x38\xf6\xea\x7b\xfd\xd7\x6a\x40\x0d\xb7\xef\x94\xfa\x35\x2f\x70\x08\x7d\x1e\xf2\x1e\xca\x8c\xdd\x48\x71\x99\x8c\x66\x79\x21\x4b\x5a\x2e\x48\x6a\xbd\x99\x8b\x15\x08\x44\x01\x04\x51\x67\x48\x61\x78\x8f\x94\x97\x6b\xa8\x34\xee\x8c\x28\xc4\x52\x5e\xe5\x3d\xe1\x09\xc1\x58\xe1\x64\x5c\x03\xf2\xbe\x45\xed\x77\x29\x45\xf6\x32\x1b\xd0\x98\xd0\xe4\x12\x2d\x28\x3f\x5b\xa8\x37\x06\xa5\xf5\x3b\x3b\x36\x25\x22\x67\x54\x78\xc7\xbe\xeb\x38\x66\xa6\xd2\x5d\x8c\x63\x47\x4e\x78\x8c\xb4\xdb\x04\xc2\xba\x23\x95\x2c\xc9\x1b\x50\x80\xd6\x3a\xfb\xa4\x17\xac\x10\xfe\x1f\xf6\xda\x68\x7d\x3d\x55\xa2\xba\xe1\x5c\x02\x91\x96\x60\x6f\x5a\x5c\xaf\x29\x34\xd9\xaa\x33\xc4\x22\xcd\x02\x26\xf2\xc8\x2d\x4b\x17\xbf\x35\xd3\x69\x46\x45\xdd\x14\x1c\xd3\x99\xc2\xbc\x15\x9e\x40\x1f\x28\xb0\x4d\x61\x3a\xfc\x14\x5e\x04\xcd\xa1\x2b\x65\x9e\x24\x45\x7c\x4d\xfd\x20\x6c\x93\x35\x41\x9e\x70\x1d\x5d\x63\x8b\xda\xfc\x72\xee\xbf\xac\xf6\x67\x40\xc9\xb2\x33\x3f\x55\x05\x46\x8a\x7d\x8a\x55\xb5\xe5\x14\x32\x2b\x82\x7e\x3d\xae\x25\xcd\x12\xa3\x0a\x9e\xc5\x9c\xea\x3a\x4f\xf8\x0f\xaf\x84\x4d\x28\x5c\x62\xbb\xd5\x5c\x57\x29\x56\x8e\x66\x15\x4f\xfb\xe3\xb7\x47\xa7\x76\x74\x54\x36\xfa\x52\x31\x7a\x51\x2c\x7a\x57\x27\x7c\xca\x66\xf7\x0e\xc9\x75\xf6\x67\xb4\x9f\x86\xcd\x31\xe2\x4c\x50\xea\xfb\xa1\x39\x61\xe0\xd2\x0d\x2e\xbc\x2b\xc9\xee\xb3\xc9\x22\xb1\xd0\x4e\x3c\x6a\xdd\x83\xc3\xe2\x9a\x80\xa2\xaa\x91\x6f\x95\x5a\x3b\x24\xc8\x84\x4d\x31\xe3\x09\xef\x01\x4f\x81\x2d\x05\x4b\x59\xc6\x34\x0b\x7a\x1c\x17\xd8\x95\xb5\x64\xb9\xbc\x32\xcb\xec\xbd\x20\xef\x94\x8d\x97\xf3\xe9\x4b\x42\x07\x51\xc1\xb1\x42\x03\x5b\x30\x96\x62\x7d\x58\xd0\x54\xb0\xac\x84\x1a\x92\xc9\xc0\xe5\xb3\x2a\xec\x1e\x5a\x82\x53\xcd\x76\xf7\x02\x3f\x56\xc9\x0c\x01\x00\xa4\xaa\x94\x39\x51\x82\x16\x6a\x2e\x35\xb8\x4c\x68\x41\x13\xae\x17\x44\x97\x34\xb9\x34\x97\x40\x1c\x15\x1e\x37\x24\xc9\xc0\xa6\xb7\x87\xe4\x8b\x4b\xd6\xf4\xbc\x94\xd5\x6c\x0e\x35\x54\x78\x55\x92\x51\xe5\xbe\x7e\xe5\xfd\xd6\x86\x57\x24\x5d\x08\x9a\xf3\xc4\xf7\x0e\x29\xe5\x15\x57\x5c\xda\x48\x97\x1b\xf7\xd4\x77\x61\xc0\xe8\xd9\x41\x46\x79\x4e\xf6\x14\x63\xe4\xc8\xb1\x04\xfe\x72\x8e\x9a\x24\x7a\x12\xcb\x38\xa9\xce\x02\x3e\x5a\xe0\x01\x73\xa6\x16\xbd\x3e\x55\x01\x95\x01\xf3\xe6\x2b\x1f\x3a\xf0\xd3\xb5\xfa\x9d\x64\x09\x09\x6f\xae\x05\x10\x13\xa9\x0c\x32\x62\xf6\x4f\x8f\x55\x68\xdf\xda\x36\x8a\x38\x12\xfc\x90\x49\x31\x0b\x81\xef\x6a\xce\x34\x42\x5e\x40\x3f\xcc\x2b\x9e\x56\x34\x43\xf1\x6e\x5f\xe6\xe0\xfc\x18\x6f\xe7\xb3\xb9\x1e\x5d\x33\xf0\x7e\xe2\x2e\x58\xaf\x19\xf7\x50\xbe\x94\x69\xcb\x15\x6c\x07\xda\x7a\xd9\xd0\x93\x0c\x3d\x27\xe9\x02\x80\x77\x6d\x72\x67\x94\x8c\xe3\x60\xea\x71\x88\x55\x14\x87\xd7\xdb\xf7\x0d\x12\x8d\x4a\x04\xee\x61\x43\x62\xe0\xd4\xe5\x77\x83\x6e\x8f\x75\xcf\x0d\x7f\x5a\xd7\x9d\x1f\x41\x21\x6e\xdf\x39\x78\x6d\x8a\xec\x55\xcd\x26\x17\x2c\x2f\x32\xaa\xfb\x49\x2d\xd9\xf9\x39\x70\x7f\x07\xc1\x63\xb3\x1c\xa9\x48\x47\x34\x33\x1c\x79\xfa\xd3\x81\xad\x6c\xc3\x05\x16\xa5\xaf\x5d\xd4\x3d\x4a\x51\x39\x40\x2d\x69\xe5\xd2\x02\x2c\xb5\x09\x4b\x41\x18\xd9\x27\x83\x8f\xe2\x5a\x60\xeb\x5f\xf3\xc7\xe9\x4f\x07\x43\xc2\xc7\x6c\xec\xfe\xf2\x97\x3a\x69\xa8\xe5\x0c\x0b\x1c\x7c\x05\x0d\xf0\x33\x76\xe1\x0e\x9c\xbf\xe1\xbd\xff\xfa\xd6\xbc\xa4\xf9\xf5\x6f\xa3\x6f\x83\x5e\x46\x7f\xfb\x97\x11\xae\xa5\xb9\x20\x3e\x1b\xe6\x97\x83\xdc\x33\x7f\xfd\xeb\x54\xa6\xe7\x05\x4b\xc6\xf8\x59\xea\x5f\x98\x25\x40\x98\xd0\x46\xd7\x3e\x95\x90\x59\xc6\x53\xe4\x72\x78\x76\xc9\xfe\xed\x02\x04\xb6\x5d\xaa\x15\x24\x09\xd5\x4c\xc0\x06\xe0\x0a\x8d\x85\xd4\x78\x3b\x36\x5a\x85\xf7\xdf\x9b\x86\xad\x4f\xb5\x94\xb0\xcc\x51\x94\xec\x0b\xc2\x3e\x70\x05\xb8\x33\xf8\xad\x40\x0e\x6a\x93\xd7\xdd\x9e\x66\x86\x35\x14\xf6\x30\x43\xd8\x3d\x3c\xcb\xc8\x17\x42\xea\x2f\xfc\xf4\xbb\xc4\x44\xd8\xb8\x24\xa1\x57\x92\xa7\xa4\x82\xbe\x59\x66\x05\x0a\xf0\x6c\xd7\xad\x0b\x27\x0b\x92\x73\xa5\xe9\x25\x1b\x93\x73\xb3\x67\x85\x19\x06\x48\x3d\x41\xa0\x0b\x0d\x4b\x49\x25\x34\xcf\xe0\xd7\x7a\x1c\xf3\xca\xe1\x5e\x76\x3c\x25\xaa\x4a\xa0\x39\x6f\xc9\x46\x6e\x77\xb4\x57\x2d\xc9\x98\xfa\x5b\x86\x7e\xb2\xe7\x14\xed\xa7\x22\x85\x5b\xb1\xd5\xaf\xb0\xec\xb5\x94\x57\x6d\xde\x53\x8a\xa4\xde\x11\x81\x98\xd0\x35\xdb\x6c\x82\x99\x4b\x00\x42\x53\xce\x06\x0c\x04\x4b\x98\x52\xb4\x5c\x60\x37\x54\xee\x9b\x36\xda\x94\x57\xd8\xa9\x73\x2a\x2a\x18\xa0\x64\xd8\x5b\xb7\x4a\x80\x3a\x94\x4c\x4a\x79\xc9\x84\x2f\x21\xf0\x0d\xd2\x7d\x42\x75\x9d\x35\x0a\xf1\x7b\x49\x92\x39\x15\x33\x56\x57\x91\xe7\x34\x05\xda\xff\xe8\x35\x2d\xf7\x3d\x86\x02\x74\x6a\x14\x16\xae\x81\x14\x13\xb3\x3f\xf9\xb0\xc7\x7b\xe1\x71\x70\x87\x75\x5c\xc2\x7c\x12\xcf\x5a\xc9\x44\xd2\x8f\x23\xbc\xbb\x0b\x7c\x04\x0a\xc5\x1a\x93\xb7\x73\xa6\x69\x4a\x35\xed\x2d\x81\xfb\x0d\xf5\x5d\x3f\x6d\x52\x07\xb0\x43\x90\xec\x61\xf7\x58\xa7\x4a\xca\x82\x87\xb8\x02\x20\x0d\xe6\x6e\xf6\x01\x97\x4a\x1b\xbe\xb6\x41\x47\xcc\xcb\x06\x5d\x8d\x66\x99\xbc\xb6\x48\x75\x6e\x34\x14\x59\x2c\x25\x69\x05\x6a\x5f\x2d\xd2\xba\x04\xc5\x7b\x89\x99\x98\x89\xee\x8d\xca\x17\x75\xec\x3f\x89\x73\xb3\x57\x2a\x68\xb8\xd7\x31\xa1\x39\xb6\xc6\x77\x40\x10\x96\xf8\x95\xc0\xa5\xda\x98\x06\x98\xa7\x19\xd3\xaa\xce\xaa\xc4\xdd\xc4\x88\x48\xbb\x97\x5b\x27\x02\x6c\x35\x76\x6a\xac\x1d\xbe\x5a\x53\xc4\x89\x53\xd2\xee\x16\x66\xff\x5a\xfb\xcc\xf4\x17\x3c\xc2\xf6\xb7\x6f\x64\xda\x3d\x0a\xd5\xe8\xe3\x5a\x0f\x5c\x57\x9b\x60\xe5\x91\x02\x27\x0f\x5e\x00\x31\x79\x15\xc1\x64\xe0\x16\x30\xa7\x57\xed\xdd\xa9\xb5\x66\x3a\xf2\xcd\xda\xe0\x71\x23\x78\xdc\xe8\x45\x57\xc7\x75\xf7\xac\x45\x77\x74\xcc\x5e\x8c\x5f\xa8\x87\x48\x85\x11\xad\xe7\xbd\x04\x12\x1a\x28\x4a\x7e\x5c\xbb\xff\xda\xcc\x0c\x9f\x0d\x63\xeb\x69\x19\x37\x52\xf3\x25\xf9\x22\xd2\xb8\xac\x66\xeb\xad\x61\xac\x62\xda\x73\xe6\xf1\xd8\x4e\xbc\x83\xf3\x8a\x2f\x1f\x34\x06\x03\x55\x6f\xb5\xd5\xe8\xaa\xa5\xbc\xfa\x6d\x54\x65\xe8\xc3\xef\x6b\x54\x0d\x33\x97\x32\xcb\x5c\xef\x76\xb4\x90\x1b\xb9\x4d\xd0\x37\x08\xa3\x25\x43\xef\x86\xf0\xfa\xbe\x60\xd7\x5e\xb1\xa3\x0a\xe1\x4a\x5d\xac\x1e\x5c\x25\x2e\xe1\x6c\xd5\x78\xbe\xa2\x6b\x5f\x2c\xf0\xd5\x0f\x03\xd2\xa2\x7b\x81\xcc\xcc\x83\x8c\x05\x20\xe8\x24\xc3\x8c\x1c\xaf\xf8\xc0\xbb\xd0\xec\x9a\x2e\x14\xac\xb2\xda\x62\xf3\xcf\xb7\x58\xef\xf5\xc0\x67\x6c\xda\xa1\x9f\x7c\x78\xf4\x16\xcd\xef\x2f\x9e\x0f\x60\x2b\x5c\xb4\x4f\xd2\xad\x87\x69\xd1\x82\xbb\x79\xf4\x97\x16\x00\x99\x91\x90\x16\xd5\x47\x7c\x35\x5a\xce\xfb\xa7\xc7\x30\xb0\xb3\xdc\x66\xf0\x87\xdb\xd1\x7d\xa0\x70\xc2\xcc\x7a\xab\x21\xa2\x80\x77\xc3\x7b\x57\xe4\x8d\xd5\x4c\xff\x23\xf4\x43\xb2\xf1\x17\x57\x0f\x6c\x36\x84\xfd\xd3\x63\x7c\xe2\x18\x5a\xe2\x52\xb1\xb0\xba\x96\x9e\xf3\x32\x1d\x15\xb4\xd4\x0b\x74\x5e\x0c\xa3\xa7\xf9\xa2\xc8\x1e\xc8\xd1\x6b\x68\xb8\x4b\x0b\xb5\xf0\x88\xe6\x08\xc8\xe7\x02\x2f\x36\x72\x76\xe3\xcc\x6c\x1a\x45\xba\x96\x68\xba\x23\xa2\x48\xd8\x42\xc7\xf9\x2e\x1e\x05\x45\xd2\x50\x10\x3f\xd4\xbe\x6c\x64\xbc\x8a\xd3\x59\x70\x9b\x05\x1d\xda\xfa\x9b\x64\x58\x37\xe6\x75\x36\x30\xfe\xcd\x48\x43\xc2\xa7\x66\x83\x93\x62\x64\xab\xd5\xbd\x73\xdc\xea\x7d\x2e\xef\x13\x0d\x79\xb3\x74\xd1\xfd\x19\x3e\x2b\x1c\xc0\xaf\x75\xb2\x27\xa4\xc0\xf5\x8f\xd7\x0e\x30\xed\xf5\x06\xff\x2e\x5c\x32\x26\x3f\xcf\x99\x08\x37\xbf\xd0\x21\x3e\xf4\x9b\x30\x17\xa9\x99\x7c\xd8\x19\xc1\x1f\xa0\xaa\x24\x61\xcc\x7b\x90\xc2\x76\xf1\xb5\x7c\xb2\xaf\x9c\x53\x9d\xcc\x99\x22\x4a\x02\xec\xa8\xd2\x34\xcb\x6a\xcf\x8d\x25\x97\x04\x3d\xc2\x79\xd1\x03\xf5\x22\x2a\xf2\xb6\x4e\xac\x22\xa3\xd6\x53\x32\xad\x44\x82\x89\x55\x5c\x2f\xdc\x1b\x1c\x36\x55\x29\x30\x57\x15\x3a\x74\xf8\x14\x7d\xb7\x81\xd9\xe9\x89\x09\x02\x76\x81\x22\x35\xde\xf9\x2d\xb6\x9e\x91\xa6\x13\x9a\x5c\x5e\xd3\x32\x55\x50\xbf\x4e\x35\xc7\x16\x87\xc3\x68\xd8\xbd\xe0\x1d\xcc\xd3\x23\x4d\x61\xe0\x8d\x5b\xc5\x7c\x2b\xbb\xfa\x31\x84\x56\x5a\xe6\x54\xf3\x04\xdc\x36\x7c\x1a\x78\xe2\x73\xdf\x02\xc2\x47\x52\x51\xb2\xc3\x5e\x61\x3f\x03\x2c\xb8\x12\xcb\x2c\xf4\xb5\x24\x3c\x37\x1a\x18\x85\xd6\xcf\x53\x5f\xad\xee\x62\x06\xb7\xbd\xa9\x51\x33\x7f\x86\x40\x4d\x70\x15\x3a\x84\x8c\xa9\xae\x60\x78\x1f\x15\xf0\xee\x70\x5b\x96\x3d\x6c\x28\x48\xf6\x1e\xc3\xd3\xe6\x5d\x03\x56\x1d\x9a\xe9\xb9\x66\x46\xef\x52\xb7\x32\xac\x1a\xaf\x7a\x23\x3e\x13\x58\xb8\xcb\x95\x73\x21\xd8\x4c\xec\xbd\xb4\x94\x45\x61\x9d\x81\xf9\xa0\xf9\x46\x10\x7b\x2b\xaf\x98\x82\xb8\xb3\xcb\xed\x36\x64\x98\x31\xc1\x4a\xaa\xc1\x93\x6f\xe1\x08\x61\xe5\x36\x1f\x11\x2d\x98\x31\x82\xb2\x0c\xc8\x3b\xdb\xe0\xdf\x33\xae\xcf\x14\xbf\x93\x62\x8a\x9e\x45\xab\x9b\x6e\x35\xca\x5b\x87\xd9\x6a\x94\x5b\x8d\xb2\xc5\xb1\xd5\x28\x9b\xc7\x56\xa3\x0c\x0f\x9f\x8c\xdc\xaf\x36\x59\x57\x17\x04\x89\x1f\x61\x2a\x55\x7d\xc1\x4d\x2e\xbf\xe3\x29\x39\x63\x89\xbc\x62\x25\x6e\x22\x47\x1f\x0a\x2a\x8c\xae\xf4\x8a\xf2\xcc\x6c\x21\x6e\x2b\xa9\xdd\x1b\xd0\x47\x27\x76\xb1\x07\x1e\x25\x3f\x1f\x76\xb1\xe6\xf6\xa5\x2c\xd2\x85\xb9\xde\x06\xf2\x8b\x92\x5d\x71\x59\x29\x97\xf0\x55\x69\x14\x16\x4a\x5b\x7d\x66\xce\x67\xbe\xdd\x9d\x4f\xc7\x28\x59\x22\xcb\xb4\x86\xac\x52\x9a\xea\x4a\xc5\x35\xa4\x09\xfa\xb4\xfb\x73\x67\x7a\x3a\x6e\xd0\xee\xd9\xe7\x3e\x83\x19\x73\xbd\xaf\xd7\xdd\xd7\x98\x89\x87\x27\x27\x96\x0d\x5d\x72\x60\x9d\x98\x68\x54\xdf\x4a\xb3\x80\x5d\x2d\x63\xdd\x7b\x0e\x23\x3c\x9a\x67\xd8\x3c\x7c\xe4\x87\x1d\xd5\xb9\x80\xad\xfb\x23\x86\x47\x8f\xb3\x49\x7a\x07\x4e\x09\x8f\x47\x97\x3a\x18\x1f\xbd\x55\x2d\x90\x07\xa9\x5c\x20\xfd\x57\x2f\x90\x87\xaf\x60\x20\xbe\xa2\xac\xff\x75\x7f\xe6\x2a\xdc\x1a\x2b\xdf\x6e\x4b\xb7\xad\xfc\x08\x4a\xcd\x8f\xc3\x15\x91\x39\xd7\x9a\xb9\x04\x12\xbf\x92\xc1\xe1\x1f\x56\xf8\x58\x99\x03\xbe\x04\xcc\x12\x61\x1f\x7c\x0f\xa9\x40\x57\x05\x8d\xf3\x9a\x2b\x30\x90\xa8\x30\x76\x2d\x22\xda\x82\xec\x18\xd9\x74\x5f\x67\xab\x6f\xe5\x50\xf7\x71\xb7\x72\x28\x3c\xb6\x72\x88\x40\x37\xae\x0c\x8a\x47\x7a\x55\x8c\xdd\xa0\x16\x4a\x87\x4e\x58\x46\x7e\xab\x58\xb9\x20\x46\xd1\xad\xd3\x4c\xa1\xdd\x96\xe2\xa9\x4d\xd4\xb4\x8e\xc9\xae\xd6\xe5\x86\xea\x78\xe0\x38\x3d\xfa\x60\xec\x04\x40\x40\xe8\x5d\xea\x37\x1f\x10\x03\x19\xe1\x2c\xf8\x99\x09\xad\x03\xcc\x11\x89\xec\x05\x63\x2a\xec\x9f\x1c\xf6\x69\xea\xf7\x91\x3e\x40\xfa\x4b\x21\x20\x4b\x2e\x99\x5b\x48\x84\xa4\xf4\xbf\xc0\xc6\xe6\xd3\x3c\xbc\xa3\x91\x5c\xb2\xc5\xd0\x66\x53\xd9\x5e\x8b\xee\x62\x4c\x4c\x8c\x1b\xbe\x74\x03\x0a\x8c\x8f\x9e\x77\xa0\x3e\x7d\x83\x78\x74\x6d\xf0\x11\x8f\xe5\x88\xdb\xcf\xa6\xd8\xf3\x26\xdb\x43\x23\x90\xf0\xb8\xa9\x29\x08\x72\x2b\xf4\x10\x70\xd5\x52\x9e\x41\xa1\x42\x0c\x24\x6c\x3f\xec\x45\xfa\x76\x4f\xe1\xe1\xa6\xf1\x81\x88\xe5\x97\x60\x54\x96\x73\xc9\x16\xbb\xca\x62\x69\x48\xa1\xe6\xbc\x70\x5d\x22\x41\x4e\xda\x55\x49\x7e\x82\xfc\x37\x37\x04\x4a\xc4\x63\x31\x24\x27\x52\x9b\xff\x1c\x41\x42\x2f\xc6\x58\x24\x53\x27\x52\xc3\x99\x8d\x26\x37\x7e\xda\x03\x11\xdb\x86\x68\x38\x84\x58\x30\x75\x1d\x6a\x57\x5d\x9a\x27\x10\xd5\xe6\xf2\xf8\x89\xe1\x8a\x1c\x0b\x22\x4b\x47\x55\xed\x1a\x5f\x29\x3b\x84\xf3\x5e\x07\xd1\xb0\x15\x63\xd8\xc9\x90\x65\x34\x17\xb7\x0c\xe7\x03\x6b\xdc\xfd\x02\xde\x6d\x88\x44\xfa\xdc\x54\x68\xbe\x44\x35\x9b\xf1\x84\xe4\xac\x9c\x01\xee\x4a\x32\xef\x7b\x8a\xfb\xda\x17\xf1\xe8\x71\x77\xc4\xa3\x57\x3e\x04\x15\xe5\x35\x64\x1d\x3f\x8c\xfa\x83\x63\xe3\x76\x9d\xd3\xc2\xb0\xe0\xff\x31\xbb\x32\x70\xc1\xff\x85\xe6\x6e\x6a\x4c\xf6\x89\xe2\x62\x96\xb1\xe8\x37\xeb\xcf\x0c\x87\x31\x23\x18\xfb\xf5\xb7\x8a\x5f\xd1\x8c\x61\x95\x00\x15\xbe\xf5\x8a\x9c\x2e\x29\x5d\x43\xdb\xe1\xcd\xc8\x65\x1f\x83\xdf\xb9\x64\x8b\x9d\xe1\x12\xdb\xee\x1c\x8b\x9d\x1a\xc2\x29\x62\x54\xaf\x5c\x40\x78\x76\x07\x7e\xdb\xf9\x3c\x7a\xda\x23\x30\x63\x7b\xe3\x49\xeb\x72\x3e\xc8\xa8\x52\x7d\xa0\xc9\x34\x0a\xc2\x1b\xa3\xaf\x6a\x2c\x71\x1e\x5c\x53\x97\x84\xdb\x0a\x94\xde\xfd\xe8\x50\x01\xd9\x57\x3e\x70\x0f\xf4\xbf\xb2\xfd\xac\xbb\xc2\xd0\xad\x84\x02\x07\x10\x36\x57\x21\x1b\x21\x2a\xd4\x69\x3a\x37\x50\xfc\x27\x88\x88\xc8\x29\x79\x55\x37\x8c\xe0\x0a\x5c\x54\xdc\xd5\xcc\x0a\xa9\x09\x17\x49\x56\xd9\x60\x08\xdc\x0a\x0e\xae\x7e\x0c\xd8\xde\xc8\xdb\x3b\x63\xd7\xc3\x3a\x8e\x76\x29\x45\x4b\x85\x50\xcd\xec\x0f\xc8\xb7\xf1\xd9\x14\x48\xed\x75\x52\x6b\xda\xaa\xe4\x23\x6e\x74\x92\xc4\xfa\xe5\x2b\x3e\x29\x19\x39\x98\x53\x21\x58\x16\xa0\xc8\x58\x67\x28\xd5\x9a\x26\x73\x8c\xd9\x51\x62\xd6\x71\xc6\xf4\xae\xc2\x06\xfd\x39\x4d\xe6\x5c\x78\x5c\x05\xe1\xd1\x94\xea\xba\xb2\x35\xb4\x06\xea\x6a\x20\xf5\xd8\x55\x66\xd7\xb6\x95\xb1\x7c\x17\xf6\x73\x89\xbb\xcd\xd4\x00\xe5\xcd\x6b\x6a\xa4\x7e\xbb\xe6\x81\xf2\xb8\x2f\x43\xeb\x13\xb8\xf6\xf6\x7e\x35\xb9\x77\x68\x73\x31\x65\x65\x89\x33\x34\x61\xf6\x86\x46\x8f\xd9\xb1\x6d\x62\x31\x97\xd7\x24\x95\xe4\x1a\xba\xad\x5e\x19\x05\x02\x52\x91\x94\x53\x3d\x82\x37\x85\xc4\xc0\x44\xe6\x45\x29\x73\xae\x5c\xf9\xa3\x65\x8f\xb5\x01\xa6\x64\x55\x6b\xcc\xd9\x78\x16\xb3\x4a\xc4\xcd\x1e\x5f\x1d\x10\x4d\xcb\x19\xd3\xe6\x19\x44\x54\xf9\x84\x75\xc4\x85\x59\x37\x2a\x79\xaf\x5d\x40\x76\x7d\x1b\x90\x88\x6a\x9f\xe8\xef\x41\xce\xdc\x5d\x90\x40\x08\x69\x8a\x53\x59\xda\x64\x4b\xff\xa3\x85\xa1\x37\x5c\xf8\x93\xdd\x38\x2b\xa1\x55\x47\x54\xf8\x2e\xfd\x41\x90\x15\x7e\xfe\xf9\xa4\x1f\x58\xf7\xdd\x7a\xbc\x9b\xb8\xee\x5a\x96\x59\x7a\xcd\x53\x54\xce\x14\xd9\x33\x17\x0f\xba\x51\x60\x8d\x28\xef\x9d\x57\xfa\xf5\x35\x4f\x7b\x22\x3e\x0c\x15\x13\xdd\xe5\x51\x1b\xa2\x13\xa0\x3a\x4f\x99\xd0\x46\x58\x96\x8a\xec\xc1\x1d\x03\x72\xc4\xb1\x12\x1f\xee\x07\x10\xd5\x7c\xc2\x45\x8d\xf2\x50\x4f\xaa\xd9\x2e\x8d\xdc\x70\xe6\xbd\x62\x1a\x6b\xa8\xa1\x0c\x59\xea\x39\x51\x3c\xaf\x32\x4d\x05\x93\x95\xca\x16\x1d\x59\xfb\xb1\x4e\xec\x34\x63\x1f\x70\x85\x77\x57\x7a\xfc\x50\xb1\xf2\x03\x89\xb6\x35\x70\xca\x92\xf6\x53\xa7\x82\xa7\xcf\xbc\x26\xe4\x81\x00\xd8\x07\x96\xd8\x1a\xb1\x22\xab\x66\xbc\x55\x51\xf0\xb6\x0f\x62\xab\xbb\xef\xd6\x07\xb1\x6e\xf7\x56\x29\x56\x23\x97\x75\xeb\x43\xbe\x81\x6d\x0b\xd7\xab\x5f\x5e\xac\x6e\x59\x98\xb2\x82\x89\x14\xa0\xd3\x5f\xd5\xeb\x0f\x5f\x7e\x6d\xb4\xb7\x90\xe5\xfd\xec\x15\x0e\xff\x3c\xda\xa5\x83\xc4\xfb\xb9\xcc\x52\x45\xd8\x07\x5d\x52\xb3\x1d\xe4\x46\xf0\xfb\x7b\xa6\x84\x8a\xae\xa2\xfd\xa9\x34\xde\x22\x9f\x49\x03\x4d\x9f\xa8\x06\xaa\x7a\xed\xc8\xb9\xab\xc2\x3e\x9c\x35\xf5\xa2\xd3\x3d\x37\xe7\xc4\x0d\xd4\x4a\x07\x15\xd7\xa1\xad\x68\xa2\x69\x9f\x12\xd7\xbf\x74\x6b\xa6\xa9\x56\xb4\xd6\x6b\xbc\xd5\x1a\x17\xeb\xb6\xb3\xe6\xe3\xea\xac\x39\x05\xb8\xa7\xee\xe0\xc7\x76\x9c\x86\xcf\xce\x9e\xb4\x6a\xeb\x5d\x7c\x74\x76\x45\x05\x7b\x32\x74\xca\xb1\x03\x59\xd8\x04\xa2\xcc\x6c\xd4\xc5\x11\x95\x10\xed\xa4\xf9\xba\xfb\x0e\x52\x4d\x15\xd3\x5d\x3c\xc9\xb1\x82\x59\x8f\x67\x44\x4e\xc8\xf9\xf6\x27\xec\xde\x09\x85\x9e\x0e\x02\x89\x8c\xfe\x66\x75\x51\x11\x5d\x69\xb4\x50\x47\x77\x07\x8e\xcc\x7c\x66\x19\x8e\x91\x9a\xd9\x4e\xa8\xee\xd8\x90\xbe\xc3\x6e\x6c\xdf\xf6\xdd\xbb\xe3\xc3\x3e\x49\x68\xc6\x73\xda\x2a\xfc\x3b\x26\xa3\xe5\x52\x00\xd0\xe5\xbf\x55\xa1\xa1\x0d\xd0\x8d\x9e\x70\xf6\xfa\x75\x50\x67\x96\xb0\x3a\x4c\x70\xc8\xd5\x65\x77\x80\xf3\xa5\x21\xe3\xe5\xfe\xc3\xc1\x11\xb1\x67\xef\xe4\x9d\xbf\x8f\x7b\xbe\x2b\x2a\xf6\x2c\x61\x75\xe0\x2e\xe5\xea\x72\x0d\xe0\xe8\x5d\x6d\xe0\x22\x3d\x69\x57\xc7\xb9\x99\x91\x86\xa6\x85\xe7\x60\x54\x03\x7c\xdf\x85\xac\xc8\xb5\x85\x11\xb4\x16\xe2\x05\x2f\x5e\x92\x23\xa1\xaa\x92\xd5\x19\x5a\xcd\xa1\x8c\xbe\x75\x67\x7b\x11\x90\x1a\xd5\xcb\xde\xa2\x12\x7d\x73\xea\x53\x09\x73\x14\xb4\xd4\x60\xc8\xf5\xc3\x48\x7e\x38\x27\xa7\x83\x13\xe2\x2e\x9c\x74\x3c\x75\xc5\x17\x43\x8b\x29\xe6\x81\xd3\xdd\x45\x86\x77\x02\x90\xd1\x90\x5b\x5e\x79\x60\x5f\xf2\x2c\x65\x57\xcf\x54\x4a\x5f\x0c\xe1\x31\xae\x64\x30\x7e\x27\xaa\xc8\xce\x8b\x9d\x31\x39\xe7\x39\xcf\x68\x99\x2d\xa2\x06\x67\xf5\x75\x66\xdb\x75\x03\x42\x36\xcb\xf3\x1d\xb2\x27\x4b\x18\x39\xa1\x82\x64\xcc\x61\x2e\xd8\x55\xbd\x40\xbb\x63\xb0\x19\x22\x92\x6c\x4c\xa4\x08\xa5\x65\x4f\xbc\x96\x3a\x9d\xca\xee\xf7\x11\x68\xed\x61\xbd\xe1\x71\x61\x76\xc1\x31\x79\x67\xb7\x2f\xab\x17\x20\x33\xc0\x62\x76\x57\x6c\xd6\x64\x6d\x9e\x3f\xa4\x95\x67\x63\x39\x74\xb7\x69\x84\x6e\xeb\x3d\x99\x71\x7d\xc6\x0a\xd9\x83\x0e\x87\x03\x35\xe2\x0b\x5c\x9b\x13\x52\x71\x68\x4f\x43\x35\xa1\x28\x92\x92\x2a\xa3\xc6\xa8\xc3\xe8\xc2\x98\x1c\x1e\x9d\x9e\x1d\x1d\xec\x5f\x1c\x1d\xbe\x24\x3f\xd8\x91\x78\x68\x07\x8c\xc9\x45\x88\x3b\x1d\x54\xb4\x59\x70\x5f\xff\xac\xa1\x15\xb1\x54\xd4\x8d\x33\x00\x87\x93\x0a\x72\x2c\xb8\xae\x5b\x86\x61\x5d\x40\x26\x85\xcd\xf4\x37\x77\xdb\xe8\xc6\x8c\x63\x3e\xaa\xb0\x83\x99\x9f\xe3\xd1\x60\x85\x62\x83\x1d\xff\x2a\xad\x1c\x24\x6b\x56\xfe\xea\xe9\x59\x87\xa1\xea\x7a\xe1\xf4\x63\x63\xf9\x3e\x48\x0e\x06\x02\xa3\xc5\xf5\x79\xdc\x6c\x7d\xdb\x47\x07\xac\x2b\xcb\xa8\x2b\xe3\x78\xbc\x3b\x26\x66\x1b\xdf\x1d\xef\x3a\x95\x2f\x5b\x6a\x1d\xea\x07\x0d\xf1\xcb\x63\x86\x1f\x13\xf2\xd6\x95\x4d\x02\xf8\xd4\xea\x2e\xa4\x88\xbf\x18\xf4\x9c\x6c\x2c\x1b\x57\xba\x5f\x4d\xc2\x87\x5a\xc0\xf3\x19\xbf\x62\x02\x3f\x6c\x7d\x92\xda\xbd\x6a\x2f\xd3\x18\x7e\xb9\xb5\x94\xcf\x5e\xaf\xef\xdb\x50\xe2\xf4\xf4\x65\x56\x7c\xd9\xef\x4a\x64\x9e\x23\x42\xf7\xdc\x83\xc9\xd4\x78\x30\x5e\x3a\xae\xc5\xca\x47\x5c\xf2\x69\xab\x85\xdd\xd8\x19\xdc\x50\x0d\xab\xde\x9f\xb6\xe5\xcd\xa2\x36\xa7\xee\xdf\xc7\xcc\x02\xe3\x2b\x07\xb2\x6a\xb7\xd9\x67\xfe\xe1\xcf\xce\x8e\xf6\x0f\xdf\x1c\x8d\xf3\xf4\x11\x0a\x69\x26\xd2\x42\x72\xa1\x55\x5b\x0b\xbf\x5d\x3f\xf4\xae\xe2\xdd\xbf\x76\x3f\x3a\x9c\x1f\xce\xad\x1f\x77\x22\xe8\x72\x90\x32\x4d\x79\xa6\x02\xee\xd2\xb2\x90\x99\x9c\xad\x6e\x80\x76\x0f\xb6\xf9\x03\x22\xe4\x8e\xe8\xc8\xf0\xe3\xfa\x8c\xdd\xf6\x7d\x94\x9b\x76\x2e\xf6\x4d\x36\x84\xac\xa9\xe5\xed\x46\x68\x77\xfc\x04\x08\xf6\x19\xcd\x88\x25\x2a\xa2\x3b\x07\xc4\x9b\x6b\x42\x51\x77\x75\x08\xba\xab\xdf\xd5\xbe\x58\x0f\xf1\xdb\x9a\x16\x46\x92\xb7\x6d\xe3\x1f\x53\xdd\x8d\x14\x6f\x20\x45\xc9\x46\x1e\x36\x1b\xda\x7b\xcb\x32\x50\xcb\xc2\xfd\xc4\x79\x82\x9d\xdf\x18\xaf\xca\x16\x4d\x8f\x70\xad\xc9\x7b\x47\x3c\x62\x11\x66\xd9\xa2\x6e\x8d\x62\xbd\x61\x74\x86\x70\xd8\xa5\x0d\xc8\x15\x25\xbf\xe2\x19\x9b\x41\xdb\x23\x2e\x66\x01\x8c\x53\x08\xfc\x64\xdb\x20\xc5\xc1\xa9\x37\xe6\xaf\xa0\xf5\x1e\x70\xd6\xc9\xdb\x0b\xe8\xa0\x05\x29\x15\x9d\x0d\x4e\xf3\x40\x58\xf3\xa3\xd1\x08\x5c\x7f\x7b\xff\x36\x96\x4f\x9a\x0d\xc8\xcf\xcc\x3e\x47\x42\x8b\xaf\x12\xda\xdc\xcf\xa5\xef\xb7\x04\xef\x5a\x53\x16\x18\x1a\xd3\xf8\xec\x55\xcf\xcc\x95\x46\xa3\xc6\xad\x3c\xba\x9e\x33\x80\xec\xae\xf3\x0c\x1e\xa3\x95\xb4\xa6\x0d\xb4\x67\x69\xef\x82\x4d\xab\xd6\x88\x4f\x1f\x70\xfb\x02\x25\x6a\x91\x67\x5c\x5c\xd6\x18\xf1\x53\x69\xf8\x18\xcb\x99\xb9\xb8\x74\xab\xa6\x64\x34\xbb\x79\xc7\x68\xc3\xa3\x6b\xdb\x2d\x74\x6f\xf1\x08\x88\x17\x18\x69\xf1\x77\x27\xbc\x6c\x02\x58\x28\xea\x77\x76\x1e\x35\xc5\xb8\x4a\x14\xef\x2e\xde\x61\x98\x48\xb6\x0b\x72\x7c\x7e\x70\x7e\xfc\x59\xa3\x7e\x37\x6d\xae\xf0\x76\x8f\xda\x7a\xe0\xbf\xb5\xcb\xaa\x1a\x91\xac\x6a\x7b\x27\xba\x5e\x4e\x65\xa9\x69\xb6\x06\xc1\x99\xcc\x69\xb1\x5f\xe9\xf9\x21\x57\x80\xd6\xd8\x8f\xfa\xb7\x34\x6a\x50\xaf\x88\x7d\xe8\x5c\xc3\x0d\xee\xd8\xd7\x5e\x77\xf0\xf7\xfd\x53\x42\x2b\xc3\x8f\xda\xb6\x18\x5a\x5b\xb2\x9c\xfb\x8a\x73\xac\x81\xee\x95\x32\x76\xcc\x4f\xd0\xc5\x5d\xb5\x49\x54\xf9\x7c\x55\x6f\xdb\x78\x34\xec\x5c\x28\xf5\x9f\x48\x0c\x9a\x0b\xae\x39\xd5\xb2\xec\x2d\x36\x18\x8d\xe8\x1d\x86\x95\xd2\x32\xb7\xab\xe8\xd8\x5d\x01\x09\x59\xa0\xbf\x2d\xdd\x54\x7b\x13\xc1\xfa\x04\x9a\x1f\x0b\x63\x2b\xd2\x84\x35\xca\x6c\x86\xd0\xfa\x07\xc7\xe6\xfe\x9a\x6f\xad\x13\x1d\x50\xec\xb3\xbf\xbd\x8c\x9a\x63\x2e\x75\x30\x76\x5e\xcc\xba\x3d\xee\xda\xbc\xd2\xfc\xb7\x7e\x44\x1b\xff\x4d\x34\xe2\x09\x48\xa2\xff\xae\x68\x86\xa4\x3d\x59\xa7\xf3\x3d\x9e\xd2\x7e\xbe\x38\xe6\x12\xfb\xf1\x35\x4b\x9c\x78\x6f\x5b\xa5\x10\xa3\x1f\x29\xa2\x4b\x2a\x94\xe1\x93\xd8\x9f\xb1\x6b\x13\x20\x76\xc9\x9e\x4e\x8a\xc1\xda\x28\xd5\x57\x39\x6c\x56\x89\x50\x59\xc5\x6f\xbf\x40\xd6\x78\xed\xcb\x61\xbb\x7d\xe6\xda\x93\x1c\x60\xb5\xf7\xe3\xb7\xb5\x63\x79\x3e\x0a\xe9\x85\x0a\x22\x79\xcd\x95\x76\x0d\x84\xe1\x04\x57\xb6\xd7\x1a\xd8\x02\xa7\x44\x96\x84\x17\xff\xa4\x69\x5a\xbe\x44\x3d\xc2\xda\xaa\xf0\x6f\xe5\xe1\xf0\xa9\xf0\xd9\x36\x7b\x7a\x51\xd8\x26\x1e\x17\x07\xa7\x04\x1b\x85\x7f\xf3\x97\xe7\x60\x17\x7c\xfd\xd5\x5f\x9e\x77\x64\xc4\xc7\x5a\x55\x48\xfa\xf6\x89\xf6\x9e\x59\xf1\x44\xaa\x48\xa2\x6a\x11\x43\x0b\xd0\x76\xcf\xb1\x38\xc3\xec\x93\x56\x68\xe2\x42\x30\x5c\xe9\x77\xef\x3e\x75\xe2\x6d\xd5\xc5\xef\xa8\xea\x82\xf8\x6a\x7c\x14\xac\xbd\x30\x72\x38\x20\xc0\xea\x2c\x0b\x70\x94\xdd\xa7\x8f\x45\x76\xb7\xa4\x6e\x5b\x4e\x8e\x39\x38\x4c\xf1\x73\xad\xf3\xeb\xf2\xd4\xc3\x93\xf3\x7f\xbe\xde\xff\xfe\xe8\x35\x7c\xab\xcd\x0a\x34\xec\x69\x2d\xa1\x36\x39\xeb\x77\x67\xf7\xf6\xce\xad\xb6\x24\xed\x23\xc1\x40\x34\x52\x0b\x04\x39\x79\x75\x7e\xdf\xac\x82\xae\xe6\xac\x98\x76\xa0\xde\x63\x8b\x6b\x40\xa7\x75\x56\xae\xa7\x72\xbe\xe7\xa0\x48\x00\x7b\x1f\xf9\x51\x0c\x0f\xe1\x37\x76\x76\x75\xb4\xe4\x0d\xb2\x71\xba\xde\xed\xf1\x6f\x43\x31\xa4\x62\xef\x91\xef\xcf\x4a\xed\x6e\x3a\x64\xd9\x17\xac\xc3\x2e\x8e\xe5\xd4\x47\x23\xc2\x70\xef\x28\xcd\xae\x6a\xf6\x53\xa6\x7c\x37\xe6\x27\xc0\xad\xc5\xaa\xd6\x83\xdd\x77\x87\x95\xc3\xda\x1e\xdc\xae\xf5\x52\x90\x55\x10\xd5\x75\xdf\xd4\xc0\xd3\x65\x64\x52\xeb\x08\x53\x05\x4d\x7a\x6d\x08\x5f\x9f\xc2\x33\x00\xbd\xf7\x18\x37\x18\x78\xf1\x35\x95\x97\xf9\x67\xf7\xb3\x1c\xfd\x70\x4d\xa4\x95\x7b\x71\x89\x6b\x5f\x5e\x48\x87\xa4\x13\x42\xb2\x6c\x24\x0b\x91\x8d\xdb\x87\xfc\x36\xf4\x73\x4b\x77\xc3\x3a\x5d\x0d\xc5\x5c\x6a\x29\x7a\xae\xa1\x5d\x35\x68\x2c\xd8\x4e\xe1\x8a\x03\xac\x74\xcf\x58\x19\xc8\x5b\xac\x20\xf2\x61\x75\x63\x79\xb8\xad\x5b\x0a\x17\x60\x8f\xc3\xeb\x8f\x4f\x12\x15\xe9\xf1\xe1\x1a\x84\xd0\x53\x03\x3b\xba\x6f\x98\x70\x6d\x89\xb2\x69\x4f\x95\xfb\x66\x20\x47\xf3\xe3\x43\x6b\x2e\xb8\xb2\x7c\x65\x97\x15\xb9\x79\x5d\xad\x45\x95\x92\xa5\xbe\x96\x65\x5f\xf0\x71\xf1\x70\x8d\x2c\x4c\xfb\xdb\x12\x18\xc7\xd3\x94\x22\xf8\x95\x8f\x5e\x92\x9c\x83\x24\x69\xb4\x41\xbd\x49\xa2\x3c\x84\x40\x79\x3c\x82\xe4\x61\x14\x97\x87\x45\xe2\x5a\x9b\xf9\xeb\x96\x47\x2f\xc4\x72\x83\x59\x37\xa8\x61\x94\x5a\xee\x52\x70\x37\x07\x92\x67\x2d\x72\xb6\x94\x46\x0e\xb5\x13\x27\xb1\x88\x75\x23\x61\x70\x10\xdb\x36\x66\x99\x99\x59\x29\xc2\x86\x8f\x16\xac\x6b\x48\xb0\x67\x62\x4e\x0b\xdb\x34\x3f\x95\xd7\xe2\x9a\x96\x29\xd9\x3f\x3d\xfe\xfc\x72\xb5\x73\x25\x28\xae\x87\x2e\xbd\x05\xe2\x5a\xd0\x7a\x3c\xc8\xc0\x87\x24\x21\xf3\xc7\x84\x6b\x85\xa9\xfc\x90\x8c\xaf\x43\x6f\x94\xd9\xa7\x7c\x26\x8b\x91\x74\x46\xaa\xd9\x91\x02\xb5\x4a\x10\x99\x68\x9a\xb9\x46\xcc\x4c\x5f\x33\x26\xc8\xf3\xe7\xcf\x31\x40\xf1\xfc\xbf\xfe\xeb\xbf\x08\x74\xdd\x4c\x59\xc2\xf3\xe5\x0b\xe1\xaa\x3f\xbf\x78\x31\x26\xff\xd8\x7f\xf3\x9a\xd0\x04\x6c\x39\x44\xbe\xc5\x91\x61\x3e\xc3\x9b\xd5\x90\xfc\xef\xf3\xb7\x27\x6e\xfb\x52\x8d\x5f\x81\x5d\xfc\xe7\x8d\xc9\x61\x90\x7b\x1f\x06\x0f\xa8\x9e\x03\x35\x84\xd4\x84\x4e\xa7\xc8\x70\x20\xb9\xb9\x72\xc2\xc4\x61\xcf\xf1\xd9\xdc\x75\xa2\x37\xac\x96\x41\x51\x00\x37\xaf\x08\x01\x1b\x87\xe3\x88\x35\x0e\x30\x96\xdf\x44\xe0\x55\x86\x24\xe3\x97\x8c\x4c\x15\xf4\xa3\xaf\x1b\xa7\x94\x4c\x19\x03\x2c\xa1\xc2\x8c\x8e\x83\xd5\x33\xa3\x58\x47\x6c\xcc\x75\x67\x4e\x74\xec\x5c\x1e\x87\x90\xed\x9a\x77\x2d\xc4\x6c\x6f\x40\x57\xa3\x85\x22\xc3\xcc\xc2\x63\xcd\x64\x88\xbe\xf6\xd4\x7f\x0f\x32\x95\x45\x3f\xac\x25\x23\xcd\xa4\x98\x85\x3c\x58\x6b\x1f\x2e\x99\x72\x51\xb0\xb6\xc4\xe8\xa9\xa1\x4e\x3f\xed\xe9\x50\xb8\xbf\xa1\x45\xb7\x4e\x20\x71\x8e\xae\x1b\x33\xc2\xa1\xa4\x13\x59\x69\x97\xb3\x67\x7f\x07\xf8\x36\x2d\x1d\xe9\x3b\xbd\x42\x6f\x5d\x8a\xfa\xeb\xfb\xd7\x53\xd3\xad\x38\x67\x0e\x76\xed\x58\x65\x1d\x12\x46\x93\x39\xb9\x64\x8b\x11\xee\x00\x05\x05\xf4\x08\xa0\xf6\xa1\xa1\x71\xd4\x86\xdf\x7b\x9e\x53\x63\x4d\xda\xa9\x70\x09\x96\x81\x7e\xe0\xd0\x27\x9c\xc1\xa5\xac\x5e\x6e\x5b\x59\x89\xc0\x43\xe9\x7a\x57\x26\x52\x68\xdb\x17\xd3\xf7\xae\x82\x84\xd1\x06\x20\x81\x91\x30\x2c\x35\xb7\xa9\xdb\x9e\x5c\x67\x95\x9a\x1d\xc5\xea\x1f\x95\x58\xba\x1b\xf0\xdc\x21\xa7\x57\x31\x8b\x8c\x44\x5d\x4f\xc4\x20\x33\x75\xce\x13\xa8\x38\x32\x97\xdb\x6b\x1d\x95\x3c\x21\x22\xc0\x04\xc5\x74\x65\x49\x03\x79\xc2\xe6\xd9\x4c\x29\xc2\xe1\x0b\x73\x5a\x5e\x32\x07\x34\x4c\xb3\x31\x39\x35\x2f\xe9\xd1\xe6\xb1\x95\xe0\x15\x16\x88\x18\x19\x13\x22\x41\x98\x87\xec\x8e\xc7\xbb\xb8\x55\xae\xc0\x85\xe8\xcc\x35\x7d\x76\x91\xeb\xad\x7b\x5c\xc4\xca\x6f\x68\xa1\xb0\x9b\x9e\x31\x2d\xa0\x63\xa5\x04\xdc\x16\x3d\x77\xca\x04\xed\x08\x21\x1e\x1e\x3d\xb7\x31\xeb\xb7\x13\x6a\x7f\x7d\x50\x3b\xc4\xda\xe3\xa3\xef\xfe\xa7\x3d\x76\x3f\xbd\xa9\xf7\xa9\xe5\x21\x2b\x49\xfa\xea\xc8\xd8\x7b\xcb\xcd\xbc\x87\xc6\x66\xee\x88\x43\x47\xa0\xdf\x46\x58\xd2\x77\xb2\x45\x2c\x94\x7a\xc6\x1e\x95\xf1\x71\x3c\x05\x91\xba\x1a\xeb\x26\xb4\xcb\xdc\x0e\x63\x28\xb0\x7e\xab\xa3\x6b\x97\x3d\x77\x3c\x44\x9b\xfa\xee\x66\x49\xf3\xe8\x92\x44\xd3\x3c\x62\x47\x46\x00\x2b\xe1\xb7\xda\xb0\xfa\x18\xa6\x4a\x4b\xe8\xd6\x59\x0b\x87\x31\x79\x63\xb7\x62\x64\x72\x3a\x51\x32\xab\xb4\x47\xa2\x58\xb1\x4f\xc3\xa0\xae\xb7\x27\x82\x36\xb9\xcb\x82\x5d\x1b\xf4\x15\xdc\xca\xfa\xd9\xc0\xf1\xe8\x51\xf8\x74\x4d\x90\xc5\xe3\x77\x96\x26\x8b\x47\x8f\xb3\xe0\xd4\xc5\x9e\x67\xc2\x0d\xeb\xd1\x3b\x5d\x45\x64\xa4\xdd\x42\x8e\xac\x56\xa8\x3a\x3b\x45\x15\x6b\x28\xdb\x22\x60\xd7\x47\x77\xaf\xae\xfd\x2e\xeb\x60\xdc\x3f\x3d\xee\xd1\x2a\x0d\x46\xbd\xc1\x2e\x0d\xaf\xd8\x5a\xa6\x77\x39\x22\x02\x1f\xa3\x65\x6a\x54\x7a\xe7\x40\x3a\xac\x29\x6a\x43\x7a\x46\x28\xff\x0e\x4c\x9b\xa5\x0f\x7f\x65\x36\xa3\xb0\x98\x2b\xee\xd0\x81\xce\xe0\x7a\xdb\x0a\xba\x7a\xb8\x1c\x1e\x10\x71\x4f\xdf\x0c\xda\x50\xe3\x05\xa8\xdf\xa1\x62\xa7\x79\xc4\xbb\xe8\x99\x23\x22\x39\x67\x99\xd9\xf4\x48\xc3\x65\x53\xc8\xf4\x25\xf6\xfc\xa6\x42\x48\x0d\x7c\xa3\x86\x24\x83\x7e\xe4\x43\x74\xc5\x18\x0d\x34\xc8\xfe\x2a\x83\xa0\x69\xcf\x3a\x67\x6f\xcc\x43\x7a\x67\x20\x02\x4c\x04\xb4\x3b\xed\x87\x93\xc8\x03\x70\x93\x39\x6a\x55\xa5\xcf\xb6\xfc\x11\x5f\xd9\xf1\x1d\x13\xa9\x64\xce\x72\x8a\xfd\x48\x1c\x81\x8c\xbc\xbe\x2e\xb9\xd6\x0c\x51\xc7\x59\x99\x2b\x22\xa7\xc3\x28\x6e\xbc\x73\xf5\x62\xa7\x2f\x7d\x96\x3c\x84\x41\x4d\xdc\x0a\x6d\x0b\x03\x76\xd3\x11\xc7\x0d\x22\xe3\xc2\xac\x4e\xb0\xa6\x33\x68\x90\x24\x1a\x0e\x4b\xa3\x44\x5c\x21\xfd\x37\x9a\x74\x0f\xe7\x8b\x68\xeb\x83\x18\x7a\xc5\x74\xeb\x83\xd8\xfa\x20\xfa\x18\xf1\xc1\x7c\x10\xc1\xc6\xed\x84\xe9\x0a\x7f\x44\x58\x88\xe7\x9c\x12\x35\x94\x45\x00\x13\x6d\x58\xde\xb9\x23\x64\x19\xc7\x0a\x76\xc7\xe3\xdd\x5d\xe7\xa4\xb0\xeb\xa3\xd2\xd3\xd1\x37\x84\x89\x44\xa6\xc8\x54\x66\xfc\x52\x69\x50\x6a\x6b\xab\x3c\x7c\x97\xdc\x3d\x2b\x8c\x37\xc0\xd8\xfd\xb2\x44\x8f\x12\xca\xa5\xa4\xbc\x7a\x50\x15\xac\x56\xbc\x3c\x0c\x98\x25\xa0\x47\x4b\xb4\x1a\x58\x9d\x22\x93\xf1\x9c\x5b\x7c\x42\x23\x2e\x98\xd2\x8a\xec\xe1\xc9\x71\x52\x54\x43\x7b\xc1\x38\x67\xb9\x2c\x17\x43\x7f\x91\xf9\x31\xba\xcb\x5e\x31\x00\xad\x2d\xa9\xca\x92\x09\x9d\x2d\x7e\xbf\xfa\x9b\x23\xf1\x06\xab\x6f\x9e\x2b\xba\xd4\x7d\xac\x3a\x62\xb6\xac\x9b\x08\x80\xf7\xce\x53\x1b\xf6\x21\x5b\x81\x31\xac\x9d\x3f\xe6\x2c\x13\x57\xe4\x8a\x96\xad\x2b\x30\x56\x1d\x0f\xa2\xb1\xa5\xfc\x8a\x2b\xd9\xba\x86\x6d\xe5\x90\x21\xf1\xce\xed\xa6\x8c\x3e\x62\x59\xe9\xa2\xd2\x76\x77\x71\x6b\xdb\x41\xf6\xf9\x35\xdd\x50\x7c\x5f\xec\xf4\xf8\x72\x05\xd5\x9a\x95\xe2\x25\xf9\x9f\xbd\xf7\x5f\x7e\x1c\x0d\xbe\xdb\xdb\xfb\xe5\xf9\xe8\xaf\xbf\x7e\xb9\xf7\x7e\x0c\xff\xf8\x62\xf0\xdd\xe0\xa3\xfb\xe3\xcb\xc1\x60\x6f\xef\x97\x1f\xdf\xfc\x70\x71\x7a\xf4\x2b\x1f\x7c\xfc\x45\x54\xf9\x25\xfe\xf5\x71\xef\x17\x76\xf4\xeb\x1d\x07\x19\x0c\xbe\xfb\x63\x8f\x1f\x41\xc5\xe2\x6d\x6f\x22\x18\x8f\xd1\x83\xa8\x11\xf1\xd8\x3d\xb3\x2e\x21\x1f\x46\xb5\x47\x7b\xc4\x85\x1e\xc9\x72\x84\x0f\x79\x49\x74\x59\xf5\x25\xba\xea\xed\xef\xe1\x64\x4c\xad\xc4\xd4\x08\x98\xce\xb0\xd9\x40\x21\x82\x89\xa9\x3d\x7a\x86\x6d\x1f\xdb\xd5\x4e\x61\xfb\xe3\xd6\x1f\x7c\x97\xe3\x01\x33\x95\x2c\x9e\xcd\xef\x3c\x4d\xe9\xdc\x76\x53\xde\xe6\x28\x2d\x1d\xdb\x1c\xa5\xe5\x63\x9b\xa3\x74\xcf\x63\x9b\xa3\xe4\x8e\x6d\x8e\xd2\xd6\x3f\xd8\xfd\xf8\x9d\xfb\x07\xb7\x39\x4a\xf7\x3d\xb6\x39\x4a\xad\x8f\x47\x94\xa3\x84\x4a\xfe\xaa\x4c\x25\xab\xe6\xd7\x69\x4a\x1b\x9b\xa5\xa4\x0c\x3f\x24\x6c\x3f\x49\x64\x25\xf4\x85\xbc\x64\x1d\x03\xb9\x0d\x9b\x74\x69\x74\x80\x44\xbc\xc1\x46\x5d\xbe\x78\x23\x0d\xd6\xbe\xf4\xd1\x1e\xf4\xc7\xfe\x34\x47\x5a\xa5\xdc\xd8\xa8\x3d\x2f\x16\x37\x6c\x08\x8b\x2d\x52\x96\xd6\x3f\x58\x91\xa6\xcd\x7c\x8f\xc9\x3e\x29\x59\xc2\x0b\x6e\x36\x00\xc0\x0a\x82\xf3\xb8\x7c\x7c\x17\x67\xae\x15\xcb\xa6\xb6\x93\xad\xa8\xcb\x9c\xcb\xc0\xfe\xb4\x3b\xca\xca\xc7\xa0\x0e\x21\x5d\xaf\x51\xa2\xe6\xb2\xca\x52\x52\xb2\x7f\x3b\xe5\xc3\xbe\xcd\x45\x38\x42\xe8\x52\x85\x4f\xa9\x1f\x6b\x07\xa7\x05\xb7\xa0\x62\x9b\x24\x06\xd9\x87\x82\x97\xb0\xd8\xce\x59\x22\x45\xda\xb7\x87\x64\x69\xfc\x5a\x57\x80\xb8\x10\x4b\x49\x5a\xe1\x05\x50\x8e\x49\x33\x9e\x72\xbd\xf0\xf9\x1c\xb8\xec\x8d\xda\x8a\xbd\x83\x2d\x23\xa8\x7a\x22\x08\x2d\x8a\x52\xd2\x64\xce\x54\xf0\x34\x54\x42\x2d\x50\x86\xaf\xf2\xcc\xaa\x19\x17\xa8\x87\xc2\x3d\x46\x59\xc9\x16\xa4\x94\xda\xa5\xa6\xdd\xf0\xc0\x8b\x60\x30\xb8\x1d\x35\x0e\x5d\x2e\x20\x7f\x4d\x86\x43\xe0\x5b\xf1\x69\xf8\x87\x22\x32\x4b\x1d\x34\xeb\x37\xcf\x8d\xe2\x9f\x58\x2e\x36\x9b\x00\x80\x66\x6a\x49\x32\xa3\x3c\x99\x8d\xe1\xe6\x9b\xbf\xfa\x13\x99\xcb\xaa\x54\xe3\x10\xec\xef\x05\x9c\x43\x0f\x87\x33\x1c\x34\xc9\x18\x55\x9a\xbc\x78\x4e\x72\x2e\x2a\xb3\xe3\xf7\xc4\x78\x7d\xe9\xba\x81\x96\xfb\x97\x3f\x75\x1c\xad\x1f\xfd\xf6\x46\xcd\xb6\xc0\x8e\x79\x56\xbd\xb5\x6b\x1c\x01\x3d\xb0\x6b\x66\x43\xd9\xb5\x5b\x52\x38\x8b\x42\xcb\x35\xaf\xfc\xdf\x2a\x39\x59\xe8\xee\x10\x36\x76\x9c\x18\xbb\xe6\xbf\xed\xc9\xbb\x40\xc5\xd6\x48\xb1\x2d\x5e\x65\xed\x3d\xbe\x67\x5c\xe9\x56\x1d\xbe\x6b\xcc\x9b\x16\x37\x77\xdd\xcc\x67\xc6\x3e\xee\xa5\x92\x1e\x46\x72\x16\x9d\xf3\x48\x27\x09\x53\x20\x8a\x1c\x28\x1c\x38\x77\xf1\xda\x96\x0f\xdd\x50\xb4\x99\x55\x20\x32\x8e\xf9\x7b\xe8\x55\xda\x89\x58\x5d\x54\x7e\xc7\xd8\x3d\x51\x0b\x07\x8b\x65\x84\xe2\x62\x86\xad\x45\xf3\x2a\xd3\xbc\xc8\x6a\xca\x9d\xb9\x1b\xec\x06\x1c\x46\x0b\x68\xe0\x9e\xa6\x08\x7a\x85\xe8\xe7\x10\x59\xd9\xf3\x63\x31\xa1\xb1\x43\x66\x69\xf6\xf1\x82\x96\xd4\x93\x3f\x91\x79\x4e\xd5\xc0\x06\x1e\x28\x64\xc1\xd8\x36\x40\xe6\x2e\x9a\xd5\x6f\x1c\x64\x1d\xac\x8b\x71\x35\x13\x54\xb4\x0e\xff\xc5\x80\xf3\x30\x14\x91\xd7\x3e\xd1\x1e\x9b\xdc\x37\x38\xd6\x2a\xc4\xdf\xd3\xe4\x92\x89\x94\xbc\x53\x8e\x70\xe9\x42\xd0\xdc\xe2\xc7\x17\xa5\xc4\x2e\xea\x2c\x6d\xdc\xaf\x86\xd6\xed\x88\xd0\x27\x0e\xc0\x0a\xf5\xad\x75\x51\xb1\x52\x3d\x81\x07\x9b\x81\x3e\x25\xef\x14\xba\x74\x4b\x7e\x95\x30\xa7\x3b\x9a\xfb\xd6\xf5\xf1\x57\xad\xd1\xea\xc8\x6a\xe8\x28\xdb\xc6\x14\x57\x21\x6c\xe9\x3e\x72\x09\x30\xf1\x34\x33\x22\x6e\xe1\x31\x7f\x1a\x0c\x36\x59\x80\xdf\x6b\x2d\xc8\x63\xe5\xa4\x3b\xa6\xd4\x6e\x39\x49\x63\x61\x76\x46\x53\xa9\xc8\xf7\x99\x4c\x2e\xc9\x21\x03\xa3\xe1\x21\x9b\xef\x97\x93\xf4\x71\x37\xce\xcc\xe9\xac\x5d\xc6\xc8\x88\xe4\x52\x70\x2d\xcb\x36\xf2\x78\x83\x80\x02\xb7\xad\x0c\xef\x82\x98\x6e\xd6\xd9\x53\x69\x64\x68\x58\xbe\x1f\xd6\x81\xa1\xbc\xeb\x04\x24\x0f\x9e\x02\xa1\xda\x5a\x8e\xfc\x61\x2e\xaf\x47\x5a\x8e\x2a\xc5\x46\xbc\x75\x22\x54\x67\x42\x5d\xb2\x05\x64\x95\xf5\x42\x2a\x3b\x58\x64\xb9\x6b\x09\x7e\x76\x38\x6f\xf4\xbb\xb3\xef\x0f\xdf\x29\x56\x8e\x43\x6b\xe5\x19\xd3\xc9\xb3\x84\x15\xf3\x67\x76\x84\x47\x4f\x56\x27\x36\xfb\xa1\xab\x1b\x0d\x15\x81\x44\x66\x99\x05\x18\x93\x53\x72\xc0\x8a\xb9\x7f\xdc\x66\xd0\xed\x31\xf7\x94\x2b\xa4\xec\xa7\xdd\xd4\xae\x19\x29\x16\x1b\x70\x06\xa5\x46\xc0\xfc\xe5\xe4\x7e\x8d\xbc\x37\x91\xdd\x3f\x63\x77\x96\x36\xad\xf8\x36\x82\xbc\x9b\xd3\xd2\x6f\x37\xea\xe9\x17\xd6\x0f\xc5\x0d\xfb\x5c\x76\x6a\x24\xb6\x8f\xa7\x68\x8c\xa6\x2c\x25\xf2\x8a\x95\x25\x4f\x99\x22\x5e\x6e\x87\x3e\x28\x9e\x6d\x06\xe5\xb7\xbd\x03\x1f\x57\xc2\xc1\xe6\xb8\x1f\x76\xc1\xff\x10\x09\x71\x38\xb3\x24\xc4\x69\x9a\x73\xb1\x19\xdc\xde\x92\x6e\x2a\xa1\x19\x3b\x7e\xdb\xd9\x5a\xb7\xe3\xc4\x06\xfb\xb9\x3d\x19\xf4\x14\xf8\x04\xce\xfe\x8f\x9e\x77\x89\x90\x69\xbb\x00\xda\x9a\xcd\xee\x19\xd5\xec\xba\xa5\x22\x34\xaa\x45\x7e\xdb\xfb\xc1\x3c\x7b\xdc\x66\xfb\x46\x74\x0a\x09\x56\x39\x42\xfe\xaf\x4b\xc9\xb2\xfc\xd4\x4f\x20\x09\xc7\x0a\x9b\xb2\x35\x5b\xb1\xb9\x35\xbb\x7f\x7a\x4c\x7e\xc0\xcb\xd7\xd7\x05\xa5\x94\x1a\x4d\x9e\x43\x99\x53\xde\x4f\x03\xf4\xe6\xa0\xcd\x7e\x58\x21\x11\x4e\xfd\xb5\xc4\x5e\x6c\x94\xa2\x1a\x6e\xb8\x2a\x59\x4a\xac\x3f\xe5\x89\xb5\x78\x58\x52\xa7\x9f\x46\x8b\x87\x87\xea\x92\x1d\xb8\xe6\x5d\xfd\x4e\xad\x45\x3b\x76\x02\x25\xc2\xe7\x3a\x11\xc5\x84\xe2\x90\xde\x10\x64\xe0\x81\xaa\x0d\x69\xe9\xbe\x58\x07\xd5\xee\x21\x79\x2d\x67\x5c\x38\x29\x26\x6d\x56\xcd\x94\xf2\xac\x1b\x39\xb7\x7a\xf2\xef\x4c\x4f\x56\x2a\x3b\x12\x74\x92\xb5\x4f\x99\x8c\x17\x81\x1f\x8e\xbc\xca\xe8\x8c\x30\xf8\xe3\x59\xca\x95\xf9\x2f\x39\x3f\x7f\x0d\xc1\xe0\x4a\x38\xfb\x12\xc2\x9c\x76\x6f\xf1\xa5\xd1\x28\x64\xd6\x27\x17\x50\x88\xf7\xd6\xc1\x23\x18\x8f\x70\x91\x9a\x4f\x67\x2a\x4a\x4a\xb6\x57\x60\xaf\x14\x5f\x77\x87\xa9\x8f\x13\x46\x2e\xe6\x3c\xb9\x3c\x0d\xe2\xbf\xb2\x34\xe7\x44\x70\x2a\x52\x52\x9a\xbf\xad\x6b\x37\xb2\x9f\x75\xda\x97\x43\x2d\x18\xcf\xed\xd4\x4e\x9c\x9e\x5b\x0a\xc2\x6f\x54\x29\x99\xf0\x3a\xff\x00\x3c\xd1\xf5\xf6\x9d\xc2\xf6\xbd\x3e\xaa\x80\xc2\xd9\x0f\x41\x50\xcf\x5d\xa1\xb5\x38\x8e\xb2\x57\x50\x15\x6a\x29\x5c\x38\xba\xad\x8d\x08\xc8\xe3\xbd\xb5\x34\xad\x87\x5b\x6e\x69\xea\xcc\xcc\x46\x88\xdc\x15\xbc\x5a\x06\x72\x26\x83\xed\xa1\xbd\xcc\x42\xbe\xb5\xa9\x6d\x66\xb2\x16\xd2\xb5\x2f\x4d\x5f\xe5\xfe\x6b\xe4\x07\xe1\x39\x1b\x34\x07\xd9\x53\xc8\xa2\xca\x30\xb3\xb6\x7b\x67\x57\x17\x63\xc4\xe7\xac\x21\x88\xbe\x69\x9d\x9d\x76\xc3\xf2\xbc\xfb\xd7\x2b\x3e\x8d\xfe\x4e\x81\x69\xf1\xfc\x2f\x7f\xfa\xd3\x63\xef\xf8\xd4\xcd\x71\xb7\xee\x96\x4f\x9d\x42\x6f\x2b\xb0\x19\x8e\xb7\xd8\x0c\x5b\x6c\x86\xf8\x58\x7b\x7c\xf8\xf3\xa3\x2f\xf4\x52\xdd\xd6\x47\x65\x5b\x57\x7c\x85\x8e\x55\x71\xfd\x54\xc4\x75\x46\x50\xf8\x1c\xb8\x09\x3d\xd5\x88\x75\xc7\x48\xd8\x22\x23\xfc\xbe\x90\x11\xfa\xab\x11\xeb\x0b\x05\xa1\x7b\x6d\xd8\xef\x07\xf1\xa0\xb3\xd8\xe8\x5a\x57\xdf\xb9\x9a\xbe\xaf\xa6\x1f\x7d\x79\xf7\x7b\xf3\x30\xec\xd6\xe3\xad\xf4\xb7\x38\x88\x37\x87\xa6\xbf\xbb\xab\x02\xb0\x7c\x2d\x8d\x74\x59\xa3\xe9\x4c\x3a\x7b\x1e\xf0\x55\x64\xab\xbd\x7b\x95\x17\xef\xed\x79\x23\x41\xc0\x9f\xde\xfc\xbc\x80\x6d\x80\xbc\x5b\x9a\xfa\xd3\x0a\x8f\x3e\xd1\x0e\xf8\x0f\x15\x1e\x55\x11\x6a\xae\xf3\x3a\x82\x80\x04\x15\x4e\x4e\xc2\xce\x34\xb5\x58\xd8\x3f\x3d\x26\x49\xc9\x00\xda\x81\x66\x6a\x4c\x56\x68\x78\x2e\x80\x64\x35\x42\xa7\xd9\x51\xad\x59\x5e\xe8\xae\x9c\xb7\x8d\x8e\xfe\xce\xa2\xa3\x0f\x1e\xa5\x98\x57\x39\x15\x23\x23\x2d\x20\x3e\x1a\xe5\x9d\x34\xf6\xc3\x31\xb1\x72\x01\xd5\x0a\xf0\x85\x42\x49\x73\x25\xf8\x6f\x15\xab\xdd\x15\x5e\xeb\xd8\x80\xe0\x0e\xbc\x47\xcf\xb4\x43\x8d\xaa\x21\x45\x12\xb9\x54\xc4\x65\x09\xe2\xe9\xe8\x04\x46\xa0\x96\x45\xae\x37\x3d\x67\xa8\xbd\x9d\x02\x48\x42\x7d\x55\x6c\x1f\xa2\x81\x48\xb3\x4c\x5e\xe3\xb3\x43\x7d\xc4\xcc\x9f\x79\x17\x8b\x4b\x32\x61\x24\xe7\x65\x29\x4b\x1b\x46\x0a\x5f\x07\xd3\x87\x8c\x9d\xc9\x4a\x34\xd8\x4a\x9b\xf4\x71\xce\xb4\x9d\x6a\x60\x15\x2d\x09\x15\x58\xc0\x69\xfe\xed\x32\xae\xe1\xd9\x4e\xde\x4d\xd8\x9c\x5e\x71\x59\x95\x78\xb7\x96\x64\xc7\xfe\x04\x7b\xef\x42\x56\xde\x77\x5e\x41\x85\x96\xff\x3a\xb5\x82\x4e\x27\xf5\x8f\x60\xe0\xa6\xd2\xb9\x23\x47\xec\x03\x57\x7a\xf9\x5b\x1c\x89\x5c\xcb\x89\x75\x70\xde\x95\x2a\xcc\x06\xfb\x53\xeb\xda\xdb\x98\xdf\xc2\xd1\x62\x4d\xf5\xea\x1c\x7e\xfa\x94\x9e\x6a\x11\x6b\xb0\x64\xde\x95\xc3\x3d\xbe\x1c\x56\xfc\xca\x96\xbd\xae\x36\x52\x51\xde\x2a\xc9\xb7\x1e\x3e\xcb\x22\xe3\xc9\xe2\xf8\xb0\xdf\xcc\x0d\x1c\xd3\x6d\x7f\xca\x67\x6d\x98\xf3\xe4\x7b\xaa\x58\x4a\xde\x50\x41\x67\xe8\x75\xd9\x3b\x3f\xfd\xfe\xcd\xc0\x70\x11\x78\x75\x8e\x0f\x57\xa6\x76\x9c\x87\x83\x9f\xac\xab\xce\x9d\x34\x49\xd7\x9b\xda\xb0\x34\x6a\x4b\xf2\xad\x0d\x02\x80\x78\x9d\xa0\x4b\xfb\xb4\x15\xea\xc0\x69\x13\x24\x0a\xd3\x37\x1c\xfa\x9b\x6a\x8a\xea\xab\x3c\xbd\x7c\x48\x02\x04\x7e\xf3\xdb\xbe\xf2\x6e\x31\xb0\x3b\xc4\xb9\xe2\x6e\x24\xba\xa4\x9a\xcd\x16\x87\xac\xc8\xe4\xc2\x30\xc0\x69\xe0\xc6\xc7\x4b\x27\xa8\x36\x94\x13\x9a\x90\xb2\xca\x18\xf6\x16\x6a\xc2\xae\x09\xc6\xd2\x5a\xd2\x71\xa1\x34\x05\xd0\x35\x1c\xff\xd6\x37\xba\xf3\x66\x75\xd7\x6d\x69\x84\xef\xf9\xc9\xab\x62\x88\x4a\xb3\x4a\x6e\xbd\xe5\xee\x1b\x13\x3c\xfe\xd3\x3c\x7b\x9f\xb8\xe6\x9d\x23\x98\x71\x77\x40\x58\xe5\x67\x55\x66\x36\x9f\x2c\x6d\xb4\x78\x05\x3d\xcd\xce\x31\xa2\x5d\x80\x4c\x30\x6f\x3f\x24\x93\xca\x28\x71\x4c\x45\x3e\xee\x65\xa8\xcf\xeb\x39\x86\xb4\xcd\x4d\x84\x16\x45\xc6\x31\x85\x59\x96\x36\x2e\x1d\x38\x34\x97\x2f\xbb\x8b\x68\xb9\xa7\x2e\x73\x3f\xdd\x65\x44\xae\x58\x39\xb9\x0b\x4e\xc5\x7d\xd5\x12\x5a\x70\x88\xe3\xdc\x59\x8b\x89\x26\x6e\xff\xf4\x18\xef\x5e\xe5\x38\x76\x3f\xe2\x0c\xda\xb9\x71\xe1\x0d\xdb\x33\x08\x2d\x17\x8f\xb4\xb4\x7f\x7a\x8c\xd0\x5e\x16\x6c\xa9\x76\x7f\x18\x3b\x81\x62\x92\x63\x8d\xf0\x48\x67\x66\x44\x4d\xa4\xf0\x0f\x65\xa2\xca\x19\x02\x34\xd5\xcd\xc6\x8c\xf1\x28\x16\xf5\xe8\xb5\xf7\xc4\xd8\x3a\x77\x57\x48\xee\x1f\xe1\xbf\x67\x44\xff\xde\x7b\x91\x90\xe2\xcc\x7e\xe6\xbb\xb3\xd7\xed\x26\xf1\x24\x1e\xc3\x02\xf2\x30\xc0\x1e\x2c\x68\xa9\x39\xcd\x48\x55\x66\x2e\x24\x88\xf9\xfd\x36\x8d\x6e\x4e\xaf\x02\xd0\xa2\x31\x21\x5f\xe0\xcc\x59\xc2\xe2\xfa\xc4\xe6\xbb\xd6\x8d\x5b\x65\xd9\x90\x4c\x39\xb4\x5b\xd7\xac\x20\x61\x48\xea\x9c\x8b\xc4\x98\x72\x62\xe4\xbb\xe9\xc0\x1b\x39\x03\xcf\x2f\x52\x88\x78\x82\xbe\xcb\xb2\x14\x80\x2c\xe1\x11\x66\xc1\x26\xe0\x6e\x30\x16\xe8\x41\x56\x29\xcd\xca\x33\x69\x36\x83\x20\xe5\x06\x40\x3d\x68\xf8\xf3\xf7\x5c\xa4\x90\x63\x75\x06\x1b\x47\x42\x05\x61\x1c\x1c\x39\x66\x48\x88\x9d\x1b\xde\xa9\x19\x6a\x4f\x55\xc9\xdc\x7c\xd2\x4e\x21\x53\xb5\x63\xc4\xc8\x0e\xba\xfb\xd4\xce\xc0\xfc\xd5\xfc\x06\xcc\xa0\x09\xee\x7b\x46\x0b\xbe\x33\x18\x12\x20\x10\x04\xef\xa4\x9e\x3f\x5e\x3e\x74\xdf\x0a\xf6\x75\x2b\x2e\x3c\x0b\x47\x00\x1e\x14\x75\x98\xee\x7a\xce\x35\xf3\xad\xd1\xd1\x4b\xe4\x51\x6a\x9a\xc2\x9a\x90\x7d\x41\x58\x5e\x68\xf0\x3c\x93\x9c\x51\x17\xce\x66\x57\xac\x5c\x18\xfb\x1e\x50\x3c\x1e\xfd\xe2\xf7\xfc\xd8\x89\xe0\x8d\xbe\xf3\x35\x93\xc3\x0a\x5b\x22\xee\xee\x17\xbb\x91\xcf\x20\xcb\x02\x69\xfe\x68\x49\x09\xdb\x6b\x2b\x32\xfe\x64\xee\x8c\x49\x88\xa7\x50\x5a\x7a\xf9\xf1\xfa\xb5\x0d\x8a\x20\xad\x7e\xe4\x22\x55\xbe\x13\xa2\xcd\xd9\xb6\xf4\x5e\x49\x64\x78\xc3\xc7\x48\xe0\x65\xf5\xf5\xae\x2a\xe7\x2d\xc3\x3b\x8d\xfd\xa6\xa1\x6e\x1d\xc0\xaa\xfd\x6f\x64\xba\x7a\xe9\x44\xf3\x7b\x1c\x5c\xec\x13\x05\x6a\x9f\x89\x1d\xcb\xaa\xaa\x8b\x62\xa5\x3e\x7f\xfb\x74\xdc\x42\xfa\x9b\xde\xa4\x76\x16\x80\x9c\x0c\x7e\x01\x4f\x10\x62\x94\x93\x69\x46\x67\x35\x1b\x81\xd4\x43\x25\xe9\xe0\xfc\x27\xf7\x09\x8a\xf0\xd5\xea\xea\x27\xf5\xd9\x4f\x69\xb0\xa3\x9a\x4a\x37\x5e\x61\x1e\xb2\xf2\xc7\x4f\xab\xb1\x7e\xf0\x9b\xb9\xe9\x2e\x81\x42\x7d\xab\x13\xee\x26\xfa\x3b\x7f\x1b\x0d\x38\xc1\x81\xad\x39\xa3\x12\x72\x9f\x40\x0f\x39\xff\x29\x62\x93\x4f\xbc\xef\x0d\x4c\x7b\xc9\x16\xd7\xb2\x5c\x8d\xa3\xde\x9a\xbf\x6e\x7d\x62\x46\x27\x2c\xfb\xf4\x02\x79\x43\x0b\xf3\xd9\x75\xa2\x29\x5a\xde\x36\x4e\x89\xba\x3f\xe6\x84\xb9\x3c\x3c\x59\xce\xa8\xe0\xff\xc1\xec\xdc\xc4\xac\x63\x59\x9a\x3f\xf7\x30\xd6\x81\x76\x7b\xc6\x12\x3d\xb0\xfc\xb7\x52\xee\x7d\x82\x41\x69\x9a\x72\xd4\x1e\x4e\x3f\xc1\x4b\xb7\x13\x81\x8b\xcb\x87\xa0\xf9\x2d\x0b\xeb\xd3\xbc\x7f\x7b\xb0\xf4\x0e\xb2\xb9\x2a\x6f\xc9\xa3\xba\xf5\xfe\x9c\x72\xdb\x55\x77\xe3\xa8\xc2\x72\xca\xdb\x7e\x16\x1e\x1d\xe8\x9a\x53\x5d\x95\x5c\xaf\xdc\x90\x6e\xbf\x91\x8b\x1f\xab\x09\xb3\xf1\xe1\x7b\xdf\x2e\x20\x4d\x70\xff\xf4\xb8\xdf\xe9\x88\x56\x38\x58\xf1\xf6\x05\x8d\xde\x42\x2a\x41\xf3\x09\x9f\x55\xb2\x52\xd9\x22\x74\x4a\x52\x08\x6f\x1b\xa3\x1e\xbd\x32\xff\x1f\x7b\x57\xf3\xdb\xb8\x8d\xc5\xef\xfd\x2b\x08\x5f\x32\x13\xc4\x1e\x2c\xda\xd9\xc3\xdc\x82\x24\xc5\x06\x9b\x8f\x81\x9d\xb6\x97\x1e\xca\x48\xb4\x2d\x44\x22\xbd\xa4\x64\xc7\x2d\xfa\xbf\x2f\xf8\xf8\x48\x89\xb6\x44\x51\xb1\x93\xa6\xc5\xf8\x92\x19\x89\x7c\xe2\xe7\xe3\xfb\xfa\x3d\xf2\x93\x92\x50\x2e\xf8\xb6\xc0\xa2\x3c\xc9\xab\x94\x79\x14\xc1\x0b\xb8\x16\x59\x4a\x68\x55\x8a\x82\x96\x59\x42\x12\xc1\x64\x02\x1e\xc3\x26\xa5\x4a\x31\x42\x3b\xea\x26\x95\x2a\x45\x41\x0a\x2a\xd5\x92\xe6\x79\xd7\x1c\x1f\xe1\x54\x0b\xa5\x1e\x1f\x43\xff\x3b\x5f\xae\x4d\xab\x5f\xb8\xbe\x7b\x32\xad\x47\xac\x6f\xdd\xb8\x83\x08\xac\xbb\x57\x69\x04\x0d\xc4\xf8\xb7\x66\x2f\xea\x99\x98\xbe\xd1\x09\xed\xdc\xde\x7e\x05\xb8\x61\xb0\x2e\x04\xe9\xb2\xf4\xba\xa0\x8b\x08\x41\xf2\x46\x6b\x07\x94\x6f\x6d\x35\x93\x68\x53\x9d\x11\x21\x31\x6a\xc4\xdd\x8b\x8e\xaf\x5c\xb2\x56\x49\xee\xc1\x1d\x27\x24\x86\x6f\xe3\x2a\x85\xa0\x7e\x26\xe7\x42\x16\x5a\xae\xcb\x24\x99\x57\x1c\x8c\x64\x0a\xa3\xbd\x41\x25\x41\x5b\x0d\xcd\x95\x70\x3b\x10\xfc\x7b\xdc\x36\x82\x50\x45\x36\x2c\xcf\x27\xe4\x3c\xcf\x31\x03\x68\x23\xd7\x43\x8d\xd7\xae\x63\x0a\x1e\xb7\x24\xcd\x16\x4c\x95\xe4\xc3\xec\x3f\xe7\x1f\xe1\xd4\x06\x3b\xc6\x96\x94\xd4\xc2\xd5\x7c\xfb\x0c\x9c\xff\x69\x05\x72\x42\x42\x4b\x9a\x8b\x85\x71\xab\x83\x9d\x96\xa7\x64\x95\xd3\x2d\xa4\xf7\x5f\x51\x09\x11\xa7\x89\xb1\xd1\x10\x59\x71\x48\x6c\xfc\xa6\x27\x4e\x3f\x2b\x08\xe5\x1e\x1e\xc3\x9a\x7c\xe1\x56\xef\xc9\xf0\xfa\xba\x47\x99\x64\xab\x9c\x76\x58\x15\xbc\x15\xfd\xe0\x81\x91\xb5\x98\x0b\x2a\xac\xe0\xcc\xd1\x98\x90\x99\x59\x3b\x05\x2d\x13\xe3\xd3\xfc\xad\x60\x25\x4d\x69\x49\x27\x5a\x17\xfc\xcd\x47\xc6\x89\x3c\xd5\x84\xba\x27\xba\xa3\xcd\x46\x5e\x6c\xbf\x10\xdf\xdf\x85\x5a\xa8\x75\xc5\x41\x3e\xb7\xfb\x31\x68\xc6\x38\x90\x3f\x41\xf7\xaf\x9e\xb5\x2a\x16\xf4\xa1\x79\x6d\xdd\xad\xe4\x5b\x19\x72\xbf\x27\xb8\x5a\x0b\x06\x69\x22\x1f\xf0\x26\x24\xfb\x04\x4c\xa8\xe7\x77\x97\xdd\xe6\xae\x7e\x93\x41\x8f\x89\xc0\x77\x0c\x04\x9a\x67\x0d\xcc\xf8\xc6\xf7\x0e\x58\x38\x0c\x00\x08\x0d\xb8\x84\xda\x6c\x30\xb6\xb0\x99\x30\x1f\xfa\x68\xea\x75\xdb\x47\xa2\xdc\x33\x31\x4e\x99\x3e\xa4\xd9\xd8\x35\xb6\xb3\x50\x9c\x8f\xa6\x17\x0d\xd6\x85\xf6\x32\x23\x0f\xe0\x10\x6b\x22\x75\x83\x1d\xeb\xd3\x8a\xb4\xef\xd8\xae\x0e\x68\xa8\x9b\x4a\x2f\xf0\xe8\x89\x6d\x4f\x14\xa2\x5e\x04\x57\xcb\x6c\x65\xe0\x8a\xe8\x86\xc0\xd9\x25\x3f\xd3\x3c\x4b\x1d\x09\xb3\xaa\xaf\xf9\x19\xb9\x13\xa5\xfe\x73\xf5\x9c\xa9\xd2\xa8\x9f\x97\x82\xa9\x3b\x51\xc2\x93\xa3\x74\xd5\x34\x61\x40\x47\x51\x01\x36\x96\x6c\xd8\x57\x0d\x35\xd9\x76\xe8\x1a\xd9\x9e\x1d\x94\x4c\x91\x6b\xae\x25\x02\xec\x91\x83\xf1\x2a\x24\x61\x31\x28\x5c\xf0\x31\xd8\xb8\x5b\x69\xe0\x40\x08\xe9\x8d\x43\x80\x1c\x92\x32\x01\x80\xf0\x26\x53\x96\x89\xbb\x33\x9b\x5a\xb3\x5b\x96\x90\x82\xc9\x05\x78\x6d\x92\x1e\xaf\x45\xac\x29\x32\xca\x00\xd9\x3b\x57\xc0\x32\x6f\x3a\x0d\x17\x7b\x93\xd4\x28\x6f\xd8\x52\x61\xac\x19\x7f\x68\xee\x03\x23\xf5\x27\x60\xb9\xd5\x84\x9c\xdb\x6b\x66\x9a\xef\xd0\x7b\xd5\x24\xa3\x29\x64\x8a\x68\x56\xb2\xa6\x39\x33\x59\xf6\x29\x77\x78\x2b\x31\xdf\x63\xec\x67\x88\xe9\xd6\x7b\xd6\x89\x4c\xa3\x27\xb6\x1d\x9d\xed\x4d\xed\xe8\x9a\x8f\x6a\xd0\x9d\x37\x99\x8e\x89\x82\xb4\x35\x82\x77\xa3\x97\x9f\x05\x41\x66\x19\x6f\x5e\xe9\x9d\x37\xf5\x94\xb5\xbb\x9f\x5b\x85\x8d\x0f\xea\xa3\x1e\x42\x70\xf9\x4a\x52\x08\x09\xe6\x4c\xfd\xb4\x99\xde\x43\x8b\xaa\x4f\xd9\x6a\x55\x67\x43\xa9\x56\x0b\x49\x53\x46\x16\x92\xae\x96\x43\xc5\x12\x23\xdb\xb4\x91\xff\xdb\x08\xba\x1d\x83\x1f\xd0\xe8\x82\xf5\x36\xec\x71\x29\xc4\x13\x40\xe1\x60\x21\xbc\xa2\xfd\xe1\x17\xf3\xad\xcb\xfa\x99\x55\x25\x15\x49\x59\x49\xb3\x1c\x62\x39\xee\x6f\x6e\x31\xda\xc3\x9e\xe3\xb6\x95\xed\x81\x13\x47\x50\x00\x68\x8a\x51\x48\x53\xb6\xce\xd8\x06\xad\x12\x5d\x71\x1a\x63\xb2\x60\x1c\x82\x13\x02\x41\x3c\x63\xa2\xb2\x94\x5d\x01\xf0\xb6\x9b\xd0\x01\x86\xf3\x8e\x36\xf7\x6d\xde\x30\x07\xef\xe5\xde\x11\xa7\xac\x53\x7f\xbf\x0a\x19\x48\x04\x14\x87\x03\x8e\xc3\xf8\x62\x24\xf9\x17\xf2\xc3\x0f\xdf\x77\x16\x2a\xe8\x73\x56\x54\xc5\x17\xf2\xef\xcf\x9f\xbf\xff\xdc\x5d\x2c\xe3\xa6\xd8\xbf\xba\xfb\x87\xbb\xed\x62\x7a\xf9\x0e\xc6\x3b\x75\xd1\x74\x61\xa7\x5c\x04\xa9\x39\xcd\xf2\x4a\x62\x1c\x67\xa4\x8a\xf0\x63\xb3\x0e\x38\x54\x6a\xe0\x03\xb5\x14\x6d\xb0\x17\x06\x81\xcd\x33\xce\x14\x5c\xe0\x52\x71\xc9\x12\xb1\xe0\xd9\xef\x2c\xb5\xf7\xb7\x40\x60\x07\x64\x7a\xb7\x4b\x9c\x30\x9e\x9a\x7b\x34\xf5\x99\xb7\xa4\x3c\xcd\x43\x0e\xff\x88\x9e\x36\x77\xf0\x41\x43\x06\x27\xcf\xa0\x01\xbb\xad\x6b\xec\x0c\x17\xdc\x06\x8a\xee\x27\x73\xa2\x99\x61\x3b\xa8\xa7\x86\x31\xce\x02\x8a\x75\x4b\x1b\xf7\xf4\x3e\xa3\xb2\xc2\xb3\xff\x55\x4c\x6e\x01\xe4\x51\x0b\xf6\x8d\x40\xb0\x87\x3a\x87\x80\xed\x06\x4a\x54\x26\x89\xcb\x8e\x2e\x5c\x0b\x31\x75\xb8\xc7\xce\xb7\xa1\x0e\x33\xee\x73\xeb\x48\x22\xe7\x84\x57\x79\xde\x55\x94\x8b\x90\xcb\xa9\x39\x76\x3d\xaa\x64\x9c\x8e\x17\x6b\x16\x68\x19\xe9\x37\x35\x0e\x34\x3b\x7e\x24\x51\xfe\x7d\x9b\x0b\x9a\x1d\x8e\x8a\xe9\x8c\x8f\xe7\x8c\x4b\x55\x13\x61\x46\x30\xbf\x21\x01\x9f\x91\x09\x66\x5e\xd3\xb0\x60\x7e\x83\xe2\x73\xe2\x8c\x0c\x2d\x4d\x7f\x77\xa6\x86\x17\x74\x3e\xc6\xec\xd0\xd2\xf5\x6f\xc6\x87\xbd\x01\x8f\x8d\x86\x1a\x10\x09\x15\x39\x93\x11\x46\x09\xf3\xfb\x66\x9a\x18\x74\x12\x45\x30\xe6\x61\x66\x8a\xe8\x59\x95\x2c\xe3\x6b\x61\x12\x3d\x0f\x92\xe1\xa6\x7b\x15\x77\x44\xb9\x0d\x70\x56\x94\xe5\x9c\xf0\xdb\x14\x69\xb5\x42\x4b\x2a\xd5\x6f\xec\x0e\xf7\x20\x8c\xfd\x38\x8a\x0e\xe2\xf7\xbc\xca\xd9\x2f\x59\xb9\xbc\xb7\x89\xdd\x71\x55\x97\xd5\x2a\x87\xce\x36\x5e\xe8\x25\x34\xad\x25\xc3\x6b\x73\x95\x18\x4b\x44\x51\x30\x9e\x9a\x20\xa2\x82\x3e\x31\x52\x5f\x57\xa9\x65\x3c\x10\x83\x81\x1c\x7b\x5e\x51\x5e\xcb\x89\x6b\xcd\xcb\x43\x2b\x2a\x72\x3d\xc5\x9e\xb5\xd1\xa0\x8a\x30\x98\xa2\x81\x86\xf0\x40\x13\xe4\x91\xe5\x02\x60\xd8\x26\x52\xd4\xc4\x32\x63\x51\x60\xc9\xf8\x14\x4f\x3d\x4c\xfa\xc8\xf8\xa2\xce\x25\xa5\x72\xb8\x58\x16\x39\xb0\xe0\x6c\x42\xa6\x28\xc2\xc4\x49\x45\x31\xec\x34\x92\x95\x46\x1f\x88\x75\x1e\x85\xc1\x23\x6b\xeb\x35\xc7\x76\x6d\x9f\xc5\x8c\xae\x2d\xfc\x4f\x1e\x5f\x77\xe9\xc2\xb0\xe1\xf5\xb7\x74\x7d\x2a\xb8\xb1\xdd\x61\x5e\x89\xb9\xb6\x18\x4c\x75\x63\x72\x31\xbd\x3a\x7f\xb8\x3a\x23\x3f\x7d\xbd\x84\xbf\x97\x57\x37\x57\xfa\xef\xc5\xfd\xdd\xdd\xd5\xc5\x83\x96\x23\x4e\x4d\xfa\x78\xad\xc6\xe9\xd1\xd5\xe7\x91\xf0\xb9\x05\xe5\x5b\x32\xaf\x4a\xcd\x0e\xea\x8f\x79\xad\xa0\xc6\x06\x40\xd3\x54\xab\x8c\x7f\xbb\x39\x6c\x1f\xf0\x5d\xb3\x49\xf3\xde\x0c\x93\x71\x1f\xc1\x52\xfd\x62\x52\xf4\x22\x89\x46\x1d\x78\x4d\x1e\xbd\x10\x6e\xf0\x2b\x27\x3f\x0a\x49\xf0\xa2\x31\xb8\x79\x32\x55\x27\x08\xea\xd0\xff\x9e\x98\x47\x9f\x72\xb1\x38\x71\x58\x0f\x46\x72\xb1\x20\xaa\x7a\x74\x18\x1c\x38\x4d\xa1\xf4\xa9\x2d\xe6\x41\x17\xce\x1c\x10\xa7\x51\xcb\x11\xf7\xea\x34\x0b\x34\xe9\x7e\x82\xdb\xc1\xbc\x92\xfa\xc1\x2e\xc1\xd3\x4f\xed\x2d\xb0\x82\x53\x26\x77\x6a\xfc\xca\xf5\x72\xdd\x64\x79\x9a\x50\x99\xee\xad\x59\x38\xdc\xcc\x94\xc3\xe8\x99\x94\xb9\xe6\x26\xe7\x9a\x38\x26\xba\x10\x6b\x26\x73\xba\x32\x11\xe2\x90\xb3\x18\x42\x8f\xe0\x23\x97\x6c\xc5\x00\x07\x65\x6f\x1a\x67\x3c\xc9\x05\xe4\xd4\x30\x27\xe3\x99\xdf\x75\x13\x8a\x64\x13\x0f\x22\x98\xa6\xde\x21\xa3\x77\xcb\xe6\x20\xcc\x78\xd0\xea\x35\x81\xc9\x9d\x89\x59\x1c\x6e\xc3\x28\x8d\x4e\xf2\x65\x64\x84\x28\xb3\xd1\x19\x19\xb9\xdc\x23\x29\x4a\xc9\xa3\xd3\x51\x5d\xa0\x89\x53\x02\x21\x19\x5d\x42\x63\xf8\x4e\x13\xcd\x08\x13\x6c\x1d\x57\xee\xd3\x75\xfe\x18\x7d\xb4\xa1\x11\x0b\xda\xe0\x13\x9a\x78\x0d\xd9\xfb\x6a\x0d\xb1\xeb\xfd\xa2\x6e\x7e\xa3\x7a\x09\x70\x74\x03\xd5\xc3\xc1\x91\x4c\xcf\x86\x0d\x48\x9b\x79\x8b\xc7\x39\xde\x9a\x09\x6e\x32\x49\x56\x54\x6a\x55\xc4\x96\xf4\xaf\x28\x3b\xed\xbd\xa0\x2c\x62\x11\x34\xfc\x2b\x91\x52\xfb\xcc\xd5\xb8\xc8\xa9\x52\x2d\x96\x57\x60\x04\x9a\x30\x61\x86\x32\xa1\xd6\xf9\x04\xf9\xa7\x97\x74\x1d\x48\x50\x10\xd1\xe8\x92\xca\x05\x2b\xc3\x9e\x11\xca\xb7\xf7\xc1\x94\x66\xe3\xe8\x24\xaa\xe3\xb8\xdd\xf4\x3c\xae\x13\x68\x8d\x33\x5e\x8e\x85\x1c\x9b\x2a\x5f\x48\x29\xab\x2e\x1f\x57\x99\x15\x4c\x54\xe5\x8c\x25\x82\xb7\x23\x1a\xb0\xdc\xd1\x5c\x3d\x03\x60\x1e\xe8\x6d\x3c\xb7\x62\x44\x33\x09\xa1\x55\xcc\x6a\x19\xc3\x7a\x18\xfd\x34\x2a\xf7\x37\xb7\x87\x4c\x36\x01\x18\x73\x78\x26\x7f\x46\xb6\xcf\x17\xae\xa5\xd8\xf2\x60\xb5\xdb\xaa\x1c\x5e\xe9\xc2\x79\xae\xc2\xa5\x71\x30\xc2\xa9\x30\x3a\xfb\xaf\x4a\x5a\x56\x7b\xab\xc1\x9b\x1b\x64\x96\x33\x03\x29\x43\x99\x7e\x06\xf5\x9a\x46\xbe\x7d\xfc\xbf\xc9\x29\x02\xe5\x6c\xb0\xe2\x84\x60\x45\xbd\x3f\x4b\x49\x33\xa3\x40\xd2\xa4\xac\x00\x9b\x4c\x4b\x0c\x6c\xc4\x04\x38\xdf\xb5\x75\xa3\x55\x65\x0c\xa9\x89\x09\x93\xa5\xba\xa1\xaa\xfc\x69\x95\xd2\x0e\xf4\xd2\x4e\xc0\xa2\x2a\x61\xc3\x18\xc1\x7a\xc3\x59\xaa\x39\x3c\x0e\x81\xa1\x47\x36\x9a\xf5\x56\x86\xe2\x50\x4f\x7e\xbd\x81\x74\xf5\xb1\xfe\x54\x7b\xab\xa7\x42\x8f\xc9\x79\x2b\x03\xf2\x43\x35\xfa\x5a\xab\x8f\x13\x09\xd4\x08\x67\xcf\x6d\x1a\xf7\xe1\x2d\xce\x19\xe5\xed\xe1\xf2\x3b\x2b\x0a\xca\x0d\x5f\x43\xf8\x01\xb2\x59\x66\x5a\x64\x35\x28\x2f\x45\xac\x08\x95\xb2\x9c\x75\x80\xbd\x0e\x0c\x25\xc5\x2f\x5c\xe2\x07\xa2\xc2\x9c\xbe\xfa\x75\x9c\x41\x1f\x85\x70\x04\x4f\xd4\xc2\x32\x4a\x0f\x4e\x6b\xda\xed\x15\x88\x2f\x8f\xb9\x48\x9e\x4c\x42\x30\xc0\xf3\x67\xbf\x33\x69\xe3\xce\xeb\xcb\xc0\xf0\x86\xaa\x85\xbd\x7d\xd3\x8e\x9b\xbd\x8e\x08\xa8\x68\xda\x7a\x00\x1d\x7d\x21\x6b\xcb\x62\xc5\x11\x3d\xf7\x36\xa1\xab\x56\x51\x81\x78\x7d\xcf\x73\xb0\xaf\xb3\x98\xdc\x21\x90\xaf\x10\x55\x46\x5a\x20\xba\xe5\xd3\x7f\xbb\x91\x20\x47\x0d\x47\x0d\xe1\x51\x4c\x09\x18\x3e\x9e\x04\x53\xcd\x04\x91\x2b\xb1\x96\xaf\x1e\x84\x0a\x89\x17\xd2\x5d\x93\x63\xa8\x1d\x35\xb8\xf0\xe8\xde\xbe\x4e\x18\x40\xfd\x1b\xe2\xc3\x8b\x4d\x94\x3a\xc8\xcb\xc4\x87\x24\xb4\xf4\x93\x87\x38\xb5\x03\x41\x9e\xc6\x13\x3f\x17\xb2\x53\x81\x39\x5e\xe3\xc3\x78\xa6\x5e\x42\x5a\xfa\xec\x8e\x5d\xdb\x07\xef\x68\xee\xe5\xaa\x9c\x11\x4a\x96\x99\x2a\x85\x44\xd7\x1a\x5c\x26\x26\x29\x5c\x76\xda\x1e\x03\x76\x9c\x68\xb8\x0b\xd7\x04\x42\x57\x2b\x46\xdd\x3d\x43\x78\x36\xc1\x45\x41\x92\x25\x42\xa6\xad\x0d\xb3\xda\x7d\xab\x2c\xd5\xfa\xf9\x23\x60\x33\x73\xaa\xca\x07\xd7\x06\x2d\x20\x44\x72\x63\x5f\xfc\xc1\x2e\xd6\xbd\xb1\xe9\x5c\x04\xaf\x5f\x0a\x42\xb9\xb1\x6a\x1c\x26\x83\xf7\x0b\x19\x75\xdf\x8c\x34\xf7\xa2\x7e\x6d\x9c\xe4\xd6\xe8\xe2\xdb\xb4\xbc\x60\x4a\x05\x81\x46\x3b\x41\x1a\x90\xd3\x97\xb8\x9c\xbe\x58\xdd\x1e\xf6\x46\x40\x30\xe1\x98\x36\xeb\xd6\xb6\x7b\xa9\x11\x10\x13\x8c\x41\xc1\x6d\xab\x83\xa6\x6c\xb5\xa4\x2a\xb6\x33\x6e\x17\xb9\x10\xdf\xe8\xed\x10\xd9\x1a\xc9\xa8\x0a\x41\x25\x77\xc6\xf6\x51\x66\x6c\x4e\x2e\x68\xc1\xf2\x0b\xaa\x8e\x39\xb8\xc0\x01\x26\x84\x4d\x16\x13\x72\x32\x6d\x78\x5b\xef\x44\x79\x1b\xba\x73\xa1\x27\x3b\x40\xcc\x8e\x7e\xd5\xbd\x7c\xb0\x92\xd0\xbf\x73\x0f\xdc\xb3\x07\xb7\x30\xb0\x43\xdf\xc5\xde\x0c\xe3\x7d\xbb\xf6\xa3\xbf\x13\x2b\x09\x16\xbf\xe4\xa5\x3b\xb2\x07\xcc\xd8\xb5\x0b\xdf\xf3\xfe\xeb\xe9\x92\x23\x31\x6b\x35\x99\xec\xf5\xee\xc1\xd3\x5c\xc1\xec\xdf\x0c\xb0\x33\xb7\xfd\x67\x4a\xab\x60\xc7\x14\x5b\xfe\x5a\xb0\x3d\x4e\x60\xe7\xfb\x80\x5c\x3e\x0e\x9f\xc2\x87\x02\xf9\x53\x70\xb4\xe8\x15\xf0\x96\x01\x18\x97\xf6\xab\x68\xeb\x70\x99\x76\xe1\x7f\x73\xbc\xd1\x0c\xcb\x78\xeb\xe3\x03\xdc\x1d\xc7\xd6\xe6\xc2\x46\x00\x7c\x30\xc2\x99\xd2\x9b\xe2\x63\xe0\xf3\x91\x0a\x55\x9c\x32\xd5\xaf\xe8\xf6\x2a\xb1\xa4\x7f\x6a\x6d\xa1\xd0\x04\x9b\x5f\xac\xce\x16\xa1\x13\x0f\x50\xd6\xfa\x35\x9e\x01\xc4\x7a\xc5\xbf\x81\xf4\xda\x0d\xb8\xbb\xbf\x9d\xcc\xbe\xba\xca\x14\x98\xb4\x71\x0c\x27\x9a\x03\x27\x90\xef\xd9\xf0\x6e\x64\x4f\xbe\xfd\x76\xba\xcb\x03\x21\xdc\xd0\x5f\xe1\xc7\xea\x56\x55\x65\xc7\x1b\xf3\xde\x0c\x1a\xd1\xf4\xde\x41\x3a\x90\xde\x05\xf4\xba\x89\x0a\xcc\xaf\x6f\xd5\xfd\xf5\xeb\x2d\x26\x21\x53\x70\x8d\xbd\x52\x66\x16\xc5\xe4\x9a\xa5\x9e\xa7\x0e\xf3\xae\xfb\xcf\x1a\x7e\xdb\x9a\x3e\x0e\x3b\xf9\xe3\xcf\xef\xfe\x1f\x00\x00\xff\xff\x1b\xfd\x79\x5c\xe0\xce\x07\x00") +var _operatorsCoreosCom_clusterserviceversionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\x7b\x73\xe3\x36\xb6\x28\x8a\xff\x3f\x9f\x02\xe5\xc9\x3e\xb6\x67\x24\xb9\x7b\x5e\xbf\x99\xfe\xcd\xdd\x29\x6f\xdb\x49\x7c\xd3\xed\x56\xb5\x9d\xe4\x4c\x25\xd9\x19\x88\x5c\x92\xb0\x4d\x02\x1c\x00\x94\xad\x39\x39\xdf\xfd\x16\x16\x1e\x24\xf5\xb0\x25\x91\xdd\x96\xdd\x40\xaa\xd2\x96\x44\x82\xe0\xc2\xc2\x7a\x3f\x68\xc1\xbe\x07\xa9\x98\xe0\x6f\x08\x2d\x18\xdc\x6b\xe0\xe6\x93\x1a\xdc\xfe\x55\x0d\x98\x38\x99\xbd\xfe\xcd\x2d\xe3\xe9\x1b\x72\x56\x2a\x2d\xf2\x0f\xa0\x44\x29\x13\x38\x87\x31\xe3\x4c\x33\xc1\x7f\x93\x83\xa6\x29\xd5\xf4\xcd\x6f\x08\xa1\x9c\x0b\x4d\xcd\xd7\xca\x7c\x24\x24\x11\x5c\x4b\x91\x65\x20\xfb\x13\xe0\x83\xdb\x72\x04\xa3\x92\x65\x29\x48\x9c\xdc\x3f\x7a\xf6\x6a\xf0\xb7\xc1\xab\xdf\x10\x92\x48\xc0\xdb\x6f\x58\x0e\x4a\xd3\xbc\x78\x43\x78\x99\x65\xbf\x21\x84\xd3\x1c\xde\x90\x24\x2b\x95\x06\xa9\x40\xce\x58\x02\xee\x7e\x35\x10\x05\x48\xaa\x85\x54\x83\x44\x48\x10\xe6\x9f\xfc\x37\xaa\x80\xc4\xac\x62\x22\x45\x59\xbc\x21\x2b\xaf\xb1\xf3\xfa\xc5\x52\x0d\x13\x21\x99\xff\x4c\x48\x9f\x88\x2c\xc7\xbf\x1d\x10\xec\xe3\xaf\xed\xe3\x1d\xe4\xf0\xf7\x8c\x29\xfd\xed\xfa\x6b\xde\x32\xa5\xf1\xba\x22\x2b\x25\xcd\xd6\xbd\x08\x5e\xa2\xa6\x42\xea\xab\x6a\x59\x66\x19\x89\x9a\xd5\xff\x76\x17\x32\x3e\x29\x33\x2a\xd7\xcc\xf6\x1b\x42\x54\x22\x0a\x78\x43\x70\xb2\x82\x26\x90\xfe\x86\x10\xff\x2c\x3b\x79\x9f\xd0\x34\xc5\x8d\xa4\xd9\x50\x32\xae\x41\x9e\x89\xac\xcc\x79\x78\xb8\xb9\x26\x05\x95\x48\x56\x68\xdc\xac\x9b\x29\x20\xd4\x88\x18\x13\x3d\x05\x72\x76\xfd\x7d\xb8\x94\x90\xff\x51\x82\x0f\xa9\x9e\xbe\x21\x03\xb3\x01\x83\x94\xa9\x22\xa3\x73\xb3\x84\xda\x55\x76\x37\xcf\xed\x6f\xb5\xef\xf5\xdc\xac\x57\x69\xc9\xf8\xe4\xa1\xe7\xbb\x97\xd8\x6c\x09\xb3\xda\x3e\xd5\x1f\xff\xfd\xd2\xf7\x9b\x3e\xde\xbf\x3e\x35\x4f\x26\x7a\x4a\x35\xd1\x53\xa6\x88\xe0\x40\x24\x14\x19\x4d\x40\x3d\xb0\xa0\x15\x97\xd8\x15\x7d\x58\xfe\x61\xcd\x92\xea\x53\x6a\xaa\x4b\x35\x28\xa6\x54\x2d\x83\x78\xb8\xf0\xed\x8a\xe9\xec\x85\xb3\xd7\x34\x2b\xa6\xf4\xb5\xfb\x52\x25\x53\xc8\x69\x85\x03\xa2\x00\x7e\x3a\xbc\xfc\xfe\x8f\xd7\x0b\x3f\x90\x26\x74\x56\x62\x3f\x61\xca\x80\x0a\x29\x08\xf1\x24\x04\xf7\x6e\x5e\x00\xf9\xe7\xca\x7b\xae\x0b\x48\xfe\x39\x58\x5a\xb9\x18\xfd\x0f\x24\xba\xf6\xb5\x84\x7f\x95\x4c\x42\x5a\x5f\x91\x01\x90\x27\x4b\x0b\x5f\x1b\xf8\xd7\xbe\x2a\xa4\x21\x0b\xba\x76\xe4\xed\xa8\xd1\xc5\xc6\xf7\x0b\x6f\x7b\x68\x40\xe2\xde\x31\x35\x24\x11\x14\xe2\xa3\xc3\x38\x48\x1d\x1c\x2d\x9e\x32\x65\x90\x43\x82\x02\x6e\x89\x24\xa2\x10\x77\xef\x34\x20\x06\x00\x20\x95\x21\x00\x65\x96\x1a\xda\x39\x03\xa9\x89\x84\x44\x4c\x38\xfb\x77\x98\x4d\x11\x2d\xf0\x31\x19\xd5\xa0\x34\xc1\x53\xcb\x69\x46\x66\x34\x2b\xa1\x47\x28\x4f\x49\x4e\xe7\x44\x82\x99\x97\x94\xbc\x36\x03\x5e\xa2\x06\xe4\x9d\x90\x40\x18\x1f\x8b\x37\x64\xaa\x75\xa1\xde\x9c\x9c\x4c\x98\xf6\x54\x3f\x11\x79\x5e\x72\xa6\xe7\x27\x48\xc0\xd9\xa8\x34\x84\xf3\x24\x85\x19\x64\x27\x8a\x4d\xfa\x54\x26\x53\xa6\x21\xd1\xa5\x84\x13\x5a\xb0\x3e\x2e\x96\x23\xe5\x1f\xe4\xe9\x6f\xa5\xdb\x64\x75\xb8\x00\xbe\x95\xe8\x4c\x3c\x81\x7d\x10\xd6\x86\xbc\x5a\x4c\xb2\xb7\xdb\x77\xa9\x40\x6a\xbe\x32\x50\xf9\x70\x71\x7d\x43\xfc\x02\xdc\xb9\x44\x08\x57\x97\xaa\x0a\xd8\x06\x50\x8c\x8f\x41\xda\x2b\xc7\x52\xe4\x38\x0b\xf0\xb4\x10\x8c\x6b\xfc\x90\x64\x0c\xb8\x26\xaa\x1c\xe5\x4c\x2b\xc4\x39\x50\xda\xec\xc3\x80\x9c\x21\xd3\x23\x23\x20\x65\x91\x52\x0d\xe9\x80\x5c\x72\x72\x46\x73\xc8\xce\xa8\x82\x8f\x0e\x6a\x03\x51\xd5\x37\xe0\xdb\x1c\xd8\x75\x9e\xbd\x7c\xc3\xd2\x19\x23\xc4\xf3\xd2\xb5\xbb\xb3\xf6\x0c\x93\x14\x92\x8c\x4a\x2b\x14\x10\x0d\x59\x46\xde\xbf\x7d\x47\xa6\xe2\xce\x60\x31\xe3\x4a\xd3\x2c\xc3\x53\xe0\xf8\xb3\x25\xa7\x09\xe5\x24\xa7\x9c\x4e\x80\xd0\xa2\x50\x64\x2c\x24\xa1\x64\xc2\x66\xc0\xfd\xe9\x1a\x6c\xba\xf8\x75\x44\x82\x58\xe2\xbe\x92\x41\xf9\x5f\xdd\x02\x17\x7e\x59\x47\x36\xcc\x58\x92\x81\x1e\x80\xda\x69\x75\x2d\x62\x36\x27\x25\x57\x5a\x96\xb8\xd9\x29\xb9\x85\xb9\x43\xf2\x9c\x16\x44\x69\x61\xbe\xbc\x63\x7a\x4a\x68\x1d\xc1\xa9\x46\x2c\x1e\x01\x51\xa0\xc9\x68\x4e\x8c\x18\x87\x04\x41\x0b\x91\x21\xb5\xc0\x7b\x91\x30\x48\xd0\x92\xc1\x0c\x08\x95\x23\xa6\x25\x95\xf3\x80\x0d\x8b\x00\x7d\x04\xa8\xf8\xb2\x35\xe1\x61\x3d\x48\xc8\x43\xb8\x48\x2c\xb9\x75\xb2\x4b\x1a\x04\xcb\x0d\xa0\x37\xbc\x74\xf8\x56\x89\xa3\xca\xe1\x1b\x28\x62\xf0\xca\xc9\x07\x41\xae\xc5\x27\x39\xc4\x4a\x89\x90\x01\x33\x0c\xd8\xea\x48\x38\x02\x43\x4e\x24\xe5\xe6\x87\x95\xc8\xbd\x03\xb4\x1e\x42\x1b\x33\xc4\x1d\x5f\x85\xa3\xf5\xb9\xa9\x94\x0d\x81\xa9\x3e\x98\x86\x7c\xcd\xcc\x0f\xc2\x2e\x7c\x6d\x16\x38\x63\x29\x18\x20\x6a\xca\x2c\xea\x98\xd3\x4a\x47\xa2\xd4\x16\x76\xee\x92\x94\xcc\x18\x25\x74\x32\x91\x30\x41\x04\x5e\xfb\xd8\x47\x60\x62\xc7\xfa\x03\x5a\x8d\xbe\x95\xe4\x1f\xbc\xc2\x90\xc1\x07\x2f\xe0\xab\x8e\x79\xfd\x82\x65\x61\xb1\x39\x1e\xdb\x43\x3b\x68\x62\x60\xe2\x41\x2b\xe4\x83\x17\x6f\xb2\xb7\x76\x3c\xb2\xc3\x76\x34\xf7\x79\x61\x21\xee\xd7\x91\x39\x1f\x15\x69\x36\xe4\x00\x2f\xac\x88\xef\x08\x48\x01\x72\x2c\x64\x6e\x0e\x0a\x27\x94\x24\x56\x7e\x0b\x84\x07\x49\x23\x4f\x1e\x02\x27\xd9\x74\xff\xed\xd8\x04\x0b\xec\xe8\x93\x82\xea\xe9\x23\x97\x6d\xb6\x55\x76\xd4\x81\xf6\xe8\xc5\x8f\x50\xb3\xa5\xb9\x2b\x0e\xd3\xf9\xdc\x06\x0c\x9d\x4f\x8a\x3c\x67\x93\x59\x1b\xa8\xf6\x81\xde\xbd\x03\xa5\x0c\xcb\x46\x29\x4d\xd2\x3b\x02\x3c\x11\x86\x58\xfc\xbf\xd7\xef\xaf\xec\xb4\x03\x72\xa9\x09\xcb\x8b\x0c\x72\x23\x88\x91\x77\x54\xaa\x29\xcd\x40\x22\x77\xfa\x8e\xe7\x8d\xcf\x0e\x13\x4b\x05\xa9\xa1\x45\x29\x64\x74\x6e\x27\x4b\x21\x11\xa9\xa1\xd1\x42\x92\xc2\x08\xb8\x79\x51\x6a\x20\xd4\xfe\x8a\xcf\x65\x7c\xb2\x8a\x48\xb7\x02\x0d\x31\x92\x48\x4e\xf5\x1b\x32\x9a\xeb\xc7\x50\x9f\x90\xfb\x7e\xba\x29\x0d\xa8\x2f\xe6\x71\x4a\x60\xc7\x46\xf4\xa0\x3e\xf1\xa3\x6f\x69\x84\x50\xca\x38\xc8\xa1\x90\x7a\x13\xa2\x65\x94\x8f\x09\xc8\x07\xaf\xf4\x20\x63\x5c\xff\xf1\x0f\x0f\x5c\x99\x42\x91\x89\xb9\xc1\x8b\xc7\xcf\xca\x86\xef\xb3\xf1\xb9\xde\x74\xbe\x4d\xcf\xf2\x86\xf3\x59\xe3\x54\x17\x33\xad\x52\xa0\x76\x9a\x88\x77\xf5\x6e\x41\x09\x7c\x32\xe6\x37\xbc\xf4\xd6\x86\x0f\x30\x06\x09\x3c\x71\xb4\xe9\xdb\x72\x04\x92\x83\x06\x55\x13\xa4\xe7\x85\xa3\x34\x46\x16\x5c\x64\x77\x4f\xc3\xe5\x1e\x91\x67\xfc\x65\x8f\x48\x35\xfe\xb2\xc7\x64\x1b\x3b\xb6\x61\x9b\x8f\x23\x9d\x1d\x5b\xd1\xd8\xc7\x11\x70\x87\x49\x67\xab\xcd\x39\x2d\xe6\x35\x3a\xf1\x1e\x48\x78\xd7\x8d\x65\x34\xe4\xbb\x31\x83\x2c\x25\xcc\x08\x6f\x66\xb1\x64\x94\x89\xe4\xd6\xd9\x2d\x3f\x9c\x13\x25\xac\xb8\x67\x24\x7c\xc3\x68\x13\xc1\x55\x99\x03\x61\x8f\x61\x70\x14\xe9\xa2\x48\x17\x45\xba\xe7\x22\xd2\x59\xff\xc0\x3e\x50\xaa\x85\x85\xac\xa5\x55\x78\x5d\xa4\x56\x0f\x8d\x48\xad\x70\x44\x6a\xf5\xc8\x78\x76\xd4\x6a\x23\x39\xed\xd1\xb9\x1e\x3b\xc8\xd1\x98\x1a\x8d\xa9\xd1\x98\xea\x46\xe4\x65\x6e\x44\x5e\x16\x79\x59\x34\xa6\x3e\x34\x65\x34\xa6\x6e\x39\x51\x34\xa6\x46\x63\x6a\x34\xa6\x46\x63\xea\x63\x2f\x13\x45\xba\x28\xd2\x45\x91\x6e\xd3\xc5\x44\x63\x6a\x34\xa6\x3e\x34\x22\xb5\xaa\x8d\x48\xad\x1e\x18\x2f\x9b\x5a\xb5\x37\xa6\x26\x19\x50\xbe\x5a\xa9\x5a\x88\xff\xc6\xeb\x50\x34\x62\x63\xe6\xf2\x20\xdc\xdd\x64\x04\x53\x3a\x63\xa2\x94\xe4\x6e\x0a\xdc\xa7\xec\x90\x09\x68\x65\xb0\x00\x34\xac\x12\xcc\x1f\xa1\x35\x0f\xd3\x97\x3e\x01\x4e\x47\xd9\xca\x89\x1f\x23\x25\xee\xce\x87\x8d\xc7\x23\x21\xcc\xdb\x2d\x43\x0c\x55\x1d\xaf\xe9\x6c\x13\xcf\x7c\xb0\x2e\xc7\x6e\x75\x50\xf3\xd9\x87\xf3\xae\x42\x99\xc9\x4f\x9c\x5c\x86\x59\x09\x5a\xa6\x31\x51\xc2\xf0\x10\xf3\xed\xfb\x3b\x0e\x29\x26\xb9\xf5\x08\xd3\xe6\x02\x73\xe8\x59\xc2\x74\x36\x0f\x0f\x1e\x1c\x6c\xbf\x89\x7b\x14\x12\x7d\xf6\xe1\x7c\x73\xf3\xbd\xdf\x80\x4f\x61\xa9\x8f\x76\xf8\x68\x87\x0f\x23\x8a\x41\x3b\x4e\x1a\xc5\xa0\x07\xc6\xcb\x16\x83\xf6\xdd\x6e\x1d\xad\xcd\x24\x5a\x9b\x1f\xbe\x2c\x5a\x9b\xa3\xb5\x39\xda\x6f\xd6\x8c\x28\xb8\xe0\x88\x82\xcb\x23\xe3\xd9\x09\x2e\xd1\xda\x1c\xa9\x55\xa4\x56\x91\x5a\x3d\x0f\x6a\xf5\x1c\x43\x77\xa3\xd1\x2f\x1a\xfd\xa2\xd1\x2f\x72\xa3\xc8\x8d\x1e\x19\xcf\x8e\x1b\x45\xa3\xdf\xb6\x13\x45\xa3\xdf\xca\x11\x8d\x7e\x8f\x8c\x68\xf4\x8b\x46\xbf\x35\x23\x0a\x2e\x3b\x4e\x1a\x05\x97\x07\xc6\xcb\x16\x5c\xa2\xd1\x2f\x52\xab\x48\xad\x22\xb5\x7a\x1e\xd4\xaa\xbd\xd1\xef\x91\x93\xf4\xf0\xbd\x0f\x9f\x94\x07\xef\x65\xc9\x43\x0f\x5c\x07\xd1\x07\x20\xf8\x28\xe1\x7a\x8c\x5c\xf5\xc9\x88\x2a\xf8\xcb\x9f\x96\xea\x96\xd7\x2f\xc9\x21\x65\xd4\x3c\x6a\xe5\x15\x8f\x93\xb0\xea\x11\xeb\xf7\x6c\x83\xbd\x0f\xcb\xd8\x71\x16\x57\x58\xf9\xd1\xa0\x58\xb3\xb5\xe9\xa5\xbd\xf8\x5a\x4b\xaa\x61\x32\xaf\x15\xf2\x46\x9b\x6c\xc5\x79\xf8\x9a\x02\xf4\x41\x69\xbc\x9b\x82\x04\xbc\xc9\x97\x9e\x56\x7e\x52\xa6\x42\xf4\x72\xba\x43\x71\xdf\xc7\xc2\x91\xfd\x73\x56\xfc\xfc\xd8\xa6\xad\xaa\xbe\xbd\x12\x58\x1e\x40\xe7\xd6\x7a\x7d\x1e\x52\x80\x17\x21\x56\x50\x69\x28\xa4\xb7\x72\x23\xd3\xae\x5d\xbd\x00\xef\x75\x44\x71\x03\x4e\xfd\x38\x87\xee\xd7\x32\x95\xd7\x59\xd6\x37\x61\xcc\xae\x07\xc6\x10\x64\xce\x94\x5a\x17\x70\xdd\x5c\xfa\x63\x64\x73\x03\x72\xb9\x06\xfe\xfe\x8d\x6a\xcb\x09\xe2\x13\xee\x80\x1c\xd1\x84\xc8\x32\x33\xc2\x14\x4f\x89\x2b\x7f\x4d\x68\x92\x88\x92\x6b\xc2\x01\x52\x6b\xd9\x58\x85\xab\x1b\x10\xdb\x0d\xe4\xa7\x4d\xa5\xa7\xbe\x5d\xe7\xa3\x57\xb9\x77\x38\xb5\xaf\xb0\xb2\xa0\x7a\x7d\x6c\x2e\x6d\xe1\xe3\x1f\xe7\x5a\xdb\xb0\xc2\x8d\x19\x61\x63\x7f\x87\x22\x63\xc9\xfc\x43\x99\x01\x99\x8a\x2c\x55\x58\xd6\xdf\x70\xf7\xe0\x70\xa8\x8b\xc8\x05\x5e\x8d\xab\xef\x91\x51\xa9\x49\x2a\x40\x11\x2e\xb4\x2f\x0c\xd0\xb8\xdd\xba\x98\xee\xa6\xb6\xb5\x83\xb9\x89\xd0\xa2\xc8\x30\x95\x42\x18\xa1\xe5\x6e\xca\x92\xa9\xed\x57\x53\xd0\x04\x56\x5d\xb6\xb9\xf4\xb2\x91\x78\x4d\xb6\x12\xb1\x89\xb7\x59\x8d\x1e\x43\x15\xb2\xa5\xac\x4d\x6c\x89\xf8\xaf\xa5\x28\x8b\x0d\x2f\x5f\xb6\x2c\xda\xbb\x0d\x95\xd7\x0b\x0d\x6c\xfc\x8f\xce\x65\x64\xf7\xc6\x5e\x16\x4c\xa2\x03\x42\x2e\xc7\x24\x2f\x33\xcd\x8a\x0c\x6f\xb1\xd5\x06\x14\xa1\x12\x2a\xbe\xd1\x23\x94\xcf\xbd\x07\xca\xb5\x89\x80\x94\xd0\x89\x99\x51\x63\x7f\x18\x5f\x92\x9e\x97\x39\x98\xd3\x9c\x56\x0f\x41\x75\x8a\xcf\xab\xd9\xc9\x1d\xcb\x32\x23\xcf\xd2\x2c\x13\x77\x90\x0e\xc8\xc1\xc1\x22\x29\x4f\x84\xac\xad\x07\x89\xc9\xc1\xef\x1a\x57\x19\xca\x51\x2d\x78\x13\x1c\x21\x5b\x0b\x96\x64\x3b\xe1\x92\x6c\x2f\x46\x13\xc2\x05\xf7\xe6\xe1\xef\x3e\xbc\xdd\x0d\x11\xae\x9a\x73\xb8\x7e\x22\xa0\xcd\xb6\x14\x54\x6a\x46\x33\x52\xca\x4c\x59\x5c\xa0\x46\x91\x90\xbe\x21\xcb\x94\xa2\x77\x31\x01\x65\x3b\x7f\x90\xdf\xd9\xdd\x77\x9b\x63\xcf\xb8\xe0\xd9\x9c\x50\xbb\x35\xe3\x32\xcb\x7a\x64\xcc\x38\x35\xa4\x1b\x0a\x9f\x4d\x63\x74\x30\x72\xcd\x78\x02\xe6\x9d\xfa\x41\x38\xc1\x15\x99\x19\x0d\x8d\x08\x07\x3d\xed\xb9\xd6\x24\x56\xe3\x56\xee\x11\xe6\xd0\x27\x74\x94\x01\xf6\xc6\x70\x62\xcf\x07\x91\xa1\x89\xdc\x19\xcf\x53\xdb\xcf\x84\xd6\x7f\xfe\x2f\xc6\x51\xd1\x21\x1f\x90\xf9\x18\x85\x09\x98\x9e\x1a\xfd\xa9\x28\xb2\xb9\x21\x36\x06\x59\x2a\xa4\x3c\x52\x65\x32\x35\xaf\x74\x50\x88\x54\x1d\x18\x52\x74\xa0\x20\x91\xa0\xd5\xc1\xb1\xf9\xb4\xf8\x0e\xf8\x7e\xf5\xfb\x4e\x68\xc1\x0e\x8e\x7b\x04\x01\x84\xcd\x52\x84\x9e\x3e\x5f\x3c\xf4\xef\xda\xe8\xd1\xf5\xd8\x68\x6a\xbe\xf5\x19\x5c\xe7\x0f\x51\xd8\x46\x1a\x86\xce\x6b\xc0\x5c\x2b\x83\x94\x88\x06\xbe\xc5\xd4\x32\xc1\x27\xe4\x94\x13\xc8\x0b\x3d\x47\x2c\xce\x81\x72\x77\x35\xcc\x40\xce\xf5\xd4\x68\xbc\x4c\x05\x02\xf2\xec\x81\xde\x0e\xe0\xee\xc0\x7b\xe0\x56\x48\x6e\xbb\x33\x2d\x02\xf7\xf0\x77\x87\x8b\x84\xb4\xe2\x08\xcf\x16\x94\xc8\xa2\x77\x02\xe3\xf7\xe6\xce\x26\x08\xed\x57\x96\x5a\x06\xfa\xf1\xf6\xad\xed\xc4\xe4\x60\xf5\x2d\xe3\xa9\x0a\xd5\x90\x52\x4b\x06\x1d\xbc\x57\x02\x19\x57\xf8\x1c\x01\xbc\x2c\x02\x6f\x2a\xb6\x3e\x32\x7d\x4d\x47\xda\x07\xb5\x06\x3b\x3b\x35\x24\x25\x43\xa7\x7a\xd6\x6d\x65\x44\x90\x8c\x8e\x20\xb3\x6d\x9b\xcc\xaf\xd5\xf2\xc9\xe9\xdb\x77\xa1\xc3\x99\x04\xfa\x88\x4d\xec\x23\x28\x33\x1b\x38\x5f\x97\xfa\xc4\x2d\x8f\xcd\xe5\x57\x04\xc5\x76\x06\x65\x72\x0d\xda\x1e\xb3\x9c\x16\xe6\x94\xd9\x39\x56\xda\x43\xdf\x22\xa4\x1f\x3f\x2c\x5b\xc9\xfd\x9b\xf7\x75\x5a\xf5\x90\x8d\x8e\xca\x66\x5e\xe3\x6d\xce\xde\x03\x56\x92\x6a\x34\xc0\xbc\x80\xd0\x4e\x37\x70\xd2\x7c\x12\x7a\xf4\x59\x0c\x56\x36\xb9\xda\xa6\xb2\x4b\xff\x7d\x35\x45\xc7\x5b\xb0\x8d\xe2\x65\x74\xef\x0c\x12\x2d\x1e\x2e\x1d\xe7\x2f\xd6\x90\x17\xd9\x63\x27\x8f\x6c\xad\xa4\xe5\x8c\x7f\x00\x9a\xce\xaf\x21\x11\x3c\xdd\x90\xc0\x36\xf6\xe3\x1d\xe3\x2c\x2f\x73\xc2\xcb\x7c\x04\x08\x62\x65\xe7\x42\x42\x62\x15\x60\x4a\x38\xdc\x65\x73\x47\x3c\x52\x52\x88\xd4\xd3\x93\x91\x51\xd8\x68\x3a\xc7\x1e\x69\x58\x64\x95\xcf\xcd\x24\x4c\x57\xdc\x47\x92\x44\x52\x65\xc4\xa2\x1e\x4e\xca\xb4\xe1\x58\x23\x40\xff\x14\x4b\xc1\xec\x31\x9d\x51\x96\x19\xd1\x7a\x40\xce\x61\x4c\xcb\x0c\x5b\xfd\x91\x57\xe4\xc8\x3c\xcc\xeb\x64\xab\x6e\x30\xe2\xae\x12\x46\x9b\x57\x2e\x4f\x1e\x17\x74\xbc\x85\xc5\x7d\x93\x1a\x80\x7e\x6c\x5a\x0b\xd0\x8f\x82\x96\x6a\x53\x55\xbe\xb1\x31\x97\x3c\x35\xe7\xa1\x2e\x89\xd6\x48\x3a\x53\x6e\xe6\xcd\x58\xf6\xc3\xf5\x13\x56\xac\x5a\x8a\x89\x04\xa5\xce\x81\xa6\x19\xe3\xb0\x3b\x7e\xdd\x4c\x81\xe4\xf4\x1e\x71\x4c\xb3\x1c\x8c\x24\x52\xc7\x30\x5a\x7f\x2b\x2d\x48\x4e\x6f\x21\x3c\x9e\x8c\x60\x8c\xad\x1c\xf1\x85\x6b\xbb\x6f\xf1\x67\x4c\x59\x66\x34\xf4\x9b\x26\x6c\xaa\x0e\xc8\x16\x71\xcc\x67\xc6\x4b\x30\x77\x15\x52\xa0\x32\x69\x6f\xad\xf3\x78\xe4\xa1\xd4\x5c\x6c\xe9\xb0\xef\xfa\x37\x5c\x00\xc5\xc5\x7d\x62\x0d\x85\x12\xa8\xc2\xcb\x2c\x6e\xaa\x52\x8e\x8d\xea\xe8\x35\xce\xda\x82\x5c\xbb\x58\x72\x25\xb4\x6b\x1e\x18\x5e\x10\xef\x76\xcd\x2c\x41\x69\x96\xe3\x01\x4b\x4b\xe9\x5b\x6b\x22\xcc\xe8\xea\xad\x6f\x1c\x95\xbf\xbc\x7a\xb5\xa1\xfc\xf6\xf1\x91\x5e\x02\x6a\xca\xbb\xe0\xcb\x55\xa0\x43\x9e\xfc\x1b\x15\xd8\xec\x31\x73\x62\x30\xf6\x08\x05\x89\xbe\x46\xa6\x34\xe3\x93\x92\xa9\x29\x19\x81\xbe\x03\xe0\x04\xee\x6d\x95\x0c\xf2\x6f\x90\x02\x37\xd5\x80\xb7\x72\x33\x34\x80\xf6\x7a\x7f\x20\x36\x63\x8a\x09\xfe\x0d\x53\x5a\xc8\xf9\x5b\x96\xb3\x47\xca\x97\xfa\xb1\xdc\x29\x39\x40\x50\x64\x29\xf6\x37\x66\x09\xbd\x06\xfb\xc2\x12\xd0\x0a\xaa\x85\x55\x4f\x89\x39\x27\x23\x9a\xdc\x7e\x34\x00\xbf\xda\x17\x08\x7b\x76\xbd\x03\x54\x51\xde\x0b\x13\x20\xd9\xb2\x48\x79\x71\x6f\xe1\xd3\x80\xf2\xdd\x54\x28\xc0\x0b\xac\xa1\x12\x6f\xf3\x8e\x05\xa6\x02\xc1\x30\xa7\x5b\x70\x50\x84\x8e\xc7\xcd\x2b\xaa\xc3\x8e\x92\x67\x5e\x2a\x4d\x72\xaa\x93\xa9\x35\x65\x89\x34\x88\x13\x87\xca\x89\xfd\xdb\x40\x79\x63\x43\xf4\xf6\x26\x63\x62\xd7\x79\x71\x6f\x74\xcb\x47\x3d\x42\xcd\xd1\x00\xf9\xe2\x34\x4d\x0d\x38\x6b\x6e\x88\x93\xdb\x72\xdb\x66\xf8\x06\x8d\xc8\xd5\x37\xb8\x0b\xa7\x57\xe7\x9b\x9b\x62\x76\x51\x70\xb7\x56\x71\x17\xcd\xe5\x0f\xbc\x94\x37\x99\xba\x5f\x9a\x36\x73\xdb\x5e\xba\x47\x28\xb9\x85\xb9\xed\x44\xbd\xd4\xda\x57\x42\xe6\x24\x09\xc0\x0e\xb7\xe6\x22\xd7\x96\x7a\x8b\xf5\x6e\x8d\x3d\x76\x6c\xe7\xce\xf0\xa3\x6f\x16\xba\xe5\x1d\xfe\xa5\xb7\xb8\x6d\x7b\x04\xb7\xe3\x16\xe6\xdb\xdd\xb0\xb0\xdd\x66\x17\x9c\xee\x63\xf7\xdd\x7c\x11\x04\xbd\xb0\xd5\xdb\xf9\x99\xea\x63\x6b\x13\x95\x1f\x1e\x88\xad\x5e\x2f\xa0\x5f\xdd\xca\x64\xde\xf1\x50\x59\x64\x34\x67\x7a\xca\x0a\x64\x44\xde\x19\xe0\x1b\xa5\x7f\x4f\x33\x96\x86\x29\xec\xf9\xbd\xe4\x3d\x23\x3e\x99\x7f\x90\xe8\x5a\x71\xed\x5c\x80\xba\x12\x1a\xbf\xf9\x64\x00\xb2\xcb\x6c\x05\x1e\x3b\x85\xb3\x42\x23\x95\x41\xc5\xab\xd6\x63\x5d\x0d\x7c\x75\xb0\x00\x4a\xa6\xc8\x25\x27\x42\x7a\x38\x60\xd7\x7b\x3b\x91\x9d\x02\xf9\xc4\xc8\x3a\x38\xd0\x3e\xbd\x72\x0e\x07\x3e\x21\x1b\xd0\x7b\x60\x3a\x37\x15\xca\x07\xf6\x17\xdb\x55\x3f\x43\x69\xd7\x89\xaa\xd4\x3b\xca\x59\x42\x72\x90\x13\xf4\xb8\x24\x1b\x7b\x1c\x9a\x9b\xb2\x1d\xdd\xb5\x63\x6b\xea\x5b\x7f\xe0\x56\x58\x80\xac\xc9\x9a\x80\xda\x30\x37\x3b\x43\xc3\xe4\xf4\x7f\x0c\x05\xc7\x3d\xf8\xbf\xa4\xa0\x4c\xaa\x01\x39\x25\x8a\xf1\x49\x06\x8d\xdf\x9c\x86\x51\x9f\xc6\xcc\xc0\x14\x31\xa4\x76\x46\x33\xa7\x4b\x51\x4e\xc0\xda\xac\xcc\xec\x8b\x2c\xb5\xe7\x24\x15\x43\x79\x82\xa3\xeb\xe0\x16\xe6\x07\xbd\x25\xa4\x39\xb8\xe4\x07\x96\xb7\x2c\xa1\x49\x60\x44\xe8\x23\x3b\xc0\xdf\x0e\xba\xe4\xc2\x5b\x32\x9c\x5d\xed\x68\xcd\x87\x6e\x8c\x11\x3e\x3e\x64\x47\x61\xbd\xa1\x25\xba\xa8\x28\x2d\x48\xa9\xc0\x4a\xeb\x78\xca\x08\x78\x39\x13\xa5\x4a\x54\x4c\x39\xdc\xa1\xf4\xb8\x37\x82\x9f\xd1\x24\x18\x9f\x7c\x57\xa4\x54\x6f\x14\x98\x6a\x47\x03\x22\x87\x1f\xec\x24\xa4\xc4\x59\x0c\x6e\x8d\xd9\x84\x14\x54\xd2\x5c\x0d\xc8\xd0\x55\x48\x44\x4c\x63\xe3\xba\x2d\xd1\xc1\xee\x66\x5e\x00\xf9\x7f\xc8\x87\xfa\x5a\x06\xa4\xdf\xef\x93\x9b\xf7\xe7\xef\xdf\x10\xfb\x8d\x95\xb2\xb5\x20\x63\x81\x4a\x90\x28\xa5\x79\xd4\x0c\x38\x2a\xfe\x46\xbe\x17\x1c\xde\x8f\xcd\x09\xa1\x1a\x66\x20\xc9\x9d\xd9\xaa\x84\xa5\x10\xac\x57\x83\xc3\x8f\x8b\xc7\xbb\x49\x26\x39\xbd\xbf\x2e\xe5\x64\x8b\x0d\x20\x4b\x9b\x50\x37\xd9\x54\xca\x24\xa2\x5e\x3d\xc3\x57\x25\x53\x48\xcb\x0c\x52\x42\x47\x62\x06\x0d\x93\x6d\xf3\x36\x64\xe9\x25\xf8\x1b\x0d\xcf\x1b\x29\x91\x95\x3a\x28\xab\x47\x70\xff\x86\xfc\x19\x5d\xdb\x94\x14\x20\x13\xe0\x9a\x4e\x60\xd1\x0c\x60\xaf\x7b\xfd\xea\x3f\x8e\x1d\x3f\x32\x33\x3a\xeb\xc9\x2b\x83\x11\xef\xe8\xfd\x77\xbc\x32\x0d\x32\x45\x5e\x0d\xc8\xe9\xc2\xc3\xf0\xbe\x2c\x29\x33\xb4\xb5\xa0\xbb\xbe\xf6\xc8\xd1\x9c\x48\x51\xa2\xc3\x9e\x94\x45\x53\x9b\xfd\xc3\x9f\xff\xc3\x28\x7d\x34\x2f\x32\x78\xe3\x0b\xab\x5a\xb5\xd9\xc8\x30\x5a\x90\x3f\xbe\xfa\x0f\x4b\x3d\xcd\xf9\xac\xb4\xc2\x0a\x66\xd4\x00\xac\x2c\x08\xcb\x6d\x38\x27\x64\xf3\xaa\x42\xab\x6c\xa2\xbf\xd2\x54\x6a\xd5\x23\xe8\xd5\x0f\xc2\xa1\x16\x9a\x66\x0b\x5a\x3e\x6a\xe1\x70\x67\x81\x94\x0a\x84\x09\xa0\xa1\x8a\xbc\xfe\xe3\xab\xff\x58\x36\xa7\xbc\xe7\x09\xe0\x9d\x78\x07\x86\x59\x8c\x8c\x72\x7f\xcb\xb2\x0c\xd2\xde\xa3\xcb\x1f\x97\x52\x4f\x41\xf6\x08\x70\xe5\x8d\x55\x66\x7d\x0b\x6b\xc3\xd9\x65\xc9\x39\xca\x08\xd6\x3a\x8c\x16\xad\x9a\x85\xcb\xbd\xac\x61\x84\x9a\xe4\x42\xe9\xd5\x4b\xde\xfc\xb8\x99\x41\xf9\xfc\xfd\x78\x5b\x71\xa0\xbf\x83\x19\x62\xf9\xee\x1d\x44\xca\xfb\xfe\x6d\xc8\xb6\xec\x33\xae\xfb\x42\xf6\xed\x34\x6f\x88\x96\xe5\xe3\x5e\x83\x6a\xe4\x8d\x13\xf0\x09\xc8\x40\x59\x3b\x6f\x4b\xbb\xfa\x51\x4e\xfe\xee\xe7\x39\x15\x77\x7c\x3d\xe5\x40\xc2\xe9\x68\xc6\x8e\xa7\xbe\x69\x71\x5b\x38\x36\xe6\xe9\xe6\xea\xff\xdf\x32\x76\x6f\x41\x0e\xdc\xd9\x0d\xa7\xdd\xc8\x55\xe8\xf1\xe8\x6d\xf0\xf4\x70\x6c\x2d\xe7\xb3\x36\x27\x73\x81\x7d\xcc\x0a\xca\xb5\x74\xc2\x57\x50\x20\xbb\x8e\xca\x21\xa3\x31\xa2\xc0\x9c\x73\xb5\xf6\xa0\x67\x40\x95\x5e\x05\x8a\x78\xd0\x1f\x1f\x0f\x27\x01\x2c\x8e\xa6\xd0\x69\x24\x24\x04\x79\x65\x63\x3c\xb3\x88\x72\xf0\x01\xac\x87\xcf\x06\x9c\x35\x84\xa8\x83\x70\x24\xcc\xfe\x35\xe5\xab\x8f\x15\x36\xe3\x8d\x9c\xbb\x88\xd6\xee\xd6\x5a\x70\xb0\x33\x9d\x3a\xe2\x15\x3c\x8a\xd6\xa5\xb9\x37\x52\x74\x0e\x9a\x3e\x9c\x28\xb2\x38\x9a\x44\xfb\x5a\x53\x9e\x52\x99\xba\x55\x1e\x1e\xaa\x30\xe5\x80\xbc\x43\x5f\x1a\x1f\x8b\x37\x64\xaa\x75\xa1\xde\x9c\x9c\x4c\x98\x1e\xdc\xfe\x55\x0d\x98\x38\x49\x44\x9e\x97\x9c\xe9\xf9\x09\x3a\xd0\xd8\xa8\xd4\x42\xaa\x93\x14\x66\x90\x9d\x28\x36\xe9\x53\x99\x4c\x99\x86\x44\x97\x12\x4e\x68\xc1\xfa\x95\xcc\xac\x06\x79\xfa\x5b\xff\xa0\x8f\x2c\x18\x37\xce\x10\x5a\x97\xe4\x0c\xfa\x25\xbf\xe5\xe2\x8e\xf7\x51\x93\x55\x5b\x9d\xa6\xcd\xa2\x18\xfc\x58\x80\xf7\x36\x81\x0b\x85\x48\x3f\xfa\x26\x98\x97\xe9\x53\x9e\xf6\xad\xd3\xf1\x23\xef\xc5\x2e\xb6\xdd\x7e\x15\x18\xb0\x49\xd4\xba\x1d\xbb\x69\x43\x34\xd1\x6c\x06\x3b\x39\xb1\xfd\x68\x6c\xf7\x7b\x1f\x30\x9a\x96\xd2\xee\x78\xcd\x9b\xed\x7d\x33\x39\x9d\xa3\xac\x83\xcf\x26\xc2\xb2\x72\x2e\x52\x70\x96\xcf\x19\xaa\xf6\xd7\x86\x99\xdf\x18\x51\xd8\xf9\xb8\xd1\xee\x3b\x57\x1a\x72\x4b\x9c\xec\xfd\xd9\x9c\x68\x39\xb7\x8e\x71\x79\x6b\x94\x4f\xe7\xb9\x36\x12\xff\x2d\x5e\xa7\x94\x48\x18\x8a\x3e\x15\x5c\xbd\xdc\xe5\x6d\x78\x94\x14\x42\x31\x7c\xb6\xe3\x79\xdb\x59\xe6\x76\x67\x97\x35\x37\xdd\x5f\xfe\xb4\xcd\xd6\x8d\xb1\x15\xc3\x96\x56\xf6\x66\x04\xc5\xb8\x9e\x25\xe0\xb6\xe7\x50\x79\xc5\xd5\x88\x25\x89\xe0\x4a\x4b\xca\xd6\xe7\x41\xad\x1e\x3b\xba\x42\x76\xf7\x37\x10\xc4\xa0\xd3\x9d\x80\x42\x96\x63\xb0\x3c\x53\x44\xb4\xf4\xa0\xae\x03\xc6\xa6\x49\xf9\x58\x42\x43\xb8\x76\x34\xad\xee\x00\x23\xd2\x0a\x4e\xf6\x6e\x18\x83\x94\x90\x9e\xa3\xf4\x79\x1d\xde\xeb\x72\xc2\x45\xf8\xfa\xe2\x1e\x92\x72\xd3\x6c\xf2\xe5\xb1\x64\xcb\xf3\x06\x11\x17\x76\x62\x17\x61\x8e\xae\xff\xc1\xc9\x1f\x02\xc1\xee\x04\x11\x45\x35\x53\x63\x9b\x73\x16\x36\x02\x6a\x8e\xcf\x80\xc2\xc1\x3d\x8c\x2c\xce\xa6\x3e\x30\x8d\xe4\x26\x99\x0a\xa1\xcc\x29\xc7\xfd\xc4\x79\x67\x4c\x58\x9f\x1f\x26\xc0\x48\x92\x1b\x1a\xe3\x13\x61\xaa\xe9\xad\xa1\xb6\xba\x8d\x29\xab\x82\x07\x08\x7a\x2f\x95\x99\x06\x0d\x8f\xe6\xc3\x04\xa5\x26\xa5\x89\x2a\x73\x33\xe9\x1d\xb0\xc9\x54\xab\x1e\x61\x03\x18\x20\xd6\x00\x4d\xa6\xb5\x69\x73\x00\xdd\xe8\xa4\x52\x47\xb5\xba\x95\xf8\x28\x64\x35\xb8\x54\x9e\x5e\xe0\x31\x8b\x7b\xb9\x12\x5c\x3d\x02\x3a\x19\x1c\xf7\x48\x95\x6c\x6e\xd6\x38\x9a\x13\xa6\xc1\xd0\x6c\xd4\x45\xa4\x28\x27\xf6\x4d\xc0\xc7\x74\xe2\xba\x42\xca\x07\x7a\x51\x53\xd4\x19\x0f\xec\xcb\x1d\x98\x7d\xc3\x95\x97\xb9\xd1\x17\x03\x51\x47\xb3\x3a\x84\xc4\x20\x09\xaa\x10\x56\xdb\x5c\x34\xb8\xff\xff\xc3\x4d\x47\xea\xb8\x02\xe6\x94\x4d\xa6\x1e\x96\xd4\x31\x82\xe6\x1e\x6c\x7f\xf6\x48\x2b\x5f\x8a\x1d\x3b\x7a\x54\xec\x68\xfa\xb6\x7d\xbe\x44\x85\x55\xb5\xfd\xd7\x20\xf3\x00\x45\x44\x11\x24\x19\xce\xce\xed\x9b\xde\x38\x1c\x23\xaf\xc8\x11\x22\x19\xd3\x87\x0a\x11\xbe\x2f\x8a\xe3\x01\x39\x25\xbc\x0c\x67\xee\xa1\x07\x70\x11\xe6\x77\x13\x99\x87\x2a\x51\xcd\xb5\xe3\x1b\xb7\x22\x77\x76\xec\xe6\x29\xaf\x8f\xbe\x83\x00\x3c\x5e\x5a\xf1\xa1\x49\x2c\xac\x77\x9c\xa0\x1d\xe9\xf6\x73\xf8\xb7\xd8\x7d\x8e\xa5\x00\x0b\x3c\xae\x55\x14\x05\xc8\xbc\x57\x97\x9e\xc2\x81\x6c\x9e\x62\x0b\x8b\x5d\xb1\x82\x74\x83\x19\xa4\x23\xb8\x92\x56\x11\x3a\xab\xc7\x62\x18\x8b\xcf\xa2\x6a\x40\xbb\x41\xe4\x47\x73\xfc\x75\xcb\xe0\xa5\xf5\xa3\x2d\xa5\xab\x46\x2b\x9a\x57\x8d\x07\x11\x6f\xff\x02\x7b\x56\x8f\x8e\xd0\xd6\x8e\xf6\xa4\xad\x1a\xdb\x87\x06\xad\x9b\x67\x87\x80\xa1\xd5\xa3\xab\xb3\x69\xc7\x0e\xc1\x45\xab\xc7\x92\x88\xfa\x71\x62\x8d\x56\x8f\x9d\x8d\xa4\xab\xc7\xae\x71\x49\xab\xc7\x42\xaa\xe2\x47\x0a\x52\xea\x35\x23\x94\xc8\xd7\xda\x9e\xe3\xb7\xad\xf8\x49\x35\x3a\x06\xf1\x6e\x91\x4d\xab\xc7\xa2\x00\xf8\x4c\xa2\x9c\x56\x4c\xf5\xb5\x36\xd3\xbc\x5d\x7b\xb3\xcd\x51\xf7\x71\x3a\x4e\xa1\xe8\xb9\xd4\x19\x6f\x67\xc6\x88\xea\x42\x02\x96\x26\xc0\xb0\x2f\x6f\x87\xf9\x34\x81\x55\xab\x47\x77\x8c\xd3\x8e\x8e\xd8\xa7\x1d\x9d\x21\x37\x0a\x3c\x5f\x59\xbb\xf0\x13\xca\x3a\xd6\x32\x1d\x65\x9d\x28\xeb\x6c\x31\xa2\xac\xb3\xe9\x88\xb2\xce\xba\x11\x65\x9d\x15\x23\xca\x3a\x51\xd6\x69\x35\xf6\x4f\xd6\xb1\x96\xaa\xce\x0c\x66\x3f\x58\x83\xeb\xa2\x85\x0c\xa5\x29\x1f\xd2\xd3\x34\x95\x19\xde\x7f\xed\x48\xec\x0d\x9a\xd7\x5c\xa4\xba\xa4\x7c\x02\xe4\x75\xff\xf5\xab\x0d\xd3\x01\x57\x8f\x36\x41\x3b\xf5\xb1\x6d\xea\xe0\xe2\x58\xe7\x91\xf8\x68\xde\x25\x77\x52\x83\xc3\xa3\x21\x61\xae\x71\x10\x85\xaa\x56\x39\x68\x42\x75\xc3\x20\xce\x72\x08\x0e\xd1\x46\x0a\x72\x15\xd3\x2b\xb8\xf3\x77\x98\x4d\x1d\xec\xb6\x82\x04\xa8\x8d\x63\x1f\x41\x58\x85\xc8\xc1\x26\x98\xfa\x43\x6f\x96\x00\x1e\x56\xe4\x08\x06\x93\x01\x49\x6d\xb2\x36\xe5\x2e\x66\xec\xb8\x57\x77\x8f\xe7\x86\xb8\x4a\xfc\xc7\x2c\xdb\xf9\xc7\x61\x06\x5c\x97\x34\xcb\xe6\x04\x66\x2c\xd1\xe1\xfd\x30\x20\x90\x69\xeb\xec\x6c\xe3\x4a\x69\x21\x1e\xb6\x15\x09\xfb\x4b\x67\x6b\x3b\x7f\xb5\x1f\xed\x65\xb7\xa5\x75\xec\x4e\x6f\x16\xe4\x12\x0b\xa1\xc1\x5a\xb5\x4a\x9b\xa7\x59\x7f\x25\xfe\x89\x08\xfe\xfe\xc3\xae\xee\x31\xd2\x11\x4f\x68\xcd\x07\x16\x15\xa8\x32\xcb\x0c\x7a\x5b\x8f\xd9\x32\x08\x56\x78\xb2\x56\x64\xdb\x58\x37\x6b\x5e\xcb\xba\xc1\x6b\x6e\x44\x21\x32\x31\x99\xd7\x77\xd0\x76\x75\xa9\x95\xb7\xa1\x44\x95\x23\x27\x02\x9a\x43\x74\xb5\xb0\xe5\xd1\x17\xb2\x76\x44\x5f\xc8\xd2\x88\xf6\x81\xc5\x11\xed\x03\x5b\x8c\x68\x1f\x58\x31\xa2\x7d\x60\x79\x44\xfb\x40\xb4\x0f\xb4\x19\x2f\xdf\x3e\x40\xa2\x2f\x64\xdd\x88\xb2\x4e\x35\xa2\xac\xb3\xf9\x88\xb2\xce\xf2\x88\xb2\x4e\x94\x75\xa2\xac\x13\x65\x9d\x5d\x47\x0b\xe4\x2e\x44\xda\x79\x8a\x4c\x21\xd2\x07\x32\x64\xac\xbd\x3a\x11\xfd\x4c\x24\xa1\xb2\x88\xb9\xc5\x79\x3e\x14\xcd\xad\x09\xbd\x47\xfe\x2d\x38\xd8\xf4\x04\x5b\xb2\x36\x07\x22\xb0\x09\x44\x21\xd2\x23\x75\xbc\x43\xe0\x79\xcc\xb0\x89\x19\x36\x9f\x41\x86\xcd\x94\x2a\x57\xf8\x08\x49\xeb\xfa\x84\x9b\xda\xf1\xbf\x01\x99\x7f\xb6\xf9\x36\x06\xe1\x1c\xc2\x60\x9f\xb9\x0a\x29\x2c\xec\x52\xe7\xdb\x85\x74\xd8\x84\x98\xd3\xcb\x6c\x8b\x9d\x34\x85\x94\x14\x20\xfb\x16\xc9\x04\x19\x33\x57\xff\x6b\x01\x7f\x1d\x84\x9f\x79\xde\x4c\x13\x12\xcf\x3a\x79\xa6\xf9\x2a\x9d\xf9\xa6\xea\x2e\xba\x06\x57\x7c\x76\xa9\x34\xdd\x68\xa5\x7d\xa2\x9d\x3b\xed\xdb\x56\x7a\x69\x57\x4a\x24\x2a\x79\xd7\x5b\x95\x39\x5e\x3f\x56\x16\xa7\xfd\x57\x09\x72\x4e\xc4\x0c\x64\xa5\x18\x85\xee\x3c\xbd\xd0\x64\x26\xa1\xae\x00\x72\x37\x06\x9e\x4e\x4c\x11\x5d\x6a\xea\x5d\x7b\x0d\xc9\x9e\x55\x3f\x5e\x3f\xba\x55\x1c\x3a\x54\x1b\x9e\x5b\x2d\xe5\xf5\xa3\x53\xf3\x1b\xe9\xd8\x04\x47\x3a\x34\xc3\x91\x6e\x4d\x71\xa4\x73\x73\x1c\xe9\xd2\x24\x47\x3e\x79\x05\xe8\xf5\xa3\x63\xf3\x11\xe9\xdc\x4a\x47\x9e\x61\x3d\xe9\xf5\xe3\x23\x80\xbb\x4b\x8b\x1d\x89\xd5\xa9\x5b\x8f\xae\x0d\x6a\xa4\x6b\xa3\x1a\xe9\x1a\x0f\x77\xaa\x82\xbd\x7e\xc4\xfa\xd8\x1f\x41\x4e\xeb\x4c\x88\x68\x5b\x53\xfb\xb1\x85\x76\x80\x93\xa1\x77\xef\xa7\x52\x80\x2c\x97\xae\x1a\xc6\x9a\x67\xd7\x7a\x75\x61\xa8\x66\xbd\xb1\xa9\x8f\x5b\x45\x8c\xc6\xef\x53\x6f\xf0\x2a\x79\xad\x78\x5c\x6d\xb2\xa5\xd6\x31\x95\xe9\x2c\x34\x8f\x31\x4a\x41\xd5\x74\xaa\x76\x33\x5e\x3b\xb0\xe1\xa4\x95\x34\xc1\xd3\xc5\x00\xd3\xea\x0e\xd4\x2f\x6c\x3b\xdb\x03\x6f\xc7\x3e\x54\xd5\x15\x07\x83\x7a\xe7\x5b\x37\xe3\xd1\xff\xf9\xbf\xc7\x8d\xea\x2d\xd5\x84\x51\xfb\xdb\x78\x44\xed\xaf\xd5\x88\xda\xdf\xda\x11\xb5\xbf\x16\x23\x6a\x7f\x9b\x8d\xa8\xfd\xad\x1f\x51\xfb\x8b\xda\xdf\x0e\x23\x6a\x7f\x51\xfb\xdb\x75\x7c\xc6\xda\x5f\xb7\x51\xcd\x75\x5d\xcc\x05\x89\xa0\xfc\xa8\xa9\x66\x49\x15\xf1\xec\xaf\xb2\x7f\x75\xab\x03\xd6\xf5\xbb\xd5\x1a\x60\x5d\x4b\x5c\xd2\x82\x07\x8f\xa8\x7b\x41\x21\x5c\xba\xf3\x61\x4d\xf0\xa5\x45\x6e\x77\x86\x89\x35\x97\x70\xa7\xa8\x78\xe3\x03\xcb\xaa\xc6\xeb\x21\xea\x2c\x25\x47\xde\x17\x8f\x8d\x54\xb8\xd0\xcd\x1f\xb9\x66\xfd\xea\x8a\xe0\x9d\xc7\xa0\x9a\x46\x3e\x7f\xc3\x85\x1c\x62\xd8\x42\x7c\x54\x85\x3d\x86\x3c\x82\x6c\xac\x01\x1b\xd7\x8e\x19\xb7\x91\x8e\xbe\xe9\x8f\xe0\x3e\x68\xca\xd2\x53\xa4\x80\x1e\xcf\xad\xe8\x8b\xeb\x41\xf9\xb7\x82\x5d\x2d\xca\x87\xe2\x21\xa3\xdc\x25\xc3\x0a\xee\xbb\xd2\xdb\x4e\xf3\x95\xbc\x1c\x7a\xa9\x84\xa7\x0f\xc8\x05\x62\x7d\x7d\x62\xa6\x10\x3e\xd4\xf6\x3f\xe9\x06\x91\xf7\xab\x70\xc3\xdd\xd6\x85\x1b\x16\x22\x46\x62\xdd\x86\x58\xb7\xa1\x55\xdd\x06\xfc\xd1\x1e\xee\xce\x0b\x38\x90\x1f\x5c\x7b\x24\x09\x08\xaa\xbc\xcc\x34\x2b\xaa\x08\x6c\x65\x1f\x95\x59\x4d\x62\xec\x22\x41\x9b\xf8\x6e\x9e\x46\x93\xe9\x22\xde\xe3\x7c\x18\xb1\xad\x90\x9c\xb8\x68\x4b\x6c\x66\x84\x15\x07\xbc\xda\x61\x43\x4a\xd9\xf3\x8f\x14\x3c\x47\x82\xad\x2a\xad\xd9\xf6\xda\x32\x74\x3e\x33\x28\x61\x28\xf6\x03\x0c\xa2\xde\xd0\x02\xa3\x56\xd9\x0c\x78\xc5\x25\x8e\xd4\xf1\xb1\x97\x86\x3a\xe5\x5e\x1f\x85\xfb\xfc\xbd\xc6\x25\xfe\x73\x13\xfe\x83\x2f\x14\x38\x50\x05\xbe\x8a\xff\x3c\xef\x90\xc8\xf6\xd1\x6d\x5d\x58\xe4\x3a\x8b\x6a\x7b\xf2\x88\xb6\xcf\xa9\xf6\xc5\x5e\xfa\x30\xf6\x4e\xeb\x78\x19\x7e\x8b\x98\x30\xba\xf9\x78\x0e\x09\xa3\x4f\xe4\x9b\x78\x3e\x79\xa3\xcf\xd6\x1f\xf1\x5c\xf2\x46\xa3\x0f\x62\xab\xf1\x52\xd3\x39\x9b\xa3\x43\x9f\x43\xf4\x37\x74\x2c\x53\x75\xc2\xfc\x3f\x8e\x9f\xa1\x13\xfc\xeb\x34\xba\x2c\x46\x96\x3d\x65\x64\x59\xd4\xc2\xa2\x16\xd6\x1c\x51\x0b\x5b\x1a\x51\x0b\xdb\x62\x44\x2d\x6c\xfd\x88\x5a\xd8\xf2\x88\x5a\x58\xd4\xc2\x36\x18\x51\x0b\x8b\x5a\xd8\xa6\xe3\x33\xd3\xc2\xba\xab\xb7\x1e\x23\xbc\x3e\x42\x84\x57\x37\x94\xb0\x03\xfa\xd7\x09\xd6\x75\x14\xd1\x15\xa3\xb9\xf6\x3b\x9a\xab\x65\xd9\x39\xae\xd9\xc7\x29\x3d\x57\xdf\xed\x75\xf5\xe7\xe8\x4c\xb0\x94\x14\xa5\x76\xd5\xb7\x62\x0d\xba\x7d\xae\x41\xd7\xd8\xd1\x58\x88\x6e\xa3\x42\x74\xeb\x60\x16\xab\xd1\xad\x19\xfb\x13\x63\x16\xab\xd1\x6d\x3b\x62\x35\xba\xd5\x23\x56\xa3\x7b\x60\xc4\x6a\x74\xb1\x1a\x5d\xac\x47\xd0\x62\xc4\x7a\x04\x2b\x46\xac\x47\xb0\xfb\x88\xf5\x08\x36\x1a\xb1\x1e\x41\xac\x47\xd0\x1c\xd1\x0b\xd5\x6e\xc4\x7a\x04\x2d\x47\xf4\x4c\xc5\x7a\x04\xad\x26\x8c\xd5\xe8\x5e\x54\xcc\x20\x89\xda\x5f\xd4\xfe\x36\x1e\x51\xfb\x5b\x3b\xa2\xf6\xd7\x62\x44\xed\x6f\xb3\x11\xb5\xbf\xf5\x23\x6a\x7f\x51\xfb\xdb\x61\x44\xed\x2f\x6a\x7f\xbb\x8e\xcf\x58\xfb\x8b\xd5\xe8\xf6\x3e\x56\x91\xec\x63\x46\x52\xac\x46\x17\xe3\x17\x77\xda\xee\x58\x8d\xee\xf1\xf1\xd9\x57\xa3\x6b\xc4\xd2\x3d\x5d\x49\xba\xed\x97\x11\xeb\xd2\xc5\xba\x74\xb1\x2e\x5d\xac\x4b\x17\xeb\xd2\xc5\xba\x74\x9b\x8f\xfd\xf7\x66\xec\x9d\xfe\xf1\x32\x3c\x18\xb1\x22\xc2\xe6\x23\x56\x44\x58\x3b\x62\x45\x84\x58\x11\x21\x7a\x23\x76\x19\xb1\x22\xc2\x96\x23\x7a\x1e\x62\x45\x84\xad\x46\xac\x4b\xf7\x62\x62\xcc\xa2\x16\x16\xb5\xb0\xe6\x88\x5a\xd8\xd2\x88\x5a\xd8\x16\x23\x6a\x61\xeb\x47\xd4\xc2\x96\x47\xd4\xc2\xa2\x16\xb6\xc1\x88\x5a\x58\xd4\xc2\x36\x1d\x9f\x99\x16\x16\xeb\xd2\xed\x75\xac\x57\xac\x4b\xb7\x62\xc4\xb8\xae\xfd\x8e\xeb\xda\x11\x57\x68\xa9\x45\x2e\x4a\xae\xaf\x41\xce\x58\x02\xa7\x49\x62\x3e\xdd\x88\x5b\xd8\x32\x96\xa8\xa9\x86\x3e\x30\x2d\x61\x3c\x65\x09\x2a\x92\x77\x53\xc0\xb2\x72\x46\xbe\xc5\xeb\x08\xb5\x17\x12\x8d\x57\x56\xe8\x85\xeb\x34\x44\x0d\x03\x6c\x70\xea\x6d\xe1\x65\x21\x34\x12\x22\x03\xca\xb7\xb8\xd3\x71\x43\x90\x5b\x9e\xe6\x06\x40\xde\x3a\x52\x5c\x4d\x46\x46\x90\x09\x3e\x71\xf1\x3c\xee\x04\x0c\xc8\x59\x75\x41\x42\x39\x1e\x9e\x52\x4a\xe0\x3a\x9b\x23\x1c\xb0\xc0\x15\x6a\x0d\xb9\x98\x41\x8a\x24\x1b\xc3\x88\xac\x1c\x49\x35\xc9\x80\x9a\x67\x71\xa8\x1e\x66\x0e\x0f\x25\x43\x9c\xdf\x4e\x3a\x02\x17\xda\xb4\x13\x10\xb7\xa7\x8d\x3b\x51\xc3\x05\xcb\x86\x13\x9b\x90\x2f\x25\xa8\x1f\xd5\xde\x10\x8f\xe6\x5c\x94\xe4\x8e\x5a\x49\x49\x96\x1c\x0f\x33\xbe\xba\x01\xed\x96\x0f\x6f\x21\x93\xec\x6e\x7e\xe8\x23\x55\xdb\xf2\xb6\x36\xe6\x00\x2a\x27\x3b\x31\xa9\xc6\xd6\x1c\x9e\xca\x49\x69\x45\x42\x87\xca\xc0\xb5\x9c\x63\xbc\x9d\x95\x29\x6a\x98\x98\xd3\x09\x1c\x1e\x2a\x72\xf6\xee\xdc\x90\xbf\x52\x19\x6a\xed\xaa\xec\x39\x72\x58\x48\x31\x63\xa9\x41\xee\xef\xa9\x64\x74\x94\x19\xb9\x73\x0c\x12\xb8\x11\x0b\xbe\x38\xfa\xfe\xf4\xc3\x2f\x57\xa7\xef\x2e\x8e\x51\x02\x85\xfb\x82\x72\x73\x2a\x4a\x55\x05\x8a\xba\xc7\x99\x07\x01\x9f\x31\x29\xb8\x59\x1f\xea\x6a\x94\xcc\xfc\xac\x49\x38\x0c\x12\x94\xc8\x66\x90\x5a\x39\x39\x3c\xcd\x73\x1d\xc6\x8b\x52\x7b\xdd\x11\xc3\x17\xcd\x01\xe2\xc9\x94\xf2\x89\x59\xe7\xb9\x28\xcd\x7c\x5f\x7c\x81\x2b\x92\x90\x96\x89\x95\x9c\xa8\xc7\xda\x2f\x7a\x9e\x53\x18\x5a\xaf\x6c\x49\x44\x95\xd0\xc2\xaf\xb9\xfe\x5a\x6a\xce\x35\xbd\x7f\x63\xe3\xf7\x0e\xbe\xa8\xfd\x74\xe0\xcb\x49\x0a\xf3\x08\xcb\x6f\xec\xaa\x32\xac\x64\x98\x91\x83\xfa\xd5\x03\x72\x61\x9e\x01\x69\x1d\x80\x36\xfc\x12\x66\x20\x51\xf3\x74\xe0\xeb\x11\x09\x13\x2a\xd3\x0c\x14\x06\x1e\x7a\xda\x6c\xb5\x03\x07\x30\x08\x7a\x2d\x17\x7a\x15\x31\x21\xef\x04\x06\x21\x8e\xc5\x1b\x32\xd5\xba\x50\x6f\x4e\x4e\x6e\xcb\x11\x48\x0e\x1a\xd4\x80\x89\x93\x54\x24\xea\x44\x53\x75\xab\x4e\x18\x37\x87\xab\x9f\x52\x4d\xfb\xb5\x53\x7d\x62\x39\x77\x3f\x11\x79\x4e\x79\xda\xa7\x0e\xbb\xfa\x61\x5b\x4f\x7e\xeb\x78\x6a\x9f\x86\xab\x18\xef\xd3\xbe\x9a\x42\x96\x1d\xee\x80\xcf\xed\x64\xbe\x16\xb2\x5e\x2b\x19\xcf\xbd\x7b\xfb\x03\x7c\x11\xce\xab\x85\xc1\x80\x5c\x09\xed\xe2\x63\x5d\x28\x36\xd2\x51\x84\xef\xda\x23\x7d\x71\x75\xf3\xe1\x1f\xc3\xf7\x97\x57\x37\xf1\x64\xc7\x93\x1d\x4f\x76\x8b\x93\x0d\x7c\xd6\xfa\x54\x7b\x99\xb3\x76\x4c\xc2\x7e\x23\xa7\x56\xa0\xfd\x31\x08\x1b\xd0\x5a\x42\xb4\xe3\xc9\xa0\xde\x80\xc0\x05\x9f\x7d\x4f\x9b\x16\x76\xbe\x12\x1c\xc4\x5d\x60\x05\xe5\x20\x83\xb7\x89\x8f\x6f\x61\xcd\x6a\xeb\xbe\xda\x49\x8a\xb4\xa3\xbd\x6b\xc9\x3c\x7a\x77\x43\x43\x63\xfb\xae\x68\x5e\x55\xa8\x5e\xb1\x6b\x03\xf2\xce\xab\x3d\xe4\xec\x97\xcb\xf3\x8b\xab\x9b\xcb\xaf\x2e\x2f\x3e\xec\xae\x47\x77\x60\x71\x41\x9b\x42\x47\x00\x38\xdc\x91\x4b\x16\x12\x66\x4c\x94\x2a\x9b\x07\x2b\xc8\x6a\x22\xb0\x78\xfa\x9d\xdf\x77\x1e\xf4\xf1\x95\xb7\x45\x66\xdb\x2d\xb3\x3d\x87\x31\x2d\x33\xab\x3d\x1d\x1c\x0c\x76\xe1\x72\x76\x74\x85\xbe\x5f\x49\xd1\xa2\x02\x73\x03\x85\xaf\x6d\xed\xf6\xb1\x90\x6b\x8f\xf1\xa1\x8b\x3e\x68\xb0\x1e\x27\x3c\x5a\x0b\x9d\x93\x1e\xad\x93\xac\x25\x74\x5a\x7a\x19\xba\xf1\xbd\x27\x82\x8f\xd9\xe4\x1d\x2d\xbe\x85\xf9\x07\x18\xb7\x33\x13\x37\xe1\x8d\xd6\x47\xe7\x4a\x46\x5b\xa5\x61\x67\xf6\x61\xed\xdc\x34\x9d\x39\x69\xba\x8a\xce\x68\x1f\x99\xd1\x5d\x20\x45\x27\x41\x14\x4b\xf5\xf0\xad\x1d\xda\x59\x94\xbb\x8a\xb1\xe9\xc4\x73\xdf\x8e\xcb\xfb\xd1\x64\x76\x75\x76\xef\xe8\xac\xde\x54\xed\x48\x04\x4f\xa0\xd0\xea\x44\xcc\x0c\xe7\x82\xbb\x93\x3b\x21\x6f\x8d\x1e\x61\x74\xd7\xbe\xc5\x5a\x75\x82\x3e\x83\x93\xdf\x5a\x37\xd8\xcd\xfb\xf3\xf7\x6f\xc8\x69\x9a\xba\xe6\x26\xa5\x82\x71\x99\xb9\x76\x02\x03\x42\x0b\xf6\x3d\x48\xc5\x04\xef\x91\x5b\xc6\xd3\x1e\x29\x59\xfa\xe5\xee\xc4\xd9\x8f\x0e\x77\x41\x14\xd6\xd5\xd9\xf1\x4e\x5c\xa3\x8f\x65\xde\xe0\x5d\x81\x88\x18\xae\xc5\xb4\x42\xdc\xf4\x56\x67\x27\x64\x74\x04\x9a\xed\x4d\xf4\x8b\x03\xb7\xb0\x5b\xba\x7a\x58\x11\x56\xeb\xe2\x74\x88\x5a\x88\xf4\x0d\x51\x65\x51\x08\xa9\x15\xc9\x41\x53\xa3\xf4\x0e\x0c\x86\xf5\x9a\x1f\xd1\x57\xd5\x23\xff\x0c\x5f\xa2\xc3\x49\xfd\x78\x78\xf8\xf7\x6f\x2f\xfe\xf1\x9f\x87\x87\x3f\xff\xb3\xfe\x2b\xb2\x42\x1b\x05\xd4\xbc\x44\x15\x90\x0c\xb8\x48\xe1\x0a\x9f\x81\x1f\x55\xc3\xcd\xe2\x7e\xd0\x54\x97\x6a\x30\x15\x4a\x5f\x0e\xc3\xc7\x42\xa4\x8b\x9f\x54\x0b\x89\x83\xec\x27\x63\xc0\x2d\x1a\x52\x3d\xdd\x13\xf6\x50\xd1\x92\x8e\x8f\xaa\x9b\xb5\xde\x44\x27\xa7\xf8\xe7\x57\x1e\x04\x46\x7a\xba\x93\x4c\x6b\x74\xbd\xb9\x54\x70\x31\xee\x99\x53\x5b\x89\x9d\xb3\xd7\xad\xeb\xa3\x74\x4a\xda\xc2\x0e\x76\x0c\x30\x84\x88\x83\x96\x3d\xc8\x81\xc1\x2e\xbb\x98\x4f\x87\x97\x64\x66\x21\xbc\x37\xc0\xf1\xe9\xbd\x5f\x7d\x54\x1a\x17\x9a\x2e\x39\x50\x05\x0d\xf1\x8d\x0d\x0a\x0a\x49\xc6\x24\x63\x39\x73\xb1\x86\xae\x41\x93\x22\x47\xf6\xcb\x41\x52\x94\x3d\x77\xc1\x20\x87\x5c\xc8\x79\xf8\x08\xc5\x14\x72\xa3\x69\xf5\x95\x16\x92\x4e\xa0\x17\x6e\xb7\xb7\x85\x4f\xf6\xc6\xc6\x03\x96\xef\xb6\xaa\x70\xe5\x2a\x75\x14\x19\xd2\x97\x47\xdb\x3c\xe8\xf7\x84\xb4\x05\xcc\xb8\xfa\x08\x22\x61\xb0\xc4\x59\x81\x33\x40\x11\xf5\xc9\x99\xc8\xca\x1c\x54\x2f\x88\x41\xd6\x1a\xc0\x67\x46\xb3\x54\x7b\x25\xa8\xa5\x6c\xc6\x54\x17\x61\xc4\x2b\xe4\x34\xe6\x22\xf2\x45\xa9\x8b\x52\xbb\x7a\x33\xb5\xc6\x6e\x42\xa1\xdd\x22\x14\x05\x68\x90\xfd\xd7\x07\xed\xa3\xd1\xa9\xd6\x20\xf9\x1b\xf2\xdf\x47\x3f\xfd\xfe\xd7\xfe\xf1\x97\x47\x47\x3f\xbe\xea\xff\xed\xe7\xdf\x1f\xfd\x34\xc0\x3f\x7e\x77\xfc\xe5\xf1\xaf\xfe\xc3\xef\x8f\x8f\x8f\x8e\x7e\xfc\xf6\xdd\xd7\x37\xc3\x8b\x9f\xd9\xf1\xaf\x3f\xf2\x32\xbf\xb5\x9f\x7e\x3d\xfa\x11\x2e\x7e\xde\x70\x92\xe3\xe3\x2f\xbf\x68\xbd\x74\xca\xe7\xef\x5b\x12\x50\x3b\xfa\x9d\x95\x0b\x5a\x9c\xb1\xa3\x38\xeb\xfb\x7e\xa5\x34\xf5\x19\xd7\x7d\x21\xfb\x76\xea\x37\x44\xcb\xb2\x1d\x31\xa9\x98\x52\xd7\xe7\xdf\x77\xef\x7a\x53\x31\xa4\xc0\xae\xf7\xe6\x80\x2b\x48\x24\xe8\x4f\x61\xc9\xb1\x4f\xf2\x72\xca\x42\xcc\xe3\x4b\xe3\x73\x9f\x83\x71\x27\x84\x0c\xe2\xbe\x56\x92\xe8\x58\x8a\x7c\x40\x6a\xee\x8d\x19\x26\x7c\xb8\xeb\x6e\xa1\x85\x15\xd4\x8f\x68\x0c\x8a\xc6\xa0\x35\xe3\x51\x63\xd0\xb5\xc5\xc3\xbd\xb5\x04\x01\x9f\xed\xea\xc2\x58\xe9\x41\xf7\xba\x8e\x16\xa4\x10\x45\x99\x51\xbd\xc6\x33\xb6\xc2\x9d\xee\x8e\x7a\x15\x8f\x5c\x05\xd3\x58\x86\x96\xaf\xf6\x61\x92\xd3\x2c\x23\x8c\xdb\x83\x8f\x13\x78\x87\x99\x04\xab\xda\x10\x6a\xfd\xd9\x33\xb3\x84\x3b\x57\x56\xae\x1e\x97\xa3\x88\xd2\x54\x6a\x8c\x3d\xc6\xb2\x73\x96\x95\x38\xef\x13\xe3\x55\xf1\xb9\x20\x1c\x86\x5c\x90\x95\x9d\x31\x33\xaa\xb4\x5f\x36\xae\x46\xd3\x5b\xf4\x36\x26\x90\x02\x4f\x00\x13\xd3\x4a\xa8\xde\x75\x64\xf4\x36\x72\xc1\x67\x76\x0e\x4a\xd2\xd2\x06\x83\x58\xf2\xb7\x7a\x8e\x97\x15\x80\x60\x10\xf1\xda\x37\x30\x0e\x71\x08\x48\xf5\x83\x86\x1d\xf2\xfb\x82\x95\x55\x3d\x4d\xe4\x41\x7b\x9e\x19\x3c\x5b\xad\x84\xa1\x25\x66\x59\x99\x9f\x9b\x4c\xf2\x25\x38\x03\xdb\xb3\xcf\xcf\x8e\x75\x76\xc4\x36\xbb\x61\x99\x5b\xf8\x4e\xba\x64\x93\x5d\x38\x4b\x0a\x09\x63\x76\xdf\xd1\x39\x3d\xe5\x95\x25\x86\xa5\xc0\x35\x1b\x33\xdb\xf3\xbe\x90\x50\x00\x4f\x43\xe1\x52\x4c\x0e\xe7\x4d\xd8\xec\x65\x30\x8f\x15\xb8\xbb\x25\x65\xd7\xab\x84\xfd\x48\xc7\x48\xa4\x63\x3b\x8f\x4f\x44\xc7\x1c\xe6\xee\x0f\x11\xc3\xc8\xf3\xf6\xd1\xef\x67\xcd\x50\x76\x44\xe4\xad\x11\xad\xca\xec\x3a\xc1\x59\x94\xcd\x92\x0c\x69\xd8\x81\x34\x6a\x61\x83\xd7\xc8\x94\x4d\x0c\x64\x33\x98\x41\xe6\xe4\x26\x92\x53\x4e\x27\x36\xbf\x5b\x0b\x6f\xaa\x35\x8a\x96\xc1\x63\xc9\xd2\xa5\xb8\x7b\x94\xe3\x0d\x6e\x67\x82\xa6\xf8\xa3\x14\x59\x06\x52\x91\x8c\xdd\x02\x39\x87\x22\x13\x73\x97\xae\xcd\x53\x72\xad\xa9\x36\x58\x7d\x0d\x7a\x37\xb7\x6f\x2b\x8c\xc5\x15\x0f\xcb\x2c\x1b\x8a\x8c\x25\x3b\x19\x55\x9a\x3b\x77\x89\xfb\x55\x94\x59\x46\x0a\x9c\x72\x40\xde\x73\x24\x1a\xa7\xd9\x1d\x9d\xab\x1e\xb9\x82\x19\xc8\x1e\xb9\x1c\x5f\x09\x3d\xb4\xd2\x77\x33\xe0\xce\x5e\x48\xd8\x98\xbc\xc1\xea\x36\x9a\x68\x3a\x41\xdd\xc9\xbb\x01\x7b\x06\xfe\xf5\x09\x2c\x7d\xb8\x63\x6a\xa5\xb2\xd2\x1a\x71\x7e\x8b\x33\x19\x5a\x65\x3f\x7f\xf2\x6d\xca\xd8\x18\x92\x79\x92\xb5\x3f\x5a\xa7\x09\x06\x30\x54\x19\xe7\x35\xfc\x76\xd5\xd4\x5d\x8e\x27\x6a\x81\x8c\x13\x5b\xe6\xdc\xd6\x6f\xaf\x50\x3d\xac\xc8\x6a\xbb\xaa\x53\x25\x71\x67\xe6\xd9\x96\x6d\x16\x42\xe9\x6b\xa3\xa1\x77\x52\x0c\xfd\x70\xe8\xa7\x23\x58\xf2\x39\xcb\x20\x25\x2c\xcf\x21\x35\x5a\x7c\x36\x27\x74\xac\x31\xd7\xb6\x61\x21\x48\x24\x58\xac\x75\x55\x4c\xa6\x94\xa7\x19\x48\x32\xa6\x2c\x73\xf6\x80\xc6\xf5\x1a\x64\xce\x38\x9a\x05\xac\x47\x16\x4d\x0c\xe6\x53\x92\x08\xe9\xcb\xd3\x33\xad\xfc\x4f\xd5\xc1\x44\x3e\x52\x43\x80\x45\xd7\x32\x19\x65\x22\xb9\x55\xa4\xe4\x9a\x65\x76\x31\x42\xdc\x92\x44\xe4\x45\x86\x47\xa7\xc5\xc9\x0a\x7f\xf6\x03\x2a\xf5\xcd\xec\xea\xe4\xb7\xd5\x4f\xf8\xc5\xae\x0c\xbd\x03\x41\xac\x0b\x31\x0c\xee\x21\xe9\x2c\xcf\xff\xe2\x1e\x92\x5a\x61\x09\xec\xc7\x80\x27\x1a\xf3\x3c\xe9\x2d\xbc\xa0\x4a\x76\x2d\x72\xe9\xea\xa3\x01\xbf\x33\x3b\xa7\x2f\x84\xe5\x1e\x41\x32\xc6\x91\xbe\xb9\xfc\x3a\xc2\xb8\x32\x9c\xbd\x71\x18\xec\xd1\x73\x42\x2b\x49\x99\xc4\x2a\x08\xf3\x10\x48\xed\xe7\xc2\x02\x03\x42\x68\x72\x74\x78\x72\x78\xbc\x64\x7f\x3c\x34\x12\x48\x06\x96\xd6\xfa\xc4\xbd\xb0\x28\xc5\xf2\x22\x9b\xe3\x3a\x0e\xd3\x1e\x61\xda\x47\x5a\xcb\x92\xfb\x55\xb9\xa4\xbf\x1e\x51\x82\x68\x49\x7d\x75\x15\xfb\xad\xb9\x48\xcb\xd2\x51\xf9\xa3\xc3\x5f\x0f\x7b\x04\x74\x72\x4c\xee\x04\x3f\xd4\xb8\xfc\x01\xb9\x11\x46\x94\xae\x26\x9a\x8b\x92\x70\xb0\x81\xfd\x70\x5f\x64\x2c\x61\x3a\x9b\x23\xc5\x22\xa2\xd4\x36\x87\x98\x6a\x9f\x6c\x78\x71\xcf\xb4\x8b\x57\x33\x24\xe3\x15\x42\xd3\x52\x2d\x42\x8d\x98\x33\x83\x93\x29\xd0\x4c\x4f\x6d\x90\x08\x17\xbc\xff\x6f\x90\x02\x73\x10\xb9\xfb\xe5\xc5\x55\xfd\xeb\x44\x73\x30\x44\xf4\x6b\xe8\xae\x89\xcf\x37\x37\x37\xc3\xaf\x41\x2f\x90\x0c\xf3\x14\x1f\xba\x83\xd6\x00\x90\x63\x21\xf3\x3d\xa0\x1d\xdd\x38\x2b\xfb\xa4\x10\x72\x1f\x48\xd8\x54\xa8\x56\x7b\x49\x96\xf6\x53\x28\x8d\xda\x90\x93\xc6\x38\x24\x66\x07\x9b\x31\x24\xbe\xcf\xcd\xe5\x70\x40\xfe\x21\x4a\xf3\x36\x23\x3a\xca\xe6\xa1\x12\x83\x02\x4d\x0e\xcc\x54\x07\x86\x3c\x19\x6c\xf8\x06\x68\x6a\x54\x14\x43\x3d\x80\xee\x47\x3f\x2b\xe2\xce\x83\x5b\x5b\xb7\x7c\xa0\x54\x5a\xe4\x64\xea\x5e\xbb\x99\x7a\xe9\x4e\xc6\x00\x4f\x8f\xcf\x6b\x92\x50\x58\x0a\xe7\xee\x79\x71\xf4\x6b\x89\x6e\x58\xb8\xbb\xef\x47\x58\xc6\x2a\xa9\x83\xcd\x35\x74\xb2\x89\x41\xdc\x02\xcb\xa0\x1a\xec\xe6\x2a\xa9\x8f\x3d\xae\x3d\xba\x73\x22\xe7\xe2\x44\xe8\xd4\x6b\x1f\xeb\xd5\x69\xe5\xd1\x6e\xe2\x06\xc8\x2a\x23\xab\xc3\x19\x6b\x7d\xe9\x08\x88\x1f\xa7\xf4\xe5\xa7\x00\x40\x37\x9b\x4f\xba\x84\x40\xd1\x41\x68\xf7\x72\x60\xb7\x16\x46\x0f\xc5\xd4\x4b\x4b\x5c\x91\x4c\x28\x90\xb3\x5d\x93\xb9\xab\xd1\xdd\xab\x8b\xdd\x35\x7e\x3f\x56\xe4\x49\x4b\xc2\xcb\x7c\x04\xb2\xca\x4c\x91\x7a\x19\x20\xb5\xc8\x84\x2b\x7b\xb9\x37\xe7\x36\xdb\x27\x9a\x3b\xff\xf2\xe7\x3f\xff\xf1\xcf\x03\x3b\x7d\x88\x52\xe0\xe4\xf2\xf4\xea\xf4\x97\xeb\xef\xcf\x30\x39\xb6\x2d\x54\x3b\x0a\xc1\xec\x3a\x00\xb3\xd3\xf0\xcb\x8f\x1a\x7c\x89\x29\x1f\xad\xa9\x48\xd3\xf6\x8f\x53\x1a\x0c\x30\x7a\x9b\xd1\x38\x9d\xec\x57\x2b\x56\x66\x64\xcd\xa6\x21\xd5\x1c\xb5\xbd\x38\x63\x3a\x29\xae\x45\x72\xdb\xa1\x5e\x73\x0e\x85\x84\xc4\xda\xc9\x6e\xce\x86\x76\x76\xa3\x5f\x5e\xbd\xbf\xa9\x52\x0d\x30\x1e\x87\xbc\xf5\xf6\xa5\x6f\x9c\x25\xcd\xe8\xa4\xb7\x50\xe8\xa0\xba\x8f\x68\x72\x7b\x47\x65\x8a\x96\x2d\xaa\xd9\x88\x65\xcc\x16\xff\xf5\x4d\x21\xb9\xb0\x01\x7f\xb6\xc8\x99\x18\x2f\x96\xd6\xac\xcc\xa1\x68\xb2\xb2\x71\x34\x63\xca\x32\xb4\xa0\x96\x5c\xb3\x1c\x5c\x44\x50\x52\x04\x93\x5e\xdd\xa6\x1d\x95\x2f\x3f\xf6\x56\xf9\x3a\x7c\xef\xbd\x7a\x5b\xeb\x61\x6d\xe3\x12\xf7\x98\xd5\x39\x16\x67\x13\x42\x22\xab\xfb\x2c\x58\x5d\x21\xe1\x5a\x8b\xa2\x23\x2f\x89\x9d\x6c\x8d\x8f\x64\x04\x63\x61\x88\xf0\x5a\xa7\x87\xef\x11\xcc\x31\x39\xd0\x5b\xb5\x44\xc3\xb1\x61\x23\x32\x55\x99\x4c\xbd\x81\x92\x83\x52\x27\xe8\x0e\x29\x0b\xab\xb5\x22\xb9\x2e\x25\xf4\xcc\xdb\x41\x8e\xab\xeb\x55\x59\x0e\xe6\xf1\xc0\xed\x97\xa0\x13\x6b\xb9\xad\x11\x72\x2c\x0c\xea\x96\xbf\xe8\x46\x49\x24\x55\x53\xc0\xf2\x22\x70\xcf\x7c\x37\x94\xa1\x48\x0f\x0f\xab\x57\x31\x8c\x65\x22\x69\x02\xa4\x00\xc9\x84\x61\x46\x25\xd7\xa9\xb8\xe3\x64\x04\x13\xc6\x95\x07\x85\x99\xdb\xc3\x0c\xfd\x31\x4c\x85\xc2\x70\x03\xf2\xa1\x51\xec\xc4\xa5\x21\x25\xa2\x3a\x9a\x6e\xcd\x8b\x9e\x24\xe4\x58\xb5\x96\xc9\x01\xc2\x3e\x3c\x56\x6f\xb0\xe4\xa3\x92\xe3\x93\x53\xc8\xe8\xdc\x46\x9b\x8e\x19\xa7\x19\xfb\x37\x48\x75\xdc\x81\xc7\xc9\x80\xb0\xfa\x6d\xed\x3a\xb0\x54\x3f\x4d\xa6\xed\x9c\xbf\xd1\x45\xb5\xe1\x88\x2e\xaa\x36\x93\x44\x17\x55\x74\x51\x3d\x32\xa2\x8b\x2a\xba\xa8\x16\xc6\xde\x6a\x49\xd1\x45\xb5\xf3\x88\x2e\xaa\x87\x47\x74\x51\x6d\x30\xa2\x8b\x6a\xc3\x11\x5d\x54\xd1\x45\x15\x5d\x54\xd1\x45\xf5\x19\xd9\xed\xfc\x88\x2e\xaa\xa5\x49\xa2\x8b\x2a\xba\xa8\x36\x1e\x7b\xab\x7c\x45\x17\x95\x1d\xd1\x45\xd5\x1c\x9f\x17\xab\xf3\x0e\x9e\xa1\x51\xf5\xda\xe7\xb4\x0d\xd1\xa9\xc0\x12\xe7\x27\xaa\x37\x8d\x0b\x8f\xaa\xf5\x89\xab\x95\x05\xf1\xa9\x38\xce\x23\x54\xf9\x99\x56\xe6\x4b\x6d\xeb\xaa\xf0\x49\x86\xea\xa4\x10\xf6\x7f\x95\xa3\xa2\xe6\xa1\xb0\x0a\xef\xee\x39\x6b\x4f\x96\x8d\xd5\xc6\x2d\xf1\x69\x5c\x12\x7b\xe2\xbf\xe9\xc0\x0d\x11\x5d\x10\x2f\xce\x05\xf1\x72\xba\xe6\x3a\xcf\xfc\xcd\x54\x82\x9a\x8a\x6c\x67\x44\x6f\x20\xf9\x3b\xc6\x59\x5e\xe6\x06\xe7\x94\xc1\x67\x36\x0b\x21\x00\x2a\xa0\xab\xa5\xd8\xd6\x8a\x68\x2e\x64\x29\x60\xb1\x53\xca\x32\xb3\x8d\x98\xbf\x39\xa5\x33\x83\xeb\xaa\x4c\x12\x00\x6c\xa5\x56\xd7\x70\xfe\x38\x08\x4f\x0a\xad\x33\x5e\xb7\xa3\x37\xed\x98\xb8\x2d\x47\x8a\xb3\xfc\xf1\x0f\x3b\xcd\x31\x91\x45\x37\x74\xf9\xeb\x0f\xc3\xb3\x7a\x9b\x6c\xee\xc9\x32\xe3\x33\x91\xcd\x6c\x87\x7d\xbc\xc8\x08\x6b\xae\x19\x3f\x36\x73\x1f\x81\xa6\x35\xdd\xc6\xa9\x05\x8a\x00\xa7\xa3\xcc\xdc\x67\xee\x0a\x1c\x79\x68\xf9\x2e\x50\x5d\x4a\x20\x13\xaa\x9f\x92\xe0\xb7\x57\x61\x5a\xa9\x2f\x5d\xf0\x9b\xb6\x12\x7a\xd3\x06\x67\xe4\xf0\xa6\x15\x6a\x82\x78\x61\x2b\xe8\x6f\x2c\x87\xb7\xa6\x94\xed\x65\xe3\xf6\x47\x8b\x60\x89\x1b\x7c\xf1\xce\x00\x7c\xe0\x5a\x3e\x7b\x76\x5e\x57\x82\x7c\x57\x29\x2d\x48\x91\xd1\xaa\x2f\x14\xee\xc0\x37\xc8\x83\xce\xa6\x90\xdc\x7e\x70\x9e\xd8\x23\x05\x10\x64\xd3\x09\xd3\xd3\x72\x34\x48\x44\x7e\x62\x48\x82\xfd\xdf\x28\x13\xa3\x93\x9c\x2a\x0d\xd2\x88\xab\x8e\xc5\xf5\x13\x33\x0b\xe3\x93\x41\x9e\x1e\x0f\xc8\x4f\xdc\x66\xb7\x57\x7d\x28\x6b\xb5\x1d\xcc\xf3\x7d\x9d\x8d\x11\x18\xea\x2a\x64\xbd\x7d\xf8\x68\x8e\xcb\x1b\xb4\x29\x94\xdc\x9a\x25\xb5\xf4\x82\x7f\x7a\x0f\x78\xa4\x5c\xa4\x03\x83\xcb\x73\xf3\x74\x77\x16\xf1\xd1\x81\x87\x7b\x8f\xbc\xdb\x7b\x23\x1a\xef\x8b\x47\x7b\x0f\xab\x4d\x77\xe0\x80\xed\xc2\x83\xdd\x9d\xf7\xfa\x23\x14\x65\xfe\x38\x5e\xeb\x0e\x4d\x7b\x1d\x79\xab\x3f\x85\xa7\xba\x93\xb7\x6e\xeb\xa1\xfe\x74\xde\xe9\x6e\x5e\xb7\x4b\x45\xe0\xb9\x7a\xa4\x3b\x30\xd1\x77\x69\x9e\xef\xcc\x34\xff\xd1\x3c\xd0\xed\xbd\xcf\x7b\xe0\x79\x6e\x0d\x64\xc6\x99\x66\x34\x3b\x87\x8c\xce\xaf\x21\x11\x3c\xdd\x99\xc3\x2c\x54\xe9\x0c\xe7\x47\xd9\x69\x9d\x9d\xaa\x99\x68\x31\xa5\xae\x18\xb9\xd1\xa8\x6c\x62\x89\xf7\x65\x38\x81\x02\xbd\xca\x76\x95\x7b\xe9\x9d\x20\x7b\x63\x10\xb3\x59\x27\x5d\x6e\xe2\x37\xe2\x8e\x88\xb1\x06\x4e\x8e\x18\xf7\xfb\x78\x5c\x53\x03\x2b\xeb\x64\x40\x6b\xf3\xeb\xeb\x57\xfe\xe2\x97\x67\x76\x44\x03\xab\x52\x1f\xdf\x0a\xec\x1e\xf4\xb8\x19\xd8\x5d\x38\x2e\xb3\xa6\x29\xd8\x9a\x87\x9b\xf4\xe6\x75\x55\x4e\xf9\x35\xce\x1b\x4e\x1b\xe5\x29\x71\x99\x68\x2f\x6f\xd3\x5a\xc7\xd5\x34\x45\xbf\x10\x47\xf3\x98\xd5\xf8\xe6\x6c\x68\x8d\xc6\xd1\x5c\xb2\x2f\xe6\x92\x27\x8a\x4d\xd9\x43\x41\xf7\x99\xc6\xa3\x44\x41\x77\x8b\x51\xcb\x4d\xfd\x5a\xd2\x04\x86\x9d\xcb\x08\xfe\x38\x91\xb4\x94\xd4\x11\xc0\x20\xf2\xf9\xc3\xc3\x01\x52\x7b\x9a\x42\x3e\x2f\x66\xca\x8e\xcb\x2c\x9b\x93\xb2\x10\xbc\x99\xfd\x6c\x7d\xed\x8b\xc9\xb4\x68\x92\x5f\xf1\x94\x4a\xb0\x2c\xa4\x70\x3c\x53\x96\x9c\x1b\x1a\x5c\xf5\x44\x43\x41\x12\xcb\x34\xd3\x46\xca\xae\x62\x13\xb3\x7c\xc3\xff\x30\x9b\xb7\x0a\x40\x6c\x4c\x68\xee\x1e\x0b\x99\xb0\x51\x36\x27\x53\x9a\x85\x06\x38\x94\xdc\xb2\x2c\x73\xd3\x0c\xc8\x35\x68\xeb\x52\xb0\xbc\x33\x13\x7c\x82\x8b\xa3\xdc\x37\x5e\x84\xc4\xdc\x9b\x64\x40\x79\x59\xd8\xe7\x19\x4e\x3c\x17\xa5\xf4\xcf\x1b\x04\xc7\x44\xe0\xc0\x9c\x65\xbd\x5a\x7b\xb7\x07\x37\x36\xc4\xfe\x94\xca\x08\x00\xef\x7d\x59\xea\x5e\x7d\x4e\x5f\x39\x5c\xd5\x9a\xfb\x14\x52\xcc\x58\x6a\xbd\x1b\x1e\x6c\xd8\x48\xda\x36\xf0\x09\xe7\x99\x0b\xde\xe7\x30\xa1\x28\xa8\xb8\x53\x64\xf7\xcc\xce\x63\x23\x08\x78\x8a\x2d\x7d\x8c\x84\x2f\x8a\x46\x3a\xfd\x8c\xd9\x66\xc4\x35\xc8\x91\x23\x2e\x88\xc0\x78\xd4\x92\x33\x6d\x1b\xdc\x4f\x4b\x4d\x52\x71\xc7\x8f\xb7\xf2\xba\xa2\xa3\xf5\x66\x25\x80\x9a\xee\xd7\x55\x72\x8e\x7d\xdf\x87\xc1\xcb\x94\x33\x7d\x8e\x49\xc9\x15\xb4\x64\xef\x9d\x09\x47\x7f\xf9\xd3\x6e\x34\x82\xe5\x20\x4a\xfd\x49\xb4\xbf\xbb\x29\x4b\xa6\x75\x61\x96\xe5\xa0\x88\x28\x17\xd4\xe2\xd7\xee\xb6\xd5\x3b\x14\x55\xc0\x55\x63\x57\xc3\xee\x0a\xeb\xd7\x62\x39\x84\xaa\xf3\x35\xc6\x89\x9f\x5f\x5d\xff\xf2\xf6\xf4\xbf\x2e\xde\x0e\xc8\x05\x4d\xa6\xf5\x9a\x18\x9c\x50\x24\x1a\x48\x28\xa6\x74\x06\x84\x92\x92\xb3\x7f\x95\xce\xe1\x7b\x14\xee\x3d\xee\xb4\x56\xfb\x8e\xdc\x17\xbb\xf3\x77\xd6\x0e\xce\xf6\xfa\xb7\x71\x59\x42\x01\x36\x70\x59\x12\x9f\x82\x97\x79\x6e\x55\x04\x14\xb8\x30\x7c\xfe\xfc\xfd\xc5\x35\x86\xe5\x17\xd2\x56\x0a\xc1\x38\x2e\xfc\x1d\x67\x1a\x81\xb9\xc3\x75\xee\x1d\x90\x53\x3e\xb7\x3f\xda\x33\xc5\x14\xc9\x98\xd2\x80\x5c\xcf\x89\x6d\xde\x7f\x7d\xf0\x6a\x80\xff\x1d\x10\x9a\xa6\xd2\xc8\x75\x21\x3c\x2d\x59\x8a\x17\xb5\x92\x1f\x1b\x65\xb5\x17\xe0\xa0\x6d\x34\xda\x3b\x91\xba\x95\x23\x27\x41\xdf\x95\x65\x83\x4a\x4b\xaa\x61\xc2\x12\x92\x83\x9c\x00\x29\xa8\x4e\xa6\x24\xa7\x73\x92\x08\x29\xcb\xc2\xd6\xf9\x4f\xa9\xa6\x03\xf2\x95\x90\x24\xf7\x87\xd8\xe0\xbc\xe1\xc3\xd7\xab\x7d\xfa\xd5\xc9\xae\xff\xc9\x94\x2a\x41\x9d\xbc\x7e\xf5\xd7\x3f\xfc\xf9\xcf\x2f\xaa\x35\x5c\x15\x2e\x64\xf6\xb6\xd6\x1a\x8e\xfa\x5d\xb0\xbb\x6e\x5b\x05\x32\x3e\xc9\xea\xf8\xb5\x1b\x03\x68\xab\x65\xb6\xd5\x31\xfb\xd5\x1b\x0c\x77\x55\x35\x3b\x69\x51\x57\xad\xa1\xa3\xc6\x4e\x15\x1f\xf4\x8a\x95\xa3\x0d\xa2\xde\xab\xf7\x72\xe8\x0f\xa6\x93\x73\xf2\x85\x06\xaf\x45\x15\x9d\xd4\x23\xaf\xc8\xdf\xc9\x3d\xf9\x3b\x2a\x5a\x7f\x69\xdb\x06\xab\xad\x0a\xd4\x45\xb0\x91\xd1\xef\x2f\x87\x1d\x41\xfc\x07\x43\x34\xcd\x8c\x06\xaa\x5a\x90\x11\x73\x82\x3d\xdc\x6b\x90\x46\xd0\x74\x3b\xf1\xa4\x0d\xc4\xcc\x02\x3f\x21\x9a\x59\xc7\xc3\xe5\xb8\x19\xe0\xb4\x1d\xa2\x99\xdb\xbf\x11\x4a\x5f\x39\x2a\xd4\x6c\x85\x53\xcd\x96\x23\xe1\x6f\x90\x31\xc3\x37\x94\xae\x0e\x98\x22\xa9\xc0\x78\x2b\x1b\xc8\x3c\x65\x2d\xc2\x28\xf6\x07\x8d\xdb\x79\xd6\x1b\xfb\xf9\xd0\x4e\x2d\x98\x52\x50\x07\x72\x22\x56\xad\x46\x56\x21\x52\x27\x9d\x99\x65\xa5\x35\x9e\xf1\x80\x78\xe6\xac\x36\xc1\xde\x8c\xb8\x64\xce\x53\x42\xb9\x4d\x25\x19\x83\x94\x36\xf6\x7c\x34\xf7\x61\x7b\xad\x37\xaf\xd5\x49\x2a\xa4\xd0\x22\x11\x2d\x7a\x9c\x35\xbd\xdd\x6e\x3a\x04\x82\x8d\xf7\xf5\x06\xf3\xef\xce\x87\x3d\x72\x73\x36\xc4\xbe\x4f\xd7\x67\x37\xc3\xa6\xce\x72\x70\x73\x36\x3c\x78\x52\x50\x10\x2f\xf0\xa1\x89\x7a\x87\x49\x1a\x26\x28\x23\x4d\xf6\x73\x5a\xf4\x6f\x61\xbe\x23\x4f\xed\x82\xaf\xf7\xc3\x0e\x77\xf2\x42\x16\xcc\x39\x2d\xb6\x9e\x4d\x02\x4d\xd9\x27\xca\xe7\xf2\x01\xb1\xe1\x99\xab\x13\xbb\x72\x31\x83\xd4\x4a\xe9\xfe\x0e\xe0\x69\x21\x98\x91\x17\x63\xb6\xd7\xf6\x77\xc7\x6c\xaf\x8d\x47\xcc\xf6\x8a\xd9\x5e\xcb\x63\x6f\x42\x5a\x63\xb6\xd7\xcb\xf2\xe0\xc7\x6c\xaf\xcf\x3c\x08\x20\x66\x7b\xad\x1e\x31\xdb\x2b\x66\x7b\x6d\x36\x62\xb6\xd7\xf6\x63\xef\xc2\x97\x62\xb6\xd7\x56\x23\x66\x7b\x2d\x8f\x98\xed\xb5\x66\xc4\x6c\xaf\x35\x23\x66\x7b\xc5\x6c\xaf\x98\xed\x15\x83\x60\x1f\x9d\x6b\x3f\x83\x60\x49\xcc\xf6\x72\x23\x66\x7b\xbd\x88\x50\x3f\x12\xb3\xbd\x36\x1a\x31\xdb\x2b\x66\x7b\xed\x32\x62\xb6\xd7\x4b\x31\x97\xc4\x6c\xaf\x98\xed\xf5\xf9\x08\xba\x31\xdb\x2b\x66\x7b\xc5\x6c\xaf\x98\xed\xf5\xe0\x2a\x62\xb6\xd7\x4b\x50\x01\x7d\x47\xe0\xf6\xd9\x4b\x87\x67\x22\x2f\x4a\x0d\xe4\x83\x9f\x32\x48\x91\x96\x30\x30\x55\x97\x08\xda\x87\x10\x26\x82\x8f\xd9\xc4\x51\xf6\x13\xdb\x86\xb7\x1f\xde\xa7\x5f\x6b\x7d\xfb\x0c\xe3\x07\x33\x96\xb3\xdd\x52\xca\xc8\xd2\xc6\xbc\xc5\xb9\x6a\x7e\x19\x73\x92\x72\x7a\x8f\x47\x84\xe6\xa2\xb4\xad\x8b\x13\xb7\x7f\x01\x84\xd6\x7b\xb5\x77\x3b\x43\xba\x51\x71\x68\xea\xe3\xea\x86\x5d\x84\x95\x50\xad\x41\xf2\x37\xe4\xbf\x8f\x7e\xfa\xfd\xaf\xfd\xe3\x2f\x8f\x8e\x7e\x7c\xd5\xff\xdb\xcf\xbf\x3f\xfa\x69\x80\x7f\xfc\xee\xf8\xcb\xe3\x5f\xfd\x87\xdf\x1f\x1f\x1f\x1d\xfd\xf8\xed\xbb\xaf\x6f\x86\x17\x3f\xb3\xe3\x5f\x7f\xe4\x65\x7e\x6b\x3f\xfd\x7a\xf4\x23\x5c\xfc\xbc\xe1\x24\xc7\xc7\x5f\x7e\xb1\xf3\x92\x5b\x8b\xc4\xdd\x09\xc4\x1d\x89\xc3\x1f\x45\x18\x76\x0e\xdd\x8e\xce\xa2\x0b\x46\x59\x3a\x8d\x8e\x61\x3d\x74\x1a\x3d\x35\x45\x31\x2f\xcc\xc3\x14\x11\x39\xd3\x46\x38\x34\xf2\x20\xad\x87\xb3\x32\xdd\x50\x4a\x1d\x1d\xc0\x80\x6e\xaa\x6d\xa3\xf5\x10\x0a\x5a\x0b\x62\x11\x5e\xf2\x73\x9d\xe8\x59\x5e\x64\xd8\xe0\x1c\xcf\x73\xdf\xc7\xb2\x20\x73\x8d\xb4\xe1\xf1\x11\x69\xc3\x4b\xa4\x0d\x0a\x92\x52\x32\x3d\x3f\x13\x5c\xc3\xfd\x4e\x16\x96\x26\x69\xb8\x6e\x4e\xe8\x62\xc6\x94\x8b\x75\xb3\xbf\x11\x51\xd8\xb8\xef\x85\xc4\xfa\xa9\x28\xb3\x14\x93\x39\x4a\x8e\x0a\xa6\xcd\xd2\x03\x6d\xb5\x3f\xd4\x7b\x30\x94\x7b\xf1\x21\x5e\x9f\xb3\x6a\xe6\xbf\x4a\x36\xa3\x99\xd1\x76\xab\x3b\x86\xa8\xc1\xd4\x6f\xda\xf4\xcc\x6b\xaa\x6e\xab\x03\x0f\x7d\x23\x43\x87\x35\x9f\xf8\x57\xc2\xaf\xe0\x5e\x3f\x47\x29\x0d\x05\xa4\xa1\x64\x33\x96\xc1\x04\x2e\x54\x42\x33\xa4\x6b\xdd\xf0\x8a\xd3\x35\xb3\xe3\xc6\x4b\x91\x29\x72\x37\x05\x43\xab\x09\xf5\x26\x00\xcc\xb0\x9b\x50\xc6\x6d\x5e\x7c\xe1\x6f\x56\xd6\x96\x60\xc8\x7f\x41\xa5\xd9\xe0\x60\x33\x40\x15\x79\x24\x44\xe6\x32\x1e\xb2\x79\x35\xbf\xcb\xfd\xe1\xe2\x17\x0e\x77\xbf\x98\xd9\x14\x19\x67\x74\x12\x4c\x05\x0a\xf4\x92\xb5\xaf\x9a\x7a\xed\x0b\x60\x3a\x41\x09\x84\x66\x77\x74\xae\x2a\xc3\x49\xad\x02\x84\x7a\x43\x5e\x1f\x23\x3a\x53\x45\xc2\x1c\x29\xf9\xc3\x31\xba\xff\xce\x4e\x87\xbf\x5c\xff\xe3\xfa\x97\xd3\xf3\x77\x97\x57\xe4\x4a\x68\xb0\x4c\xad\xd6\x26\x30\x09\x1a\x86\x59\x25\x3e\x03\xb5\x74\xa1\x06\x68\xbb\x64\x8a\xdc\x31\x9e\x8a\x3b\xb5\xb3\x8d\xd6\xa2\x9f\x01\x1e\x50\xbe\xd3\x1c\x09\x2d\x28\x76\x3f\x6c\xc1\x61\x96\x22\x4c\xea\x93\x22\x0f\x4f\xd3\x93\x54\x8a\xc2\x02\xc1\x1b\xb9\x2a\x56\xdb\x54\xa3\xeb\x31\xac\xb8\xbf\xe3\xe6\x84\x13\x49\xb9\xae\xac\x3d\xd5\x9e\xb9\xb6\x8b\x83\xd6\xdb\xf1\xbc\x33\x9a\x68\xda\x5d\x36\xd3\x69\x9a\x42\xda\x00\xff\x8b\x8b\x1c\x3c\xf3\x2f\x37\xaf\xaa\x54\x90\xe1\xfb\xeb\xcb\xff\xbd\x80\xc7\xf3\xa2\x5d\xa0\x54\x37\x99\xb1\x52\x14\x9d\xed\xee\x07\x97\x79\x19\xf7\x77\x2f\xf6\x37\x70\xcb\x6e\xdc\xf3\x1f\x4a\xde\x2c\x69\x54\xcd\x4f\x72\x91\xc2\x80\x0c\x83\x9f\xa0\xf9\x6b\xad\xc0\x01\x95\x40\xcc\x25\x5c\x33\x9a\x65\xf3\xba\x88\xa6\x85\xcd\x42\x6c\xd4\x66\xa8\x13\xf2\x31\xcd\xd4\x53\x53\xe3\x36\xbc\xd1\xc8\x11\xef\x8c\x3e\xdc\xc9\x76\x84\xd9\x48\x0a\x5c\x68\x27\x58\x9b\x55\x62\xbd\x0b\x29\x12\x62\x95\xef\x5a\x30\x56\x83\xbf\x29\xeb\xab\xf0\xac\x91\x29\x0f\xec\x61\x98\xd9\x1a\xaa\x4b\x05\x8b\x02\xba\xef\x48\x1c\xd4\x71\x33\xbb\x04\x9a\x0a\x9e\xcd\x31\xf2\xd2\xc6\x52\xe4\x54\xdd\x42\x6a\xbf\x70\xa2\x59\xf0\x54\x98\x19\xc3\xa3\x6e\xcc\xba\xbd\x5b\x02\x45\x32\x1b\xe1\x81\xee\x0c\x48\x9f\x78\xd7\x5b\x1c\x42\x03\x94\xf7\x3c\x9b\x7f\x10\x42\x7f\x15\xd2\x68\x3b\xc1\x80\x1f\x9c\xb4\xdc\x34\x45\xa3\x38\x49\xf1\xb9\x7d\xdc\x0d\x3c\x54\xf5\x0c\xde\xf3\x6a\xc7\x9f\xfb\x91\x92\x25\x3f\x55\x5f\x4b\x51\xee\xcc\xc4\x96\x84\xcd\xaf\x2f\xcf\x91\x14\x95\xce\x55\xc9\xb5\x9c\x63\xe9\x80\xe5\xfa\x6f\x41\x31\xf8\xce\x39\x5b\xeb\x67\xa2\xf2\x8b\x91\x77\x74\x4e\x68\xa6\x84\x87\x25\xe3\x2b\xb5\x50\xa7\xe2\x9a\x9f\x47\x42\x4f\x97\x74\x5b\x73\xa0\x96\xef\xeb\xd5\x3c\x97\x55\x41\x3a\xc6\x97\x6e\xd7\xf4\x16\x14\x29\x24\x24\x90\x02\x4f\x9e\x7a\xdb\x9f\xda\xe1\x87\xa8\x73\x25\xb8\x39\x98\x9d\x20\xcf\x65\xf0\xf4\x3a\x90\xd6\x51\x05\x7d\xc6\x4e\xfb\xa3\xe8\x39\xc6\x63\x59\x2a\x90\xd6\xcd\x2d\x4b\xb0\x3b\xf9\x6d\x39\x82\xcc\x40\xde\xa8\xa4\xae\x67\xbc\x35\x67\xb0\x9c\x4e\x80\x50\x1d\x30\x4d\x0b\x02\x5c\x19\x8a\x69\x0d\xa0\x9a\xa4\x02\xaa\xec\x7b\xaa\xc8\x77\x97\xe7\xe4\x15\x39\x32\xcf\x3a\x46\xfc\xc1\x96\xf2\x5a\xd8\x20\xb7\x45\x1d\x75\xec\xa7\xc0\x25\x21\xf2\x12\x21\x2d\x91\xe8\x11\x2e\x88\x2a\x93\x69\xbd\x8f\xbd\x57\x9b\x5d\x20\x24\xba\x56\xf6\x13\xd7\x9f\x96\x42\x7d\xa7\x40\x76\x46\xa0\xbe\xdb\x81\x40\xd5\xc5\x28\x83\x73\x4d\xe8\x59\xc4\xca\x41\xd3\x94\x6a\xea\x08\x97\xbf\x60\x6f\xb7\xf4\xf3\x26\x5f\x0a\xde\x32\x5e\xde\xdb\xc0\xa3\xee\x4c\x2d\xd7\x17\x38\x2d\x49\x3c\xd4\x71\xd7\x69\x51\x64\xcc\x56\xdb\x58\x08\x84\xbb\x6c\xe0\x4a\x6f\x8d\x98\x88\x74\x82\x66\x99\x30\xf4\xd1\x08\x27\x94\xa7\x22\x5f\x7a\x98\x11\x22\xa1\x51\x39\x75\x40\x22\xf6\x35\xc7\x9e\x18\x85\x32\x98\x41\x8b\xda\x62\x8b\x95\x62\xcd\x6c\x06\x38\x1e\x23\x70\x7a\x92\xd1\x11\x64\x16\xc6\x16\x03\xd5\x32\x06\x3e\x75\x34\xaa\x14\x59\x77\xe9\x33\x1f\x44\x06\x36\xbc\xcb\x03\xc2\x4c\xff\x2c\xe0\x80\x93\x74\x05\x07\xd4\x06\x1b\x70\x40\xbd\xf6\x39\xc0\xa1\x6c\xc1\xea\xc9\x22\x1c\x8c\xdc\xd0\x84\x03\x32\xef\x7d\x87\x83\x82\x24\x11\x79\x31\x94\xc2\xa8\x9d\x9d\xf1\x26\x37\x6d\xe5\x33\xb4\x86\x8d\x15\xc1\x58\xc8\x0b\x9a\x17\x53\x59\x0b\xec\xa4\xda\x32\x09\x1f\xdd\xf9\xbf\x6a\x3c\x0b\x49\xcf\x22\x23\xf3\xb3\x34\xdc\x8b\xe6\x4e\xf7\xc3\x73\x66\x07\x5d\xe4\x46\xb4\x30\x76\x76\xc2\x8d\x44\x42\x33\xac\x1d\xdb\x0e\xe5\xc8\x22\xda\x2d\x4e\x5c\x0b\xe7\x45\x1f\x25\x7e\xe7\x03\x48\xb0\x8c\x28\x7e\xe3\x4c\x98\x5c\xa4\x50\xf3\x65\xdb\x38\xe4\x1b\x1b\xf6\x89\xd7\xf9\x48\x62\x23\x57\x78\xb7\x72\xda\xb8\x5b\x0b\x57\x01\xed\x5d\xa8\x48\x6b\x16\x08\x3c\x65\x7c\x82\x76\xb5\x1e\x91\x90\xd9\x18\x64\x47\x04\x6e\xad\x06\x79\x88\x47\xc2\x4f\xea\xcf\x83\x7f\x34\xca\x62\x4c\x70\x37\x33\x5a\x8a\xbc\x84\x35\xb6\xe4\x96\x29\x72\xf0\xd6\x03\xa0\x45\x09\xcf\x7d\xe4\x30\x07\xf6\x0d\xc3\x6e\x5a\x4b\xe7\x2d\xe3\xa9\x0b\xd7\x6d\x00\x2b\xd4\x80\xb7\x72\x30\x06\x82\xb3\xb4\x4e\x5b\xde\x90\x9f\x38\x09\xc0\x22\xfd\x9d\xd1\xe3\x83\x15\x99\xbd\x8d\xae\xff\xb0\xe1\x35\x3c\x64\x71\x9a\xef\x38\xee\xbd\x79\x6e\xdf\x68\xee\xcb\xd7\xf9\x77\x79\xd2\xd2\x3d\x8e\xfa\x75\xad\xc5\xfc\x60\xa7\xf5\x22\x7d\x62\xd0\x5a\x33\x3e\x51\x75\x4d\x86\x66\x59\xc3\x18\xbe\x4a\x95\xf1\x3b\x1c\x2a\xfe\x2f\xab\x10\x0b\x69\x06\xcf\x45\x0d\xc9\x8c\x38\xf1\xcc\x95\x90\x49\xae\xe8\x99\x34\x90\xd0\x8c\x66\xd7\xc5\xee\x25\x4a\xc9\x52\x39\xbc\x77\xd7\xa7\xcd\xa9\x91\x59\x63\x43\x0a\xb3\x57\xe6\x77\x42\xd3\x9c\x29\x85\x86\x30\x18\x4d\x85\xb8\x25\x47\x0f\x76\x6a\xe8\x2b\x36\x51\x27\x0e\xe7\xfb\x66\xf5\xc7\x84\xf1\x2c\x44\x45\xa1\x1e\xcc\xb5\xf2\x86\x1c\x7c\x48\x12\x56\x81\x7b\xe8\xea\x56\xbb\x60\x85\xe5\x65\xda\x4a\xd5\x06\x0b\x9e\x9c\x60\x2f\x6f\xcf\x55\xcb\xb2\x2b\x8f\x6c\xd1\x95\xc3\xed\xc5\xca\x6a\x2b\xe1\x68\xa5\xc7\x27\x07\x92\x13\x2e\x12\x50\xdd\x15\x74\xfa\xa6\x9a\x93\xa4\x60\xb3\x78\x00\xa3\x9f\xe8\xda\x20\x3b\xb4\x4b\x1f\x62\x32\xa8\xbb\xf5\xb0\x2e\x51\xdf\x54\xc4\xc5\xe8\x23\x59\x31\xa5\x7d\xab\xa4\x1b\x8a\x86\x24\xd0\x8b\x10\x53\xc1\x85\x4b\x92\x30\x4c\x54\x70\x44\x69\x24\x51\xd6\x9b\x87\x7b\xe2\x48\x74\x6d\xa9\x67\x95\x97\xb8\xee\x08\xc4\x64\x32\x1d\x5a\xab\xd8\x35\xdc\x31\x3d\xc5\x3a\xaf\xd3\x05\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\x4f\x87\xaa\xee\xa8\xae\x4a\xc1\x63\xbc\xa2\xc1\x26\x18\x8f\x21\x41\x41\xab\x0e\x60\x4b\xb5\x8f\xaa\xc2\xb7\x2e\xcb\xc0\x20\x98\x2b\x25\x9f\xb3\x7b\xf3\x94\xfa\x5d\x75\x97\xb8\x2b\x38\xbb\xfa\xe7\xe3\x01\x21\x97\x3c\x44\xf0\xf6\xcc\x2e\xd6\xaf\xf4\xa1\x67\xda\xbc\x62\xbd\x0f\x01\xbe\x40\xdd\x70\x66\xa4\x43\x59\x76\x80\xf1\x6d\xcc\xe1\xa4\x6e\x12\xef\x94\x1c\xa0\x69\xdc\x4d\x6a\xb6\xde\xcb\x00\x6d\x4c\xe5\xe6\x92\x8f\x65\x2e\x7f\x1e\x0e\x10\xd2\x96\xce\xb9\x6a\x0a\x1d\x15\x87\xbf\xae\xcd\x56\x93\xde\x83\xc3\x6d\x28\x52\x5b\x4d\x25\x54\x83\xc8\xe6\xbe\xba\x0b\xfb\xb7\x97\xcf\x2a\x19\x8f\x0b\x9b\x1d\x50\x2f\xb3\xe2\x4a\x6a\xa7\xc4\x88\xda\x99\xb7\x2d\xe4\x45\x06\x98\xc5\x59\x9b\xb9\x4a\x50\xad\x55\x93\xef\x85\x85\x54\x05\xe9\x5d\x71\x97\x1e\xf9\x1f\x3c\x94\x21\x10\xd5\xd7\x9d\x18\x86\xdb\xad\x86\xc8\x94\x6f\x2d\x81\x19\x96\x5a\x78\xd3\x05\x49\xd9\x78\x0c\x3e\xe0\xd5\x68\x8e\x54\xd2\xdc\x90\x78\x45\x1c\x08\x46\x30\x61\x36\x20\x32\x10\xb6\x43\x23\xee\xb9\x5c\xbf\x9e\x25\x86\x4c\x93\x9c\x4d\xa6\x16\x51\x08\xc5\x0c\x5d\xe2\x9d\x8a\x99\xa0\x29\xb6\xa4\x22\x42\x92\x3b\x2a\x73\xc3\x37\x68\x32\x45\x0f\x25\xe5\x24\x2d\x25\x56\x59\xd6\x40\xd3\x79\x5f\x69\xaa\x8d\xa4\x0c\xd2\x29\x94\x7e\xfd\xb1\xa4\xfe\x83\x23\x96\xd4\xdf\x70\xc4\x92\xfa\xb1\xa4\xfe\xf2\xd8\x9b\xe8\xd0\x58\x52\xff\x65\x95\x49\x8a\x25\xf5\x9f\xda\x9b\x10\x4b\xea\xc7\x92\xfa\x0f\x8d\x58\x52\xff\x91\x11\x4b\xea\xef\x30\x5e\x00\xe5\x8a\x25\xf5\x77\x18\xb1\xa4\xfe\xea\x11\x4b\xea\x2f\x8f\x58\x52\x7f\xed\x88\x25\xf5\x77\x1e\xb1\xa4\x7e\x2c\xa9\x1f\x2b\x8d\x6e\x37\xd7\x7e\x56\x1a\x25\xb1\xa4\xbe\x1b\xb1\xa4\xfe\x8b\xa8\xa7\x48\x62\x49\xfd\x8d\x46\x2c\xa9\x1f\x4b\xea\xef\x32\x62\x49\xfd\x97\x62\x2e\x89\x25\xf5\x63\x49\xfd\xcf\x47\xd0\x8d\x25\xf5\x63\x49\xfd\x58\x52\x3f\x96\xd4\x7f\x70\x15\xb1\xa4\xfe\x4b\x50\x01\x95\x4e\xd9\x4e\x15\x40\x37\x29\x56\xe4\x82\xd0\x6b\xb5\x01\x46\xe5\x78\x0c\x12\x29\x17\x3e\x79\x29\x78\xaa\xaa\xcb\xb8\xe8\x64\x05\xdd\xc3\xba\x47\x2e\x5f\x67\xcd\xed\xae\x18\x01\x56\xea\xac\x22\xc5\x2f\xde\x7f\xb5\xa2\x32\xd2\xce\x51\x85\xbb\xc6\x48\xe3\x9a\xdf\xf3\xdd\xfc\xe3\x6b\x00\xbe\x2a\x7f\xcc\xc1\x3d\xc9\x84\x72\x11\xee\x08\xac\x64\x4a\x39\x07\xaf\xef\x31\x8d\x76\x94\x11\x00\x27\xa2\x00\xe7\x9d\xa6\x44\x31\x3e\xc9\x80\x50\xad\x69\x32\x1d\x98\x27\x71\x0f\xec\x2a\x1a\xdd\x7d\xa3\xb4\x04\x9a\xfb\xb8\xfc\x9c\x32\x3b\x15\xa1\x89\x14\x4a\x91\xbc\xcc\x34\x2b\xc2\x64\x44\x01\x26\xd4\x58\x46\x15\x80\x81\x51\x71\x55\x08\x7b\xaf\x7a\x9a\x5b\x96\xa8\x97\xa6\x43\x6d\xb3\x87\xf5\xc0\xf3\x42\xcf\x43\x1c\x2f\x90\x31\x93\x4a\x93\x24\x63\xc8\xad\xf1\x89\x36\x77\x1a\xe7\xeb\x79\x5e\xcd\xdd\x4a\x95\x5b\x2a\x4f\x51\x6c\x2d\xb4\xb2\x51\xb1\xd5\x84\x6e\xaa\x94\x29\x27\xe6\xab\x1e\xa1\xbe\x6e\x9a\x05\xb4\x5f\x29\x82\xda\x73\x16\x3b\xbb\xfb\xaa\x36\x5d\xad\x5e\x6c\x15\x36\x5c\x21\x3a\xa6\x38\x78\xe4\xec\x35\xb2\x39\x2a\x81\x02\xa3\xf4\x96\x8e\x01\x6e\x00\x87\x99\xc1\x01\x48\xc0\xf0\x57\xba\x06\xeb\x3f\x39\xd2\xd7\x98\xe2\x3b\x50\x8a\x4e\x60\xb8\xa3\xa3\x61\x9d\x46\x86\xbe\x86\x6a\x63\x10\x15\x32\x9b\x5d\x1b\xbe\xa9\xa2\x33\x9b\x62\x10\xc9\xed\x9a\x82\xf0\x73\x27\x99\xd6\x80\x9b\x8a\x15\xf6\xd0\x57\xb9\x98\x80\x7f\xb8\x10\xe3\xf9\xce\x4f\x52\xdd\x6c\x88\x3a\x4f\x6d\xc4\xe5\x08\xc8\x48\x32\x18\x93\x31\xc3\x30\x4e\x0c\xac\xec\xd9\x82\x4b\xd4\x5a\x01\x94\x32\xfa\xae\xe0\x5e\x96\xf5\xeb\x1a\x90\x1f\xdc\xc2\xb4\x2c\x79\x42\x6b\xb5\x6c\x31\xc3\x94\x8d\xc9\x04\x03\x33\x9d\xb4\xf8\xa7\x57\x7f\xfb\x0b\x19\xcd\x0d\x4b\x43\xc9\x4a\x0b\x4d\xb3\xf0\x92\x19\xf0\x89\x81\x95\x3d\x9e\xcd\x1c\xc9\x00\x01\xec\xe6\x61\x17\xfe\xfa\x0f\xb7\xa3\x26\x8f\x3d\x49\x61\x76\x52\x83\x5f\x3f\x13\x93\x55\xfd\x51\x76\x0f\xd9\xde\x51\x25\x5a\x81\x66\x22\x63\xc9\xbc\x35\xa2\xf9\xca\x5f\x64\x2a\xee\xac\xac\xbf\x02\x7b\xaa\x74\xab\x42\x14\x65\x66\x8d\xce\x5f\x85\xec\xe2\x52\xc1\x72\x0e\xe0\xca\x73\x81\x66\x52\x37\xc5\x62\xdd\x74\x1b\x8f\xeb\x1f\x29\x5c\x6e\x89\x33\xe4\x85\x02\x60\xa8\x08\x7d\x45\xb3\x6c\x44\x93\xdb\x1b\xf1\x56\x4c\xd4\x7b\x7e\x21\xa5\x90\xcd\xb5\x64\xd4\x50\xcb\x69\xc9\x6f\x6d\x07\x87\x50\x22\x41\x4c\x8c\x68\x55\x94\xda\x27\x32\xac\x7a\x61\x9b\x2f\xef\x89\xb0\x57\x83\xaa\x59\xe0\x9e\x55\xba\x8e\x4b\xd5\xb2\x18\x59\x9f\x5f\xd5\x91\xed\x0f\xaf\xfe\xf4\x57\x8b\xba\x44\x48\xf2\xd7\x57\x18\xb3\xad\x7a\xf6\x10\x23\x6d\x33\x8c\x22\xa7\x59\x66\xd4\x86\x3a\x52\x1a\x40\xaf\x42\xc2\x4f\x8e\x83\xba\x3d\xba\x6d\x2c\x4a\xdd\xdc\xfc\x03\xe5\x28\xa6\x15\x64\xe3\x9e\xcd\x4a\x0a\x6a\xcd\x21\x32\x86\x43\x47\x7d\x30\x35\x6c\x0f\x04\xa0\x99\xc8\xca\x1c\xce\x61\xc6\xba\x68\xe2\xd4\x98\xcd\xab\xfa\x19\x53\x98\x00\x36\xca\x44\x72\x4b\x52\xf7\x63\x2d\xf2\x64\xb1\x12\xf8\xee\x50\xd8\x35\x06\xa7\x45\xec\xcd\xda\xf7\x6f\x44\xdd\xe4\xb4\x28\x42\x8e\x90\xa4\x77\x0d\x60\xe0\x99\xc4\x72\x05\x2d\xeb\xc9\xb4\x36\x33\xb7\x35\x32\xf7\xdd\x1b\x19\xba\xb9\xf3\x14\x3b\x47\x9d\xb4\xb7\x51\x57\xab\xdf\xdd\x30\xd9\x40\x88\x6a\x42\x7f\x1a\x0a\xfc\xdb\x66\x95\x2c\x65\x45\x86\xc4\xba\x80\x18\x56\x00\x30\xe8\x83\x24\x79\x77\x83\x6b\x07\xd6\xcd\x76\x21\x47\x0d\xb8\xf0\x60\x55\xce\xa9\x76\x02\xa1\x37\x5f\x53\x52\x80\x54\x4c\x19\xbe\xfc\x3d\x1e\xa8\xb3\x8c\xb2\xbc\x66\x02\x7c\x1a\x20\xd8\xc3\x8d\xe5\x93\xdb\x53\xca\xa1\x48\xdd\x84\x48\x0a\x6d\xe9\xe8\x15\x62\x6d\x53\xaa\xed\x90\xa1\x3e\x35\xa9\xfc\xbe\x82\x66\x93\x52\x9a\x6f\x02\xa9\xb4\x57\xbd\x24\x02\x89\xef\xf7\x5c\xe9\x63\x58\x7c\x47\x64\x00\x09\xa3\xdb\xdc\x26\x25\x6c\x28\x8f\xf6\xa0\xd4\x44\x7a\xa7\x07\x0e\x88\xf5\x82\x9b\x33\xe1\x6e\x25\x87\x6f\x0e\x9f\x94\x48\x5a\x10\x49\x51\xd0\x49\xab\x5e\x3e\x0b\x90\x5a\x9c\xb6\x5e\x68\xc2\xa8\x41\xf8\x7b\x28\xbb\x86\x57\x41\x5a\xd5\xd1\xc1\x2a\x49\xd6\x3b\xea\x01\xec\x14\x04\x9b\x8f\x7d\x47\xe7\x84\x4a\x51\xf2\xd4\xd9\x97\x82\x81\xef\xdd\xc2\x83\xaf\x04\x07\x6f\x38\x5f\xac\x53\x81\x16\x7d\xc6\xc9\xeb\xc1\xeb\x57\x2f\x85\x53\xe1\x1b\x2e\x70\xaa\xab\xc0\xa9\x2c\x7d\x7a\xd2\x77\xf5\x15\xef\x3b\x7a\xdf\x77\xce\xc4\x52\x15\xb4\x67\xbe\x5c\x36\x7e\x75\x27\x99\x86\x5a\x8f\xbf\x23\x54\x5c\x8c\x7e\x58\xab\xca\x70\xbc\xaa\x93\x44\x4b\x20\xb5\x2b\x83\xa1\xca\xd1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x65\xe1\x52\x0f\x90\xb0\x3a\xa0\x0e\x0e\xc8\x91\xbd\xf2\xd0\x26\x34\x1f\x3f\x29\x6a\x39\xa0\x5d\xdc\x17\x2d\x6a\x6c\x2e\xe4\xce\x17\x14\x6d\x70\x45\x87\x10\xfc\x2f\x98\xd2\x19\x60\x22\x37\xcb\xa8\xcc\xd0\xe7\x78\x6d\xd7\x4e\x46\xa5\x26\xc0\x67\x4c\x0a\x9e\x03\xd7\x64\x46\x25\xc3\xaa\x38\x12\xb0\xb2\x83\xd1\x45\xbf\x38\xfa\xfe\xf4\x03\x06\x34\x1c\xbb\x92\x14\x6e\x95\xa5\xf2\xe5\x6b\xea\x2b\xa9\x4d\xf7\xe8\xf6\xf9\x75\x18\x18\x22\xcd\xf5\xeb\x32\xcf\xc9\x4b\x5d\xda\xb6\x2c\xf7\x49\x56\x2a\x36\x7b\x2a\x4a\xe2\x32\xec\xcf\xd9\x4e\xfb\xbc\x90\xed\x5f\x01\x6a\x29\x71\x1f\x4d\xeb\x2b\x12\xf4\x96\x1c\x26\x87\x2a\x24\xed\xd5\x7d\xe0\xce\xf4\xe4\x6a\x69\xd8\xf0\x39\x5f\x71\x71\x49\x84\xc0\xba\x31\x4f\x6b\x84\x4a\xb9\x3a\xc3\x15\x6e\x07\xd6\x66\x40\x72\x23\x8f\xef\xfc\xea\xba\x5e\x84\xc4\xaa\x4b\x22\x1d\x90\x61\xf5\x65\x55\xa9\x06\xeb\xa7\x05\x25\x12\xe4\xa4\x2a\x2a\x3e\x01\x0e\x12\x85\x04\x33\x65\xa3\xad\x2a\x19\x51\x65\x9d\x3c\xe7\x57\xd7\xd6\x66\xbb\x1d\xcc\x76\x16\xb3\x77\x97\x50\x0d\xc7\xb7\x69\x0c\x3b\x08\xb7\xcd\x9e\x69\xc1\x60\x65\x00\x83\x4a\xa9\x9d\x98\x5c\x0e\x09\x4d\x53\x89\x6e\x1f\x27\xfa\xd4\x2a\x55\x06\xdf\x02\x56\x85\xa1\x0a\xea\x6b\xaa\x81\x1b\x49\x5c\x05\x58\x72\x5e\x16\x19\xb3\x6e\x84\xfa\x0d\x55\x35\x1b\x6c\xf2\xb5\x3d\xd2\xb6\x51\xf3\x76\x56\xf2\x5a\x50\x21\xb1\x6b\x51\xca\x07\x76\x4f\x82\x12\xd9\xac\x2a\x28\xbc\xb0\x6b\xee\x44\xa0\x49\x3c\xec\x9a\xaf\x41\xb9\xd1\x8e\x01\xd7\xd2\x1c\xcd\xc5\xdd\xc2\x2e\xf6\x59\x89\xa7\x29\x4c\xc8\x66\x80\xfe\x71\x57\x7e\xd3\x95\x71\xab\x4a\x1c\x5b\xdf\xb0\xad\x32\x0d\x54\x7a\x8a\x86\xab\xda\xf1\x24\x92\xa7\x42\x84\x45\x63\xc7\xf9\xd5\xb5\xa5\x84\xf6\xe5\x43\x77\xda\x55\xbb\x54\x51\xb5\x9d\x31\xf0\xc9\xaa\x0c\xb5\xd1\x3c\x16\x9a\xfb\xb9\x76\xdd\xad\x02\x59\x5a\x88\x7f\xad\x92\xed\x5a\x3c\x5d\x01\x95\xc9\x74\x17\xf8\x3f\x40\x08\xec\xa4\x24\x15\x36\x12\x60\x2c\x24\xaa\xc4\x7d\x24\xef\x99\x10\xb7\x65\xb1\x09\x45\x77\xd3\xd8\x86\x6b\x1b\x11\x88\xc6\x1d\x9f\x15\x4d\x4f\xb9\xda\xc5\xdf\xdb\x94\x7d\x40\x5b\x89\x07\x27\xaa\x12\x28\xc4\xa2\xde\x74\x96\x95\x4a\x83\xfc\x8a\x49\xa5\x0f\x7c\xbd\x68\xc4\x60\x6b\x13\x39\xac\x5f\xf0\x03\xd3\x53\x57\xba\xf1\xb0\xd7\xfc\xc9\x7c\x76\x13\x1f\x1a\x9d\xf6\xf0\x4a\x70\x38\x1c\x2c\x8a\x5d\x81\x94\x07\xb2\xb6\x96\xa7\xb8\xa5\x2b\xc8\x6c\xbc\x28\xfe\x50\xc3\x95\x1b\x57\xb6\xd2\x3c\xc1\xd3\x3f\x05\x9a\x50\x2c\x11\x87\x57\x4f\xab\x32\x93\xb6\x6e\x94\xad\x93\x29\x9c\xa0\x37\xaf\x83\xa8\x56\x4a\x4a\x8b\xf5\xaf\xbd\x8b\x3c\xb7\x35\x06\xd8\xf2\xa3\xae\x5e\xc8\x5b\xc6\x6f\xb7\x44\xbf\x66\x74\xc9\xc5\xd2\x6c\x8d\x7a\xe2\xd6\x47\xcb\xb8\x0d\xbe\x33\x2c\x86\x8e\x44\xa9\x7d\x4d\x12\x55\x53\x1c\x19\xff\x1f\xbb\x17\x68\x6f\x2f\x6c\xc5\xbe\x55\x3a\xa2\xea\x59\xa3\x8f\x57\x02\xd5\x9c\x6b\x8a\xb5\x45\xcf\x45\x72\x0b\x92\x64\x66\x19\x03\x52\x05\xbe\x34\xaa\x59\xca\x12\xb6\x8c\xba\xd8\xd5\xd2\x01\xc5\x14\x72\x90\x34\xab\x8a\xba\xb6\x00\xf5\x5b\x47\x38\xc3\xac\xf5\x98\x14\x5b\x14\xcd\x95\x61\x34\xe7\xf0\x62\xd5\x55\x39\x9d\xfb\x4a\xb7\x8c\x63\xb8\xc1\x3d\x53\x68\xd6\x2f\x44\x5a\x4f\x3c\x2b\x15\xc8\x7e\x48\x0b\x74\xb9\x37\x2a\x04\xe2\xa4\x30\x2a\x27\x13\xc6\x27\x8e\x3a\x23\x4d\xaf\x95\xdb\x0e\x9a\x0e\x46\x7a\x27\x12\x6c\xc1\x59\x94\x1e\x6c\x7c\x19\xab\x5f\x9f\x8b\xd4\x5e\x3e\x9a\x5b\x6d\xd0\xef\x6c\x15\x20\x7d\xc9\x89\x90\xae\x34\x02\x4d\x53\x5c\xfb\xf2\x1b\xe2\xaf\xcd\xb7\xea\x85\x38\x0e\x1b\xd9\x1d\xee\xaa\x81\x45\x95\x23\x23\xec\x94\x72\xdb\x0a\xa1\xbb\x12\xfe\x9d\x88\x7e\xb3\xde\xcf\x29\xaf\xb6\xf8\xac\x1e\x30\x47\x89\x86\xbc\x10\x92\xca\xf9\xa2\x0b\xd3\x10\x29\x83\x02\x06\x80\x0b\x90\x1a\x8a\x14\xe9\xf8\x8a\x8d\x9f\xd9\x4e\xbe\x2b\xf6\x7e\x25\x8e\x21\x15\xe4\x82\x78\x88\x1a\x7a\xad\x92\x29\xa4\x25\x46\x8f\x4f\x4a\x8a\x9d\xc6\xcd\x29\x76\xc6\xee\xb9\x0b\xcb\xb3\xc8\x10\x02\xfe\x42\x9a\xc0\x1c\x83\x64\xb0\x0a\xa7\xf9\x06\xab\x79\xda\xd0\x40\xdb\x68\x19\x9b\xae\x86\x28\xc1\x9b\xaa\xf7\x03\xbe\x2c\xcc\x58\xa2\xfd\x4d\xe3\x75\x88\x93\xd0\xd0\xdf\x75\x28\x5c\xf5\xbf\x04\x0c\x31\xd2\xaa\x7a\x15\x17\x55\x82\xf5\x3d\x7f\xe2\x86\x49\xac\xc7\xc5\x0a\xf1\x1e\x41\x39\x94\xab\x9b\x5b\xf1\xc0\xf1\x0d\x50\x5a\xf1\xee\xdb\x16\x4b\x6a\x21\x94\xef\xee\x71\xdb\xc9\x53\xd6\x46\xfe\xa7\x72\xd2\x5e\x57\x3a\x3c\x95\x93\x32\xb7\x35\xbc\xc5\x42\x19\x65\x8b\x73\x68\xd7\x32\x2c\xeb\xec\xdd\x79\x3d\x85\xa1\x1e\x9b\xed\x13\x40\x8c\x28\xd4\xd2\xde\xb9\x68\xf0\xbc\x34\xca\x59\xb0\xa2\x56\xb4\xd5\x69\x71\xce\xa2\x17\x9e\xe6\xb5\x58\xc6\x0b\xc3\x8d\x51\x86\xa8\x6c\x7a\x3c\x99\x52\x3e\x41\x33\xb8\x28\xcd\x7c\x5f\x7c\x81\x2b\x92\x90\x96\x89\xeb\x1b\xe1\xe3\x9f\xbf\xf0\xd6\x3f\x57\xc2\x07\xdb\xd7\xa9\x84\x16\x7e\xcd\xf5\xd7\xb2\xac\xfa\x0d\x61\x03\x18\x90\x83\x2f\x6a\x3f\x1d\xd8\xa7\x17\x52\x98\x47\xb8\xd0\x69\x5c\x55\xc6\x34\x1e\x84\x83\xfa\xd5\x03\x72\x61\x9e\x81\x1e\x91\x00\xc0\x5a\x74\xef\xa8\x02\x5f\x8f\x48\x98\x50\x99\x66\x98\x71\x37\x0e\x42\x89\xcd\xcb\x71\x00\xc3\xd3\x87\xf1\x74\x5c\xe8\x55\xd6\xc9\x0d\xd3\x22\x34\x55\xb7\xea\xc4\x8a\x32\xfd\x94\x6a\xda\xc7\x5e\x1b\x96\x68\x9c\x58\xf5\xba\xef\xaa\x9c\xf6\xa9\xc3\xa9\x7e\xd8\xd6\x93\xdf\xba\xcc\xaa\x3e\x0d\x57\x31\xde\xa7\x7d\xac\x37\xba\x7b\xac\xe8\x13\x84\x15\xb4\xd2\x74\x5b\x14\xbb\x5d\x14\x4f\x43\xb1\x73\x84\x01\xb6\x0a\xa9\x8a\x5b\x87\x08\x06\x57\xcf\xb5\x71\x90\x2f\xae\x6e\x3e\xfc\x63\xf8\xfe\xf2\xea\x26\x9e\xe7\x78\x9e\xe3\x79\x6e\x71\x9e\x81\xcf\x5a\x9f\xe5\xa0\xff\xac\x52\x09\x17\x8a\xcb\xd5\x32\xaa\x5f\x50\x70\xd6\x05\x9f\x7d\x4f\x8d\xc0\x57\x48\x50\x28\x8b\x18\xb9\x71\x95\x17\xd5\x5d\x60\xbb\x6d\x9d\x3d\xfb\xe8\xac\x27\x8c\xad\xea\x30\x66\xe5\xaa\x56\x08\x60\xd5\xae\xd5\xdb\xdb\x9d\xfd\x72\x79\x7e\x71\x75\x73\xf9\xd5\xe5\xc5\x87\x27\x0d\x36\x68\x59\xdc\xad\xc9\x8d\x77\xe4\x92\x85\x84\x19\x13\xa5\xca\xe6\xa1\x3e\xec\x6a\x22\xb0\x1c\xaf\xc6\x8d\x7a\x36\x0f\x25\x70\x57\xde\x16\x99\x6d\xb7\xcc\xb6\x19\x7b\xd1\xa2\xae\x47\x57\xe8\xfb\x95\x14\x79\x47\x28\x7c\x6d\x55\x76\x6f\xf2\x5e\x85\x4f\x87\xae\x04\x40\x83\xf5\x38\xe1\xb1\xaa\x37\x60\xa4\xd0\xbc\xd0\x2d\x8a\xff\x77\x52\xce\xb3\x9b\xca\x97\x36\x4e\xe1\x1d\x2d\xbe\x85\xf9\x07\x68\x59\x3e\x64\xc1\xd5\x90\x41\x62\x18\x1d\xb9\x85\xb9\xf5\x40\x9e\xf9\x87\xb5\x29\x73\xb2\x97\xd5\x50\x6f\xa1\x4d\xa5\xda\x2e\xcb\x98\xde\x42\x8b\xc0\x45\x3f\x96\x0a\x7a\x9a\x2d\x44\x39\xcd\xec\x69\xbb\xdd\x23\xdd\x96\x30\xfd\x08\x65\x5b\x0f\xeb\xec\xde\xd1\x59\xbd\x75\x75\x05\x31\x33\x9c\x0b\xee\x4e\x5c\xd0\x56\xdf\x68\xac\x7d\x8b\xb5\xea\x04\x23\x53\x4e\x7e\x8b\xff\x90\x9b\xf7\xe7\xef\xdf\x90\xd3\x34\x75\xc1\xc3\xa5\x82\x71\x99\xd9\x30\x60\x35\x20\xb4\x60\xdf\x83\x54\xd8\x3d\xed\x96\xf1\xb4\x47\x4a\x96\x7e\xd9\xa6\xe8\x92\x1d\x1d\xee\x82\xf0\x0e\x9b\x6e\x77\xe2\xda\xf9\xe3\xea\xbc\x2b\x10\x11\x62\x33\x03\x11\x37\x7d\xfd\x15\x27\x64\x74\x04\x9a\xb6\x8d\xe2\x88\xdd\xc2\x6e\xe9\xea\x61\x45\x58\x6d\x9c\x78\x28\x50\x95\xbe\x21\xaa\xc4\x42\x31\x2a\x74\x77\xc3\x7e\xa9\xbd\xe6\x47\x55\xd0\x04\x7a\xe4\x9f\xe1\x4b\xec\xc7\xae\x7e\x3c\x3c\xfc\xfb\xb7\x17\xff\xf8\xcf\xc3\xc3\x9f\xff\x59\xff\x15\x59\x21\x6a\xcd\x0b\x97\xa0\x7f\x87\x8b\x14\xae\xf0\x19\xf8\xd1\x89\x6b\xa7\x49\x22\x4a\xae\xdd\x0f\x98\xd5\x3b\x98\x0a\xa5\x2f\x87\xe1\x63\x21\xd2\xc5\x4f\xaa\x55\x25\xb1\xbd\x64\x0c\xb8\x45\x2d\xb2\x53\xec\xe8\x8e\x3d\x54\xb4\xa4\xe3\xa3\xea\x66\x0d\x9d\x2b\x92\x29\xe4\xb6\x96\xd1\x57\x1e\x04\xd8\x81\xd6\x97\x0f\xe0\x98\x73\x6d\x24\xd3\x66\x59\xb9\x83\xd9\xeb\x56\xad\xba\xed\xe8\x90\xb4\x85\x1d\xec\x18\x60\x08\x11\x07\x2d\x7b\x90\x03\x83\xf5\x5a\x4a\xe5\x8d\x3d\x1d\x5e\x92\x99\x85\xf0\xde\x00\xc7\x7b\xc1\xbe\xfa\xa8\x34\xae\xee\x6b\x6b\x68\x88\x6f\x6c\xc3\x56\xff\xbb\xcb\xb3\x57\xa1\xf4\x15\x18\xc5\xe6\xc8\x7e\x39\x48\x8a\xb2\xe7\x2e\x18\xe4\x90\x0b\x39\x0f\x1f\x83\x8f\xaf\xaf\xb4\x90\x74\x82\x79\x19\xf6\x76\x7b\x5b\xf8\x64\x6f\x6c\x3c\x60\xf9\x6e\xab\x0a\x27\xa5\x34\x42\x43\x36\xf7\x14\x79\xc7\x7a\x11\xd5\xd8\x43\xda\xe6\x41\xbf\x27\xa4\x2d\x60\x46\xdb\xb6\xac\x76\x34\x11\xb2\x72\xd4\xa3\xc0\x19\xa0\x88\xfa\xa4\xcb\x3b\xed\x05\x31\xc8\x5a\x03\xf8\xcc\x68\x96\x3b\x57\xce\xaa\x46\x87\xd4\x2c\x65\x33\xa6\x44\x8b\xec\x93\x30\xd1\xfa\x90\x7a\x57\xfa\xc2\x06\x0e\x05\xb3\xd9\x7d\x81\xc5\x82\xc2\x79\x5d\x20\xfb\xaf\xdb\xf4\x0b\xb2\xa3\xa0\x5a\x83\xe4\x6f\xc8\x7f\x1f\xfd\xf4\xfb\x5f\xfb\xc7\x5f\x1e\x1d\xfd\xf8\xaa\xff\xb7\x9f\x7f\x7f\xf4\xd3\x00\xff\xf8\xdd\xf1\x97\xc7\xbf\xfa\x0f\xbf\x3f\x3e\x3e\x3a\xfa\xf1\xdb\x77\x5f\xdf\x0c\x2f\x7e\x66\xc7\xbf\xfe\xc8\xcb\xfc\xd6\x7e\xfa\xf5\xe8\x47\xb8\xf8\x79\xc3\x49\x8e\x8f\xbf\xfc\xa2\xf5\xd2\x3b\xa8\xdd\x69\x47\x97\x15\x3c\x9b\x33\x76\x82\x7e\x1f\xb1\x6c\xbd\x1d\x1e\xbd\xba\x3e\xff\x3e\x7a\xf8\x4d\xc5\x90\x02\xbb\xde\x9b\x03\xae\x20\x91\xa0\x3f\x85\x25\xc7\x3e\xa9\x56\x41\xe0\x50\x91\xa0\x5a\xbc\x34\x3e\xf7\x39\x18\x77\x42\xc3\x39\xdc\xd7\x4a\x12\x1d\x4b\x91\xfb\xac\x70\x74\x6f\x60\x17\x7a\x7f\xdd\x2d\xb4\x6a\x81\x6a\x47\x34\x06\x45\x63\xd0\x9a\xf1\xa8\x31\xe8\xda\xe2\xe1\xde\x5a\x82\x80\xcf\x76\x75\x61\xac\xf4\xa0\x7b\x5d\xa7\x5e\x42\x6d\x33\x87\xda\xc0\x1f\xf5\xaa\x53\x63\x15\x42\x63\x19\x5a\xbe\xda\x87\x49\x4e\xb1\x23\xb3\x3d\xf8\x38\x41\x95\x76\x61\x55\x1b\x57\xe1\x0f\x66\x66\x09\xa1\x44\x74\xa3\x18\x24\x06\x3a\x62\xe8\xe9\x0f\x36\x12\xf4\xd6\x06\x87\x1a\x25\x8d\xf1\xaa\x8c\x66\x10\x0e\xab\xda\xcb\x54\x29\x91\xd8\xa0\xd6\x90\x04\x80\x95\xdd\xdc\xb2\x71\x35\xd8\x06\xbe\x90\x90\x40\x0a\x3c\x01\x57\x97\xb9\xd1\x95\x92\x72\x72\xc1\x67\xbe\x36\x75\xea\x53\x4a\x70\x25\xab\xe7\x78\x59\x01\x08\x06\x11\x9d\x13\xac\x16\x87\x80\x54\xbf\x8a\x66\xc5\x50\x0c\x31\xae\xac\xac\xbb\x35\xae\x6b\xcd\xc5\xdb\xf3\xcc\xe0\xd9\x6a\x25\x0c\x2d\x31\xcb\xca\xfc\xdc\x64\x92\x2f\xc1\x19\xd8\x9e\x7d\x7e\x76\xac\xb3\x23\xb6\xd9\x0d\xcb\xdc\xc2\x77\xd2\x25\x9b\xec\xc2\x59\x52\x48\x18\xb3\xfb\x8e\xce\xe9\x29\xaf\x2c\x31\x2c\x05\xae\xd9\x98\xd9\x14\x93\x42\x42\x01\xdc\x66\x09\xd0\x64\x8a\xb4\xdf\x71\xca\xca\x39\xbd\x8f\xc1\x3c\x56\xe0\xee\x96\x94\x5d\xaf\x12\xf6\x23\x1d\x23\x91\x8e\xed\x3c\x3e\x11\x1d\x73\x98\xbb\x3f\x44\x0c\x23\xcf\xdb\xc7\xbc\x9f\x35\x6b\xad\x20\x22\x6f\x8d\x68\x55\xda\xd1\x09\xce\xb2\x93\x01\xba\x15\x3e\xe0\x63\x87\x65\x96\x75\x54\x9f\xfa\xf0\x12\xa1\x51\x94\x59\xe6\xd2\x72\x07\xe4\x3d\xc7\x23\x79\x8a\x7d\x10\x7a\xe4\x0a\x66\x20\x7b\xe4\x72\x7c\x25\xf4\xd0\xca\xb6\xcd\x70\x36\x7b\x21\x61\x63\xf2\xc6\x68\x4d\x4a\x13\x6d\x6b\xd1\xd7\x2a\xe7\x08\xd9\x98\xa0\x2a\xca\xd5\x22\x0c\x7d\xfd\xb6\xfc\xd6\x27\x4c\xf6\x9f\x68\x9b\x42\xb3\x8f\x0e\xd4\x53\x37\x93\x0f\x90\xc3\xa0\x48\xe7\x1d\x59\x95\xf5\xfa\x0c\x0b\x51\x14\x42\xe9\x6b\xa3\xc5\x76\xd3\x08\x66\xe8\xa7\xc3\xde\x0a\x34\xcb\x20\x6d\x74\x02\xb2\x1d\x2c\x68\x53\x8b\xc6\x7c\xdc\xd0\x50\x01\xc8\x94\xf2\x34\x03\x89\x45\xd1\xd5\x62\xe5\x27\x56\x75\x01\x08\x7d\x1b\x7c\x82\x26\x4d\x12\x21\x53\xd7\x81\xd5\x25\x4a\xe2\x62\xc2\xf1\x42\x5a\x9b\x53\x4e\x27\x80\x96\x85\xa5\xd2\xba\x58\x70\x59\xd5\x9a\x3f\x4c\x85\xb8\x25\x89\xc8\x8b\x0c\x0f\x40\x8b\xf3\x51\xf5\x9e\x09\x28\xda\x37\xb3\xab\x93\x5a\x5b\x1a\xfc\xa2\x5d\x57\x9a\x56\xc2\x4a\x17\xa2\x0a\xdc\x43\xd2\x59\xdf\xba\x8b\x7b\x48\x6a\x8d\x17\xcd\x96\xb8\xce\x8b\x5a\xa0\x6d\xa3\x7d\x3f\xdd\xd6\x66\xf9\xae\x4c\xe1\x2d\xb2\xcc\xea\x63\xa1\xd0\x1a\xce\xe9\xeb\x4a\xbb\x47\x60\x89\x7e\x9b\x55\x8c\x99\x67\xbe\xd4\x74\xe3\x30\xd8\xa3\xb7\x54\x9d\x2d\x04\x1b\xfb\xb9\x30\xf7\x59\x08\x4d\x8e\x0e\x4f\x0e\x8f\x97\x6c\x74\x0b\xc5\x89\x6f\x6a\x77\x32\xac\xc6\x57\x60\x69\x3b\x48\x0e\xd3\x1e\x61\xda\x13\x5b\x5b\x14\x00\x57\xe5\xd2\xe1\x7a\x44\x09\xa2\x25\x4d\x99\xd3\x82\xf0\x5b\x73\x91\x96\xa5\xab\x08\x70\x74\xf8\xeb\x61\x8f\x80\x4e\x8e\xc9\x9d\xe0\x87\x1a\x97\x8f\xe5\x33\x4a\x55\x9b\x68\x2e\x4a\xec\x52\x67\x41\x10\x6a\x61\x18\x8a\x45\x44\x69\x5b\xda\x4c\xa9\xf6\x69\x78\x17\xf7\x4c\xfb\x36\x0e\x62\x4c\x5e\xd9\x8e\x3a\x40\x9d\x95\x30\x63\x33\x38\x99\x02\xcd\xf4\xd4\x06\x52\x70\xc1\xfb\xb6\x29\x9a\x21\x25\xee\x97\xb6\x3e\x85\x76\x26\xb7\xfa\x68\x61\x7e\x5b\x5e\x50\x4b\xe9\xda\x10\xd1\xaf\x77\xef\xd4\x4a\x96\x9a\x18\xdf\xdc\x0c\xbf\x6e\xf4\x6a\x45\x2a\xae\x75\xe1\xc3\x5b\x6a\x75\x25\xf6\x80\x76\x74\xe3\xd0\x6b\xd5\xb4\x95\x74\x48\xc2\xda\x36\x6f\x25\xcb\x4d\xa9\xb7\xeb\xda\x4a\xfe\x21\x4a\xec\x36\x47\x47\xd9\x9c\xdc\x51\xae\x7d\x2a\xde\x81\x99\xea\xc0\x90\x27\x83\x0d\xdf\x00\x4d\x41\x2a\xa4\x1e\x40\x77\xae\x9f\xe5\x47\x67\x8e\xa6\xda\xda\xba\xe5\x03\xa5\xd2\x22\x27\x53\xf7\xda\xcd\xf4\x44\x77\x32\x06\x78\x7a\x7c\xee\x8f\x84\xc2\x52\x38\x77\xcf\x8b\xa3\x5f\x4b\x74\xc3\xc2\xbd\x51\x67\x3e\xa9\x83\xad\xde\x8d\x84\x71\x0b\x2c\xdb\x47\xb0\x23\x5a\xda\x41\x80\x00\xe9\x30\x48\x80\xb4\x4b\x76\x5c\x9c\x08\x1d\x5f\xed\xe3\xa1\x3a\x8b\x3b\x20\x9d\xf9\xd6\xc9\x2a\x43\xa4\xc3\x19\x1b\x05\xdb\x11\x10\x3b\xf5\x68\x93\xf6\xe9\x94\xf5\xf1\x30\x00\xba\xd9\x7c\xd2\x25\x04\x8a\x0e\xc2\x9f\x97\x83\x9f\x97\xba\x69\x23\x99\xb0\xf5\x5a\xf7\x86\xcb\xb4\x6d\x2d\x4e\x56\xe7\x12\x4b\xc2\x43\x27\xd8\xe7\xd1\x5e\x9c\x74\x17\xa6\xd8\x75\x90\x62\xa7\x21\x8a\x1f\x35\x40\x11\xd3\x22\x5a\x53\x91\xa6\x7d\x1c\xa7\x34\x18\x60\xf4\x36\xa3\x71\x3a\xd9\xcf\x59\x77\x7c\xb7\x8a\xa6\x39\xd4\x1c\xb5\xbd\x38\x63\x3a\x29\xae\x45\x72\xdb\xa1\x5e\x73\x0e\x85\x84\xc4\xda\xc9\x6e\xce\x86\x76\x76\xa3\x5f\x5e\xbd\xbf\xa9\xc2\xf1\x31\x66\xa5\x32\x5c\x7e\xe3\x2c\x69\x46\x27\xbd\x85\x42\x07\xd5\x7d\x44\x93\xdb\x3b\x2a\x53\xb4\x6c\x51\xcd\x46\x2c\x63\x7a\x8e\xca\xb9\x04\x8c\xf5\xe7\xc2\x06\xc5\xd9\x22\x89\xc2\xb7\x3a\x0d\x7d\xb8\x83\x0d\x0b\x2d\x64\x2e\x7a\x66\x4c\x99\xd1\xc7\x43\x3f\x5b\x1b\x35\x93\x14\xc1\xa4\x57\xb7\x4c\x47\xe5\xcb\x8f\xbd\x55\xbe\x6a\xbd\x5a\xb7\xd5\xc3\xda\xc6\xee\xed\x31\xab\x73\x2c\x4e\x86\x56\x64\x91\xd5\x75\x34\xdf\xfe\xb2\xba\x42\xc2\xb5\x16\x45\x47\x5e\x12\x3b\xd9\x1a\x1f\xc9\x08\xc6\xc2\x10\xe1\xb5\x4e\x8f\xb4\x04\x57\x2e\xf3\x74\x78\x19\xac\x5a\xa2\xe1\xd8\xb0\x51\x8b\xbe\x46\x66\xc6\x66\xc0\x41\xa9\x13\x74\x87\x94\x85\x6b\xc7\xef\xba\xce\xf6\xcc\xdb\x41\x8e\xab\xeb\x55\x99\x00\xae\xe7\x2d\x7e\x09\x3a\xb1\x96\xdb\x1a\x21\xc7\x76\x5a\x6e\xf9\x8b\x6e\x94\x44\x52\x35\xb5\xfd\x60\xe1\x9e\x69\xd7\xd3\x78\x68\x6b\xe8\xd6\xdb\xd2\x4e\x24\x4d\x80\x14\x20\x99\x30\xcc\xa8\xe4\x3a\x15\x77\x9c\x8c\x60\xc2\xb8\xf2\xa0\xc0\x2a\x98\x0e\x66\xe8\x8f\x61\x2a\x94\x4c\x1b\x90\x0f\x8d\x82\x20\x2e\x55\x27\x11\xd5\xd1\x74\x6b\x5e\xf4\x24\x21\xc7\x42\x38\xd9\xee\x2a\x01\xc2\xf5\x86\x33\x8f\x2d\xf9\xa8\xe4\xf8\xe4\x14\x32\x3a\xb7\x11\x99\xd8\x2b\x9a\xfd\x1b\xa4\x3a\xee\xc0\xe3\x64\x5b\x26\xf9\xdf\xd6\xae\x03\xcb\x8f\xd2\x64\xda\xce\x85\x1b\x5d\x54\x1b\x8e\xe8\xa2\x6a\x33\x49\x74\x51\x45\x17\xd5\x23\x23\xba\xa8\xa2\x8b\x6a\x61\xec\xad\x96\x14\x5d\x54\x3b\x8f\xe8\xa2\x7a\x78\x44\x17\xd5\x06\x23\xba\xa8\x36\x1c\xd1\x45\x15\x5d\x54\xd1\x45\x15\x5d\x54\x9f\x91\xdd\xce\x8f\xe8\xa2\x5a\x9a\x24\xba\xa8\xa2\x8b\x6a\xe3\xb1\xb7\xca\x57\x74\x51\xd9\x11\x5d\x54\xcd\xf1\x79\xb1\x3a\xef\xe0\x19\x1a\x55\xaf\x7d\x23\x5e\x54\x18\x1d\x8d\x7d\x91\x69\x4f\x6d\xec\xff\x9f\xc6\xf6\xbf\x27\x8e\x92\x0e\xec\xfd\xd1\xd6\xff\xe2\x6c\xfd\xdd\xd8\xc9\x3a\xb0\x91\xb5\xa6\xc9\xce\x05\x7e\x33\x95\xa0\xa6\x22\xdb\x19\xd1\x1b\x48\xfe\x8e\x71\x96\x97\xb9\xc1\x39\x65\xf0\x99\xcd\x82\xaf\x5d\x55\xdd\x89\xd1\x05\x6f\xcd\x75\xe6\x42\x96\x02\x56\xde\xa4\x2c\x33\xdb\x88\x89\x92\x53\x3a\x33\xb8\xae\xca\x24\x01\xc0\xbe\x5e\x75\x55\xe2\x8f\x83\xf0\xa4\xd0\xc7\xe1\x75\x3b\x7a\xd3\x8e\x5b\xda\xda\x98\x38\xcb\x1f\xff\xb0\xd3\x1c\x13\x59\x74\x43\x97\xbf\xfe\x30\x3c\xab\xd1\x65\xca\x3d\x59\x66\x7c\x26\xb2\x99\xed\xfe\x8a\x17\x19\xa9\xc8\xb5\x8d\xc5\x6e\xa5\x23\xd0\xb4\xa6\x44\x38\xf9\x5b\xd9\x36\xc5\xe6\x3e\x73\x57\x48\x69\x1f\xda\x40\x0a\xa0\xba\x94\x40\x26\x54\x3f\x25\xc1\x6f\xaf\x2b\xb4\xd2\x13\xba\xe0\x37\x6d\x45\xe1\xa6\x1c\x63\x04\xde\xa6\xb9\x67\x82\x78\x61\xcb\xb9\x6f\x2c\xf0\xb6\xa6\x94\xed\x85\xd0\xf6\x47\x8b\x60\xbd\x15\x7c\xf1\xce\x00\x7c\xe0\xfa\x6c\x7b\x76\x5e\xd7\x36\x7c\x8b\x23\x2d\x48\x91\xd1\xaa\x49\x11\xee\xc0\x37\xc8\x83\xce\xa6\x90\xdc\x7e\x70\x2e\xcf\x23\x05\x10\xe2\x55\x26\x4c\x4f\xcb\xd1\x20\x11\xf9\x89\x21\x09\xf6\x7f\xa3\x4c\x8c\x4e\x72\xaa\x34\xc8\x93\x54\x24\x8e\xc5\xf5\x13\x33\x0b\xe3\x93\x41\x9e\x1e\x63\x1b\xdc\xcb\x66\x53\xc4\x5a\x29\x04\xf3\x7c\xa7\x0c\x92\x11\x18\xea\x2a\x50\xe1\xaf\xd5\x53\x33\xcb\xdb\xba\x71\x6d\x7d\xb4\x66\x49\x2d\xdd\xcd\x9f\xde\xd5\x1c\x29\x17\xe9\xc0\xb2\xf1\xdc\x5c\xca\x9d\x85\x56\x74\xe0\x4a\xde\x23\x37\xf2\xde\x88\xc6\xfb\xe2\x3a\xde\xc3\xd2\xc7\x1d\x78\x3a\xbb\x70\x15\x77\xe7\x26\xfe\x08\x15\x82\x3f\x8e\x7b\xb8\x43\x1b\x5a\x47\x6e\xe1\x4f\xe1\x12\xee\xe4\xad\xdb\xba\x82\x3f\x9d\x1b\xb8\x9b\xd7\xed\x52\x11\x78\xae\xae\xdf\x0e\x6c\xe1\x5d\xda\xc1\x3b\xb3\x81\x7f\x34\x57\x6f\x7b\x37\xef\x1e\xb8\x78\x5b\x03\x99\x71\xa6\x19\xcd\xce\x21\xa3\xf3\x6b\x48\x04\x4f\x77\xe6\x30\x0b\x25\x23\xc3\xf9\x51\x76\x5a\x67\xa7\x6a\x66\x34\x4c\xa9\xab\x8c\x6d\x34\x2a\x9b\xc1\xe1\xfd\x13\x4e\xa0\x40\xd7\x82\x5d\xe5\x2e\x45\xe7\xee\x84\xbc\xcd\x04\x4d\xd5\x49\x21\xec\xff\xaa\x7c\x85\x5a\xa2\x82\x7d\x56\xbb\x4c\x85\xa7\x36\x88\xd9\xf4\x8e\x2e\x37\xf1\x1b\x71\x47\xc4\x58\x03\x27\x47\x8c\xfb\x7d\x3c\xae\xa9\x81\x95\x75\x32\xa0\xb5\xf9\xf5\xf5\x2b\x7f\xf1\xcb\x33\x3b\xa2\x81\x55\xa9\x8f\x6f\x05\x76\x0f\x7a\xdc\x0c\xec\x2e\x1c\x97\x59\xd3\x14\x6c\xcd\xc3\x4d\x7a\xf3\xba\xaa\xed\xfb\x1a\xe7\x0d\xa7\x8d\xf2\x94\xb8\x94\xaf\x97\xb7\x69\xad\x03\x58\x9a\xa2\x5f\x08\x58\x79\xcc\x6a\x7c\x73\x36\xb4\x46\xe3\x68\x2e\xd9\x17\x73\xc9\x13\x05\x81\xec\xa1\xa0\xfb\x4c\x03\x3f\xa2\xa0\xbb\xc5\xa8\x25\x81\x7e\x2d\x69\x02\xc3\xce\x65\x04\x7f\x9c\x48\x5a\x4a\xea\x08\x60\x10\xf9\xfc\xe1\xe1\x00\xa9\x3d\x4d\x21\x71\x16\x53\x52\xc7\x65\x96\xcd\x49\x59\x08\xde\x4c\x33\xb6\xbe\xf6\xc5\xac\x55\x34\xc9\xaf\x78\x4a\x25\x58\x16\x52\x38\x9e\x29\x4b\xce\x0d\x0d\xae\x1a\x74\xa1\x20\x89\x55\x8d\x69\x23\x37\x56\xb1\x89\x59\xbe\xe1\x7f\x98\x36\x5b\x45\xfa\x35\x26\x34\x77\x8f\x85\x4c\xd8\x28\x9b\x93\x29\xcd\x42\x37\x16\x4a\x6e\x59\x96\xb9\x69\x06\xe4\x1a\xb4\x75\x29\x58\xde\x99\x09\x3e\xc1\xc5\x51\xee\xbb\x00\x42\x62\xee\x4d\x32\xa0\xbc\x2c\xec\xf3\x0c\x27\x9e\x8b\x52\xfa\xe7\x0d\x82\x63\xa2\xea\xba\xcf\xb2\x5e\xad\xd7\xd8\x83\x1b\x1b\xfa\xd3\x94\xca\x08\x00\xef\x7d\x15\xe7\x5e\x7d\x4e\x31\x03\x29\x59\xea\xec\xfc\xf6\xbb\x42\x8a\x19\x4b\xad\x77\xc3\x83\x0d\xbb\x1a\xdb\x6e\x32\xe1\x3c\x73\xc1\xfb\x1c\x26\x14\x05\x15\x77\x8a\xec\x9e\xd9\x79\x6c\x04\x01\x4f\xb1\xbf\x8c\x91\xf0\x45\xd1\xc8\x5b\x9f\x31\xdb\x19\xb7\x06\x39\x72\xc4\x05\x11\x18\xf8\x59\x72\xa6\x6d\xb7\xf5\x69\xa9\x49\x2a\xee\xf8\xf1\x56\x5e\x57\x74\xb4\xde\xac\x04\x50\xd3\xfd\xba\x4a\xce\xb1\xef\xfb\x30\x78\x99\x72\xa6\xcf\x31\x29\xb9\x82\x96\xec\xbd\x33\xe1\xe8\x2f\x7f\xda\x8d\x46\xb0\x1c\x44\xa9\x3f\x89\xf6\x77\x37\x65\xc9\xb4\x2e\xcc\xb2\x1c\x14\x11\xe5\x82\x5a\xfc\xda\xdd\xb6\x7a\x87\xa2\x0a\xb8\x6a\xec\x6a\xd8\x5d\x61\xfd\x72\x0d\x4b\x97\xe3\xf7\x6a\x0d\x99\x31\x34\xfb\xfc\xea\xfa\x97\xb7\xa7\xff\x75\xf1\xd6\x9d\x4f\x5e\x67\xfa\x25\x67\xff\x2a\x81\xd0\x5c\x18\x59\x38\xab\x87\x01\xf6\x50\xa3\xaf\x7d\x81\x27\xb9\xdb\x80\xc1\x1d\x19\x32\x76\x8f\x6f\x1f\x16\x89\x3d\xe8\x3f\x7e\x54\xe4\x53\x77\xd5\xaa\x82\x5b\x8c\xdc\x58\xeb\xaa\x45\x09\x07\x6d\x4e\x9e\x95\x28\x6d\x97\x35\xc6\x27\x59\x5d\x98\xdc\x8d\x5c\xb5\xd5\x89\xda\x6a\x44\xfd\xea\x0d\x86\xbb\x2a\x46\x9d\x74\xf7\xaa\xd6\xd0\x51\x4f\x9c\x8a\x6a\x7b\x35\xc0\x36\x2d\xf6\x6a\x80\x15\x3d\x2e\x87\x84\xa6\xa9\x44\x31\x05\x4f\x7d\xbe\xd0\x1b\xb3\xa8\x62\x69\x7a\xe4\x15\xf9\x3b\xb9\x27\x7f\x47\xb5\xe0\x2f\x6d\x3b\x08\xb5\x15\xd8\xbb\x08\x8d\x31\xda\xe8\xe5\xb0\x23\x88\xff\x30\xa5\x1a\x67\x34\x50\xd5\x82\x8c\x98\x13\x43\xe1\x5e\x83\x34\x62\x91\xdb\x89\x27\xed\xbd\x64\x16\xf8\x09\xd1\xcc\x9a\xc9\x2f\xc7\xcd\x70\x9c\xed\x10\xcd\xdc\x6e\xf4\xfb\x2b\x47\x85\x9a\x7d\x4e\xaa\xd9\x72\xaa\x93\x69\x93\x8c\x19\x01\x43\x35\x98\x53\x2a\x90\x8c\xdb\xb0\xdb\x29\x6b\xe1\xf4\xdf\x1f\x34\x6e\xe7\x07\x6e\xec\xe7\x43\x3b\xb5\xa0\xf8\x23\x9f\x77\x82\x41\xad\x74\x52\x21\xd2\x01\xb9\xa0\xc9\x14\x97\x95\xd6\x78\x86\xd1\x40\x70\xb2\x29\x9d\x99\x8d\x77\xf7\xda\xbe\x40\x28\xad\x04\xeb\x28\xe2\x92\x39\x4f\x09\xe5\xb6\x39\xe7\x18\xa4\xb4\x91\xd2\xa3\xb9\x0f\x32\x6b\xbd\x79\xad\x4e\x52\x21\x85\x16\x89\x68\xd1\x1e\x6a\x31\xfb\x02\xa7\x43\x20\xd8\xe8\x54\x6f\xde\xfd\xee\x7c\xd8\x23\x37\x67\x43\x6c\xea\x73\x7d\x76\x33\x6c\x4a\xd8\x07\x37\x67\xc3\x83\x27\x05\x05\xf1\x66\x36\x34\xa8\xee\x30\x49\xc3\x60\x92\x31\xa5\xfb\x39\x2d\xfa\xb7\x30\xdf\x91\xa7\x76\xc1\xd7\xfb\x61\x87\x3b\x79\x21\x0b\xe6\x9c\x16\x5b\xcf\x26\x81\xa6\x2c\xa6\xf9\x6c\x3e\x62\x9a\xcf\x86\x23\xa6\xf9\xc4\x34\x9f\xe5\xb1\x37\xb1\x8c\x31\xcd\xe7\x65\xb9\x6e\x63\x9a\xcf\x67\xee\xfd\x8d\x69\x3e\xab\x47\x4c\xf3\x89\x69\x3e\x9b\x8d\x98\xe6\xb3\xfd\xd8\xbb\xb8\x95\x98\xe6\xb3\xd5\x88\x69\x3e\xcb\x23\xa6\xf9\xac\x19\x31\xcd\x67\xcd\x88\x69\x3e\x31\xcd\x27\xa6\xf9\xc4\xe8\xc7\x47\xe7\xda\xcf\xe8\x47\x12\xd3\x7c\xdc\x88\x69\x3e\x2f\x22\xc6\x8b\xc4\x34\x9f\x8d\x46\x4c\xf3\x89\x69\x3e\xbb\x8c\x98\xe6\xf3\x52\xcc\x25\x31\xcd\x27\xa6\xf9\x7c\x3e\x82\x6e\x4c\xf3\x89\x69\x3e\x31\xcd\x27\xa6\xf9\x3c\xb8\x8a\x98\xe6\xf3\x12\x54\x40\xdf\x73\xb5\x7d\x8e\xca\x07\x3f\xd3\xe6\x61\x7d\xe4\x62\xc5\xb7\x68\x09\x51\x85\x99\x44\x56\x53\x66\x12\x68\x3a\xc7\x29\xb1\xcf\x43\x4d\xc8\x7a\x86\xd1\x81\x19\xcb\xd9\x6e\x69\x41\x64\xe9\xd0\xbc\xc5\xb9\x6a\x5e\x17\x03\x96\x9c\xde\xe3\x01\xa0\xb9\x28\x6d\xeb\xd7\x44\xe4\x45\xa9\x9b\x30\xc5\xed\xd9\xa5\x6b\xeb\x98\x4d\x1c\x47\x3d\xb1\x0d\x66\xfb\x61\xda\x7e\xad\xa9\xeb\x13\xb6\x6a\xa5\xa9\x8f\x9a\x1b\x76\x11\x34\x42\xb5\x06\xc9\xdf\x90\xff\x3e\xfa\xe9\xf7\xbf\xf6\x8f\xbf\x3c\x3a\xfa\xf1\x55\xff\x6f\x3f\xff\xfe\xe8\xa7\x01\xfe\xf1\xbb\xe3\x2f\x8f\x7f\xf5\x1f\x7e\x7f\x7c\x7c\x74\xf4\xe3\xb7\xef\xbe\xbe\x19\x5e\xfc\xcc\x8e\x7f\xfd\x91\x97\xf9\xad\xfd\xf4\xeb\xd1\x8f\x70\xf1\xf3\x86\x93\x1c\x1f\x7f\xf9\xc5\xce\x4b\x6e\x2d\xf0\x76\x27\xee\x76\x24\xec\x7e\x14\x51\xd7\xb9\x6b\x3b\x3a\x8b\x2e\xd4\x64\xe9\x34\x3a\x76\xf4\xd0\x69\xf4\x1a\x37\x0a\x71\x61\x1e\xa6\x88\xc8\x99\xd6\x8e\x8a\xd2\x7a\xb0\x2a\xd3\x0d\x95\xd3\xd1\x01\x6c\x88\x4d\xb5\x6d\x54\x1d\x02\x3d\x6b\x21\x2a\xc2\xcb\x75\xae\x93\x37\xcb\x8b\x0c\x1b\x44\xe3\x79\xee\xfb\x48\x15\x64\x9d\x91\x36\x3c\x3e\x22\x6d\x78\x89\xb4\x41\x41\x52\x4a\xa6\xe7\x67\x82\x6b\xb8\xdf\xc9\x7e\xb2\xce\x80\x74\xdd\x9c\xda\xc5\x86\x29\x17\xd3\x66\x7f\x23\xa2\xb0\xf1\xdd\x6b\x33\xa7\xa7\xa2\xcc\x52\xcc\x4b\x2a\x39\xaa\x94\x36\xc5\x0d\xb4\xd5\xf7\x50\xd3\xc1\xe0\xed\xc5\xc7\x79\x0d\xce\x4e\xfd\xaf\x92\xcd\x68\x66\xf4\xdb\xea\x8e\x21\xea\x2c\xf5\x9b\x76\x32\x62\x3d\xb1\x8c\x85\xe2\xcd\x50\xb2\x19\xcb\x60\x02\x17\x2a\xa1\x19\x52\xa5\x6e\x28\xfd\xe9\x9a\xd9\x71\x8b\xa4\xc8\x14\xb9\x9b\x02\x76\xe0\xa7\x5e\x3d\xc7\x44\xb2\x09\x65\x9c\xe4\x86\xa8\x16\xfe\x66\x65\xf5\x7c\x43\xbc\x8d\xd4\xcb\x75\xa5\xcf\xa3\xfa\x3a\x12\x22\x73\xd9\x08\xd9\xbc\x9a\x9f\x59\xd3\x1b\x17\xbf\x70\xb8\xfb\xc5\xcc\xa6\xc8\x38\xa3\x93\xa0\xc6\x2b\xd0\x4b\x96\xb8\x6a\xea\xb5\x2f\x80\xa1\xfe\x25\x10\x9a\xdd\xd1\xb9\xaa\x8c\x1a\xd5\x1c\x4c\xbd\x21\xaf\x8f\x11\xf1\xa8\x22\x61\x8e\x94\xfc\xe1\x18\x5d\x73\x67\xa7\xc3\x5f\xae\xff\x71\xfd\xcb\xe9\xf9\xbb\xcb\x2b\x72\x25\x34\x58\x96\x54\x6b\x92\x96\x50\x6e\x34\x04\xb7\x4a\x7c\x06\x6a\xd0\x42\x0d\xd0\xae\xc8\x14\xb9\x63\x3c\x15\x77\x6a\x67\xfb\xa9\x45\x3f\x03\x3c\xa0\x7c\xa7\x39\x12\x5a\x50\xec\xfd\xd6\x82\x3f\x2c\x45\x7f\xd4\x27\x45\x0e\x9c\xa6\x27\xa9\x14\x85\x05\x82\x37\x40\xd5\x95\xa4\xf3\x05\xbb\xb2\x8f\x2f\xc5\xfd\x1d\x37\x27\x9c\x48\xca\x75\x65\x89\xa9\xf6\xcc\x35\x9d\x1b\xb4\xde\x8e\xe7\x9d\x6d\x44\xd3\xee\x32\x8d\x4e\xd3\x14\xd2\x06\xf8\x5f\x5c\x54\xdf\x99\x7f\xb9\x79\x55\x8c\x81\x0c\xdf\x5f\x5f\xfe\xef\x05\x3c\x9e\x17\xed\x82\x98\xba\x49\x00\x95\xa2\xe8\x6c\x77\x3f\x40\x2e\x66\x71\x7f\xf7\x65\x7f\x03\xb7\xec\xc6\x75\xfe\xa1\xe4\x75\x86\xc6\x6b\xf3\x93\x5c\xa4\x30\x20\xc3\x60\xc3\x6f\xfe\x5a\x2f\x32\x23\x81\x98\x4b\xb8\x66\x34\xcb\xe6\x75\x61\x4a\x0b\x9b\x21\xd8\x28\x41\x50\x27\xe4\x63\x9a\xa9\xa7\xa6\xc6\x6d\x78\xa3\x91\x23\xde\x19\x6d\xb6\x93\xed\x08\xb3\x91\x14\xb8\xd0\x4e\x18\x36\xab\xc4\xb2\x0e\x52\x24\xc4\xaa\xce\xb5\x40\xa9\x06\x7f\x53\xd6\x8f\xe0\x59\x23\x53\x1e\xd8\xc3\x30\xb3\x35\x22\x97\x0a\xd4\x6a\xd6\x58\x29\xd3\x66\x76\x09\x34\x15\x3c\x9b\x63\x54\xa4\x8d\x73\xc8\xa9\xba\x85\xd4\x7e\xe1\x44\xb3\xe0\x45\x30\x33\x86\x47\xdd\x98\x75\x7b\x97\x01\x8a\x64\x36\xfa\x02\x5d\x0d\x46\xc3\x7f\xd2\x5d\x6f\x71\x08\x0d\x50\xde\xf3\x6c\xfe\x41\x08\xfd\x55\x48\x71\xed\x04\x03\x7e\x70\xd2\x32\x02\xa4\x19\xe9\x45\xf1\xb9\x7d\xdc\x0d\x3c\x54\xf5\xec\xda\xf3\x6a\xc7\x9f\xfb\x91\x92\x25\x3f\x55\x5f\x4b\x51\xee\xcc\xc4\x96\x84\xcd\xaf\x2f\xcf\x91\x14\x95\xce\x8d\xc8\xb5\x9c\x17\x82\x59\x1b\xd4\x1a\xc5\xe0\x3b\xe7\x08\xad\x9f\x89\xca\x67\x45\xde\xd1\x39\xa1\x99\x12\x1e\x96\x8c\xaf\xd2\x17\x89\x53\x46\xcd\xcf\x23\xa1\xa7\x4b\x5a\xa8\x39\x50\xcb\xf7\xf5\x6a\x5e\xc5\xaa\x36\x18\xe3\x4b\xb7\x6b\x7a\x0b\x8a\x14\x12\x12\x48\x81\x27\x4f\xbd\xed\x4f\xed\x8c\x43\xd4\xb9\x12\xdc\x1c\xcc\x4e\x90\xe7\x32\x78\x61\x1d\x48\xeb\xa8\x82\xfe\x5c\xa7\xfd\x51\xf4\xea\xe2\xb1\x2c\x15\x48\xeb\x82\x96\x25\xd8\x9d\xfc\xb6\x1c\x41\x66\x20\x6f\x54\x52\xd7\x31\xdb\x1a\x1e\x58\x4e\x27\x40\xa8\x0e\x98\xa6\x05\x01\xae\x0c\xc5\xb4\xe6\x4b\x4d\x52\x01\x55\x66\x3c\x55\xe4\xbb\xcb\x73\xf2\x8a\x1c\x99\x67\x1d\x23\xfe\x60\x43\x6d\x2d\x6c\x00\xda\xa2\x8e\x3a\xf6\x53\xe0\x92\x10\x79\x89\x90\x96\x48\xf4\x08\x17\x44\x95\xc9\xb4\xde\xc5\xdb\xab\xcd\x2e\x48\x11\x1d\x23\xfb\x89\xeb\x4f\x4b\xa1\xbe\x53\x20\x3b\x23\x50\xdf\xed\x40\xa0\xea\x62\x94\xc1\xb9\x26\xf4\x2c\x62\xe5\xa0\x69\x4a\x35\x75\x84\x2b\x74\x55\xdf\xd7\x2d\xfd\xbc\xc9\x97\x82\xb7\x8c\x97\xf7\xd6\x44\xda\x9d\xa9\xe5\xfa\x02\xa7\x45\x1c\x42\xa8\xe3\xae\xd3\xa2\xc8\x58\xe5\x40\xae\x05\xa9\x5d\x36\x70\xa5\xb7\x46\x4c\x44\x3a\xe1\xfd\xd0\x46\x38\xa1\x3c\x15\xf9\xd2\xc3\xd0\xe9\x4d\x93\x69\xfd\x01\x11\xfb\x9a\x63\x4f\x8c\x42\x19\xcc\xa0\x45\x09\xad\x05\xcc\x7b\x6b\x66\x33\xc0\xf1\x18\x81\xd3\x93\x8c\x8e\x20\xb3\x30\xb6\x18\xa8\x96\x31\xf0\xa9\x23\x45\xa5\xc8\xba\x4b\x6d\xf9\x20\x32\xb0\xa1\x57\x1e\x10\x66\xfa\x67\x01\x07\x9c\xa4\x2b\x38\xa0\x36\xd8\x80\x03\xea\xb5\xcf\x01\x0e\x65\x0b\x56\x4f\x16\xe1\x60\xe4\x86\x26\x1c\x90\x79\xef\x3b\x1c\x14\x24\x89\xc8\x8b\xa1\x14\x46\xed\xec\x8c\x37\xb9\x69\x2b\x3f\x9f\x35\x6c\xa0\xdd\xbe\xae\x01\x3b\xaf\x5e\xf3\x62\x2a\x6b\x41\x97\x54\x5b\x26\xe1\x23\x2f\xff\x57\x8d\x67\x21\xe9\x59\x64\x64\x7e\x96\x86\x23\xd0\xdc\xe9\x7e\x78\xce\xec\xa0\x8b\xbc\x85\x16\xc6\xce\x4e\xb8\x91\x48\x68\x86\x25\x52\xdb\xa1\x1c\x59\x44\xbb\xc5\x89\x6b\xa1\xb6\xe8\xa3\xc4\xef\x7c\xf8\x07\x56\xcb\xc4\x6f\x9c\x09\x93\x8b\x14\x6a\x5e\x67\x1b\x23\x7c\x63\x43\x32\xf1\x3a\x1f\xe5\x6b\xe4\x0a\x17\x05\x02\x69\xe3\x6e\x2d\x5c\x75\xb2\x77\xa1\xf0\xaa\x59\x20\xf0\x94\xf1\x09\xda\xd5\x7a\x44\x42\x66\xe3\x83\x1d\x11\xb8\xb5\x1a\xe4\x21\x1e\x09\x3f\xa9\x3f\x0f\xfe\xd1\x28\x8b\x31\xc1\xdd\xcc\x68\x29\xf2\x12\xd6\xd8\x92\x5b\xa6\xc8\xc1\x5b\x0f\x80\x16\x95\x2a\xf7\x91\xc3\x1c\xd8\x37\x0c\xbb\x69\x2d\x9d\xb7\x8c\xa7\x2e\x94\xb6\x01\x2c\xaf\xe7\x3a\x39\x18\x83\xb4\x59\x5a\xa7\x2d\x6f\xc8\x4f\x9c\x04\x60\x91\xfe\xce\xe8\xf1\xc1\x8a\xcc\xde\x46\xd7\x7f\xd8\xf0\x1a\x1e\xb2\x38\xcd\x77\x1c\xf7\xde\x3c\xb7\x6f\x34\xf7\xe5\xeb\xfc\xbb\x3c\x69\x59\x1d\x47\xfd\xba\xd6\x62\x7e\xb0\xd3\x7a\x91\x3e\x31\x68\xad\x19\x9f\xa8\xba\x26\xd3\xac\x87\xbf\x5a\x95\xf1\x3b\x3c\x96\xc2\xa6\x60\x2e\xab\x10\x0b\x29\x00\xcf\x45\x0d\xc9\x8c\x38\xf1\xcc\x95\x90\x49\xae\xe8\x99\x34\x90\xd0\x8c\x66\xd7\xc5\xee\xe5\x43\xc9\x52\xa9\xba\x77\xd7\xa7\xcd\xa9\x91\x59\x4f\x41\x5a\xde\x6f\x7e\x27\x34\xcd\x99\x52\x68\x08\x83\xd1\x54\x88\x5b\x72\xb4\xa2\x56\x56\x2d\xca\x4a\xb1\x89\x3a\x71\x38\xdf\x37\xab\x3f\x26\x8c\x67\x21\x92\x09\xf5\x60\xae\x95\x37\xe4\xe0\x43\x92\xb0\x0a\xdc\x43\x57\x9e\xd9\x05\x2b\x2c\x2f\xd3\x16\x64\x36\x58\xf0\xe4\x04\x7b\x79\x7b\xae\x5a\x96\x44\x79\x64\x8b\xae\x1c\x6e\x2f\x56\x3d\x5b\x09\x47\x2b\x3d\x3e\x39\x90\x9c\x70\x91\x80\xea\xae\xd8\xd2\x37\xd5\x9c\x24\x05\x9b\x61\x03\x18\xfd\x44\xd7\x86\xc3\xa1\x5d\xfa\x10\x13\x35\xdd\xad\x87\x75\x89\xfa\xa6\x22\x2e\x46\x1f\xc9\x8a\x29\xed\x5b\x25\xdd\x50\x34\x24\x81\x5e\x84\x98\x0a\x2e\xa4\x45\x51\xc3\x44\x05\x47\x94\x46\x12\x65\xbd\x79\xb8\x27\x8e\x44\xd7\x96\x7a\x56\x79\x89\xeb\x8e\x40\x4c\xf4\xb2\xb5\x1d\xaa\x35\xdc\x31\x3d\xc5\x1a\xac\xd3\x05\xaf\x21\xae\x44\x82\x42\x07\x0c\x27\x20\xa5\x90\x2e\x20\xcb\xdb\xad\x71\x26\xa4\xe4\x18\xd1\x65\x90\x84\x9a\x4f\x87\xaa\xee\xa8\xae\x2a\x9e\x63\x8c\xa1\xc1\x26\x18\x8f\x21\x41\x41\xab\x0e\x60\x4b\xb5\x8f\xaa\xa2\xb4\x3e\x85\x43\x0b\x5f\x31\x3d\x67\xf7\xe6\x29\xf5\xbb\x16\xfa\xae\x70\xc1\xfb\xab\x7f\x3e\x1e\x10\x72\xc9\x43\xfc\x6d\xcf\xec\x62\xfd\x4a\x1f\x7a\xa6\xcd\x2b\xd6\xcb\xed\xe3\x0b\xd4\x0d\x67\x46\x3a\x94\x65\x07\x18\xdf\xc6\x1c\x4e\xea\x26\xf1\x4e\xc9\x01\x9a\xc6\xdd\xa4\x66\xeb\xbd\x0c\xd0\xc6\x54\x6e\x2e\xf9\x58\xe6\xf2\xe7\xe1\x00\x21\x6d\xe9\x9c\xab\x74\x10\x6b\xa0\x6f\x36\x62\x0d\xf4\x0d\x47\xac\x81\x1e\x6b\xa0\x2f\x8f\xbd\x09\x19\x8c\x35\xd0\x5f\x56\x5d\x9b\x58\x03\xfd\xa9\x4d\xcc\xb1\x06\x7a\xac\x81\xfe\xd0\x88\x35\xd0\x1f\x19\xb1\x06\xfa\x0e\xe3\x05\x50\xae\x58\x03\x7d\x87\x11\x6b\xa0\xaf\x1e\xb1\x06\xfa\xf2\x88\x35\xd0\xd7\x8e\x58\x03\x7d\xe7\x11\x6b\xa0\xc7\x1a\xe8\xb1\x34\xe4\x76\x73\xed\x67\x69\x48\x12\x6b\xa0\xbb\x11\x6b\xa0\xbf\x88\x02\x78\x24\xd6\x40\xdf\x68\xc4\x1a\xe8\xb1\x06\xfa\x2e\x23\xd6\x40\x7f\x29\xe6\x92\x58\x03\x3d\xd6\x40\xff\x7c\x04\xdd\x58\x03\x3d\xd6\x40\x8f\x35\xd0\x63\x0d\xf4\x07\x57\x11\x6b\xa0\xbf\x04\x15\x50\xe9\x94\xed\x54\x16\x72\x93\x0a\x36\x2e\x32\xb9\x96\x30\x3e\x2a\xc7\x63\x90\x48\xb9\xf0\xc9\x4b\xc1\x53\x55\xb1\xbe\x45\x27\x2b\xe8\x1e\x16\xc3\x71\x49\x1c\x6b\x6e\x77\x19\xea\x58\xbe\xb1\x0a\x1f\xbe\x78\xff\xd5\x8a\x72\x39\x3b\x47\x15\xee\x1a\x38\x8b\x6b\x7e\xcf\x77\xf3\x8f\xaf\x01\xf8\xaa\xa4\x22\x07\xf7\x24\x13\xca\x85\x3d\x23\xb0\x92\x29\xe5\x1c\xbc\xbe\xc7\x34\xda\x51\x46\x00\x9c\x88\x02\x9c\x77\x9a\x12\xc5\xf8\x24\x03\x42\xb5\xa6\xc9\x74\x60\x9e\xc4\x3d\xb0\xab\x10\x65\xf7\x8d\xd2\x12\x68\xee\x83\xb5\x73\xca\xec\x54\x84\x26\x52\x28\x45\xf2\x32\xd3\xac\x08\x93\x11\x05\x98\x65\x61\x19\x55\x00\x06\x46\xc5\x55\x71\xcd\xbd\xea\x69\x6e\x59\xa2\x5e\xaf\x0c\xb5\xcd\x1e\x96\x78\xce\x0b\x3d\x27\xe6\x95\x33\x57\xf6\x55\x2a\x4d\x92\x8c\x21\xb7\xc6\x27\xda\x84\x5a\x9c\xaf\xe7\x79\x35\x77\x2b\x55\x6e\xa9\x3c\x45\xb1\xb5\xd0\x8a\x60\x18\x70\x35\xa1\x9b\x2a\x65\xca\x89\xf9\xaa\x47\xa8\x2f\xa6\x65\x01\xed\x57\x8a\xa0\xf6\x9c\xc5\xce\xee\xbe\xaa\x4d\x57\x2b\x22\x6a\x70\xd3\x1a\xb0\x2a\x44\xc7\xb8\x77\x8f\x9c\xbd\x46\x88\x7f\x25\x50\x60\x94\xde\xd2\x31\xc0\x0d\xe0\x30\x33\x38\x00\x09\x18\xfe\x4a\xd7\x60\xfd\x27\x47\x7a\x4d\xe5\x04\x74\x88\x67\xda\x35\x56\xbc\x19\x16\x52\x2f\xf7\x5b\x57\x44\x2a\x90\x21\x74\x86\x22\xc5\x94\x9f\x2a\xaf\x6a\x55\x3d\x61\xbb\x42\x57\x46\x6d\xd5\x05\x5e\x30\xb2\x21\x9a\xe1\xa1\xaa\xa0\x09\x28\x72\x74\x39\x3c\xeb\x91\xe1\xe5\xb9\x8b\xc3\x14\xe3\x55\x79\xcc\x8e\x86\x59\x0c\x5c\x57\xd9\x38\x54\x68\xab\x4d\x5f\xcb\xfd\x74\xcf\x1e\x06\xf9\xea\x27\xee\xc2\x4b\x17\x29\x00\x8a\x5c\xa1\xba\x39\x51\x25\x8a\x48\xce\x26\xc4\x42\x62\x86\x43\x3e\xa8\xd2\x11\x7d\xdd\x21\x7f\x47\x58\x88\x83\x92\xcb\xba\xf0\xbe\x6e\x24\xb0\xc8\xaf\x97\x52\x3b\x30\x14\xd4\xc5\xbd\xec\x14\xef\xd2\x4a\x43\xaa\x89\x62\xef\x40\x29\x3a\x81\xe1\x8e\xee\xad\x75\x76\x00\xf4\x70\x55\xe4\x00\x09\x50\x66\x13\x7d\xc3\x37\x55\x4c\x70\x53\xf8\x26\xb9\x5d\x53\xc0\xac\x3b\xc9\xb4\x06\x24\x25\x58\xec\x0f\x37\x7b\xb1\x16\xc0\xe1\x42\x64\xf1\x3b\x3f\x49\x75\xb3\x11\x25\x78\x6a\xe3\x7c\x47\x40\x46\x92\xc1\x98\x8c\x19\x06\x0f\x63\x38\x6f\xcf\xd6\x7e\xa2\xd6\xf6\xa4\x14\x48\x5c\x8f\xd3\xa0\xfc\xba\x06\xe4\x07\xb7\x30\x2d\x4b\x6e\x9b\x8e\x38\xe1\x1e\x93\x5d\xd9\x98\x4c\x30\x1c\xd8\xe9\x28\x7f\x7a\xf5\xb7\xbf\x90\xd1\xdc\x08\x52\x88\x90\x5a\x68\x9a\x85\x97\xcc\x80\x4f\x0c\xac\x2c\x53\x68\xa6\x6b\x06\x08\x60\x5b\x10\xbb\xf0\xd7\x7f\xb8\x1d\x35\x25\xbb\x93\x14\x66\x27\x35\xf8\xf5\x33\x31\x19\x90\xb3\x90\x1d\x59\x16\x29\xda\xf9\x77\x2f\xd5\xdd\x1d\x9a\x89\x8c\x25\xf3\xd6\x88\xe6\x8b\x90\x91\xa9\xb8\xb3\x1a\xe6\x0a\xec\xa9\x32\xbf\x0a\x51\x94\x99\x75\x75\x7c\x15\x12\x9d\x4b\x05\xcb\xe9\x88\x2b\xcf\x05\x1a\xe7\xdd\x14\x0b\x74\xd4\x45\x81\xfb\x47\x0a\x97\xe6\xe2\xcc\xc7\xa1\x16\x19\x12\x93\xaf\x68\x96\x8d\x68\x72\x7b\x23\xde\x8a\x89\x7a\xcf\x2f\xa4\x14\xb2\xb9\x96\x8c\x1a\x1e\x3d\x2d\xf9\xad\x6d\x05\x11\xaa\x35\x88\x89\x11\xe8\x8b\x52\xfb\xe2\xde\xab\x5e\xd8\xa6\xee\x7b\xd6\xef\x95\xef\x6a\x16\xb8\x67\x95\x86\xed\xb2\xc6\x2c\x46\xd6\xe7\x57\x75\x64\xfb\xc3\xab\x3f\xfd\xd5\xa2\x2e\x11\x92\xfc\xf5\x15\x66\x0a\xa8\x9e\x3d\xc4\xc8\x51\x8d\x78\x92\xd3\x2c\x33\x84\xbc\x8e\x94\x06\xd0\xab\x90\xf0\x93\xe3\xa0\x6e\x8f\x6e\x1b\x0b\xf0\x37\x37\xff\x40\x2e\xc2\xb4\x82\x6c\xdc\xb3\x09\x52\x41\x99\x3e\x44\x71\xe4\xd0\x51\x1f\xcc\x52\xdb\x03\xb1\x7b\x26\xb2\x32\x87\x73\x98\xb1\x2e\x7a\x3d\x35\x66\xf3\x06\xa6\x8c\x29\xe4\x83\xa3\x4c\x24\xb7\x24\x75\x3f\xd6\xe2\x9d\x16\x8b\x92\xef\x0e\x85\x5d\x23\xbf\x5a\x44\x7c\xad\x7d\xff\x46\xac\x57\x4e\x8b\xc2\xc8\x00\x98\x87\x29\xe9\x5d\x03\x18\x78\x26\xb1\x72\x42\xcb\xd2\x36\xad\x9d\x1b\x6d\x5d\x1b\x7d\xf7\x46\x86\x6e\xee\x3c\xc5\xce\xb1\x4e\xed\x3d\x23\xd5\xea\x77\x37\x87\x37\x10\xa2\x9a\xd0\x9f\x86\x02\xff\xb6\xb9\x4c\x4b\x82\x79\x28\xaa\x19\x10\xc3\x0a\x00\x06\x7d\x90\x24\xef\x6e\xe6\xef\xc0\xa6\xde\x2e\xd0\xad\x01\x17\x1e\x7c\x19\x39\xd5\x4e\x20\xf4\xba\x0a\x25\x05\x48\xc5\x94\xe1\xcb\xdf\xe3\x81\x3a\xcb\x28\xcb\x6b\x86\xe7\xa7\x01\x82\x3d\xdc\x58\xc9\xb9\x3d\xa5\x34\x7a\x8a\x9d\x10\x49\xa1\xad\x62\xbd\x42\xac\x6d\x4a\xb5\xd7\xe5\x08\xf1\x07\x2f\xdf\xa6\xa1\x5e\x87\x9c\xf8\xa9\x69\xec\xf7\xd5\x36\x34\x49\xac\xf9\x26\xd0\x58\x7b\xd5\x4b\xa2\xac\xf8\x7e\xcf\x95\xb0\x86\xc5\x77\x44\x3f\x90\xa2\xba\xcd\x6d\x92\xd0\x86\xd6\x69\x4f\x58\x4d\x17\x70\x0a\xe4\x80\xd8\xa0\x0d\x73\x26\xdc\xad\xe4\xf0\xcd\xe1\x93\x52\x57\x0b\x22\x29\x0a\x3a\x69\xd5\x8f\x68\x01\x52\x8b\xd3\xd6\x8b\x65\x18\xfd\xa9\x46\x4a\x0a\x77\x95\xa1\x24\xbe\x16\x10\x56\x7a\xb2\xce\x7c\x0f\x60\xa7\x59\x60\xbf\x38\x72\x47\xe7\x84\x4a\x51\xf2\xd4\x99\x43\x83\x3d\xfa\xdd\xc2\x83\xaf\x04\x07\xef\xe7\x59\xac\xb5\x81\x0e\x28\xc6\xc9\xeb\xc1\xeb\x57\x2f\x85\xc5\xe1\x1b\x2e\xb0\xb8\xab\xc0\xe2\x2c\x7d\x7a\xd2\x77\xf5\x55\xfb\x3b\x7a\xdf\x77\xce\x36\x53\x15\xe5\x67\xbe\xe4\x37\x7e\x75\x27\x99\x86\x5a\x97\xc1\x23\xd4\x78\x8c\x62\x59\xab\x2c\x71\xbc\xaa\x1b\x46\x4b\x20\xb5\x2b\xe5\xa1\xca\xd1\x47\xa4\x5b\x8e\x40\xe1\x71\x5b\x65\x1a\x53\x0f\x90\xb0\x3a\xa0\x0e\x0e\xc8\x91\xbd\xf2\xd0\xe6\xdf\x1f\x3f\x29\x6a\x39\xa0\x5d\xdc\x17\x2d\xea\x84\x2e\x94\x7a\x28\x28\x1a\xef\x8a\x0e\x21\xf8\x5f\x30\xa5\x33\xc0\xba\x03\x2c\xa3\x32\x43\x17\xf9\xb5\x5d\x3b\x19\x95\x9a\x00\x9f\x31\x29\x38\xda\x89\x67\x54\x32\xac\xec\x23\x61\x0c\x12\xb8\x51\x62\xbf\x38\xfa\xfe\xf4\x03\xc6\xdf\x1c\xdb\xae\x2f\x7e\x95\xa5\xf2\x25\x78\xea\x2b\xa9\x4d\xf7\xe8\xf6\xf9\x75\x18\x18\x22\xcd\xf5\xeb\x32\xcf\xc9\x4b\x5d\xda\xd6\x32\xf7\x49\x56\x2a\x36\x7b\x2a\x4a\xe2\x0a\x42\x9c\xb3\x9d\xf6\x79\xa1\x38\x45\x05\xa8\xa5\x3a\x13\x95\x9b\xe0\x91\x32\xdc\x87\x2a\xe4\x98\xd6\x43\x36\x9c\xcd\x8a\xe4\x6c\x32\xd5\x2e\xda\x73\xc1\x73\x50\x73\x41\xe5\x68\xe6\x7d\x4a\xeb\x95\x61\xbb\xa7\x19\xa3\x6a\x5b\x91\x6b\x29\x91\xd1\xcd\x82\x81\x1e\xdc\xd5\xfa\xa3\x59\x30\xca\x98\x07\x59\x4b\xe5\xe5\xd0\x79\xd0\x3c\xdc\x18\xff\x1f\x1b\x58\x13\xd4\x12\x1b\x28\x63\x6f\xb1\xe6\xc6\x31\xa9\x15\x05\xf2\x01\x25\x48\xfc\xb1\x12\x15\x6a\x24\x5c\xf0\xfe\xb4\x56\xb4\xa9\x10\xe9\x96\x49\x7e\xbb\x2a\x1e\x3b\xa9\x1c\xab\x21\x48\xa6\x22\x4b\x7d\x0f\x6d\x6b\xcb\x19\x81\xbe\x03\xe0\xe4\x72\x88\xf0\x33\xaf\x88\x1e\xa1\x35\x50\xb4\x6e\x05\x2c\xcf\x54\x53\x65\x1b\xf0\xdc\x16\xc1\x5a\x68\x25\x6d\x44\xfa\xf0\xa6\xad\xcf\xfc\x37\x01\x66\x3e\x22\x9b\x8e\xc4\x0c\x10\xa4\x69\x2a\x41\xb5\x28\x6f\xf4\x04\x7a\x6a\x2b\x52\xca\x76\x6a\xef\xd3\x74\x8c\x04\xb0\x79\xd3\x12\x8a\xef\x78\x54\x11\xf1\x3e\x31\x05\xbb\x1c\x9e\xb5\xa0\x5e\x87\xdf\x39\xbf\x88\x99\xea\xf0\x50\x11\x56\x24\x95\xcf\x75\x40\x2a\x77\x63\x2d\x51\xc2\x4a\x8c\xdb\xf9\xba\x76\x15\x13\x6b\x44\xad\x25\x91\x26\xdc\x4e\x63\xc8\x8a\x4b\x92\x76\xe6\x1c\x74\x3a\x14\x22\xc5\xfe\x4b\x15\x34\x94\xbf\xa3\x0e\x10\x1f\x2c\x61\x89\xbc\x0b\x1d\xe9\x85\x20\xe4\x05\xc2\x84\xa6\x77\x1f\x7e\x58\xa3\xe2\x4b\xc0\xfc\x64\xb0\x1c\x5e\x9e\x77\x89\x2e\x05\x4b\xf7\x0e\x5d\xbe\x53\x5b\x27\xdb\x3f\xfc\x92\x58\xb9\xef\xb1\xb7\xb4\xce\x26\x57\x8c\xcf\x7d\xc6\x30\x75\xa1\x89\xeb\xee\x18\x22\x61\x57\x05\x74\x20\x15\x69\x3e\xa9\x67\x3e\x8f\xcb\x0c\x91\xb4\x0a\xee\x0d\x91\xc9\x34\xc4\x85\xa2\x34\x40\x67\x94\x65\xb6\x2e\xa6\x58\x3f\xa5\x77\xbf\x67\x82\xa6\x36\xdd\xe3\x16\x24\x87\x8c\xe4\x22\x2d\x33\x6b\xcd\x0b\x5d\x84\xdf\xbd\x3f\xff\xee\xed\x85\x0f\xc2\x82\x6a\x3b\x7b\x84\x12\x0e\x77\x38\x3b\x47\x81\x24\x71\xe5\xb9\x42\xda\x8f\x39\x4f\xbe\xe2\xa6\x55\x43\xad\x61\xc2\xbf\x50\xce\x34\x9b\xd8\x32\x9a\x95\x58\x38\x92\x40\x6f\x45\xa9\xc9\xac\xcc\x38\xc8\xaa\x0b\x26\xcc\x80\x5b\x1b\xac\xb9\xc1\x3c\xb6\x5e\x91\x91\xc9\x46\x21\x4c\x57\x1e\xcd\x17\xf7\xa4\x89\x93\xe4\x5d\x8a\x11\xfe\x58\x6b\x01\xdd\x68\x14\xf9\x70\x81\x52\x2f\x79\xd5\x6a\x93\xda\x74\xe2\xe5\xc2\xa4\xbe\x86\xa4\x0d\xa3\xb9\xf6\x11\x30\x2e\xf0\xe5\xd3\x1d\x87\xed\xcd\x2d\xcd\x0c\xd1\x66\x61\x15\x37\xa1\xe7\x7d\x43\x91\xae\xd1\x1a\x2a\xb9\x0b\xaf\xaf\x37\xc6\xd6\x82\x50\x62\xcd\xed\x7d\x5f\x98\x06\x23\x65\x77\x21\x83\x5b\x33\x4d\xd4\x3c\x86\x65\x96\x5d\x43\x22\x61\x5b\x37\x43\x93\x52\x5c\x2e\xcc\xb5\x4e\x03\xa8\xa9\xb3\x58\xad\xc3\x5d\xcc\xab\x9a\xb0\xb5\x38\xa7\x2a\x17\xb7\x28\x33\x0c\x0d\xa7\x7c\xee\x01\x8e\xab\x57\x35\x9f\x2e\x53\x3e\xca\xcc\x52\x9f\xc6\x2e\x28\x08\x0f\x0b\x2d\xd6\xa8\x52\x36\xf2\x80\xf1\x94\xcd\x58\x5a\xd2\x0c\x1f\x84\x4a\x99\x0b\xd8\xa2\xae\x5a\xb9\x3d\xcb\xb9\xaf\x71\xbc\x6d\x0c\x73\x75\x26\x4f\xec\xba\x7f\x6b\x97\x37\x67\x7c\xd2\xc7\x6f\xcc\x83\xdd\x0a\xfb\x82\xf7\x69\xdf\xa0\xcd\x33\xd1\x5b\xb0\x4a\xff\x7b\x54\x0c\x3e\xf8\xfd\xf5\x64\x48\x11\xe0\xa2\x9c\x4c\x11\x58\x32\xa7\xbe\x60\x66\x06\x1a\x6b\x21\xba\x78\x06\x1b\xc4\xe6\xee\x4d\x9d\x96\x51\xaf\x0d\xd9\xc4\x8d\x67\xa2\xbb\xec\x6a\xe0\x5d\x08\xc6\xaf\x91\x19\x07\x23\xbd\x35\x06\x8a\x19\xc8\x19\x83\xbb\x13\x27\xf9\xf5\x0d\x4f\xe8\x5b\x88\xa8\x13\x04\xec\xc9\x6f\xad\x76\x74\xf3\xfe\xfc\x3d\x36\x16\x77\x56\x77\xcf\xaa\x0c\x2b\x50\x03\x42\x0b\xf6\x3d\x48\x85\xa5\x93\x6f\x19\x4f\x7b\xa4\x64\xe9\x97\x9f\x30\xe0\x8b\x71\x56\x45\xb1\xb6\xa2\x5a\x6f\x1d\x55\x72\x59\xf4\xec\xdf\x16\x3d\x6b\x1c\x74\x04\x99\xe0\x93\x5a\x0d\x00\xe4\xe6\x97\x9c\xe9\xa5\x1e\xcc\xb6\x9e\x29\x5a\x78\x84\x4c\x31\x56\x98\x09\xd9\x70\x67\x98\xf9\xb0\xca\x63\x2d\xe2\xd8\x90\x34\xd6\x98\x0f\xc3\xb8\x54\x25\x23\xd9\x40\x20\x9f\x2e\xec\x8b\x60\xfb\xea\x91\x96\x17\x4f\x29\x4f\xf1\x63\x92\x08\x99\xba\xf5\x32\x1d\xc2\x9b\x6d\x30\x9c\x8d\xc0\x42\x36\x64\x28\x1a\xe5\x8b\x4f\x46\x31\x4d\xe6\x8d\x50\x58\x2f\xb5\x97\x9c\xfd\xab\x04\x42\x73\x61\x08\xf1\x62\xab\x87\x05\x88\xe4\x74\x8e\xbc\x10\x97\xfa\xd6\xa7\x6b\xb8\x1c\x5b\xd5\x23\x1f\xc0\x08\x5d\x55\x99\x80\x1e\x79\xdb\xac\x1b\xd0\x33\x6b\xb9\xb6\x09\xcd\xee\x2b\xbb\x7a\x09\x4a\x94\x32\x81\x0f\xd6\xc7\x99\xfb\x78\xba\xe5\x97\x31\xbb\xa2\xe9\x2d\x70\x6b\x53\x32\xa0\x41\x37\x6e\x29\xff\x3f\xf6\xfe\x86\xbb\x6d\x1b\xdb\x17\xc6\xbf\x0a\x96\x67\xd6\xdf\xf6\x54\x92\x93\x76\x3a\xa7\x27\xb7\xff\xe9\x72\x6d\xa7\xf5\x6d\xe2\xf8\xc4\x4e\xfb\xcc\xd3\xf4\xcc\x40\x24\x24\xe1\x98\x04\x58\x02\xb4\xa3\xb9\xb9\xdf\xfd\x59\xd8\x7b\x03\x04\x25\x39\xb1\x49\x26\x92\x5d\x71\xd6\x9a\xc6\x12\x05\x82\x78\xd9\xd8\xaf\xbf\x1f\xcc\x41\x32\x13\x69\x05\xa7\xca\x78\xce\x26\x12\xf9\x5f\xe0\x68\x97\xd3\x99\x30\xd6\xdb\x46\x07\x90\xa3\x56\x53\xe9\xf9\x0e\xc0\xf2\x8d\x92\xd9\x6b\x2f\x6c\xce\x01\x9d\x1c\xb6\x2c\xb7\xbe\x5e\x0b\xb5\x41\x53\xe5\x7e\x2f\x2f\x8e\xb4\x19\xb1\x17\xee\x51\xb8\x9e\x22\x5e\x0d\xb9\x30\xb8\x10\x63\x26\x37\x32\x9b\x70\x33\x03\xd6\x99\xc5\x29\x20\xca\x8a\xa4\x2a\x9d\xc0\x40\x24\x79\x9e\xa6\x4e\xba\x96\xac\x44\x62\xf9\x55\x7e\xc7\x8e\xf5\x39\xae\xb3\xc3\xe8\xbc\x7b\x28\x87\xd8\x61\xa8\xb7\x70\x03\x9f\x2c\x48\x02\x9c\x49\x77\x60\x79\xc4\x35\xa7\x70\x87\x80\xbf\x93\x0a\x9f\xef\x48\x6a\x1f\xde\x6f\x15\x96\xef\x72\x02\xf2\x72\xda\xdd\x71\xb7\x7b\x58\x4e\x2b\xdc\xe8\x24\x85\x6b\xdc\xf9\xd1\x42\xde\x3d\x28\x53\xce\x56\x3d\x7a\x79\x1c\x17\xfa\xc5\x15\x4c\xbe\x4c\x72\xc4\x7e\xee\x1a\x66\x59\x8c\xb3\x38\x81\x5e\x07\x6f\x6a\xd6\x18\x27\x34\xb2\x6b\x6f\x12\x84\xa7\x79\xcd\x57\xaa\xa2\xb2\x74\x12\xd6\x3e\x13\x95\xcc\xb8\x9a\x82\x9b\x44\x57\xae\xbd\x3f\xff\x19\x7a\x54\x8a\xb4\x4a\x88\x72\xc7\xaf\xda\x3f\xfb\xa0\x03\x01\xdd\x81\xb8\x32\x09\x2f\x7c\x9f\xe3\xd7\x32\x73\x65\xf9\xbb\x67\x4c\x8e\xc4\x88\xed\xfc\x39\xfa\x6a\x07\x9f\x5e\x94\xda\x3d\x82\x0a\x8c\xa0\x57\x99\xb4\x90\xe8\xb3\x13\xdf\x3d\x62\x27\xee\x19\x10\x88\x0d\x03\x18\xd5\xc0\x8c\xeb\xe1\x1b\xb0\x52\x4c\x79\x99\x66\xe4\x30\xbc\x89\x0a\xa7\xc2\x80\x89\x77\xd2\x58\x43\xde\x82\x0e\xc2\xc9\x72\x73\xe5\x44\x91\xdb\x5c\xc3\x94\x5b\x3e\x8c\x76\xf5\x01\x9a\x5a\x43\xc2\x02\x1f\x72\x5a\x5d\xb5\xd4\x3a\xf8\x13\xd5\x1f\x0f\x79\xb8\x4b\x3a\xa5\x1c\x50\xb9\xdb\xab\x3a\x0f\xcd\x4b\xdc\x01\x12\xbe\xb9\x81\x4f\x6a\x9e\x08\x18\x03\x60\x59\xaa\x55\xa6\x20\x47\x09\xf5\xfc\x96\x2d\x7d\x72\x76\xf9\xfa\x1f\xe7\xaf\x4e\xcf\x2e\xb7\x3b\x7b\xbb\xb3\xb7\x3b\xbb\xc3\xce\x16\xea\xba\xf3\xae\xf6\xd6\xd3\xaa\xbc\x85\x45\x30\xd6\xa8\x04\xef\x11\x65\x87\x9e\xa8\xeb\x9f\xb9\x53\xa6\xc9\xaf\x4d\x41\xd7\x15\x69\x1c\x74\x03\xaa\xee\x47\x0f\x3e\x3d\x74\x8d\xc9\x9d\x3d\x26\xcd\xc5\x8e\x95\x55\xb3\x16\x73\x84\x1e\xfd\xf3\xf4\xf8\xe4\xec\xf2\xf4\xf9\xe9\xc9\xeb\xb5\x66\x3b\x75\x04\x43\x6d\x9e\xcb\x2d\x4f\xc9\xa2\x14\xd7\x52\x57\x26\x9b\x07\x3c\xf5\xd5\x42\x60\x39\x61\x56\xa5\xe0\xf1\xf0\x90\xf1\x2b\x7f\xb6\x3d\x6c\xfb\x3d\x6c\x9b\xc9\x5f\x1d\x70\xb0\xfa\x5a\xbe\xcf\x4b\x9d\xf7\xb4\x84\x2f\xd0\x17\xe3\x83\x6d\xab\xd6\xd3\x2e\x41\xe6\x34\x8e\x1e\x52\x1e\x6b\x7c\x1e\xa7\x8f\xe6\x85\xed\x40\x96\xd3\x0b\xfc\x75\x3f\x48\xd1\x98\x70\xf6\x92\x17\x3f\x89\xf9\x6b\xd1\x11\x6e\xab\x39\xde\x22\x13\x89\x3b\xe8\xd8\x95\x98\x63\x76\xf1\x91\x7f\x58\x17\x58\xb0\x8d\x44\x0f\xbf\x12\x5d\x90\xdd\xfb\x84\xfd\xbe\x12\x1d\x32\xa7\xfd\xb5\x04\x80\xed\xa6\x10\xf4\x34\x37\xa7\xdd\x66\x8f\xf5\x0b\xf9\xfd\x09\x60\xce\x1f\x6f\x1c\xa5\x79\xf5\x38\x0b\x3e\x7c\xdb\xf3\x4c\x60\x24\x7d\xde\x38\xbb\x82\x10\x61\x58\xd3\x0c\x6b\xd3\x87\x1e\x48\xc9\xe8\x69\x68\xba\xb2\x6d\x32\x9c\xc2\x7e\xe5\xea\x6e\x2d\x58\x31\xe7\x22\x00\x3a\xa6\xcf\x3c\x06\x88\x09\x14\x99\x40\x3a\x3d\x68\xfe\x49\x69\x2d\xff\x0a\x1f\x66\x7c\x2c\x32\xf3\xeb\xee\xee\xb7\x3f\x9d\xfc\xe3\xef\xbb\xbb\xbf\xfd\x2b\xfe\x16\x8e\x42\x0c\x6f\x37\x6f\x01\x40\x13\xa5\x53\x71\x06\xcf\x80\x3f\x49\x5d\x3b\xc4\x10\x0a\x7d\x01\x78\x04\x23\x4c\xbd\x0b\x7f\x16\x3a\x5d\xfc\xcb\x74\x42\xde\xdc\xc8\x83\x01\xa6\xa8\x43\x79\x1c\x5e\xfd\x1d\x0f\xb5\x2c\xe9\x79\xab\x52\xab\x81\xe9\x29\x99\x89\x1c\xb1\xff\x9e\xfb\x21\x00\x1a\x6f\x0f\x7c\xa2\x00\x2d\xc2\x69\xa6\x4d\x18\xd6\x9d\xeb\xa7\x3b\x1b\x75\xc0\x84\x19\xec\x79\xc0\x60\x44\x68\xb4\x70\x23\x87\x03\x36\xa4\xb9\x04\x9a\xd9\xc3\xf3\x53\x76\x8d\x23\xbc\x31\x83\xe3\xc3\x9b\xcf\x3f\xa9\x8c\x0b\x41\xd4\xc5\xaa\xf4\x67\x98\x56\xe6\xbf\x27\x84\x10\x13\xa0\x22\x85\x33\x6c\xf6\xf0\xc3\x51\x52\x54\x03\xba\x61\x94\x8b\x5c\x97\xf3\xf0\x67\xa8\x4c\x1e\x1a\xab\x4b\x3e\x85\xc2\x30\xfc\x39\xfe\x2c\xfc\x85\x3f\x6c\x3c\x60\xf9\xd7\x68\x0a\xd7\xb1\x54\x92\xc8\x2d\x91\x6e\xea\x6b\x03\x65\x9b\x1f\xfa\x0d\x11\x6d\x49\x57\xbc\xb2\xe6\xd5\x5c\x90\xc1\x13\x87\x0a\x67\x18\x45\xb0\x27\xa9\x62\x7e\x50\x67\xb1\x81\x37\x40\x5d\x3b\xcb\xb2\x35\xd2\x64\x7d\xf5\x28\xcd\x52\x79\x2d\x8d\xee\x50\xfe\x16\x1a\xba\x3d\xe3\x91\x40\x7b\x30\x8b\x2b\xb8\xcd\xde\x15\x00\xae\x17\xf6\xeb\x82\xd8\x7f\xda\x85\x5f\x0f\xaf\x82\x5b\x2b\x4a\xf5\x8c\xfd\xf7\xde\xdb\x2f\xde\x0f\xf7\xbf\xdb\xdb\xfb\xf5\xc9\xf0\x3f\x7f\xfb\x62\xef\xed\x08\xfe\xf1\x97\xfd\xef\xf6\xdf\xfb\x3f\xbe\xd8\xdf\xdf\xdb\xfb\xf5\xa7\x97\x3f\x5c\x9e\x9f\xfc\x26\xf7\xdf\xff\xaa\xaa\xfc\x0a\xff\x7a\xbf\xf7\xab\x38\xf9\xed\x8e\x8d\xec\xef\x7f\xf7\xe7\xce\x5d\xef\x01\xeb\x1a\xaf\x3e\x11\xaf\x9b\x2d\xf6\xb2\xfc\x3e\x21\xcd\x0b\x5e\x7e\x79\xf5\xbd\xff\x5f\x7b\xa9\x19\x65\xf5\xf8\xe3\x7a\x63\x36\x38\xa6\x85\x7e\x0e\x4f\x0e\x3e\xa9\x59\x30\x16\x4c\x8b\xc7\x76\xce\xfd\x11\x9c\x3b\x81\xa0\x15\xe6\xb5\xd6\x44\x27\xa5\xce\x3d\x2c\x05\x84\x37\xb0\x80\x92\xee\xbb\x12\x9d\x28\xc3\xf1\xda\x3a\x83\xb6\xce\xa0\x5b\xae\x8f\x3a\x83\xb0\x88\x60\x73\x3d\x41\x42\x5d\xb7\x0d\x61\xac\x8c\xa0\x7b\x5b\x27\x06\x7f\xbc\x5b\x40\x6d\xe4\xb7\x7a\xcd\x6c\x5c\x27\xd3\xe0\x81\x96\xaf\x8e\x61\xb2\xc3\x2c\x63\x52\xe1\xc6\x87\x06\x42\x2d\x96\x40\xd3\xc6\x17\x11\x5f\xbb\x2e\x84\xaa\xab\x06\x78\x32\xe4\x16\x4b\x35\xa5\xc2\x28\x3c\x4a\x28\xfa\x24\x55\x0d\x3b\x1d\x94\xc3\x9a\xab\x80\x1b\xa3\x13\x20\x05\xc3\x4a\xab\x80\x49\x49\xdd\x86\xde\x58\x7e\x05\xd1\xc6\x44\xa4\x42\x25\x82\x78\x0c\x1a\x2c\xce\x5c\xb1\x13\x75\xed\xb9\x1c\xd2\x0a\x93\x41\x50\xfc\xad\x6e\xe3\x71\x25\x20\xb8\x85\x48\x41\xb0\x28\x0f\x01\xa4\x7e\xb0\xb0\x39\xa4\x62\xe8\x49\xed\x65\x6d\x47\xf4\xda\xf9\x14\xef\x7e\x66\x86\xc8\x56\x27\x65\x68\xe9\xb0\xac\xdd\xcf\xcd\x43\xf2\x31\x04\x03\xbb\x1f\x9f\x7f\xb8\xa3\xb3\xa7\x63\xb3\x9f\x23\xf3\x1e\xb1\x93\x3e\x8f\xc9\x3e\x82\x25\x45\x29\x26\xf2\x5d\x4f\xfb\xf4\x30\xaa\x27\x94\xa9\x50\x56\x4e\x24\x72\x59\x17\xa5\x28\x84\x02\x57\x2b\x94\x68\x38\xd9\x4f\x27\x65\x1d\x9c\xde\xc4\x64\x1e\x54\xb8\xfb\x15\x65\x17\xab\x94\xfd\xad\x1c\x63\x5b\x39\xd6\xfa\xfa\x4c\x72\x8c\x56\xee\xe6\x08\x31\xc8\x3c\xef\x9e\xfd\x7e\xd4\x4c\x65\x87\x85\xdc\xbd\x84\x78\xa1\x40\x3f\x88\x46\xab\x31\x79\x0d\xeb\xd8\x4a\x86\x35\xfb\xa8\x37\xb1\x9c\x2b\x3e\x45\x2a\x0a\xab\x03\x78\x95\x2e\x03\x9d\xd8\x62\xde\x3d\xe8\xf1\xbe\xc4\x0b\xbe\x2c\x75\x96\x89\xd2\xb0\x4c\x5e\x09\x76\x2c\x8a\x4c\xcf\x73\xca\x7d\x4d\xd9\x85\xe5\xd6\xad\xea\x0b\x61\xdb\x85\x7d\xbb\xa1\xda\xf8\x2a\xf4\x9e\xb0\xff\xb1\xac\x1d\x8a\xc2\x59\x41\x15\x94\xaf\x14\x08\x8d\x43\x60\x36\x1a\xb0\x33\x71\x2d\xca\x01\x3b\x9d\x9c\x69\x7b\x8e\xda\x77\x33\xe1\x0e\x6f\x64\x72\xc2\x9e\x39\xbb\xce\x58\x66\x91\x5d\x26\x2a\x50\xd7\x65\xa3\x81\x1a\xb7\xb0\x8f\xfa\xbc\xe5\xda\x73\x68\x29\x54\x9e\xb7\x8a\x64\x74\x9a\xa6\x40\xdf\xd5\x79\x82\x0e\xb1\x9e\xb4\x86\xb2\x8e\xd6\x37\xe2\x2a\x78\x24\x3e\xb0\x02\xa5\x62\xa5\x30\x85\x56\x46\x34\x61\x46\x43\x8f\xd0\xda\xed\x17\xc3\xb8\xf5\xe1\xd9\xf5\xd8\x2c\xb4\xb1\x50\x42\xdb\x0f\x29\xdc\xb9\x6f\x0e\x2a\x92\x79\x96\x89\xb4\xc1\x0a\x88\x6c\x56\xbc\xe9\x21\x20\x34\x94\xc0\x6f\x83\x85\xca\x8d\x1a\xe7\xc6\xfd\x81\x61\xd2\x73\x38\x79\x7a\xf1\xdb\x2a\x9b\xeb\x8d\x09\xe7\x48\xb4\x00\x96\x00\xcf\x01\x06\xdf\x44\x44\x50\x33\xad\xaf\x58\xa2\xf3\x22\x83\xad\xd3\x61\x67\xd5\x3c\x74\x61\x29\x0d\x5d\xeb\xe6\x20\xa2\xa8\x83\x0f\xba\x31\xd4\x75\x52\xc4\xfa\x50\xc3\xc4\x3b\x91\xf4\xc6\x61\x7b\xf2\x4e\x24\x11\x09\x33\x40\xb2\x25\x1e\x21\xc2\xed\xd8\xee\xdc\xfa\x9d\x43\x0e\x7d\xb9\xf9\x3b\xd4\xd2\xc5\xd7\x02\x8a\x25\xb4\xe9\xd1\xfe\xe9\x11\x40\x9c\x02\xb6\x10\xd6\xd7\xc5\x30\x1a\x61\x31\xe2\xd6\x5b\x82\xbe\x0c\x89\xd4\xbe\x2d\xa0\x48\xd3\xda\xb2\xbd\xdd\x83\xdd\xfd\x25\xff\xe3\x02\x64\xfc\x65\xf4\x4b\x09\x50\xa7\x05\xe0\x86\x8a\x64\x37\x1d\x30\x69\x7d\xa6\x35\xc2\x3d\x41\xaf\xa8\xe8\x6f\xc0\x8c\x66\xb6\xe4\xa9\x24\x35\x06\x3e\x75\x37\xd9\xb2\x22\x29\xbf\xb7\xfb\x7e\x97\xa8\xbd\x6e\xb4\xda\xb5\xd0\xfd\x11\xbb\x44\x9c\x98\xd0\xd0\x5c\x57\x80\x0b\x85\x43\x50\x64\x32\x91\x36\x9b\x83\xc4\x62\xba\x42\x4c\x2a\x77\x5e\x50\xb1\xe1\xc9\x3b\x69\x3d\xb9\x8e\x9e\xb0\x27\xc8\xae\x87\x18\x4e\xdc\x00\xc3\xfa\xc1\x4c\xf0\xcc\xce\x30\x49\x44\x69\x35\x44\x82\x54\x27\x4a\xe8\x9b\xae\xf1\x92\x6e\xee\xc4\xf8\xea\xe0\x5a\x5c\xee\x50\x47\xcb\xc1\x09\xd1\x1f\xda\xb3\xb6\xb3\x25\xf4\xba\xcb\xcb\xf3\x1f\x1a\xbc\xed\x20\xc5\xad\x2d\x7c\xea\x0e\x78\x03\x44\x39\xd1\x65\xbe\x01\xb2\xa3\x9f\x60\x65\x27\x02\x77\xd6\xa3\x08\xeb\x4a\xe4\xce\x56\xa3\x11\xde\x9d\xc1\x9d\xfd\x43\x57\x00\x06\xc2\xc7\xd9\x3c\x20\x31\x18\x61\xd9\x8e\x6b\x6a\xc7\x89\x27\xb7\x1a\x7e\x14\x3c\x45\xa0\x0c\x63\x05\x6f\xa5\xba\xc5\x57\x6f\x41\xb4\xa8\x6f\xfd\x9e\x03\x95\xb1\x3a\x67\x33\x7a\xed\x66\xe9\x25\xed\x8c\x11\xec\x1e\x5f\xd7\x54\x8a\x02\x25\x1c\xfd\xe6\xd1\xc9\xaf\x25\xb9\x81\xe3\xde\x20\xf1\x48\xe2\x61\x8b\x39\xa2\xa4\xc2\xc1\x42\xdc\x99\x9e\x64\x69\x0f\xc9\x0f\xac\xc7\x04\x08\xd6\xad\x90\x73\xb1\x21\x08\xea\x75\xcf\xf5\xea\x2d\xa7\x82\xf5\x96\x37\xc0\x56\x39\x59\x69\xcd\xa0\xf7\xa5\xa7\x41\xec\x35\x5a\xcf\xba\x97\x8a\xc6\xd7\x87\x07\xa0\x9f\xc9\x67\x7d\x8e\x40\xd1\x43\x6a\xf7\x72\x62\x37\xc2\x48\x41\xe9\x25\x0a\x57\x10\x13\x08\x7c\xb9\x31\xa7\x8c\xd3\x16\x7a\x7d\x75\x74\x94\x97\x4c\x05\x56\x78\x8f\xf2\xbb\x3c\x20\x51\x66\x02\x91\xc8\x7b\x77\xae\x3f\x8e\xb8\x9a\x0a\xf6\xd4\xfd\xf2\x6f\x5f\x7f\xfd\xd5\xd7\x23\x6c\x3e\x64\x29\x28\x76\x7a\x78\x76\xf8\xcf\x8b\x9f\x8f\xa0\x38\xb6\xeb\xa8\xf6\x94\x82\xd9\x77\x02\x66\xaf\xe9\x97\x9f\x34\xf9\x12\x4a\x3e\x3a\x4b\x91\xa6\xef\x1f\x9a\x8c\xf1\x3d\x49\xf7\x8b\x70\xf6\x10\x83\x36\x76\xa4\xba\xad\xb6\x11\x7b\xcc\x26\xc5\x85\x4e\xae\x7a\xb4\x6b\x8e\x45\x51\x8a\x04\xfd\x64\x97\x47\xe7\xd8\xba\xb3\x2f\xcf\x5e\x5d\xd6\xa5\x06\x90\x8f\x53\x83\xe9\xfd\x48\x9e\x34\x67\x93\x5e\x89\xc2\x06\xd3\x7d\xcc\x93\xab\x1b\x5e\xa6\xe0\xd9\xe2\x56\x02\x74\x30\x62\xff\x95\x82\x68\xdc\x30\xe1\x0f\x41\xce\x3c\x4d\x36\xca\x72\x74\x20\x78\x77\x28\xb8\xac\x30\x8f\x66\xc2\x65\x06\x1e\x54\x62\xa8\xc6\x8c\xa0\xa4\x08\x2e\xbd\xd8\xa7\xbd\x35\xbe\xfc\xb5\xb1\xc6\x57\xc4\xa0\x7d\x5f\x3b\xac\x6b\x5e\xe2\x06\x1f\x75\x74\xc4\x95\x0d\x32\xfb\xed\x51\xd7\x43\x7b\x9b\x7b\xd4\x15\xa5\xb8\xb0\xba\x15\x23\x06\x5b\x8e\x92\x60\x63\xb7\xc4\x48\xc6\x62\xa2\x9d\x10\xbe\x35\xe8\x91\x56\xb0\x09\xb9\x82\xe2\x40\xef\xd5\xd2\x8d\xc0\x06\x66\x64\x06\xfc\x7a\x02\x4e\x3d\x30\x31\x5a\xaa\xe7\x02\x1f\xb8\xb7\x13\x39\xf4\x6e\x50\x57\x39\x10\x13\x39\x7c\x28\x6c\x82\x9e\xdb\x48\x90\x03\x72\x28\x75\x7f\x31\x8c\x92\x94\xdc\xcc\x90\xa5\x5b\xbc\x93\x96\x70\x59\xcf\x75\xba\xc8\xad\x3f\x2d\x79\x22\x58\x21\x4a\xa9\xdd\x61\x54\x29\x9b\xea\x1b\xc5\xc6\x62\x2a\x95\xf1\x43\x01\xe0\xe9\x34\x66\x10\x8f\x91\x26\x00\xc3\x8d\xd8\xeb\x06\xd8\x09\x95\x21\x25\xba\xde\x9a\xd4\xe7\xc5\x48\x12\x9c\x58\x30\x4e\x08\x78\x1f\x46\x38\x66\xf3\xfa\x58\x97\xf7\x2a\x05\x4f\x4e\x45\xc6\xe7\x98\x6d\x0a\x0c\xfe\xf2\xdf\xa2\x34\xfb\x3d\x44\x9c\x90\x8f\xce\x7f\x77\x6b\x3f\xa4\x61\xa5\xe0\xc9\xac\x5b\xf0\x77\x1b\xa2\xba\xe3\xb5\x0d\x51\x75\x69\x64\x1b\xa2\xda\x86\xa8\x3e\x72\x6d\x43\x54\xdb\x10\xd5\xc2\xb5\xb1\x56\xd2\x36\x44\xd5\xfa\xda\x86\xa8\x3e\x7c\x6d\x43\x54\x77\xb8\xb6\x21\xaa\x3b\x5e\xdb\x10\xd5\x36\x44\xb5\x0d\x51\x6d\x43\x54\x7f\x20\xbf\x9d\xbf\xb6\x21\xaa\xa5\x46\xb6\x21\xaa\x6d\x88\xea\xce\xd7\xc6\x1a\x5f\xdb\x10\x15\x5e\xdb\x10\x55\xf3\xfa\x63\x1d\x75\x3e\xc0\x73\xee\x4c\xbd\xee\x35\x6d\xe7\x10\x54\x90\x09\xc5\x89\xf4\xa4\x51\x07\x85\x8f\x1a\xd5\x1c\x15\x11\x2c\x88\x2f\xc5\xa1\x88\x50\x1d\x67\x5a\x59\x2f\xd5\x91\x47\xae\xd0\x69\x1d\xa8\x88\x22\x14\x68\xf0\xb6\xaf\x59\x5b\x5b\x35\x56\x97\xb0\xc4\xe7\x09\x49\x6c\x48\xfc\xa6\x87\x30\xc4\x36\x04\xf1\xe8\x42\x10\xfd\xb8\xef\x7a\x70\xdd\x75\x3e\x2a\x28\x32\x7f\x39\x2b\x85\x99\xe9\xac\xf5\x42\x6f\x2c\xf2\x97\x52\xc9\xbc\xca\x81\x29\xd6\xad\x67\x79\x1d\x52\x00\x4c\x4d\x45\x0f\x12\x1b\xbd\x88\x11\xa5\xac\xa7\x92\x85\xfa\x4d\xa2\x86\x37\x55\x92\x08\x01\x54\x6a\xb1\x85\xf3\xd5\x28\x3c\x29\x50\x67\x3c\xed\x26\x6f\xba\x1d\xe2\x08\x47\x0a\xad\x7c\xf5\x65\xab\x36\xa6\x65\xd1\x8f\x5c\xfe\xe1\xf5\xf9\x51\x24\x97\xb9\xf2\x62\x59\xaa\x6b\x9d\xc1\xa8\x72\xbc\xc9\x29\x6b\x44\xb0\x2f\x9d\xc1\x34\x16\x96\x47\xb6\x0d\x99\x05\x06\x49\xf4\xdd\xef\xdc\xaf\xc2\x89\x7c\x8e\xe7\x2e\xf2\xe7\xb3\x29\xb7\xeb\x14\xf8\xdd\x4d\x98\x4e\xe6\x4b\x1f\xe7\x4d\x57\x0d\xbd\xe9\x83\x73\x7a\x78\xd3\x0b\x35\x85\x75\x81\x08\xfa\x77\xd6\xc3\x3b\x4b\xca\xee\xba\x71\xf7\xad\xc5\x00\xe2\x06\x5e\xbc\xb7\x01\xde\xb9\x20\xea\x28\x3a\xce\x63\x23\xc8\xb3\x4a\x59\xcd\x8a\x8c\xd7\xbc\x50\x30\x03\x3f\xc2\x19\x74\x34\x13\xc9\xd5\x6b\x8a\xc4\xee\x19\x21\x82\x6e\x3a\x95\x76\x56\x8d\x47\x89\xce\x0f\x9c\x48\xc0\xff\x1b\x67\x7a\x7c\x90\x73\x63\x45\xe9\xd4\x55\x3a\xe2\x86\x89\x6b\x45\xaa\xe9\x28\x4f\xf7\x47\xec\xad\xc2\xea\xf6\x9a\x87\x32\xc2\x76\x70\xcf\xf7\x38\x1b\x63\xe1\xa4\xab\x06\x3f\x44\x04\x61\xe7\xba\x37\xea\x02\x94\xdc\xf9\x48\xea\x18\x05\xff\xfc\x11\xf0\xad\xe4\x62\x3d\x38\x5c\x1e\x5a\xa4\xbb\xb7\x8c\x8f\x1e\x22\xdc\x1b\x14\xdd\xde\x18\xd5\x78\x53\x22\xda\x1b\x88\x36\xdd\x43\x00\xb6\x8f\x08\x76\x7f\xd1\xeb\x4f\x00\xca\xfc\x69\xa2\xd6\x3d\xba\xf6\x7a\x8a\x56\x7f\x8e\x48\x75\x2f\x6f\xdd\x35\x42\xfd\xf9\xa2\xd3\xfd\xbc\x6e\x9f\x86\xc0\x43\x8d\x48\xf7\xe0\xa2\xef\xd3\x3d\xdf\x9b\x6b\xfe\x93\x45\xa0\xbb\x47\x9f\x37\x20\xf2\xdc\x79\x90\xa5\x92\x56\xf2\xec\x58\x64\x7c\x7e\x21\x12\xad\xd2\xd6\x27\xcc\x02\x4a\x67\xd8\x3f\x06\x9b\x25\x3f\x55\xb3\xd0\x62\xc6\x09\x8c\xdc\x59\x54\x58\x58\xe2\x63\x19\xa4\x50\x40\x54\x19\x7b\xb9\x91\xd1\x09\xb6\x31\x0e\x31\xac\x3a\xe9\x73\x12\x7f\xd4\x37\x4c\x4f\xac\x50\x6c\x4f\x2a\x3f\x8f\xfb\x91\x19\x58\x7b\x27\xc3\xb2\x76\xdf\x3e\x7d\xe2\x6f\x7e\x7c\x6e\x47\x70\xb0\x1a\xf3\xe9\xbd\xc0\xf4\xa0\x8f\xbb\x81\xe9\xc6\x49\x95\x35\x5d\xc1\xe8\x1e\x6e\xca\x9b\xa7\x35\x9c\xf2\x53\x68\x37\xec\x36\xae\x52\x46\x95\x68\x8f\x6f\xd2\x3a\xe7\xd5\x34\x55\xbf\x90\x47\xf3\x31\xaf\xf1\xe5\xd1\x39\x3a\x8d\xb7\xee\x92\x4d\x71\x97\xac\x29\x37\x65\x03\x15\xdd\x07\x9a\x8f\xb2\x55\x74\xef\x71\x45\xb5\xa9\x3f\x94\x3c\x11\xe7\xbd\xeb\x08\x7e\x3b\xb1\xb4\x2a\x39\x09\xc0\xa0\xf2\xf9\xcd\xa3\x84\x48\x71\x37\x85\x7a\x5e\xa8\x94\x9d\x54\x59\x36\x67\x55\xa1\x55\xb3\xfa\x19\x63\xed\x8b\xc5\xb4\xe0\x92\x5f\xf1\x94\x5a\xb1\x2c\x4a\x4d\x67\x66\x59\x29\xe5\x64\x70\xcd\x89\x06\x8a\x24\xc0\x34\xf3\x46\xc9\xae\x91\x53\xd7\x7d\x77\xfe\x41\x35\x6f\x9d\x80\xd8\x68\xd0\xfd\x7a\xa2\xcb\x44\x8e\xb3\x39\x9b\xf1\x2c\x10\xe0\x70\x76\x25\xb3\x8c\x9a\x19\xb1\x0b\x61\x31\xa4\x80\x67\x67\xa6\xd5\x14\x3a\xc7\x95\x27\x5e\x14\x89\xfb\x6d\x92\x09\xae\xaa\x02\x9f\xe7\x4e\xe2\xb9\xae\x4a\xff\xbc\x51\x08\x4c\x84\x13\x58\xc9\x6c\x10\xd1\xbb\x7d\x70\x62\x43\xee\x4f\x65\x9c\x02\xf0\xca\xc3\x52\x0f\xe2\x36\x3d\x72\xb8\x89\xc8\x7d\x8a\x52\x5f\xcb\x14\xa3\x1b\x7e\xd8\x80\x48\x1a\x09\x7c\xc2\x7e\x56\x5a\x0d\x95\x98\x72\x50\x54\x68\x17\xe1\x9c\x61\x3b\x98\x41\xa0\x52\xa0\xf4\x71\x1a\xbe\x2e\x1a\xe5\xf4\xd7\x12\xc9\x88\xa3\x91\x63\x7b\x4a\x33\x0d\xf9\xa8\x95\x92\x16\x09\xee\x67\x95\x65\xa9\xbe\x51\xfb\xf7\x8a\xba\x42\xa0\xf5\x72\xe5\x00\x35\xc3\xaf\xab\xf4\x1c\x7c\xdf\x0f\x0f\xaf\x34\xe4\xfa\x9c\xb0\x4a\x19\xd1\xf1\x78\xef\x4d\x39\xfa\xdb\x5f\xdb\xc9\x08\x99\x0b\x5d\xd9\xcf\x62\xfd\xdd\xcc\x64\x32\x8b\x95\x59\x99\x0b\xc3\x74\xb5\x60\x16\x3f\xa5\x9f\xad\x9e\xa1\xad\x09\xb8\xea\x6a\xeb\xd8\x5d\xe1\xfd\x5a\x84\x43\xa8\x99\xaf\x21\x4f\xfc\xf8\xec\xe2\x9f\x2f\x0e\xbf\x3f\x79\x31\x62\x27\x3c\x99\xc5\x98\x18\x8a\x71\x10\x1a\x20\x28\x66\xfc\x5a\x30\xce\x2a\x25\x7f\xaf\x28\xe0\xbb\x17\x7e\xbb\xdf\x2b\x56\x7b\xcb\xd3\x17\xd8\xf9\x7b\xa3\x83\x43\xae\x7f\xcc\xcb\xd2\x46\x00\x81\xcb\x92\xfa\x14\xa2\xcc\x73\x34\x11\x40\xe1\x82\xf4\xf9\xe3\x57\x27\x17\x90\x96\x5f\x94\x88\x14\x02\x79\x5c\xf0\x3d\xb4\x34\x16\xee\x17\xc4\xdc\x3b\x62\x87\x6a\x8e\x5f\xe2\x9e\x92\x86\x65\xd2\x58\x01\xa7\x1e\xa9\x6d\x3e\x7e\xbd\xf3\x64\x04\xff\xdb\x61\x3c\x4d\x4b\xa7\xd7\x85\xf4\xb4\x64\x29\x5f\x14\x35\x3f\x39\xce\xa2\x17\x50\xc2\x62\x36\xda\x4b\x9d\x52\xcf\xe1\x24\x81\xd8\x15\x1e\x83\xc6\x96\xdc\x8a\xa9\x4c\x58\x2e\xca\xa9\x60\x05\xb7\xc9\x8c\xe5\x7c\xce\x12\x5d\x96\x55\x81\x38\xff\x29\xb7\x7c\xc4\x9e\xeb\x92\xe5\x7e\x13\xbb\x35\xef\xce\xe1\x8b\xd5\x31\xfd\x7a\x67\xc7\xff\x94\xc6\x54\xc2\x1c\x3c\x7d\xf2\xcd\x97\x5f\x7f\xfd\xa8\xa8\xe1\xea\x74\x21\x37\xb7\x11\x35\x1c\xf7\xb3\x80\xb3\x8e\x54\x81\x52\x4d\xb3\x78\x7d\xb5\x3b\x00\xba\x5a\x99\x5d\x6d\xcc\x61\xfd\x06\xe7\x6d\x4d\xcd\x5e\x28\xea\xea\x3e\xf4\x44\xec\x54\x9f\x83\xde\xb0\x22\xd9\xa0\x63\xae\xde\xd3\x73\xbf\x31\x49\xcf\xc9\x17\x08\x5e\x8b\x3a\x3b\x69\xc0\x9e\xb0\x6f\xd9\x3b\xf6\x2d\x18\x5a\x7f\xeb\x4a\x83\xd5\xd5\x04\xea\x23\xd9\xc8\xd9\xf7\xa7\xe7\x3d\x8d\xf8\x2f\x4e\x68\xba\x16\xdd\xa8\x5a\xcd\xc6\x92\x14\x7b\xf1\xce\x8a\xd2\x29\x9a\x34\x13\x6b\x25\x10\x73\x1d\xfc\x8c\xcb\x0c\x03\x0f\xa7\x93\x66\x82\xd3\xfd\x16\x9a\xfb\xf9\x8f\xda\xd8\x33\x92\x42\x4d\x2a\x9c\xba\xb5\x1c\x04\x7f\x43\x8c\xb9\x73\xc3\xd8\x7a\x83\x19\x96\x6a\xc8\xb7\xc2\x44\xe6\x99\xec\x90\x46\xb1\x39\xcb\xb8\x5b\x64\xbd\x31\x9f\x1f\x9a\xa9\x05\x57\x0a\xd8\x40\xa4\x62\x45\x18\x59\x85\x4e\x49\x3b\x73\xdd\x4a\xa3\x33\xe3\x03\xea\x19\x79\x6d\x82\xbf\x19\xd6\x92\xdb\x4f\x09\x57\x58\x4a\x32\x11\x65\x89\xb9\xe7\xe3\xb9\x4f\xdb\xeb\x3c\x79\x9d\x76\x52\x51\x6a\xab\x13\xdd\x81\xe3\xac\x19\xed\xa6\xe6\x60\x10\x30\xdf\xd7\x3b\xcc\xdf\x1c\x9f\x0f\xd8\xe5\xd1\x39\xf0\x3e\x5d\x1c\x5d\x9e\x37\x6d\x96\x9d\xcb\xa3\xf3\x9d\xb5\x0e\x05\xf3\x0a\x1f\xb8\xa8\x5b\x34\xd2\x70\x41\x39\x6d\x72\x98\xf3\x62\x78\x25\xe6\x2d\xcf\xd4\x3e\xce\xf5\x61\x98\xe1\x5e\x5e\x08\x87\x39\xe7\xc5\xbd\x5b\x2b\x05\x4f\xe5\x67\xaa\xe7\xf2\x09\xb1\xe1\x99\xab\x0b\xbb\x72\x7d\x2d\x52\xd4\xd2\xfd\x2f\x84\x4a\x0b\x2d\x9d\xbe\xb8\xad\xf6\xba\xff\xaf\xb7\xd5\x5e\x77\xbe\xb6\xd5\x5e\xdb\x6a\xaf\xe5\x6b\x63\x52\x5a\xb7\xd5\x5e\x8f\x2b\x82\xbf\xad\xf6\xfa\x83\x27\x01\x6c\xab\xbd\x56\x5f\xdb\x6a\xaf\x6d\xb5\xd7\xdd\xae\x6d\xb5\xd7\xfd\xaf\x8d\x4b\x5f\xda\x56\x7b\xdd\xeb\xda\x56\x7b\x2d\x5f\xdb\x6a\xaf\x5b\xae\x6d\xb5\xd7\x2d\xd7\xb6\xda\x6b\x5b\xed\xb5\xad\xf6\xda\x26\xc1\x7e\xb4\xad\xcd\x4c\x82\x65\xdb\x6a\x2f\xba\xb6\xd5\x5e\x8f\x22\xd5\x8f\x6d\xab\xbd\xee\x74\x6d\xab\xbd\xb6\xd5\x5e\x6d\xae\x6d\xb5\xd7\x63\x71\x97\x6c\xab\xbd\xb6\xd5\x5e\x7f\x1c\x45\x77\x5b\xed\xb5\xad\xf6\xda\x56\x7b\x6d\xab\xbd\x3e\xd8\x8b\x6d\xb5\xd7\x63\x30\x01\x3d\x23\x70\xf7\xea\xa5\xdd\x23\x9d\x17\x95\x15\xec\xb5\x6f\x32\x68\x91\x28\x18\xa4\x89\x35\x82\xee\x29\x84\x89\x56\x13\x39\x25\xc9\x7e\x80\x34\xbc\xc3\xf0\x3e\xc3\x88\xfa\xf6\x01\xe6\x0f\x66\x32\x97\xed\x4a\xca\xd8\xd2\xc4\xbc\x80\xb6\xa2\xb8\x8c\xdb\x49\x39\x7f\x07\x5b\x84\xe7\xba\x42\xea\xe2\x84\xe6\x2f\x0c\x21\x46\xaf\x36\x6e\x66\x58\x3f\x26\x0e\x4f\x7d\x5e\xdd\x79\x1f\x69\x25\xdc\x5a\x51\xaa\x67\xec\xbf\xf7\xde\x7e\xf1\x7e\xb8\xff\xdd\xde\xde\xaf\x4f\x86\xff\xf9\xdb\x17\x7b\x6f\x47\xf0\x8f\xbf\xec\x7f\xb7\xff\xde\xff\xf1\xc5\xfe\xfe\xde\xde\xaf\x3f\xbd\xfc\xe1\xf2\xfc\xe4\x37\xb9\xff\xfe\x57\x55\xe5\x57\xf8\xd7\xfb\xbd\x5f\xc5\xc9\x6f\x77\x6c\x64\x7f\xff\xbb\x3f\xb7\xee\x72\x67\x95\xb8\x3f\x85\xb8\x27\x75\xf8\x93\x28\xc3\x14\xd0\xed\x69\x2f\x52\x32\xca\xd2\x6e\xa4\x03\xeb\x43\xbb\xd1\x4b\x53\x50\xf3\x42\x3b\xd2\x30\x9d\x4b\xeb\x94\x43\xa7\x0f\xf2\x38\x9d\x55\xda\x86\x51\x4a\x72\x00\x12\xba\xb9\x45\xa2\xf5\x90\x0a\x1a\x25\xb1\x68\xaf\xf9\x11\x13\xbd\xcc\x8b\x0c\x08\xce\x61\x3f\x0f\x7d\x2e\x0b\x1c\xae\x5b\xd9\xf0\xf1\x6b\x2b\x1b\x1e\xa3\x6c\x30\x22\xa9\x4a\x69\xe7\x47\x5a\x59\xf1\xae\x95\x87\xa5\x29\x1a\x2e\x9a\x0d\x52\xce\x98\xa1\x5c\x37\xfc\x8e\xe9\x02\xf3\xbe\x17\x0a\xeb\x67\xba\xca\x52\x28\xe6\xa8\x14\x18\x98\x58\xa5\x27\x2c\x5a\x7f\x60\xf7\x40\x2a\xf7\xe2\x43\xbc\x3d\x87\x66\xe6\xef\x95\xbc\xe6\x99\xb3\x76\xeb\x5f\x9c\x83\x05\x13\xff\xe8\xae\x7b\xde\x72\x73\x55\x6f\x78\x31\x74\x3a\x74\xe8\xf3\x81\x7f\x25\xf8\x48\xbc\xb3\x0f\x51\x4b\x03\x05\xe9\xbc\x94\xd7\x32\x13\x53\x71\x62\x12\x9e\x81\x5c\xeb\xe7\xac\x38\xbc\xa5\x75\x98\xf8\x52\x67\x86\xdd\xcc\x84\x93\xd5\x8c\x7b\x17\x00\x54\xd8\x4d\xb9\x54\x58\x17\x5f\xf8\x1f\x1b\xf4\x25\x38\xf1\x5f\xf0\xd2\x4d\x70\xf0\x19\x80\x89\x3c\xd6\x3a\xa3\x8a\x87\x6c\x5e\xb7\x4f\xb5\x3f\x4a\xff\x53\x89\x9b\x7f\xba\xd6\x0c\x9b\x64\x7c\x1a\x5c\x05\x46\xd8\x25\x6f\x5f\xdd\xf4\xad\x2f\x00\xe5\x04\x95\x60\x3c\xbb\xe1\x73\x53\x3b\x4e\x22\x04\x08\xf3\x8c\x3d\xdd\x87\xe5\xcc\x0d\x0b\x6d\xa4\xec\xcb\x7d\x08\xff\x1d\x1d\x9e\xff\xf3\xe2\x1f\x17\xff\x3c\x3c\x7e\x79\x7a\xc6\xce\xb4\x15\x78\xa8\x45\x34\x81\x49\xb0\x30\x5c\x2f\xe1\x19\x60\xa5\x6b\x33\x02\xdf\xa5\x34\xec\x46\xaa\x54\xdf\x98\xd6\x3e\x5a\x5c\x7e\x6e\xf0\x04\x57\xad\xda\x48\x78\xc1\x81\xfd\xb0\xc3\x09\xb3\x94\x61\x12\x37\x0a\x67\x78\x9a\x1e\xa4\xa5\x2e\x70\x10\xbc\x93\xab\x3e\x6a\x9b\x66\x74\x9c\xc3\x0a\xf3\x3b\x69\x36\x38\x2d\xb9\xb2\xb5\xb7\xa7\x9e\x33\xa2\x5d\x1c\x75\x9e\x8e\x87\x5d\xd1\xc4\xd3\xfe\xaa\x99\x0e\xd3\x54\xa4\x8d\xe1\x7f\x74\x99\x83\x47\xfe\xe5\xe6\x35\x4a\x05\x3b\x7f\x75\x71\xfa\xff\x2c\xac\xe3\x79\xd1\x2d\x51\xaa\x9f\xca\xd8\x52\x17\xbd\xcd\xee\x6b\xaa\xbc\xdc\xce\xef\x46\xcc\x6f\x38\x2d\xfb\x09\xcf\xbf\xae\x54\x13\xd2\xa8\x6e\x9f\xe5\x3a\x15\x23\x76\x1e\xe2\x04\xcd\x6f\x23\x80\x03\x5e\x0a\xe6\x6e\x51\x56\xf2\x2c\x9b\xc7\x2a\x9a\xd5\x58\x85\xd8\xc0\x66\x88\x05\xf9\x84\x67\x66\xdd\xd2\xb8\xcb\xd9\xe8\xf4\x88\x97\xce\x1e\xee\x65\x3a\x42\x6b\x2c\x15\x4a\x5b\x52\xac\x5d\x2f\x01\xef\xa2\xd4\x09\x43\xe3\x3b\x4a\xc6\x6a\x9c\x6f\x06\x63\x15\xfe\x68\x94\xc6\x0f\xf6\x79\x68\x19\x1d\xd5\x95\x11\x8b\x0a\xba\x67\x24\x0e\xe6\xb8\x6b\xbd\x14\x3c\xd5\x2a\x9b\x43\xe6\x25\xe6\x52\xe4\xdc\x5c\x89\x14\x3f\x20\xd5\x2c\x44\x2a\x5c\x8b\xe1\x51\x97\xae\xdf\x3e\x2c\x01\x2a\x19\x66\x78\x40\x38\x43\xa4\x6b\x9e\xf5\x0e\x9b\xd0\x0d\xca\x2b\x95\xcd\x5f\x6b\x6d\x9f\x87\x32\xda\x5e\x56\xc0\x2f\xa4\x2d\x37\x5d\xd1\xa0\x4e\x72\x78\xee\x10\x66\x03\x36\x55\x5c\xc1\x7b\x5c\xcf\xf8\x43\xdf\x52\x65\xa5\x0e\xcd\x0f\xa5\xae\x5a\x1f\x62\x4b\xca\xe6\x0f\xa7\xc7\x20\x8a\x2a\x0a\x55\x2a\x5b\xce\x01\x3a\x60\x19\xff\x2d\x18\x06\x6f\x28\xd8\x1a\xef\x89\x3a\x2e\xc6\x5e\xf2\x39\xe3\x99\xd1\x7e\x2c\xa5\x5a\x69\x85\x92\x89\xeb\xbe\x1e\x6b\x3b\x5b\xb2\x6d\xdd\x86\x5a\xfe\xdd\x20\x8a\x5c\xd6\x80\x74\x52\x2d\xfd\xdc\xf2\x2b\x61\x58\x51\x8a\x44\xa4\x42\x25\xeb\x9e\xf6\x75\x07\xfc\x60\xe9\x9c\x69\xe5\x36\x66\x2f\x8b\xe7\x34\x44\x7a\x69\x48\xe3\xa5\x02\x31\x63\xb2\xfe\x38\x44\x8e\x61\x5b\x56\x46\x94\x18\xe6\x2e\x2b\x81\x33\xf9\x53\x35\x16\x99\x1b\x79\x67\x92\x12\x67\x3c\xba\x33\x64\xce\xa7\x82\x71\x1b\x56\x9a\xd5\x4c\x28\xe3\x24\x26\x3a\x40\x2d\x4b\xb5\xa8\xab\xef\xb9\x61\x6f\x4e\x8f\xd9\x13\xb6\xe7\x9e\xb5\x0f\xeb\x07\x28\xe5\xad\xc6\x24\xb7\x45\x1b\x75\xe2\x9b\x80\x2e\xc1\xe2\x65\xba\x44\x21\x31\x60\x4a\x33\x53\x25\xb3\x98\xc7\xde\x9b\xcd\x94\x08\x09\xa1\x95\xcd\x5c\xeb\xeb\x95\x50\x6f\x8c\x28\x7b\x13\x50\x6f\x5a\x08\xa8\x58\x8d\x72\x6b\xae\x39\x7a\xb8\xb0\x72\x61\x79\xca\x2d\x27\xc1\xe5\x6f\xd8\xd8\x29\xfd\x63\x8b\x2f\x23\x5e\x48\x55\xbd\xc3\xc4\xa3\xfe\x5c\x2d\x17\x27\xd0\x2c\x4b\xfc\xa8\xc3\xac\xf3\xa2\xc8\x24\xa2\x6d\x2c\x24\xc2\x9d\x36\xd6\xca\xe0\x16\x35\x11\xe4\x04\xcf\x32\xed\xe4\xa3\x53\x4e\xb8\x4a\x75\xbe\xf4\x30\xa7\x44\x8a\x06\x72\xea\x88\x6d\x57\x5f\xf3\xda\x10\xa7\x50\x26\xae\x45\x07\x6c\xb1\x45\xa4\x58\xd7\x9a\x1b\x1c\xbf\x22\xa0\x79\x96\xf1\xb1\xc8\x70\x8c\x71\x05\x9a\xe5\x15\xb8\xee\x6c\xd4\x52\x67\xfd\x95\xcf\xbc\xd6\x99\xc0\xf4\x2e\x3f\x10\xae\xf9\x07\x31\x0e\xd0\x48\x5f\xe3\x00\xd6\x60\x63\x1c\xc0\xae\x7d\x08\xe3\x50\x75\x38\xea\xd9\xe2\x38\x38\xbd\xa1\x39\x0e\x70\x78\x6f\xfa\x38\x18\x91\x24\x3a\x2f\xce\x4b\xed\xcc\xce\xde\xce\x26\x6a\xb6\x8e\x19\xa2\x63\x63\x45\x32\x16\x9c\x05\xcd\x9b\x79\x19\x25\x76\x72\x8b\x87\x84\xcf\xee\xfc\xff\x45\x67\x16\x88\x9e\xc5\x83\xcc\xb7\xd2\x08\x2f\xba\x5f\xd2\x17\x0f\xf9\x38\xe8\xa3\x36\xa2\x83\xb3\xb3\x97\xd3\x48\x27\x3c\x03\xec\xd8\x6e\x4b\x8e\x2d\x2e\xbb\xc5\x86\xa3\x74\x5e\x88\x51\xc2\x67\x3e\x81\x04\x60\x44\xe1\x13\x72\x61\x2a\x9d\x8a\x28\x96\x8d\x79\xc8\x97\x98\xf6\x09\xf7\xf9\x4c\x62\xa7\x57\xf8\xb0\x72\xda\xf8\xb5\xd5\x84\x80\xf6\x32\x20\xd2\xba\x0e\x0a\x95\x4a\x35\x05\xbf\xda\x80\x95\x22\xc3\x1c\x64\x12\x02\x57\x68\x41\xee\xc2\x96\xf0\x8d\xfa\xfd\xe0\x1f\x0d\xba\x98\xd4\x8a\x5a\x06\x4f\x91\xd7\xb0\x26\x28\x6e\xa5\x61\x3b\x2f\xfc\x00\x74\x80\xf0\xdc\xc4\x13\x66\x07\xdf\x30\xcc\x26\x7a\x3a\xaf\xa4\x4a\x29\x5d\xb7\x31\x58\x01\x03\x1e\xf5\x60\x48\x04\x97\x69\x2c\x5b\x9e\xb1\xb7\x8a\x85\xc1\x62\xc3\xd6\xcb\xe3\x35\xaa\xcc\xde\x47\x37\xfc\xb0\xe3\x35\x3c\x64\xb1\x99\x37\x0a\xe6\xde\x3d\x77\xe8\x2c\xf7\xe5\xfb\xfc\xbb\xac\x15\xba\x87\xa4\x5f\xdf\x56\xcc\x2f\xd8\xac\x57\xe9\x13\xb7\xac\xad\x54\x53\x13\x5b\x32\x3c\xcb\x1a\xce\xf0\x55\xa6\x8c\x9f\xe1\x80\xf8\xbf\x6c\x42\x2c\x94\x19\x3c\x14\x33\x24\x73\xea\xc4\x03\x37\x42\xa6\xb9\xe1\x47\xa5\x1b\x09\x2b\x79\x76\x51\xb4\x87\x28\x65\x4b\x70\x78\x2f\x2f\x0e\x9b\x4d\xc3\x61\x0d\x84\x14\x6e\xae\xdc\xf7\x8c\xa7\xb9\x34\x06\x1c\x61\x62\x3c\xd3\xfa\x8a\xed\x7d\x90\xa9\x61\x68\xe4\xd4\x1c\xd0\x9a\x1f\xba\xde\xef\x33\xa9\xb2\x90\x15\x05\x76\xb0\xb2\xc6\x3b\x72\xe0\x21\x49\xe8\x05\xcc\x21\xe1\x56\x53\xb2\xc2\x72\x37\x11\xa9\xda\xad\x82\xb5\x0b\xec\xe5\xe9\x39\xeb\x08\xbb\xf2\x91\x29\x3a\xa3\xb5\xbd\x88\xac\xb6\x72\x1c\x51\x7b\x5c\xfb\x20\x91\x72\x91\x08\xd3\x1f\xa0\xd3\x8f\x75\x9b\x2c\x15\x58\xc5\x23\x20\xfb\x89\xdf\x9a\x64\x07\x7e\xe9\x5d\x28\x06\xa5\x9f\xee\xc6\x1a\xf5\x65\x2d\x5c\x9c\x3d\x92\x15\x33\x3e\x44\x23\xdd\x49\x34\x10\x81\x5e\x85\x98\x69\xa5\xa9\x48\xc2\x1d\xa2\x5a\xc1\x92\x06\x11\x85\xd1\x3c\x98\x13\x12\xd1\x51\x57\x8f\xea\x28\x71\x1c\x08\x84\x62\x32\x1b\xa8\x55\xb0\x0f\x37\xd2\xce\x00\xe7\x75\xb6\x10\x35\x84\x9e\x94\xc2\x40\x00\x46\x31\x51\x96\xba\xa4\x84\x2c\xef\xb7\x86\x96\x40\x92\x43\x46\x97\x5b\x24\xdc\xfd\xb5\x6b\xe2\x40\x75\x0d\x05\x0f\xf9\x8a\x6e\x35\x89\xc9\x44\x24\xa0\x68\xc5\x03\x8c\x52\x7b\xaf\x06\xbe\xa5\x2a\x03\xb7\xc0\x08\x4a\x3e\x97\xef\xdc\x53\xe2\x5f\xc5\x21\x71\x02\x9c\x5d\xfd\xf5\xfe\x88\xb1\x53\x15\x32\x78\x07\x6e\x16\xe3\x3b\x7d\xea\x99\x75\xaf\x18\xf3\x10\xc0\x0b\xc4\x8e\x33\xa7\x1d\x96\x55\x0f\x2b\xbe\x8b\x3b\x9c\xc5\x2e\xf1\x5e\xc5\x01\xb8\xc6\xa9\x51\x37\xf5\x5e\x07\xe8\xe2\x2a\x77\xb7\x7c\x2a\x77\xf9\xc3\x08\x80\xb0\xae\x72\x8e\xd0\x14\x7a\x02\x87\xbf\x88\x5a\x8b\xb4\xf7\x10\x70\x3b\xd7\x29\xa2\xa9\x04\x34\x88\x6c\xee\xd1\x5d\xe4\xbf\xbd\x7e\x56\xeb\x78\x4a\x63\x75\x40\x0c\xb3\x42\x90\xda\x29\x73\xaa\x76\xe6\x7d\x0b\x79\x91\x09\xa8\xe2\x8c\x5a\xae\x0b\x54\x23\x34\xf9\x41\xe8\x48\x0d\x48\x4f\xe0\x2e\x03\xf6\x3f\xb0\x29\x43\x22\xaa\xc7\x9d\x38\x0f\x3f\x47\x0b\x51\x1a\x4f\x2d\x01\x15\x96\x56\x7b\xd7\x05\x4b\xe5\x64\x22\x7c\xc2\xab\xb3\x1c\x79\xc9\x73\x27\xe2\x0d\xa3\x21\x18\x8b\xa9\xc4\x84\xc8\x20\xd8\x76\x9d\xba\x47\xb5\x7e\x03\x14\x86\xd2\xb2\x5c\x4e\x67\xb8\x50\x18\x87\x0a\x5d\xe6\x83\x8a\x99\xe6\x29\x50\x52\x31\x5d\xb2\x1b\x5e\xe6\xee\xdc\xe0\xc9\x0c\x22\x94\x5c\xb1\xb4\x2a\x01\x65\xd9\x0a\x9e\xce\x87\xc6\x72\xeb\x34\x65\x51\x92\x41\xe9\xfb\xbf\x85\xd4\xff\xe0\xb5\x85\xd4\xbf\xe3\xb5\x85\xd4\xdf\x42\xea\x2f\x5f\x1b\x93\x1d\xba\x85\xd4\x7f\x5c\x30\x49\x5b\x48\xfd\x75\x47\x13\xb6\x90\xfa\x5b\x48\xfd\x0f\x5d\x5b\x48\xfd\x8f\x5c\x5b\x48\xfd\x16\xd7\x23\x90\x5c\x5b\x48\xfd\x16\xd7\x16\x52\x7f\xf5\xb5\x85\xd4\x5f\xbe\xb6\x90\xfa\xb7\x5e\x5b\x48\xfd\xd6\xd7\x16\x52\x7f\x0b\xa9\xbf\x45\x1a\xbd\x5f\x5b\x9b\x89\x34\xca\xb6\x90\xfa\x74\x6d\x21\xf5\x1f\x05\x9e\x22\xdb\x42\xea\xdf\xe9\xda\x42\xea\x6f\x21\xf5\xdb\x5c\x5b\x48\xfd\xc7\xe2\x2e\xd9\x42\xea\x6f\x21\xf5\xff\x38\x8a\xee\x16\x52\x7f\x0b\xa9\xbf\x85\xd4\xdf\x42\xea\x7f\xb0\x17\x5b\x48\xfd\xc7\x60\x02\x1a\x9b\xca\x56\x08\xa0\x77\x01\x2b\xa2\x24\xf4\x08\x1b\x60\x5c\x4d\x26\xa2\x04\xc9\x05\x4f\x5e\x4a\x9e\xaa\x71\x19\x17\x83\xac\xc2\x0e\x00\xf7\x88\xea\x75\x6e\xf9\x39\x81\x11\x00\x52\x67\x9d\x29\x7e\xf2\xea\xf9\x0a\x64\xa4\xd6\x59\x85\x6d\x73\xa4\xa1\xcf\xaf\x54\xbb\xf8\xf8\x2d\x03\xbe\xaa\x7e\x8c\xc6\x3d\xc9\xb4\xa1\x0c\x77\x18\xac\x64\xc6\x95\x12\xde\xde\x93\x16\xfc\x28\x63\x21\x14\xd3\x85\xa0\xe8\x34\x67\x46\xaa\x69\x26\x18\xb7\x96\x27\xb3\x91\x7b\x92\xf2\x83\x5d\x67\xa3\xd3\x27\xc6\x96\x82\xe7\x3e\x2f\x3f\xe7\x12\x9b\x62\x3c\x29\xb5\x31\x2c\xaf\x32\x2b\x8b\xd0\x18\x33\x02\x0a\x6a\xf0\xa0\x0a\x83\x01\x59\x71\x75\x0a\xfb\xa0\x7e\x1a\x75\x4b\xc7\xd0\x74\x60\x6d\x0e\x00\x0f\x3c\x2f\xec\x3c\xe4\xf1\x0a\x36\x91\xa5\xb1\x2c\xc9\x24\x9c\xd6\xf0\x44\xac\x9d\x86\xf6\x06\xfe\xac\x56\xd4\x53\x43\x5d\x55\x29\xa8\xad\x85\x35\x98\x15\x5b\x37\x48\x4d\xa5\xd2\x90\x9a\x6f\x06\x8c\x7b\xdc\x34\x1c\x68\xdf\x53\x18\x6a\x7f\xb2\x60\xeb\xf4\x51\xd4\x5c\x84\x17\x5b\xa7\x0d\xd7\x0b\x1d\x4a\x1c\xfc\xe2\x1c\x34\xaa\x39\x6a\x85\x02\xb2\xf4\x96\xb6\x01\x4c\x80\x12\xd7\x6e\x0d\x88\x44\xb8\xf3\x95\xdf\xb2\xea\x3f\xfb\xa2\x8f\x0e\xc5\x97\xc2\x18\x3e\x15\xe7\x2d\x03\x0d\xb7\x59\x64\x10\x6b\xa8\x27\x06\x96\x42\x86\xd5\xb5\xe1\x93\x3a\x3b\xb3\xa9\x06\xb1\x1c\xfb\x14\x94\x9f\x9b\x52\x5a\x2b\x60\x52\x01\x61\x0f\x62\x95\x8b\x05\xf8\xbb\x0b\x39\x9e\x2f\x7d\x23\xf5\x8f\x9d\x50\x57\x29\x66\x5c\x8e\x05\x1b\x97\x52\x4c\xd8\x44\x42\x1a\x27\x24\x56\x0e\x10\x70\x89\xa3\x17\xc0\x18\x67\xef\x6a\xe5\x75\x59\xdf\xaf\x11\xfb\x85\x3a\x66\xcb\x4a\x25\x3c\xc2\xb2\x85\x0a\x53\x39\x61\x53\x48\xcc\x24\x6d\xf1\xaf\x4f\xfe\xf3\x6f\x6c\x3c\x77\x47\x1a\x68\x56\x56\x5b\x9e\x85\x97\xcc\x84\x9a\xba\xb1\xc2\xed\xd9\xac\x91\x0c\x23\x00\x6c\x1e\xd8\xf1\xa7\x5f\x5e\x8d\x9b\x67\xec\x41\x2a\xae\x0f\xa2\xf1\x1b\x66\x7a\xba\x8a\x1f\xa5\x7d\xca\x76\x4b\x93\x68\xc5\x32\xd3\x99\x4c\xe6\x9d\x17\x9a\x47\xfe\x62\x33\x7d\x83\xba\xfe\x8a\xd5\x53\x97\x5b\x15\xba\xa8\x32\x74\x3a\x3f\x0f\xd5\xc5\x95\x11\xcb\x35\x80\x2b\xf7\x05\xb8\x49\xa9\x89\x45\xdc\x74\xcc\xc7\xf5\x8f\xd4\x54\x5b\x42\x8e\xbc\x00\x00\x06\x86\xd0\x73\x9e\x65\x63\x9e\x5c\x5d\xea\x17\x7a\x6a\x5e\xa9\x93\xb2\xd4\x65\xb3\x2f\x19\x77\xd2\x72\x56\xa9\x2b\x64\x70\x08\x10\x09\x7a\xea\x54\xab\xa2\xb2\xbe\x90\x61\xd5\x0b\x63\xbd\xbc\x17\xc2\xde\x0c\xaa\x5b\x11\xef\x64\x6d\xeb\x50\xa9\x16\xae\xc8\xb8\x7d\x13\x2f\xb6\x2f\x9f\xfc\xf5\x1b\x5c\xba\x4c\x97\xec\x9b\x27\x90\xb3\x6d\x06\xb8\x89\x41\xb6\xb9\x83\x22\xe7\x59\xe6\xcc\x86\x78\x51\xba\x81\x5e\xb5\x08\x3f\xfb\x1a\xb4\xdd\x97\xdb\x9d\x55\xa9\xcb\xcb\x7f\x80\x1e\x25\xad\x11\xd9\x64\x80\x55\x49\xc1\xac\xd9\x85\x83\x61\x97\xa4\x0f\x94\x86\x6d\x80\x02\x74\xad\xb3\x2a\x17\xc7\xe2\x5a\xf6\x41\xe2\xd4\x68\xcd\x9b\xfa\x99\x34\x50\x00\x36\xce\x74\x72\xc5\x52\xfa\x32\xca\x3c\x59\x44\x02\x6f\x3f\x0a\x6d\x73\x70\x3a\xe4\xde\xdc\xfa\xfe\x8d\xac\x9b\x9c\x17\x45\xa8\x11\x2a\xf9\x4d\x63\x30\x60\x4f\x02\x5c\x41\x47\x3c\x99\xce\x6e\xe6\xae\x4e\xe6\x21\xbd\x91\x93\x9b\xad\x9b\x68\x9d\x75\xd2\xdd\x47\x5d\xf7\xbe\xbd\x63\xb2\xb1\x20\xea\x06\xfd\x6e\x28\xe0\xdf\x58\x55\xb2\x54\x15\x19\x0a\xeb\xc2\xc2\x40\x05\xc0\x2d\x1f\x10\xc9\xed\x1d\xae\x3d\x78\x37\xbb\xa5\x1c\x35\xc6\x45\x05\xaf\x72\xce\x2d\x29\x84\xde\x7d\xcd\x59\x21\x4a\x23\x8d\x3b\x97\x7f\x86\x0d\x75\x94\x71\x99\x47\x2e\xc0\xf5\x0c\x02\x6e\x6e\x80\x4f\xee\x2e\x29\xcf\x75\x4a\x0d\x82\x28\x44\xe8\xe8\x15\x6a\x6d\x53\xab\xed\xf1\x40\x5d\xb7\xa8\xfc\xb9\x1e\xcd\xa6\xa4\x74\x9f\x04\x51\x89\x77\x3d\x26\x01\x09\xef\xf7\x50\xe5\x63\xe8\x7c\x4f\x62\x00\x04\x23\x4d\x6e\x53\x12\x36\x8c\x47\xdc\x28\x91\x4a\x4f\x76\xe0\x88\x61\x14\xdc\xed\x09\xfa\x29\xdb\x7d\xb6\xbb\x56\x21\x89\x43\x54\xea\x82\x4f\x3b\x71\xf9\x2c\x8c\xd4\x62\xb3\x31\xd0\x84\x33\x83\xe0\xfb\x00\xbb\x06\x77\x89\xb4\xc6\xd1\x01\x94\x24\x8c\x8e\xfa\x01\x26\x03\x01\xeb\xb1\x6f\xf8\x9c\xf1\x52\x57\x2a\x25\xff\x52\x70\xf0\xbd\x5c\x78\xf0\x99\x56\xc2\x3b\xce\x17\x71\x2a\xc0\xa3\x2f\x15\x7b\x3a\x7a\xfa\xe4\xb1\x9c\x54\xf0\x86\x0b\x27\xd5\x59\x38\xa9\x50\x3e\xad\xf5\x5d\x3d\xe2\x7d\x4f\xef\xfb\x92\x5c\x2c\x35\xa0\xbd\xf4\x70\xd9\xf0\xd1\x4d\x29\xad\x88\x38\xfe\xf6\xc0\x70\x71\xf6\x61\x84\xca\xb0\xbf\x8a\x49\xa2\xe3\x20\x75\x83\xc1\x30\xd5\xf8\x13\xca\x2d\x12\x50\xb0\xdd\x56\x79\xb8\xcc\x07\x44\x58\x3c\x50\x3b\x3b\x6c\x0f\xef\xdc\xc5\x82\xe6\xfd\xb5\x2e\x2d\x1a\xb4\x93\x77\x45\x07\x8c\xcd\x85\xda\xf9\x82\x83\x0f\xae\xe8\x71\x04\xbf\x17\x33\x7e\x2d\xa0\x90\x5b\x66\xbc\xcc\x20\xe6\x78\x81\x7d\x67\xe3\xca\x32\xa1\xae\x65\xa9\x55\x2e\x94\x65\xd7\xbc\x94\x80\x8a\x53\x0a\x40\x76\x70\xb6\xe8\x9f\xf7\x7e\x3e\x7c\x0d\x09\x0d\xfb\x04\x49\x41\xbd\xac\x8c\x87\xaf\x89\x7b\x12\x35\xf7\xd1\xe9\xf3\xfd\x70\x63\x08\x32\xd7\xf7\xcb\x3d\x27\xaf\x6c\x85\xb4\x2c\xef\x92\xac\x32\xf2\x7a\x5d\x92\x84\x2a\xec\x8f\x65\xab\x79\x5e\xa8\xf6\xaf\x07\x6a\xa9\x70\x1f\x5c\xeb\x2b\x0a\xf4\x96\x02\x26\xbb\x26\x14\xed\xc5\x31\x70\x72\x3d\x11\x96\x06\xa6\xcf\x79\xc4\xc5\x25\x15\x02\x70\x63\xd6\xeb\x84\x52\x3a\x15\xf7\x47\xdd\x69\xa6\xf7\x50\x13\x18\x33\x8f\x2a\xf8\x4c\x32\x13\x69\x05\xf0\x4e\xd2\x20\x38\xaa\x33\x1f\x78\x8d\xc2\xa7\x80\x25\xe8\x74\x12\x20\x0d\xd4\x10\x9c\x83\x38\xe6\xfe\xf7\xa5\x07\x40\xf0\x1f\x98\x85\x16\xc1\x28\x75\x6d\x0d\x18\x37\xa6\xca\x71\x4b\x20\x01\xc2\x44\x5a\x13\x38\x66\xbd\x76\xec\x36\xc6\x3d\x0b\xaa\x3a\x8c\xef\x85\xc8\x60\x71\x75\x18\xe3\xdd\xb3\xa8\x1d\x1c\x68\xe3\xff\xa2\x05\x47\x09\x13\x10\x6d\x0b\x79\x9c\x1a\xbc\xa4\x13\x09\x24\x4a\x9c\xc6\xfb\x62\xc5\x2f\x51\x75\xc0\x3b\x00\x1e\x86\x8f\x45\x66\x16\x1b\x1a\xd7\x93\x42\xa8\xa4\x34\xf0\x1d\x59\x72\xb9\x31\x72\xaa\x80\x3f\xd3\xb5\x76\x4f\xa6\xcc\xd6\x36\x53\x1f\x2c\xb8\xad\xa5\x5a\x23\x0b\x2b\xe7\xc5\x90\xac\x5e\xab\x73\x99\xdc\xa3\x25\x7d\xcf\x2e\x2f\xd4\x4a\x37\x6a\x70\x5f\x5d\x2c\x79\x7c\x4c\xe4\xd5\x18\xb1\x0b\x9d\x53\x8a\x93\x8a\x58\xbc\x3c\x99\xaa\x3b\x31\x4a\xe1\xc6\x02\x12\x8f\x64\x1d\x8d\x07\xd6\x1b\x5f\x05\x0d\xcf\x09\x2a\x39\x85\x71\x01\x7e\x92\xc8\x5c\x75\x96\xe9\x1b\x48\x2c\xc6\x76\xfd\xda\x86\x14\x98\x67\x6c\xb8\xc0\x4c\x3b\x6a\x82\x86\x7e\xf8\x39\x74\xef\xe0\xe3\x4f\xc1\xfc\x1c\x80\xe3\x3b\x3d\x8e\xff\x3c\x3d\x3f\x8a\xff\x7c\x63\xdc\x28\xd1\x07\x8b\x5d\x6b\xb2\x32\xdc\x7e\x57\x8c\x8f\x7d\xdb\x5d\x13\x24\x36\xfa\xc8\xd7\x47\x33\xae\x7c\x20\xeb\xd6\xe7\xcd\x4d\x62\xb3\xba\x3b\x33\x5e\x0a\xc2\x8f\x73\x92\xdc\x14\x3c\xb9\xb5\x17\x01\xac\xed\x83\x37\x7c\xb0\xa7\xa6\x2a\x3c\xe1\x76\x06\x37\x86\x9e\xd4\xcb\xee\xd7\xbf\xfc\x76\xc7\xc1\xfc\xd8\x6f\x56\x0d\xed\x87\x7f\xd3\xa0\xed\xbb\xd3\x2f\x56\x93\x7a\xdd\xed\xb7\x11\x2f\xde\x9d\xee\xbf\x8d\x93\xf7\xae\x4f\xf3\x5c\x6e\x77\x7b\xb1\xc5\xd9\xbe\xc3\xed\x30\xa5\xf7\x43\x2b\x68\x2d\xc2\xdb\xba\xbb\x5a\x38\xa9\xda\x3b\xa7\xda\x19\xfb\x0b\x0a\xc0\x2d\x50\xa6\x04\xb3\xa6\xa6\xac\x01\x1e\x55\x95\xa5\x50\x40\x7b\x5f\x41\xa6\xa3\xa7\xb3\x47\x21\x0d\xc2\x96\x80\x3a\x11\x6d\x9e\x1d\x86\xb3\x90\x32\xe0\x72\x0e\xe0\x9d\x11\x58\xf5\xa4\x82\x84\x46\x10\xfd\x08\x46\xa7\x95\xeb\xc7\xb3\x55\x08\x19\xba\x10\x2a\xe2\xba\x27\xad\x79\xe8\xd6\x50\x03\x33\x03\x15\x81\x51\x9e\xfe\xa9\xc8\xb8\x9d\xe8\x32\x1f\x7a\xf5\x70\xd8\x50\x12\xd8\x11\xa4\xd6\x18\x6f\x5f\x61\x7e\x2b\x82\x6a\xaa\x34\x13\xd1\x69\x1e\x5e\x55\xa5\x08\x41\xc5\x2a\x55\x8a\x44\x4f\x95\xfc\x77\x3d\x10\x70\xae\x05\xe7\x10\x37\xee\x24\x65\xaa\xca\xb2\xfb\xe7\x21\xb4\x54\x02\xf4\xb5\x28\x67\x82\xdf\x73\xf1\x2e\xa4\xb4\x50\x1b\x35\xf7\xa8\x21\x4c\x01\x52\x79\xfd\x43\x9c\x6a\xac\x13\xa8\x6d\xc3\x10\xbb\x4f\x5c\xe6\x70\xa0\x3b\x4d\x8f\xb3\xa9\xbc\x16\xca\x43\x8e\x1f\x65\x3c\xf0\x67\x7b\x94\x55\x82\x3d\xaf\xac\x0e\x49\x0b\x8c\xdb\x08\xf8\x18\x72\x9c\x28\x5e\x1a\xb7\x13\xdd\x42\xec\xdb\x99\x67\x3a\xbb\xcb\x9d\x90\x37\x80\xd4\x8f\x83\xfa\x95\x72\xef\x5b\x6d\x20\x6b\xb2\x04\xb2\x5b\xbc\x29\x42\x59\x2d\x1f\x7f\x04\xa5\xa4\x39\x19\xb4\xaa\x19\x52\x97\x03\x04\x6c\x3d\xb0\x99\x13\xff\x73\x54\x72\x4e\x27\xcd\x27\xc9\x06\xe8\x3e\xd4\x3e\x81\xfa\x5d\xdb\x83\xe7\x3a\x75\x5a\xd8\x80\x85\xa9\x8c\xc9\xc7\x29\xde\x82\x7b\x32\xda\x8c\xa8\xa4\x95\xa5\x30\x85\x46\xec\xff\xf8\xb1\x83\xc8\xff\x25\x6d\x23\xd9\x0e\x59\xdc\xc2\xd6\x40\x74\xb6\x7f\x8b\x52\xaf\xd4\xe1\xa7\xd2\x8e\xae\xbe\x01\x05\x5e\xa8\x19\x57\x09\xda\x4e\x07\x57\xa2\x30\x07\x46\x4e\x51\x5f\xff\xdb\x37\xdf\x80\xf2\xee\x87\xe4\xe0\xf5\xc9\xe1\xf1\xcb\x93\x51\x9e\x3e\x20\x4d\xbe\xe0\xd6\x8a\x52\x3d\x63\xff\xbd\xf7\xf6\x8b\xf7\xc3\xfd\xef\xf6\xf6\x7e\x7d\x32\xfc\xcf\xdf\xbe\xd8\x7b\x3b\x82\x7f\xfc\x65\xff\xbb\xfd\xf7\xfe\x8f\x2f\xf6\xf7\xf7\xf6\x7e\xfd\xe9\xe5\x0f\x97\xe7\x27\xbf\xc9\xfd\xf7\xbf\xaa\x2a\xbf\xc2\xbf\xde\xef\xfd\x2a\x4e\x7e\xbb\x63\x23\xfb\xfb\xdf\xfd\xf9\x9e\x1d\x6d\x59\x97\xd2\xb5\x16\xa5\x53\xfd\x49\x8f\x35\x27\x45\x29\x44\x0e\xe2\xaf\x4d\xb6\x56\xd3\x4b\xba\xd0\x94\x3f\x60\xe9\x2f\x27\x13\xfd\xd3\xd4\xd4\x89\x49\x83\xa2\x33\xd3\x37\x90\x61\x29\xb5\x53\x7e\x46\xec\x15\x9c\x83\xec\x4c\x5c\x8b\x72\xe0\x5b\x7d\xe1\x6e\x3a\x0f\xf7\xc4\x6e\xb8\x55\x77\xb4\xcc\xf1\x6f\x39\x27\xbe\xef\x1d\x06\x0f\x79\x4b\xa8\xf3\x20\x9f\x46\xec\x67\x5e\x4a\x5d\x19\xd2\x45\x62\xb8\x6f\x4c\x21\x0b\x27\x09\x78\x25\x28\xc0\x13\x1a\x09\x95\x61\x3e\xc6\x13\xc6\xe6\x30\xc8\xeb\xa3\xd5\x47\x82\xb4\x6e\xa6\xae\xfd\xa3\x4a\x9f\xea\xba\x84\x14\x8e\x87\xc1\x4a\xf9\xef\x4f\x34\x13\x77\x14\x9a\xf1\xfd\x00\xd9\xea\x34\x31\x6c\x65\x26\xa7\x3e\xa1\x1a\xde\x1f\xcd\xd7\xe8\xd3\xb0\x42\x5a\x4c\x69\x9b\x6d\xda\x36\xaf\xbf\x58\x7c\xbf\x0e\xcb\xa2\x89\xa7\x1c\x43\x32\xfb\x8a\xa2\x7a\xdf\xec\xe0\x3a\x81\x43\x64\x98\x94\xd2\xca\x84\x67\x3b\x70\x38\xf9\xaf\x92\xac\x72\x7a\x62\xfc\x6d\x29\x98\xbd\xd1\xf8\x14\x9e\xb1\x2b\x31\xbf\xd1\x65\xea\xcf\x67\xff\xc4\x7a\x2e\x8c\xf5\x8f\x74\xf6\x1c\x6c\x60\x74\x33\x94\xb9\x28\xd9\x58\x78\x0f\xfa\xc2\xcd\xf3\x11\x3b\x54\x73\x0a\x3f\xaa\xb8\xc8\x30\x42\x66\x03\x1d\x01\xb5\xa8\xc6\x22\xa1\x43\xcc\x3f\x8d\x63\xf9\xe7\x6d\xde\x65\xa7\x80\x85\x5d\xe0\x4f\x7f\xef\x5e\xd6\x25\x55\x39\xc1\xee\x28\xb1\x46\x4b\xfb\xaf\x3f\x8b\xb4\x70\xfa\x8d\x54\xc2\x98\x1f\xdc\x54\x76\x51\x57\x9b\xab\x83\x83\x5a\x42\x6d\x43\xa5\x54\x9d\x52\x2c\xdc\x96\xc2\x18\xb1\x13\xc3\x3a\xad\xef\x1c\xb1\x43\xf8\x00\x72\xe2\x9d\xe6\x05\x55\x74\xae\x31\x69\xcd\x22\xb9\x3c\xde\x71\x78\x76\xec\x73\x97\x51\x53\x30\x4d\xb8\x74\x54\x99\x9b\x3d\x01\x4d\x8f\x32\x68\xc5\xef\x15\x07\x9e\xdc\x9d\xcb\xb2\x12\x3b\xed\x54\x25\x04\xe2\x3f\xf8\xfa\x9b\x27\xa0\x2d\x85\xe7\x0d\xe1\x79\x6d\x54\xa5\xfb\xe7\xc8\xb4\xca\x8e\x59\x4c\x0c\x7a\x1d\xaf\x07\x3f\xe0\xde\xee\xa0\xa0\x15\xd4\xf6\xc2\x34\x85\x31\x6f\xe5\x5a\x6d\x95\x0b\xd3\x3e\x0b\x66\x58\x77\xf7\xf2\xfe\x1c\x66\x5d\x12\x58\x1a\xcf\xed\x23\xca\x55\xb7\x86\xb3\x62\x70\x4a\xc2\x73\x22\xcf\x2e\x52\x5d\xd0\xc7\x90\x0e\x0b\x82\x0b\xa2\x02\x20\x1e\xe7\x45\x87\xd4\xdf\x16\xf2\x06\x2a\x5d\x3a\xeb\x77\xbb\xaf\xb1\x21\x56\xd4\x0a\xdd\x52\x05\x43\x88\xf0\x82\xde\x41\xaa\xdc\x21\x94\x83\x0d\xd8\x2b\xf5\x1c\xf3\xe3\x07\xa8\xdd\x35\xd0\x47\xf0\xa6\x5e\xcb\x04\x0f\xfe\x44\xef\x3e\xc4\x2e\xb7\x11\x0a\xf7\x1f\xee\xc8\x72\xec\x78\xfa\xef\xbe\x5e\x68\xab\xb1\xf4\x1a\x96\x31\x9d\x90\xb2\xe6\x3e\x23\xf1\xc9\xa6\xa5\xae\x0a\x1f\x49\x6d\x12\x99\xd5\xec\x1d\x18\x00\x44\x9e\x5f\xa5\x9b\x4d\x07\xe7\x07\x2c\x60\x51\x7b\xcd\x52\x96\xa0\x79\xec\x4f\x5d\xac\x82\x42\x0f\x42\x59\xa9\x26\xcf\x79\x14\x8b\xdc\xc9\xc4\x94\x27\xf3\x9d\xe6\x73\x56\x45\x7e\x25\x14\xe7\xc8\x1c\x01\xd3\xf1\x79\x75\x4d\x03\x94\x3e\x80\xfe\x80\x7b\x0d\x54\x83\xca\x50\x17\xfd\x91\xef\x8b\xf2\xd0\xb3\x55\x76\xb0\xcc\xbf\xfe\xe6\xeb\xa1\xf7\xbd\x41\x57\x3e\xcb\x82\x0a\x91\xdb\x5e\x75\xc9\xc6\x9c\x39\x05\x49\x9a\x02\xe6\x17\x34\xb1\xfa\x38\x0f\x4f\xff\x90\xba\xb5\xba\x11\x3f\x01\x75\x13\x9f\x65\xb8\x9a\x5e\xf4\x2e\xdb\x6f\x91\xf6\x65\xa6\xb3\x14\x36\x0a\x91\x33\xf9\x47\x31\x6e\x6d\x29\xc7\x95\x25\x37\x69\xa2\xf3\xbc\x59\x33\x49\x04\x79\x23\x56\x17\xcd\xc5\x26\x2c\xac\xe4\x11\x63\x17\x42\x20\x39\x64\xd4\x0f\x90\xb3\x7e\x28\xc9\xdb\xaa\x27\xc8\xe4\x8d\x46\xd8\x67\x72\x0b\xb5\x3f\x8e\x29\x98\xd6\xd1\x6b\xbf\x73\x18\xac\x94\x38\xe6\x85\x02\x6e\x89\xaf\x77\xe1\x64\x82\x74\xe2\x3a\xea\x4a\xd9\x45\x6e\x2c\x0c\x62\xc4\xc2\x5a\xfe\x09\xb9\x3d\x21\x75\x12\x22\x7f\xe8\x9b\xbc\x71\x4d\xcc\x64\x81\x36\x35\xb7\xe1\xe7\x10\xc4\x77\x5f\xc7\xd0\x0b\x40\x56\xf9\x14\x8d\x5a\x7d\x03\x5e\xe1\x1f\x4e\x8f\xc3\x1e\x71\x77\x3d\xbf\xc0\x90\xde\x97\x23\xa2\xde\xb5\x53\x99\xb2\x31\x26\x6e\x38\x79\xb9\xa7\xc4\x0d\xa6\x82\x93\xe3\x34\xe8\xd5\xd7\x3e\x45\x1a\x5b\x0b\x0f\xa7\x26\xf7\xd9\x57\x44\x82\x2a\x4a\x6f\x95\x8f\x25\xa5\x8a\xbe\x7a\xbd\xeb\xdd\xd5\x37\xc3\xf2\x66\x38\x1c\x0e\x29\xbe\x0b\x52\x7a\xd0\x18\x83\x20\xcc\x73\x9d\xca\xc9\x7c\x61\x24\xdc\x32\xaf\x1f\x01\x2b\x92\xab\x39\xf5\xae\x3b\x5f\xef\xfd\xe1\xb9\xbb\xb9\xe3\xba\xc0\x31\xac\x08\x15\x77\x8d\x4f\xad\x8a\x3e\xa3\x9d\x6c\x6a\x54\x73\x3d\xc1\x45\x0a\xd9\xf3\xb7\x4c\x8c\xf7\x02\xd1\xaa\x21\xac\x3e\xb4\xd2\xc5\xbb\x42\x23\x12\x30\x54\xa7\x00\x63\xdb\x62\x78\x02\x32\x42\xdd\xae\x82\x24\xbb\xc6\xae\x21\x85\x02\x23\x62\x7e\x10\xd8\x98\xbb\x26\x43\x77\xf6\x16\xd6\xc9\xfe\x88\x9d\xd2\xd2\x02\x83\x50\x69\xe2\x7d\x63\x5a\x31\x51\xcc\x44\x2e\x4a\x9e\x35\x1f\x44\x55\xba\xcf\x9c\xb8\x2d\xdd\x2a\xc5\x10\x40\xce\x0b\x94\xb6\x20\x3c\x53\x59\x7a\xde\xd8\x28\x34\xb7\xf3\x4a\xbd\xd6\xda\xbe\x94\x06\x74\x17\x72\x86\xa0\xa6\xb9\xb3\xea\x40\xf3\xdf\xd5\x29\xcf\x5d\x57\xf2\x67\x8b\x7f\x31\xcf\xfd\xd6\x87\xac\x75\x12\xc4\x09\xad\xfb\xd2\xbb\xbd\x21\x10\x9f\x06\x8b\x6e\xf0\xc5\xae\x22\x6f\x5b\x62\x6e\xfb\xcc\xd4\x6d\x94\x95\xc5\x6d\x03\x2d\xeb\x73\xd3\x8d\xaf\x4f\x7a\xc1\x92\x39\xd3\xb0\x4f\x3a\x2e\x9a\xd3\x65\xc6\xb8\x7a\x89\x80\xbb\x2f\x50\x61\x2a\xad\x86\xc0\xe0\x54\x19\x1f\xb8\x2c\xbd\xcb\xb7\x71\x00\x11\xad\x24\x1e\x9b\x48\x0d\xc8\x6b\x95\xde\xa9\x4e\xca\x54\xa5\x08\x19\x8a\xa9\x16\x35\x9b\x13\x37\xec\xcd\xe9\x31\x7b\xc2\xf6\x20\x3b\x37\x54\x68\x23\x26\x85\x33\x65\x17\x52\x48\x27\xbe\x89\xa6\xe9\x42\x80\x10\x4a\xa3\x2c\xf2\x54\x97\x5a\x85\x63\x98\x80\x35\x6f\x21\x28\x5c\xf7\x1a\x6f\xbb\x1e\xdb\xe5\xe0\x87\x2c\x97\x1e\x64\xd0\x9b\x16\x32\x28\x56\xac\xfb\xa0\x97\x5c\xf7\xec\xfd\xd1\x25\x54\x33\x51\xad\x87\x45\x75\x71\x02\x0d\x22\x18\xc4\x3b\x4b\x6a\xfc\x3d\xb9\xcb\x97\x41\x7f\x08\xf9\x28\xe0\x03\x94\x5c\xa5\x3a\x5f\x7a\x9a\x9b\x4d\x30\xde\xa2\xd9\xdc\x2e\xbb\xdb\xae\x4e\x25\x9c\xdd\x2a\x20\xc1\xc6\xef\xa1\xf4\xf5\x05\xf8\x0a\xa4\x09\x2b\x01\x9d\x07\x90\x14\xbe\x64\xb6\x76\x46\x46\xe8\x5c\x09\x54\xea\xac\x65\x31\x5d\xe3\xad\x5f\xeb\x8c\x8a\x18\xfc\x6b\xbb\x86\x37\xf6\xad\x6d\xcb\x30\xc1\xa2\x78\x99\x17\x0b\x6f\x0d\xee\x9c\x4d\x7d\xeb\xaa\xd5\x29\xcd\x16\xdf\x1a\x52\x5a\x1b\x6f\x0d\xe7\xee\x26\xbe\x75\x33\x83\xb9\x87\xc3\x84\x1a\x64\x9a\xf2\xa8\x89\x49\x60\x11\xe4\xa4\xce\x90\x04\x27\xd4\xc3\x92\xa3\x5d\xca\xe0\x31\xd1\xe9\x73\x8b\x6e\x9d\xf0\x8c\xb8\xff\xdb\xcd\x33\x5b\x9c\xeb\xc5\x26\xa3\x64\x0c\xee\x7a\x0b\x9f\x45\x29\x85\x1c\x11\x9a\x74\x1d\x90\x59\x08\xbe\x90\x9b\x8e\x7e\xe9\xb3\x21\xdc\xf9\x5b\x67\x38\xc6\xbf\xb6\x9a\xa8\x65\x3d\x12\x3c\x87\x0e\x0a\xcc\x57\x2c\xb8\x9d\x0d\x58\x29\x32\x04\x77\xa5\x7d\x76\x85\xa6\xd4\x6e\x23\x6d\xd2\xaf\x58\xff\x68\x50\x58\x80\x5a\x1a\x5a\x06\x97\x8f\x57\x43\x26\x28\xbf\xa4\x61\x3b\x2f\xfc\x00\xec\x3c\x64\x01\xbd\x83\xef\x13\xe6\x0e\xbd\x58\x57\x52\xa5\x84\x7a\xda\x18\x9a\x90\xa2\x8b\xba\xa1\xf7\x30\xf9\xbd\xce\x4b\x01\xce\xde\x30\x34\x6c\xd8\x7a\x31\x50\x28\xcc\x07\x44\x87\xb7\x28\x99\xde\xa7\xe2\x1f\xb2\xd8\xcc\x1b\x05\x33\xad\xa0\xfe\x41\xe9\x15\xf7\xf9\x77\x69\xc7\x80\xd8\x45\xf4\x2e\x15\xaa\x74\x14\xbf\x87\x01\x6b\x6a\x8a\x75\x2f\x91\x0a\x5f\xe3\x51\x92\x5d\x48\xf4\xce\x0b\xaa\xf7\x00\x66\x87\xf2\x5d\x97\x4e\x27\x4c\xaf\xca\x79\x39\x67\x3f\x9c\x1e\xa3\x06\xde\x30\x04\x94\xf6\x8f\x0e\x2b\x25\x25\xc8\x41\xae\xe6\x1b\xa0\x38\xb7\x83\x7d\x69\x0d\xfa\xd2\x15\x4e\xb7\x93\x99\x88\x65\x58\x1d\xd7\xd4\x05\x15\x73\xcd\x74\x96\x32\x1e\x16\x98\xf2\x85\x5c\xa9\x7f\x0e\x06\xd0\xa3\x92\xce\x91\x33\xbe\x28\x38\x5d\xa9\xba\x52\xc4\xdf\xbf\xb7\xa8\x12\xf8\x3d\xbd\x4f\xf5\xcd\xde\x33\x95\xf1\x4a\x25\xb3\x3f\xca\x92\x59\x31\xfa\x21\xd4\xc1\xd9\x95\x28\x95\xc8\x58\xc1\x4b\x9e\x0b\x1b\x18\x0c\x8d\x68\x83\xe7\xd3\x11\x0e\xa8\x1b\x18\x50\x07\x20\x9f\xf6\x4c\x84\x5d\x21\x80\xba\x00\xab\xac\xa0\x67\x9b\xe0\xe9\xe8\xba\x34\x27\xd6\xce\x96\x8d\x77\x46\xbb\xe8\xc4\x2d\xd8\x44\xb6\x42\x58\xfe\x8d\x78\xb7\x66\xed\x6e\x0f\xd6\xcd\x2f\xd8\x60\x0d\x32\xe0\x33\x19\xee\xeb\x2e\xf3\x2a\xd3\x32\xb4\xd7\xae\x59\x72\x45\x35\x79\x10\x3e\xb3\xaf\xbc\xb5\xdc\x85\x3a\xc0\x07\xe5\xe1\x9a\xe6\x86\x1f\x95\xee\xbd\xad\xe4\xd9\x45\x21\x5a\x32\xf3\x37\x79\xf9\x5f\x5e\x1c\x36\x1b\x85\x43\x09\x92\xad\xdd\x9c\xb8\xef\xa3\x92\x81\x1b\x31\x9e\x69\x7d\xc5\xf6\x56\x94\x3d\x46\x55\x2e\x46\x4e\xcd\x01\x2d\xef\xa1\xeb\xf7\x3e\x93\x0a\xf0\x69\x97\x71\x7d\xfd\x43\x92\xd0\x0b\x98\x2b\xca\x59\xa3\x63\x78\xb9\x9b\x20\xa3\x30\xa3\x66\x1d\x06\xce\xf2\x64\xdc\x3f\xdf\xcb\x5f\x1f\x99\x90\xdb\xca\x5f\x57\x8e\x1a\x3a\x34\xd6\x32\x24\x64\x6e\x3b\xf5\xbd\x87\x71\xf8\xb1\x6e\x2d\x86\x53\x93\x93\x06\xd2\x7b\x6d\x28\x85\x60\xe5\x2e\x30\x4e\xd1\x4f\x77\x63\xad\xbe\x89\x87\xc6\xb3\x62\xc6\x29\x35\x0c\xcb\x81\x7d\x06\xc5\x58\xb0\x99\x56\xba\xa4\x32\x87\xba\x90\x07\xc4\x0c\xd6\xdd\xc0\x0c\x90\xbc\x8d\xba\x7a\x54\x7b\x90\x3c\x09\xca\x24\xe3\x53\x60\xac\x59\xa8\xc6\x01\xe1\xaa\x2b\x8c\x6a\xc6\x37\xfb\x92\x45\xcf\xc6\x00\x60\xd0\x06\xa5\x98\x0f\x66\x52\xd9\x06\x64\x81\x1c\xba\x7e\xbb\x61\x39\xf7\xc9\xcc\xbe\x0b\xe0\xa6\x08\x45\x9b\xc6\xad\x1d\xcc\xdf\x90\xd7\xa2\x31\xc0\x28\x79\xf7\x3c\x14\x8d\xc5\x24\x2b\x3c\x2f\xe0\xf7\x9c\xe5\xf2\x9d\x7b\x4a\xfc\xab\xb8\xda\x40\xa5\x10\x25\x5e\xfd\xf5\xbe\x33\xc6\x6a\xcb\x6d\xe0\x66\x31\xbe\x33\x62\x4a\x50\xf0\xc5\x19\x96\x0b\xe0\x0b\xc4\x91\x16\x22\x3d\xe8\xb2\xbe\xdb\x43\x95\x85\x50\x69\x4f\x5b\x1d\x42\xa6\xd4\x9c\x9b\x68\x7f\x7c\x77\x09\xa1\xba\x5b\xfa\x08\xa3\x2e\x9f\xd1\x9f\xfd\x68\xff\x9c\x32\xcc\x88\xf2\x5a\x26\xe2\x30\x49\x74\xa5\x3a\x65\xa1\x1e\x0b\xf7\x0a\xdc\x8a\xf4\xa2\xd1\x26\x7a\xdc\x53\xf8\x16\x2b\xd1\x79\x26\x39\xc2\x0c\x35\xef\xc4\x22\xbb\xba\x1d\xf0\xd8\x2f\xf4\x90\x96\x8c\xb1\x82\xb7\xcb\x28\xed\x38\x42\x5d\x53\xe5\x97\xdf\x78\xd5\x09\xb7\x30\x82\xe4\xac\x5f\x4a\x83\xbf\x5b\x0d\x82\xe5\xe6\xaa\x06\x5f\x12\x50\x86\x14\x36\x53\xf4\x39\xbd\xe8\x90\xe3\x53\x5b\x01\x32\xb5\x18\x5d\xeb\xe4\x9e\x7b\xf9\x43\xf3\xfc\xbf\x8e\xcf\xba\x65\x8e\x07\xde\x19\xac\x6f\x99\x51\xd3\x41\x55\x8f\xcb\xf2\xe3\xf2\x44\xf7\xe4\x01\x2b\x39\x41\xea\x13\x9d\x5a\x26\x38\xfa\x54\xd8\x5e\x94\xa9\xbf\x3f\x72\x32\xbd\x8e\x96\xa3\xa8\x27\xf6\xb3\x5c\x70\x65\xa2\x12\x54\x01\x4d\xfb\xac\xd8\xd0\x1f\x3c\x08\x69\xb6\xc9\x7b\xb0\xe7\x9d\xae\xcd\x3b\x8c\x2d\xab\xc4\xb2\xca\x1a\xf7\x39\x3e\xdc\x0b\xcc\x3b\x3c\xbe\x14\x53\x69\x6c\x39\xf7\xbc\x6c\x93\xa8\x13\xe4\x15\x0a\xb7\x5c\x89\x39\xfb\xf1\xa7\x93\x7f\xfc\xf3\xc5\xab\xa3\xc3\x17\xff\x7c\x79\x78\xf4\xe3\xe9\xd9\xc9\xdb\xb7\x17\xff\xb8\xb8\x3c\x79\xf9\xf6\xed\x11\x22\x8c\x50\x39\xee\x85\xb0\x6f\xdf\xd2\x4a\x35\x6f\xdf\x5e\x26\x85\x2c\xde\xbe\x3d\xf7\x3e\x10\x64\x5c\xf8\xaf\xe3\x33\x90\x9f\x58\x15\x16\xd2\x9e\xe0\x6c\xc5\x41\x87\x7e\xcf\xb8\xa9\x93\x2c\x1b\xf5\x36\x2d\x50\x3a\xdb\x1e\x77\x2b\x21\x91\x3a\x6d\x76\xd7\x60\x4d\x95\xe4\x5d\xbc\xc1\x4b\xc7\xc6\xc2\xde\x08\x2a\x63\x5c\x09\xc2\xc5\xa3\xc2\xe8\x08\x57\x6b\x15\x1d\x0b\x2a\x67\x9a\x5d\x4b\x71\x83\x98\x13\xc8\x7c\x57\x73\x02\x41\x59\x33\x96\xb6\x2e\x43\x7d\x81\x92\x54\xe8\x34\xf0\x1f\x2d\xf8\xa5\x97\x7c\xd2\x8d\x32\x1a\x04\x73\x13\x29\x3b\x3f\x3d\x66\x4f\x47\xa8\xe4\x9c\x1e\x23\xb6\xe4\x4a\xa4\x29\x6f\xa9\xba\x03\x15\x4f\xdf\x15\x55\x07\xf5\x02\x68\x23\x8c\x5a\xac\x80\x6a\x9c\xea\x9c\xdf\x97\xe9\xec\x23\xf5\x2b\xc8\x43\xf9\x7b\xc5\x33\xd4\x01\xce\x75\xba\x2c\x99\x76\xbe\xf5\x1f\xfd\x7d\xf4\x6d\xe8\xc7\xdf\x47\xdf\x02\xc3\xa5\x1f\xb6\xbf\x8f\xcc\x75\x32\xfa\x96\x0a\xa4\x19\xdd\xb4\x32\x47\x78\xa9\xda\x89\xf4\x59\xfc\x0d\x3c\x9b\x83\xbe\xfb\x59\xca\x5d\x7a\xa4\x0a\xed\x99\x20\x14\xb5\x40\xa8\xbd\x4e\x4a\xc1\x31\xd5\x9c\xa5\x22\x13\x35\x0e\xcc\x06\x30\x54\xde\x4e\xd9\xe9\x63\x6d\x0d\x42\xd3\xd8\x37\x15\xf4\xa5\x3f\x3c\xef\x69\x6c\x30\x7c\x55\xd3\xc8\xb7\xd8\x00\x1d\x91\x1a\xee\x15\x36\xb2\x3a\x13\x38\x3f\x5d\x76\xca\xca\xba\xba\x5d\x13\xb7\xde\x66\x20\xd6\x51\x8d\x7e\xe9\xd1\x49\xdd\x8a\xb8\x0c\xfd\x07\x4b\x03\xf9\xfc\x30\xb8\x8a\xdf\x40\xb5\xdb\x9c\xb9\x53\xcb\xa2\x27\x23\xae\x10\xb5\x25\x30\x0f\x7e\x7b\x25\xe6\x03\x04\xf4\x40\x25\xe4\xef\x11\xcc\x72\x28\x89\x46\xe0\x35\x5d\xb2\x6f\xfd\xbf\xfe\x7e\x5f\x6b\xad\x83\x1f\xb5\x8b\x17\x15\x5f\xaa\x73\xe4\xeb\x04\xab\x60\x9a\x08\x1f\x38\xb2\x54\x20\x63\x35\x0e\xd7\x88\x9d\x40\xdd\x2b\x6a\xa4\x04\x35\x9b\x65\x8d\x9b\x8d\xa7\x8d\x6c\xa0\x43\x80\xff\x25\xaa\x8e\x39\xd3\x17\x54\x99\x09\x30\x3b\x13\x51\xd6\x9f\x80\x80\x39\xd3\x27\xef\x44\x52\xd9\xcf\x59\xad\x8e\xd7\x95\xe8\x4e\xe4\xf5\x93\x08\x10\x44\x38\x36\x4e\x0b\x0f\x95\x09\xf5\xee\x8c\x92\xd3\x3e\x3c\xb6\x57\x62\x6e\x02\xc8\xda\x15\xb6\x4e\x55\xcd\x61\xfd\xfa\x83\xec\xe4\x9d\x34\xd6\xfc\x2f\xcf\x22\x96\x8f\x6b\xfe\x36\x8e\x59\x62\x75\xeb\x11\xc0\x9e\xfb\x13\x1e\xf3\xb9\x07\xdc\xbf\x40\xe7\x51\x7f\xe5\x47\x22\x82\xd0\xe3\xee\x9d\x76\x0d\xa5\x27\x69\x05\x85\x6a\x31\x16\x5b\x9d\x58\x83\x3f\xc6\xf5\x89\x63\x08\xe3\x72\xe2\x94\xbc\xe6\x31\x43\x1f\xd1\x4d\x12\x50\x45\xe4\x35\xcf\x84\x22\x68\xda\x2c\x4d\x78\x89\x21\x7a\x02\x14\x32\x84\x6e\x4d\x48\x1a\xee\x8c\x23\x49\x56\xcf\xb2\xa1\x50\x1e\x2f\xad\x4c\xaa\x8c\x97\xcc\xed\xc7\xa9\x2e\xef\x89\x3b\x84\x57\x37\x36\xbb\xb0\x44\x3b\x90\x3c\x37\xe5\xfb\x62\x8b\x8b\x40\x87\xa4\xbd\x38\x93\x09\xea\x6b\x9a\x1b\x65\xaf\x89\x8e\xad\x27\x5e\x36\x05\x41\x11\x43\xe5\xd9\x86\x73\x5c\x4e\xc1\xff\xbd\x1f\x1d\x1e\x61\x67\x8e\xd8\xf7\xa1\x5a\x7c\xc0\x6a\x9f\x31\xd4\xa4\xd2\x33\x69\xdb\xd0\x74\xd5\x9b\x7a\xa2\x4b\xa0\x26\xdc\x4b\x35\xfc\x46\x5c\xcb\xc4\xee\x8f\xd8\xff\xeb\x34\x45\x70\x22\x7b\x75\x92\xb6\x59\xa8\xc3\xad\x01\xfb\x9e\xb0\x3d\xf8\x59\xac\x4a\xee\xfb\x40\x11\x21\x81\x3e\xb0\x6c\x98\x0e\x11\xee\x15\xd1\xed\x86\x18\x45\x4d\x71\x61\x69\x84\x93\x5f\x07\x09\x19\x64\xa2\x34\xb4\x4b\x1b\x9e\xdb\x10\x67\xf1\x22\x34\x2c\x9c\xff\x01\x1f\x3d\x2b\xc5\x14\xf6\x1f\xee\x9e\xcf\xb8\xfb\xac\x2e\x74\xa6\xa7\xf3\x8b\xa2\x14\x3c\x3d\xd2\xca\xd8\x12\x44\x43\x17\x7c\xb7\xdb\xda\x8c\xd8\xb0\x66\xfa\x86\x71\x2a\x67\xd7\x13\x44\xc8\xd3\xd5\x74\x86\xf8\xff\xf0\x43\xcf\x1c\xeb\xbb\x48\x46\xa7\x19\xb1\x8b\x80\xef\x0f\x0b\x3c\xd0\x05\x40\x2b\xe0\xf0\xb8\xe1\x73\xda\x4c\x7c\x2c\x53\x61\xa2\x1c\x65\xdf\x19\x0c\xfd\xdc\xfa\xfe\x20\x95\x0f\xcf\x8e\xef\x4b\xaa\xb0\x46\x85\xf6\x96\x57\x09\x9a\x11\x8e\x7a\x3d\xbe\x41\x23\x85\x71\xe3\xb9\x26\x4d\x15\xb1\x5c\xfd\xc8\x7c\x46\xdd\xb4\x0b\xf8\x52\xce\xdf\x5d\x5c\x89\x9b\x16\xbf\xf4\x2f\xfa\x93\xb8\x7f\x2a\xd8\x10\xec\xd1\x37\xca\x70\x2b\xcd\x04\xd8\x57\x3e\xa3\x3e\x0e\x45\x07\xed\x48\x22\xf0\x6a\xd6\xee\xc4\xad\xf9\xa2\xf0\x80\xb7\xd8\x58\x2c\x94\xff\x57\xdb\x41\x78\x00\x62\x11\x44\xe0\x97\x70\x3b\x28\x21\xce\x25\xab\xeb\x38\x34\x46\x2a\xaa\x7c\x2c\xca\xb0\xf7\xd1\x19\x20\xcb\x05\x68\xda\x85\xbd\xdf\x5e\x30\xb6\xce\x84\xeb\x9a\x56\x06\xc3\x73\xf2\xce\x69\x1e\xa6\x5d\xa2\x12\x5e\x4d\xca\xb4\x85\x46\x31\x3c\xe6\x13\x38\x17\xa6\xa1\x41\x5d\x02\x66\x6f\xfc\x49\x5b\x39\x57\x5f\xdd\x48\x17\x59\x37\xe2\x45\xb6\x22\x51\xfa\xd6\xd7\x5f\xe0\x3f\x89\x0b\xfe\xc8\x29\x64\x06\xa8\xc0\xa3\x03\x9b\xab\xfa\x60\x27\x2e\xfc\x2c\x68\x73\xce\x28\x72\x37\xe1\xef\xba\xb2\x1b\x75\x20\x6e\x64\x3d\x90\x37\x32\x90\x65\x57\x2d\x24\x60\xfc\x7b\x3f\x58\xad\x1b\xe9\x4e\xe3\xc8\xda\x1b\xd4\xf5\xd5\x58\x50\x57\xb5\x69\x8d\x2b\xab\x61\x5a\xd7\xc2\xae\x36\xac\x3b\x3d\xbb\x07\x6e\x33\xd6\xd1\xc6\xad\xaf\xc6\x40\xe8\x7b\x58\xbb\x1c\x02\x4c\x7a\xe2\x77\xc7\x4a\x9b\xf7\x54\x0d\xd8\x99\xb6\xee\x3f\x91\xf9\x7b\xac\x85\x39\xd3\x16\x3e\xd9\x88\xa1\xc4\x57\xe8\x71\x20\x3d\x8d\x00\xe0\xbd\x81\xdc\xa4\x10\xad\x3b\xf1\xfc\x80\xad\x30\x2c\x4e\x15\xd3\xa5\x1f\xb1\x60\x5d\x18\x6a\x22\x0e\x2b\x10\xc6\xd6\xad\xc6\x89\x6b\x27\x1e\xe7\x0f\x34\x47\x4d\x41\xf6\x17\x7e\x03\xe0\xa9\x45\x06\x05\x02\x69\x55\x22\x86\xad\xd3\x35\xad\x98\xca\x84\xe5\xa2\x9c\x02\x17\x74\x32\xeb\x63\xfa\xba\x9c\x2b\x78\x75\x3c\x5d\xe2\xce\x74\x58\x4b\x70\x64\x83\x8a\xd5\xa3\x0a\x80\xed\xe1\xb1\x96\x73\xb0\xa4\xfe\x4f\xf0\x41\xff\x5f\x56\x70\x59\x02\xe6\x2d\xc5\x8e\xe3\xef\x28\xfa\x12\x37\xe3\x5a\x58\xf2\x2d\x71\xc5\x04\x56\x32\xb9\xd6\x17\x15\x8f\x01\xbb\x99\x69\x83\x87\x61\x70\x7f\xec\x5c\x89\xf9\xce\x60\x69\xe9\xed\x9c\xaa\x9d\x3a\x30\xdc\x58\x6c\xe1\x10\x86\x0c\xc2\x1d\xf8\x6e\xe7\xd3\xe9\x2a\x9d\x0e\xdb\x3e\x18\x03\x16\x3b\xd4\x72\x5d\xd5\x93\xf7\x93\x98\x77\xf7\x98\xbd\x6c\x34\xe7\x95\x25\x4b\x3a\x7a\x7d\xfa\x19\xcc\xf9\xcf\xc0\x53\x3f\x23\xb3\x5b\x5f\x0b\xcf\x0b\x87\xe6\xa5\x93\x0b\x21\x63\x86\x67\x09\x72\x7e\xe0\xa4\x42\x23\x6e\x32\xbd\x89\x91\x69\x7d\x55\x15\x7e\x51\x04\x6e\x5f\xa9\x12\x9d\x93\xd1\x41\xcc\x72\x6e\x5d\xd1\x8a\x1b\x52\x1c\x0f\x57\x6f\x58\x1b\x84\xb4\xdf\xb0\x66\x9a\x1d\x0e\x6e\x07\xe1\x84\x5f\xb0\x80\xef\xf8\x0a\x21\xe5\x25\xee\xdd\x88\xc1\x98\x81\x5e\x90\x6a\xb5\x6b\xb1\x6d\xbf\xcd\x56\xbc\x48\x68\x99\xbc\x85\x6e\x9f\xaa\x2a\xcb\x02\x7e\x28\xea\xf3\xe8\x0c\x84\x7d\x41\x5e\xf4\xa9\xdb\x29\xb6\xf9\x82\x0f\x8a\x2c\xbd\xa3\x2c\x6d\x30\x42\xb8\x31\x6a\x4b\x80\x87\x17\x39\x0e\x3a\xef\x9e\xdd\x97\xd8\x50\xe4\xe4\xc2\xc0\xfa\xb4\x14\x58\xd1\x0c\x2b\x0b\x56\x1a\x51\x24\x55\x4a\x5c\x0b\x37\xb3\xa9\x34\x04\xaa\xe9\xf3\x74\xfe\xb5\xe4\x57\xf8\xff\x1f\xeb\x33\x6d\xbd\xeb\xeb\x5f\xde\x77\x8c\x42\xfc\x9d\xcc\xab\x1c\xc1\xe7\xac\x5b\xa2\xa9\x9c\x78\x34\x6d\x9f\x1e\xd4\x34\xba\x9b\xbe\x1f\x5a\xa5\x96\x97\x53\x48\x13\x26\xa3\xdb\xcb\xea\x69\xa6\xc7\x3c\x63\xb9\x54\xee\x31\x94\x01\xd0\xf8\x2c\xf4\x84\xfe\xfc\xc0\x83\xe0\x40\x91\x53\x39\xce\x04\x59\xf5\x0b\x40\xf5\xd1\x8f\x17\x6e\x04\x99\x94\x09\x63\x30\x68\xff\x52\xaa\x63\xef\x12\x7c\xee\x76\xcd\x3b\x9e\x17\x99\xc0\x3a\x57\xf6\xd5\xf0\xdf\x5a\x09\x46\x59\x2e\x03\xe6\xa7\xa7\x66\xf4\x7b\x8a\xa7\x51\xcd\xce\x11\x52\x98\x9a\xc2\xc3\xbb\x23\x0d\xfb\xf2\xe0\xcb\x83\xa7\xcf\x9c\x22\x86\xb1\x2e\x6e\x08\xc7\x6b\x79\x34\x9e\x8e\xd8\x7b\xe6\x7a\xf0\x94\xfe\xfb\x25\xfd\xf7\x2b\xf6\x9e\xbd\x67\xec\x9c\x9d\xb3\xf8\xbf\xee\x3f\xec\x3d\x1b\xba\x41\x88\xba\xfa\x74\xd0\x94\x1d\x89\xb3\x49\x7d\xd5\x7a\x60\xd4\xb4\x9a\x9a\x86\x92\xc1\x44\xe7\x02\xba\xfa\xe5\xff\xf2\xf7\x40\xbe\x85\x45\xd2\x53\xe8\xd4\x1e\x74\x69\x9f\xdd\x80\x67\x3a\xe7\x57\xe8\x95\x39\x4c\x6c\xc5\x33\xf7\xf0\xbd\xaf\x86\x4f\xf7\x99\x56\xcd\xdb\xaf\xa5\x76\x32\xd0\xf7\x70\xef\xe9\xfe\x68\xa9\xcb\x5f\xae\xe8\xf2\x02\xff\x27\xd5\x0c\xbb\x46\x6f\x5f\xef\x7e\xa9\x1f\xaa\xf9\x0d\x9f\x87\x05\xef\x8f\x8c\xa9\xbc\x0e\x94\x19\x11\x92\x0f\x84\xec\x61\xfd\x4a\x0f\xce\x86\x8d\xce\x99\xb4\x23\x76\x6a\x77\x77\x3d\xdb\xac\x33\x98\x3d\xb7\xc7\x71\x0c\x3a\x0b\x03\x0f\x6b\xe3\xc9\x42\x4a\x7f\x0b\x88\xc3\x5e\x63\x23\xf7\x22\xe7\xc0\x2b\x0f\xbb\xa4\xb3\x88\xdb\xa9\x77\x5c\x03\x12\x62\x79\xd7\x2f\x6e\xdc\x90\x7d\xf8\xc1\xdd\xbd\x00\x1d\xef\xc5\xd0\x15\x69\x23\xf5\xce\xaf\xdf\x69\x00\x89\x70\xde\xf5\xcd\xd0\xf7\x8d\xf1\x2e\xc3\xde\xee\x34\xf7\xe5\xdb\x1d\x88\x80\x05\x25\x94\xc8\xb0\xe8\x64\x27\x08\x51\xbf\x8c\x23\x98\xbb\x43\x95\xd6\x79\x47\x2d\xfb\x0f\x3c\x10\x60\x78\x4d\x21\x18\x57\x2e\xbf\x49\x94\x9b\xd4\x48\x65\x75\xbb\xb0\xde\xc7\x23\x76\x88\x0b\xd8\x40\x04\xf1\x2e\xfd\xba\x75\xec\x6a\xa2\xe4\x1b\xd0\x59\x42\x24\x25\xd7\x88\x33\xa8\xfc\xf1\x48\x0e\x5f\x4d\xda\x57\x98\xd6\xd3\xc9\x8a\x64\xb2\x3a\xca\x82\x08\xae\x6e\x91\x40\xf1\x51\xbc\x7e\x22\x6a\x8c\xa7\x2b\xe0\x4c\x69\xbb\x98\xe6\x70\x3d\xa1\x85\x54\x3f\x53\x5b\x7c\xee\x2f\x8b\xf2\x23\x58\xb0\x8d\x73\x13\xc8\x64\xdb\x1c\x16\x5f\x0e\x16\x7a\x4f\x9f\x7f\xdd\xe6\x0c\xf9\xf2\xd9\xfd\x0e\x07\xfa\xef\x65\x63\x9a\x57\xce\xee\xd7\x7b\x75\x2f\xf7\x21\x0b\x60\xc5\x26\x80\x8a\xa1\x3a\x22\x3c\x0a\x07\x9a\x91\xb6\xe2\x58\x64\xa4\xc4\x0d\x65\x7e\xde\xfe\x52\x51\xa1\xa8\x17\xee\x03\x77\xfe\xf0\xca\x08\xa8\xfc\xaa\x00\x14\xc0\x0d\xa4\x57\x76\xbf\xda\xfb\x8a\x0d\xd9\x93\x7d\xb7\x1a\x14\x2e\x2b\x18\xcc\xf8\x28\x73\x47\x03\x25\x32\xdb\x99\x53\x9e\xdc\xc8\x98\x41\xe0\xa3\x5b\x38\x84\x60\x4a\x2f\x29\xaf\x99\x3b\x7d\x87\x7b\x6a\x46\x95\x7a\x41\x8f\xea\x49\x3d\x36\xa7\xea\x5c\xa7\xcd\x88\x59\x28\x23\x9b\x42\xd4\x1d\xea\x79\x88\x26\x8a\xed\xf9\x7f\xd4\x50\xef\xfb\xad\x50\x45\xd6\x7b\x16\x28\x9d\x8a\xc3\x09\x70\x08\xcc\xdb\xa2\x37\x2f\x9e\x09\x67\x4b\x6d\x46\x67\xc3\x4c\xdf\xb0\x1b\xca\x4f\x46\x42\x4d\x2c\xb3\x8b\x3b\x72\x10\x53\x9d\xa3\x3c\x0b\x22\x99\x54\x88\x20\x4a\x69\x1b\x19\x98\xf6\x57\x31\x34\xcd\x90\xfd\xa8\x95\x2e\x9f\xa1\x76\xe4\x9a\x34\xb5\x28\xbe\xfd\x71\x28\x6a\x92\xac\x4a\x23\x76\xc4\xfa\x40\x30\x4e\xbd\x39\x05\x03\xed\xd9\xc7\x5a\x09\x66\x1c\xa4\x4a\xa7\x41\x8e\x7d\xa8\x71\xcf\x38\xbd\x32\x27\x37\xa0\x5f\x2f\x39\x65\xdc\xb7\xf0\xba\xc4\x4f\x32\x8a\xd6\x7f\x5c\x99\xe9\x57\x74\xb4\x7a\xdd\x4f\xdd\x94\x9d\xba\x7e\x99\x40\x60\xf7\xa1\xfd\x00\x35\x98\xed\x17\x7b\x4b\x43\xcf\x0d\xe1\x25\x84\xe2\xfb\x5c\xa9\x71\x8b\x1f\x5c\xa7\x88\x43\x85\xa9\x00\x9d\xd7\x24\x2e\x87\x50\xb2\x0a\xad\x0e\x18\xcf\x34\x38\x18\x9c\x80\x75\x1f\x89\x94\x6e\x9c\x04\x8a\xfd\x25\xdf\xc1\x0c\xaa\x74\xeb\x64\x94\x41\x63\x91\x2d\xae\x56\xff\x02\x77\x58\x9f\x9d\xd6\x22\x3e\xf3\x11\x2f\xc6\x28\x47\xa0\x87\xc4\xb4\xd0\x96\x37\x9b\xaf\x04\x9c\x78\x30\x65\xe8\x1d\x1a\xc1\xb8\x90\x01\x43\x45\x17\xe8\x80\xa3\x03\x59\x9a\x10\x81\x94\x50\xc3\x9e\x44\xf4\xc5\x25\xea\x60\x32\x15\x25\x1e\xa9\x63\xd1\x28\xd1\x09\xb9\x1d\xec\x97\xfa\x4e\x2c\xcd\x81\x1c\x66\x6c\xe8\xef\x58\x12\xbe\x33\xae\x92\x2b\x61\xbd\xef\xb6\x84\xaa\x82\xa2\xb2\x6c\xcc\x33\xae\x12\xb7\x6a\x17\x63\xf9\x56\x63\x63\xf8\x4b\x78\x0a\xe2\xdc\x84\xd2\x11\x6c\x3a\xca\x3c\x94\xca\x58\xd7\x1a\xa6\x24\xd6\x1d\x3c\xcc\x8c\x1e\xb8\xbd\xe9\x1b\x58\x76\x1f\x40\x53\xf4\x6f\x74\x47\x93\xf8\x17\xc2\x52\x6d\x5a\xe4\x43\xa6\x71\x5e\x38\xb2\xb0\x04\xbb\x29\x1f\x46\x4c\x8c\xa6\xa0\xe2\x2e\x4c\xd9\x4e\xb3\x40\xd2\xd7\xdc\xec\x0c\xf0\xad\xdd\xcc\x51\xc1\x2a\xf9\x37\x88\x4a\x23\x7a\x2b\x95\x42\x1d\xf7\x62\xc3\xe1\x8e\xe6\x13\x9c\x02\xe4\x5b\x07\x45\xf5\xc3\xad\x9f\xda\x55\x36\xee\xe7\xde\x33\x4b\x16\x7d\x77\x17\xdb\xb2\x92\xdf\x14\xe1\x90\x65\xc2\x33\x5f\xfd\x01\x54\x7f\x01\xe7\x5c\xed\xee\xd6\xbe\x00\xd8\x0a\x28\x59\x6a\x6b\xc5\x89\xcf\x86\xb5\xc0\xf6\xbc\xb2\xc7\xac\xc8\x32\xdc\xac\xb5\xd1\xe4\x94\x5f\xab\x6b\xab\x49\x42\x0b\x4d\xbf\xc5\xca\x1f\xc6\x3f\xf2\x35\x30\xe0\x1a\x9b\x07\x84\xc2\x01\x1b\x57\x96\x4d\xe5\xb5\x93\xfc\x77\x72\x73\xa0\x2b\x67\x26\xb2\x82\x95\x22\xad\x12\xc2\x2d\x80\x63\xe9\x30\xb6\xc9\x90\x59\xda\x4b\x87\x9d\xc6\x80\xee\x20\xd5\x99\x6a\x9e\x3a\x72\x02\x1b\x04\x54\x2b\x39\x61\xe2\x5a\x94\x73\x56\x68\x63\x60\x1b\x82\xd8\xc2\xe2\x3d\x88\x13\x05\x30\x65\xb0\x1f\xa0\x57\x5e\x65\xdf\x21\x9d\x7d\x07\x6c\x5a\xdd\x10\x45\x9f\xc7\x85\xf7\xd5\xc1\xd3\x83\xa7\x1f\x36\xbf\xce\xe1\x7f\xb5\x4f\xce\xff\xf7\x74\xb2\xc2\xca\xac\xfb\xd2\x58\x39\xf7\x71\xdb\x7d\x09\xde\xb5\xaf\xf6\x23\xef\xdd\x57\x07\x5f\x1e\x3c\xdd\x73\x7d\xfd\x72\xdf\xf5\x3a\xf2\xcb\x7d\x19\xf9\xe5\xc2\x2f\xa9\x47\xc2\x34\x3c\x73\xa7\x8a\x2a\x35\x81\xe6\x94\x6c\x73\xaa\xfa\x73\x3d\x32\xd6\x87\x20\x72\x2f\xcb\x71\xd9\x35\xfd\x02\xbb\x16\x1d\x84\xd2\xb2\xbf\xe4\xba\x14\x7f\x89\xee\xbf\xd5\xa3\xd6\xde\x51\xd6\x42\xdc\x2c\x87\x04\x72\x5e\x0c\xaf\x5a\x04\xc5\xba\xa4\x03\x76\x4d\x06\xbc\x2d\xb0\x91\xf3\xe2\x1e\xed\x20\x9f\x4c\x27\xae\xd5\x17\x94\x48\x46\x4d\x51\xa2\x14\xba\x71\x73\x4a\xe8\x1b\xcf\xe3\xfa\xdf\xb1\x70\xba\x2c\x7a\xbd\x6a\x90\xc0\x7b\xd2\x1b\x1a\xab\x4b\x3e\x15\x07\xf4\xd8\x87\x42\x6b\xfa\x33\x12\xf8\x34\xb2\x62\x10\x7e\x89\xa8\x7d\x7c\x09\xb6\xcf\x97\x04\x29\xc0\x13\xa8\x5e\x84\x81\x6c\xe0\x67\x46\x75\x91\x0f\x24\xf5\xb6\x05\xd8\x5f\x97\x44\x2f\x7e\x63\x4e\x32\x6e\xac\x4c\xbe\xcf\x74\x72\x75\x61\x9d\xb9\xd3\x59\xb5\x58\xd5\x6a\x63\x4e\x15\x3b\xfc\xe5\x82\x1d\x4b\x73\x55\xb3\x44\x22\x13\x4b\xb3\x60\x90\x07\x24\x62\xc2\x8e\x60\x39\x4f\x66\xa8\xba\x92\xd7\xd9\xb3\x51\xf5\xb7\x57\xfe\xc4\x6f\x8c\xc0\xee\x8f\x5d\xf7\xdd\xd7\xa2\xbd\x08\x5e\x1b\x6e\x24\xbe\xce\xe9\xf1\x1a\x12\x75\x27\xa6\x2d\x7d\x2e\x5b\xc1\x69\xe6\xc1\xf1\x11\x03\x21\x13\xc4\x6b\x0f\x88\xcc\x4d\x9e\x32\x58\x43\x73\x5d\xb1\x1b\x8e\x06\x35\x48\xd8\x11\xbb\x94\xc5\x33\x76\x12\x31\xfe\xac\x6a\xca\x69\x1f\x01\x7d\x95\x0c\x6a\x58\x73\x98\x78\xe3\x04\x32\xd5\xf4\xb0\x13\x54\xad\xcc\x33\xb6\x23\xde\xd9\xbf\xee\x0c\xd8\xce\xbb\x89\x71\xff\x51\x76\x02\x0c\x61\xc4\x3c\xea\x74\x3c\x35\x11\x65\x6d\x3a\xe2\x0f\x96\x81\x8f\xfa\x5f\xb2\xec\xf2\xd5\xf1\xab\x67\xa0\xcb\xa7\xda\x59\x7d\xc4\xcd\xef\x61\xbc\x48\x36\x46\xc3\x00\xb9\x22\x89\xce\x8b\x52\xe7\x32\x2a\xb6\x85\x2d\xd7\x66\x07\xb0\x3e\xb2\xbd\xc0\xb0\x85\xc5\xd0\xcb\x7a\x0a\xcd\xf9\x25\x15\x7d\xa0\xee\xb2\x98\x4e\x27\x4c\x63\x6a\x40\xb3\xdc\x5f\x9a\x70\x93\x5b\x3e\xd4\x0a\x32\xce\xd7\x0b\xc6\x69\xe6\xf4\xd5\x41\x2a\xae\x0f\x4c\xca\x9f\x0e\xe0\x31\xb8\x1a\xe6\x0b\x7d\xe2\x86\xed\x3c\xdd\x19\xb1\x0b\x99\xcb\x8c\x97\x19\x51\xe1\x52\x13\xf5\x7d\xce\x50\xf0\x0d\x82\xf9\xfb\x64\x87\xed\x61\xbd\x3d\xa8\x1b\x99\xf0\xe8\x6b\x01\x6d\x14\x32\x63\xf6\x5b\x69\x97\xac\x07\xf7\x3b\xeb\xec\x82\x67\xc4\x8a\xff\x4a\x65\xad\xb3\x94\x9b\x8b\xc3\xb7\xe6\x8b\xd5\xca\x8a\x1c\x99\x13\x5d\x92\x11\x18\x6e\xf1\xa0\x3e\x52\x91\xda\xf2\xd2\x4d\xfd\xfd\x99\xa8\x3f\xd5\xf1\xc3\x7a\x00\x9a\x63\xe1\x14\xe9\x67\x7c\x7d\x6b\x90\x7c\xa0\xe4\xef\x95\x60\xa7\xc7\x5e\x88\x17\xa2\x34\xd2\x58\x27\xa2\xd2\x86\x6a\x20\x51\x5f\xd8\x3b\xcc\xf9\xbf\xb5\x62\x27\xdf\x5f\x50\xb7\xf6\x37\x70\xb0\x5b\x4a\x3a\xfe\xef\xaa\x14\x4e\x23\xea\xac\x7e\x85\x96\x16\x55\x2e\xf7\x39\x3b\xe6\x96\xa3\xe6\x85\x92\x4a\xd7\x40\x58\xa0\x54\x8d\xa1\x40\xc9\xa3\x9c\xb5\x54\x9e\xd9\xfa\xb5\x1f\xb7\x82\xce\xda\x23\x67\xbb\x9f\xbf\x79\x7d\xba\x06\xdd\x29\x81\xe3\x76\xfa\x52\xa7\x3d\x29\x50\x51\x83\xfe\xc8\x03\x60\xd2\x23\xfc\x9c\xe5\xee\x49\xec\x4c\x2b\x31\x60\xaf\x05\x4f\x99\x93\x6e\xf4\xcf\x5f\x4a\x69\xef\x8b\xf5\x54\x5f\x9d\x8f\x7e\x3f\x89\xbd\x0c\x84\x6f\xcc\x0f\xc2\x59\x84\xef\x07\x60\x94\x20\x74\x48\x07\x18\x67\x7a\xcc\x48\x58\xac\xf3\xed\xdf\xbc\x3e\xed\xed\xe5\xdf\xbc\x3e\xf5\xef\xee\xfe\xa9\x27\x9b\xf9\xda\x3d\x1a\x0f\xb5\xed\xf0\x7c\x41\xd9\xaf\xd5\xb9\x9a\x16\x67\xd1\x20\xb8\xbb\x35\x30\xea\xcb\x0e\x58\xd7\x98\x5f\x49\xd5\xba\xde\xad\x29\x6d\x80\x12\x27\xc0\x3f\x45\x41\x34\x40\x9d\x4b\x9f\xb1\xbc\xca\x2c\x20\xfc\xc0\x5a\x73\x8b\x0f\xf2\xc3\xfc\xaa\x63\x84\x76\xc9\xd8\xb1\xc0\x70\x44\xfa\xcc\xd7\x5c\x84\x5f\xac\xfe\xc1\x4b\xae\xf8\xd4\xdd\x0e\x27\x20\xcb\xf1\xcf\x68\x91\xef\xa1\xd3\x5d\x85\xaf\xf8\x35\x97\x19\x1f\xcb\x4c\x5a\xd0\xe7\xf6\x47\x5e\x9b\xc7\xbc\x7c\xe8\xf2\xda\xa4\x5f\xaf\xaa\x6d\x50\x5b\x63\x2c\x14\x80\xf2\x63\x7b\xee\xbb\x83\x1b\x27\xea\xf7\x47\x20\xf7\xe1\x46\x40\x5e\x5f\x50\x7e\x5f\x7f\x4c\xf9\x5d\x8b\x9e\x0a\xf3\xfd\xbc\x25\x5f\xd7\xb2\xee\xe4\x5a\x5a\xa9\x3b\xc1\x17\x04\xb0\xf9\xc8\xd5\x27\xe4\x4c\xef\xa0\x40\xc1\xde\x69\xf9\xfb\xae\x2a\xd4\xa7\xd9\x38\xe9\xe3\xdb\x38\x0c\x99\x0d\x69\xa6\x7b\x19\xae\xba\x39\xaf\x6b\x04\x20\x65\xfc\x6a\xa1\x54\x1c\x77\xd6\x05\xc9\x72\x0f\xb0\x0c\xbf\x77\xfb\xa9\x0d\x90\x04\x5e\x9d\xc5\x6f\x58\xc1\xfd\x8c\x8b\x6f\xcd\x0f\x0b\x1e\x52\xf0\x31\x6b\xbd\xcf\x3a\xbe\x66\x22\x8a\xd9\xa4\x7b\x2e\xbb\x6b\xe6\xf9\x45\x33\x6a\x73\x24\x8a\x19\x7b\x7e\xb1\x42\x4c\x62\x1d\x81\x7b\x6f\x83\xb1\x9c\x5d\xc3\x32\x39\x11\x56\xb6\x1a\x84\x35\x0b\xca\x5c\x2b\x69\x75\x69\xd6\x20\xe6\xfc\xa3\xfb\x51\xdc\x7c\x6b\x6e\x7d\xbe\xf6\x83\xc2\x5e\x46\x9f\x72\x96\xe8\x2c\x13\x89\xcf\xee\x87\x29\x0e\x3f\x5b\xe1\x88\xa1\x0c\x04\x33\xba\xfa\x06\x5c\x31\xe4\x74\x39\xc0\x65\x77\xf0\xfa\xe4\xf0\xf8\xe5\xc9\x28\x4f\xff\x34\xd3\x37\x43\xab\x87\x95\x11\x43\x69\xbb\xe9\x5b\x6b\xc4\xce\xe8\xc1\xd3\x6d\x67\x7d\x39\xb9\xed\xcc\x4d\x59\x0d\xe0\xfc\xc6\xd4\x10\xeb\x3e\xee\x5c\x6a\x6d\x97\x41\xd6\x27\x55\x96\xe1\xdc\xda\x52\x88\x41\xec\xdf\xbe\x27\x04\x7d\x7d\x6d\x96\x2e\x5c\xbb\x79\x1b\x43\xf4\x69\x35\xe3\x4d\xd9\x20\xdd\x75\x85\xb6\x9a\x36\x5b\x9a\x87\xba\xbd\xe6\x4c\x5c\x34\x3e\xc7\x80\x88\x9d\xb9\x79\xb9\x12\x73\x06\x30\x09\x13\x5d\x02\x65\x49\x73\x7d\x0a\x9b\xc0\xe0\x1d\x54\x46\x94\x23\x52\x38\x36\x64\xe0\xbb\xa8\x22\xf0\x22\xaf\xc5\xa4\xcf\x61\x7f\x2d\x26\xab\x46\x9d\x3e\x06\x5c\xd7\x90\x1e\xe7\xf4\x95\xca\xce\x30\x37\x16\xf1\xa4\x71\x6c\x57\x4e\x03\xe1\x5c\x6c\xc8\xb8\x77\x42\x28\xe8\x03\x45\xa7\x0b\x1b\x22\x5b\x9a\xbc\xd8\x6d\x49\x93\x64\xef\x1d\x06\xd1\xd7\xce\x8a\x15\x37\x07\x37\xba\xbc\x92\x6a\x3a\xbc\x91\x76\x36\xc4\x91\x32\x07\x80\x6e\x7f\xf0\x27\xf8\x0f\x45\x91\x0f\xd3\x94\xf2\xdf\x2a\x23\x26\x55\x86\x99\x69\x66\xc4\x78\x21\x7f\x16\xa5\x81\x2c\xcb\x2b\xa9\xd2\x01\xab\x64\xfa\x5d\xdb\x19\x63\x7d\xec\x96\xf6\xec\xf4\x8b\x63\x5d\x11\x41\xbd\x8e\x8f\xd1\xd2\xcb\xa4\x92\xa7\xda\x20\xc7\x91\x1b\xaa\xc6\x16\xe0\x69\x2e\xd5\xa6\xec\x80\xb6\xd6\x81\x54\x69\xbb\x91\x5c\x08\x40\x40\x3b\x4d\xf3\x80\x3e\xa3\x30\x76\xc8\xf9\xe1\xde\x7b\x82\x24\xe6\x94\xfd\xd3\xcc\xfd\xb9\x93\x60\xc9\xe7\xe6\xf7\x6c\x88\x4f\x19\x16\x69\x3d\xae\xdb\x44\x9e\xfb\x5c\x9f\x2f\x91\xa7\x5f\x87\xfc\x67\x48\xcf\xf9\xa4\x2b\x8e\x6d\xb0\xce\xfc\x69\xfd\x60\x6b\x1c\xea\xee\x9a\xf1\xa7\xd1\xd0\xea\xd3\x07\xf8\xf7\x8c\x07\x85\x03\x05\x0c\xa5\x92\xf7\xa7\x41\x8e\x7c\x4d\xf8\xe4\xf1\x1d\x12\xad\x14\x71\x01\xbc\x2a\x84\xba\xb0\x3c\xb9\xea\x18\xd5\xdd\x6a\x55\x7f\x30\xad\xea\x13\x25\x02\xf9\x25\x8a\x85\x77\x94\xfe\x56\x27\x7b\xe3\x26\x7f\x80\x02\x18\x89\xed\x5e\xf2\xa2\xbb\x77\xd5\xb7\xb4\xa0\x41\x85\x8f\xc9\xa1\x0a\xc5\x41\x85\x2e\x00\x59\x8b\x6a\x4f\x61\x1c\x3f\xbf\xc6\xd3\x75\x7f\xd3\x11\xd3\x5f\x0e\x4c\xd4\x60\x53\xa2\xe6\xee\x93\xb1\xb4\xb5\xac\x34\xc2\x22\xf8\x13\xc1\x01\x6b\xc5\x12\x02\x78\x00\x7d\x24\x82\x2d\x88\x74\x15\xc5\x74\x62\x7d\xd5\x68\xc0\x89\x7a\xf2\xe4\xc9\x13\xc4\xbe\xf9\x8f\xff\xf8\x0f\xa6\x4b\xe0\xdd\x4c\x64\xbe\x7c\x23\xdc\xf5\xf5\xd3\xa7\x23\xf6\x8f\xc3\x97\x2f\xa0\xa2\xa1\xb0\x06\xd9\xd8\xb0\x65\x77\x43\xe3\xc7\x66\xc0\xfe\xf7\xc5\xab\xb3\x1a\x95\xa1\xf9\x2d\x98\xe6\xe1\xf5\x9a\x1c\x18\x4f\xfe\xf6\xd7\xbf\x8e\xd8\xb1\x2c\xa1\xa2\x4b\x8a\xc0\xaf\x1e\x5c\x2d\xbc\x14\x88\xd5\x03\xa8\x29\x5e\xe3\x92\x81\xca\x90\x0a\x93\x73\x39\x9d\x59\xaa\x88\x75\x0b\x32\x93\x89\xc5\xe2\x31\x14\x6b\x9e\xbe\x1d\xe9\x33\x88\x90\x86\xb4\x3f\xe8\xdc\x80\x65\xf2\x4a\xb0\x89\xf9\xa1\xd4\x55\x51\x43\x1a\x12\xe9\x30\x15\xca\x60\x63\xf5\x5c\x19\x61\x1f\x78\xda\x6a\x27\x57\x73\x63\x6d\x43\x4b\x0b\x0a\x2b\x95\xb7\xd6\xb8\x7e\x05\x97\xa1\x18\x06\x32\x00\x1b\x7c\x97\xc1\xd7\x93\xb2\xa3\x20\x55\x3c\xca\x48\x51\xea\xff\xc1\x25\x00\xb5\xc8\x91\x78\x86\x5a\x61\x98\x49\xaa\x14\x8e\xa2\x5b\xbe\x9e\x9a\x08\xd6\xfd\xc7\xc4\xda\xb2\x4c\x7d\x95\x49\xe3\x1e\x01\xf0\x3e\x1f\x78\x72\xcd\xdb\xeb\x56\xa9\xc1\xf5\x52\xa9\xa5\x5f\x13\x94\x0a\x89\x4b\x22\xbc\x24\xf4\xe1\xba\x0d\xc4\x05\x20\xe4\x1b\xba\xd7\x8f\x52\x18\x88\x46\xbe\xb5\x11\xb6\xa2\xa1\x81\x2c\x7a\xf7\x6c\x20\x63\x84\x37\xcc\x79\x79\xe5\x0c\x57\x92\x2e\x23\x76\xee\x3a\x19\xc0\x73\x10\xd8\xf7\x1a\x03\x9b\x39\x9f\xc3\x63\x49\x71\x83\x87\xec\x8e\x46\xbb\xb8\xfd\x74\xc9\x8c\xe5\x25\xed\x25\xf7\xf9\xe3\x40\x14\x7f\xc9\x0b\x83\x08\xb7\x4e\x53\x05\xf4\x67\x0d\xb5\xeb\x76\xe6\x45\x10\xa7\xb1\xde\xa2\x80\xb3\x21\x0c\x4c\xeb\x06\x36\x1c\x01\x9c\x66\x9f\x76\xf9\x46\xc0\x53\xe7\x1d\x14\x0e\xbc\x16\x63\xaa\xe9\x42\x64\xe3\x4e\xfa\x06\x31\x20\x65\xe2\x41\x29\x18\xab\x19\x4f\x49\x70\xc6\x0a\x58\x4c\x85\xf9\x70\xf5\x08\xbc\xfa\xd0\x26\xf0\xea\xae\x53\xe0\xd5\x25\x88\x8c\x57\x63\x0d\xfb\x48\x32\x0e\x26\x1d\x60\x78\x46\x4d\xea\x29\x00\x5e\xba\x22\xda\xd6\x48\xe2\xea\xc9\x88\x15\xe3\x63\xa3\xb3\xca\xe2\x4f\xeb\x2f\xe3\xd3\x0f\x1a\xf5\xf8\xd8\x70\xe4\x85\xdb\xa2\xb3\x10\xb4\x00\x3c\x3e\xba\x1c\x8b\x78\x75\x16\x1b\x5d\x9c\x10\x7f\x20\x07\x44\xe7\x71\x0e\x06\x5b\x1f\x63\xed\x1b\x0b\x15\x77\x37\x33\x41\x29\x10\x91\xde\xe7\xa4\xa9\x93\x11\xa0\x54\x7a\x15\x0e\x81\x73\xd2\xb5\xb8\x19\x13\x23\xbb\xfb\x12\x8c\x64\x7b\x47\xa1\x3c\xde\xa7\xdd\x9d\x2a\x2b\xca\x09\x4f\xc4\x7e\xec\x63\x10\xc5\x4c\xe4\xa2\x74\x03\x45\xf7\xf9\x1a\xed\x19\x57\x29\xc1\x4e\x25\xa2\x84\x1d\x2c\xde\x59\x51\xba\x41\x3d\xba\x38\x65\x69\x29\xaf\x45\x69\xd8\xde\xf7\x00\x20\x88\x70\x53\xfb\x0f\x30\x0d\x16\x5f\x64\x1d\x1e\x10\x78\x70\x3f\xa5\x1f\xd0\x94\x97\xe1\x2a\x92\x33\xf5\x54\x79\x6c\x2c\x37\xad\x26\xf6\x1d\x8d\xdc\x86\x80\x23\x14\xa4\x2f\xb0\x37\x63\x6c\xd3\x23\xb7\x03\xc9\x54\x62\xb1\x61\x6e\x58\x29\xa6\xce\x1a\x2b\x23\x98\x3e\x84\x49\x59\x5b\x71\x43\xff\x05\x25\x75\xb0\xea\x43\xb5\x1f\x13\xb2\x2b\xf5\xb5\x4c\xbd\x3a\x84\x68\xf4\x01\x13\xae\xe0\x26\x02\x2f\xe0\xc6\xe8\x44\x82\xab\x29\x9a\x1a\xb4\x52\x41\x69\x6a\xd2\x7e\xf9\x70\x73\x1c\x26\xd3\x40\x9e\xd3\x8a\x73\x94\xf5\x72\x20\xea\x54\x9c\x57\xe3\x4c\x9a\xd9\x45\xaf\x21\x91\x55\x0d\x63\x52\xe2\x52\xa6\xca\xad\x91\x11\x23\x94\x91\x44\x11\x8f\xea\x96\x74\xda\xb6\x86\x69\xf0\xbf\x8e\x37\x85\x86\x6a\x78\x20\x9e\xf7\x5f\x9d\xd5\xfd\x20\xb0\x12\x64\x3c\x4e\xc5\x1b\x55\x34\x3e\x4f\x78\x96\x19\xd2\x6f\x03\x9f\x87\x3f\x7b\x50\x43\xf5\x00\x26\xb8\x2a\xa4\x5b\x30\xbe\xf7\x90\x82\x83\xc2\x2b\x90\xcf\xac\x7c\x31\x13\x01\x0c\x6b\xe5\x6f\x02\xe2\x66\xff\x83\x30\x42\x58\x89\x83\x8b\x6e\x8d\xb4\x1f\xdb\xf0\xcf\xc3\x0b\xff\x7c\x9a\x9a\x8a\x9a\x4e\x93\xc3\x87\x43\xa8\xd0\xc2\xd0\x46\x45\x14\xb1\xfe\xa0\xf1\x07\xd2\x47\xd2\x34\xd7\x16\x02\xc6\xfe\x1d\x5a\x62\x9f\xe8\xc7\xbb\xbb\xd8\x28\xa8\x62\xce\x14\x07\x09\x35\xa4\xf1\x4b\xa2\x2d\x45\x36\x72\xd8\xe7\xcb\x72\xad\x3e\xd3\xe1\x38\xc7\x0f\x77\x0d\x4b\x75\x52\x39\xe3\xab\x1e\xf6\x3a\xe1\xa2\x1b\x33\xdf\xe3\xa2\x0a\x4a\xf5\x8d\xba\xe1\x65\x7a\x78\xde\xaa\x36\xb7\xa9\x9c\xd5\x6d\xc5\xaa\xb7\xff\x98\xb9\xcf\xf9\x18\x90\x6e\x09\xdb\x70\x1b\xed\x5b\xd9\x44\x2c\xcd\x57\xb9\xdb\xac\x76\x42\xf6\x8e\xd1\xbc\xfb\x3a\xec\xb6\x01\xc2\x6d\x80\xb0\x71\x6d\x52\x80\xf0\x14\x03\x84\x31\xab\x6d\x43\xbc\x90\x87\xd6\x8d\xf8\xa3\x88\x31\x1d\xd7\x22\x15\x35\xf1\xc5\x7a\xde\x05\xe5\x1f\x37\x6f\xbd\xea\x22\x83\xc1\xcb\x5c\xd0\xcb\x1e\x43\x3c\x6a\x03\xe2\x49\x30\x96\x1d\xac\x42\xbc\x9a\x02\xbf\xae\x57\x43\x94\x5a\x0c\x4c\x47\x11\xee\x42\xa7\xc4\x66\x00\x34\x1b\x48\x19\x30\x08\x34\x78\xca\x97\x9b\x82\x76\x5e\xf0\x44\x80\x7c\x0b\xea\x4f\x2f\x41\x82\x8e\x0b\x80\xf5\xb4\x08\x18\x2c\x04\x18\x9d\xf3\x2e\xab\x81\xf5\xb6\x22\xdc\x55\x5b\x3c\x5d\x5b\x5a\x44\x14\xc5\x56\xfd\x42\x30\xc9\x4c\xe4\x1c\xfe\xf9\xdc\x0f\x81\x93\x8d\xce\x78\xb0\x02\x21\xe0\x44\x99\x1b\xa6\x27\x83\x46\xa6\xeb\xce\xf5\xd3\x9d\x6e\xc1\x06\xd6\x5f\x9c\x92\xf9\x7d\x74\xde\x39\xd8\xc3\x16\x07\xec\xbc\x11\xdb\x71\x7b\xa8\x26\x7c\xf4\xb8\xf7\x21\x83\x02\xce\x0f\x1c\xe1\x8d\x19\x9c\xbe\x83\xb8\x6d\x83\xb7\x83\x10\x35\x78\x00\xca\xdf\x36\x78\xfb\x18\x83\xb7\xd1\xc1\xe8\x05\xdd\x8a\x40\x6e\x1c\x12\xf0\xd1\xdc\xb1\xf0\x46\x0d\xd9\x30\x3e\x94\xeb\xe3\xb8\xba\x6c\xa6\x2e\xed\x8e\x46\xbb\xbb\x3e\xba\x4b\xeb\xbe\xb2\x93\xe1\x37\x4c\xa8\x44\xa7\x9e\xad\x76\x22\x4b\x63\x41\xdd\xab\xdd\x6d\x71\x5f\x72\xff\xac\x38\xfd\x09\xda\xee\x63\xaa\x3b\xcb\x16\x0f\x49\xf8\xfc\x13\x28\x31\xb5\xea\x12\x80\x0f\x69\x88\x02\x9e\x35\xe9\x30\xfe\x7b\xc3\x32\x99\x4b\xe2\x7a\x77\x1b\x5d\x18\x6b\xd8\x1e\x7e\x38\x4a\x8a\x6a\x40\x37\x8c\x72\x91\xeb\x72\x3e\x08\x37\xb9\x2f\x1b\xbf\xa2\x3b\xf6\x91\xef\xa4\x2a\x4b\xa1\x6c\x36\x7f\xcc\x1a\x90\x1f\xc4\x0d\x51\x80\xc2\x1c\x77\x41\x1c\xa9\xaf\xe6\xd2\xaa\x23\xbe\xe0\x36\x8f\xf8\x05\x02\x1a\xad\x19\xd4\x71\x71\xf7\xa9\x50\xd7\xec\x9a\x97\xf7\x44\x8e\x5f\x75\xf5\xa8\xf3\xa4\xf2\x5a\x1a\xdd\x3a\x2c\x1a\x35\x14\x0f\xcf\x45\x70\x42\xbb\xcd\xa6\x2b\x5b\x54\x96\x24\xba\xdf\x81\x1e\x65\x3c\xec\xbc\x05\xe5\xf0\x69\x1b\x16\xa5\xe6\x55\x70\x6b\x45\xa9\x9e\xb1\xff\xde\x7b\xfb\xc5\xfb\xe1\xfe\x77\x7b\x7b\xbf\x3e\x19\xfe\xe7\x6f\x5f\xec\xbd\x1d\xc1\x3f\xfe\xb2\xff\xdd\xfe\x7b\xff\xc7\x17\xfb\xfb\x7b\x7b\xbf\xfe\xf4\xf2\x87\xcb\xf3\x93\xdf\xe4\xfe\xfb\x5f\x55\x95\x5f\xe1\x5f\xef\xf7\x7e\x15\x27\xbf\xdd\xb1\x91\xfd\xfd\xef\xfe\xdc\xb9\xeb\x5c\xcd\x5f\x75\x14\x85\x78\x0d\x7b\x3c\x92\x9b\x2d\xf6\xb2\xfc\x16\x68\x25\xa4\xb2\x43\x5d\x0e\xb1\xe9\x67\x00\x16\xdc\xf1\x01\x7e\x79\xf5\xbd\xff\x6b\x35\xa0\x86\xdb\xf7\x4a\xfd\x9a\x37\x38\x84\x3e\x8f\x65\x0f\x65\xc6\xbe\xa5\x66\x99\x8c\x15\x79\xa1\x4b\x5e\xce\x59\x4a\xde\xcc\xf9\x0a\x04\xa2\x08\x82\xa8\x33\xa4\x30\xf4\x23\x95\xe5\x1a\x2a\x8d\x3b\x23\x0a\x89\x54\x56\x79\x4f\x78\x42\xd0\x56\x3c\x19\x37\x80\xbc\x4f\xa8\xfd\x3e\xa5\x88\x6e\xa3\x80\xc6\x98\x27\x57\x68\x41\x85\xd9\x42\xbd\x31\x2a\xad\xdf\xd9\xa1\x94\x08\xa4\xf3\x27\xc7\x3e\xe4\xb6\xe8\x54\xb8\xa9\xf4\x37\x63\xdb\x0d\x27\x3c\x46\xda\x29\x81\xb0\x66\xa4\xd2\x25\x7b\x09\x0a\xd0\x5a\x67\x9f\xf5\x82\x15\x22\xff\x2d\x5e\x38\xad\xaf\xa7\x4a\x54\xdf\x9c\x4f\x20\xb2\x1a\xec\x4d\xc2\xf5\x9a\x00\xc9\x56\x9d\x21\xd6\xd0\x2c\x60\x22\x4f\xfc\xb6\xf4\xf1\x5b\x37\x9d\xae\x55\xd4\x4d\xc1\x31\x9d\x19\xcc\x5b\x91\x09\xf0\x40\x81\x6d\x0a\xd3\x11\xa6\xf0\x32\xa2\xe6\xaf\x8c\x7b\x92\x56\xcd\x7b\xea\x07\x21\x4d\xd6\x18\xd7\x84\xe7\xd3\x6e\x5a\xd4\xee\x9b\x8b\xf0\x66\xb5\x3f\x03\x4a\x96\xbd\xf9\x69\x2a\x30\x52\xe8\x29\xa4\x6a\xeb\x09\x64\x56\x44\x7c\x3d\x9e\x92\x66\x69\xa1\x2a\x99\x35\x57\xaa\x67\x9e\x08\x2f\x5e\x29\x4a\x28\x5c\x5a\x76\xab\x57\x5d\x65\x44\x39\x9c\x56\x32\xed\x6f\xbd\x3d\x38\xb5\xa3\xa3\xb2\xd1\x97\x8a\xd1\x8b\x62\xd1\xbb\x3a\x11\x52\x36\xbb\x33\xbc\xd6\xd9\x9f\x8d\xf3\x34\x26\xc7\x68\x66\x82\xf2\xc0\x87\xe6\x85\x81\x4f\x37\xb8\x0c\xae\x24\x3a\x67\x93\x79\x42\xd0\x4e\xb2\x41\xdd\x83\xcd\xe2\x9e\x80\xa2\xaa\x61\x20\xaa\xae\x1d\x12\x6c\x2c\x26\x98\xf1\x84\xbf\x01\x4f\x01\x95\x82\xa5\x22\x13\x56\x44\x0c\xf3\x05\x72\x62\x97\x22\xd7\xd7\x44\xcc\xfa\xc6\x50\xbc\x5c\x4e\x9e\x31\xbe\xdf\x28\x38\x36\x44\x79\x2c\x44\x8a\xf5\x61\x11\xa9\x60\x59\x29\x33\x60\xe3\x7d\x9f\xcf\x4a\xf4\x97\x25\x38\xd5\x88\xdd\x0b\xfc\x58\xa5\x70\x03\x00\x20\x55\xa5\xce\x99\x51\xbc\x30\x33\x6d\xc1\x65\xc2\x0b\x9e\x48\x3b\x67\xb6\xe4\xc9\x95\xbb\x05\xe2\xa8\xf0\xb8\x01\x4b\xf6\x29\xbd\x3d\x1e\xbe\x66\xc9\x9a\x9d\x95\xba\x9a\xce\xa0\x86\x0a\xef\x4a\x32\x6e\xfc\xdb\xaf\xfc\x3d\xd9\xf0\x86\xa5\x73\xc5\x73\x99\x04\xee\x90\x52\x5f\x4b\x23\x35\x45\xba\x7c\xbb\xe7\x81\x85\x01\xa3\x67\x47\x19\x97\x39\xdb\x33\x42\xb0\x13\xbf\x24\xf0\x9b\x0b\xd4\x24\xd1\x93\x58\x36\x93\xea\x08\xf0\x91\x80\x07\xdc\x27\xb5\xe8\x0d\xa9\x0a\xa8\x0c\xb8\x9e\xaf\x7c\xe8\x7e\x98\xae\xd5\x7d\xd2\x25\x24\xbc\x79\x0a\x20\xa1\x52\x1d\x65\xc4\x1c\x9e\x9f\x9a\xd8\xbe\x25\x1a\x45\x6c\x09\xbe\xc8\xb4\x9a\xc6\xc0\x77\xf5\xca\x74\x42\x5e\x01\x1f\xe6\xb5\x4c\x2b\x9e\xa1\x78\xa7\xce\x1c\x5d\x9c\xe2\xcf\xe5\x74\x66\x87\x37\x02\xbc\x9f\x78\x0a\xd6\x7b\xc6\x3f\x54\x2e\x65\xda\x4a\x03\xc7\x81\x25\x2f\x1b\x7a\x92\x81\x73\x92\xcf\x01\x78\x97\x92\x3b\x1b\xc9\x38\x1e\xa6\x1e\x9b\x58\x35\xe2\xd0\xbd\xc3\x40\x90\xe8\x54\x22\x70\x0f\xbb\x21\x86\x95\xba\xdc\x37\x60\x7b\xac\x39\x37\xc2\xc7\xb6\x66\x7e\x04\x85\xb8\x3d\x43\xf0\xda\x14\xd9\xeb\x7a\x99\x5c\x8a\xbc\xc8\xb8\xed\x27\xb5\x64\xe7\x97\xc8\xfd\x1d\x05\x8f\xdd\x76\xe4\x2a\x1d\xf2\xcc\xad\xc8\xf3\x9f\x8f\xa8\xb2\x0d\x37\x58\x23\x7d\xed\xb2\xe6\x28\xf5\xbc\xd4\x4e\x4b\x5a\xb9\xb5\x00\x4b\x6d\x2c\x52\x10\x46\xf4\x64\xf0\x51\xdc\x28\xe4\x08\x76\x7f\x9c\xff\x7c\x34\x60\x72\x24\x46\xfe\xaf\x70\xab\x97\x86\x56\x4f\xb1\xc0\x21\x54\xd0\xc0\x7a\x86\xae\xc4\xce\xdf\xf8\xb7\xff\xfa\xd6\x75\xd2\x7d\xfb\xf7\xe1\xb7\x11\x97\xd1\xdf\xff\xe5\x84\x6b\xe9\x6e\x68\x7e\x1a\xe7\x97\x83\xdc\x73\x7f\xfd\xeb\x5c\xa7\x17\x85\x48\x46\xf8\x5a\xe6\x5f\x98\x25\xc0\x84\xb2\x4e\xd7\x3e\xd7\x90\x59\x26\x53\x5c\xe5\xf0\xec\x52\xfc\x8f\x0f\x10\x10\x5d\x2a\x09\x92\x84\x5b\xa1\xe0\x00\xf0\x85\xc6\x4a\x5b\xfc\x39\x12\xad\x42\xff\xf7\x26\x31\xf5\xa9\xd5\x1a\xb6\x39\x8a\x92\x43\xc5\xc4\x3b\x69\x00\x77\x06\xdf\x15\x86\x83\x53\xf2\xba\x3f\xd3\x5c\xb3\x6e\x84\x03\xcc\x10\x70\xaf\xba\xbe\xfd\x45\x69\xfb\x97\x30\xfd\x3e\x31\x11\x19\xcc\x19\xbf\xd6\x32\x65\x15\xf0\x66\xb9\x1d\xa8\xc0\xb3\x5d\x53\x17\x8e\xe7\x2c\x97\xc6\xf2\x2b\x31\x62\x17\xee\xcc\x8a\x33\x0c\x70\xf4\x14\x03\x16\x1a\x91\xb2\x4a\x59\x99\xc1\xb7\x75\x3b\xae\xcb\xf1\x59\x76\x3a\x61\xa6\x4a\x80\x9c\xb7\x14\x43\x7f\x3a\xd2\x5d\x4b\x32\xa6\x7e\x97\x41\x98\xec\x19\x47\xfb\xa9\x48\xe1\xa7\x48\xf5\xab\x68\x79\x2d\xe5\x55\xbb\x7e\x6a\x95\xd4\x27\x22\x0c\x26\xd0\x6b\xbb\x43\x30\xf3\x09\x40\x68\xca\x51\xc0\x40\x89\x44\x18\xc3\xcb\x39\xb2\xa1\xca\x40\xda\x48\x29\xaf\x70\x52\xe7\x5c\x55\xd0\x40\x29\x90\x5b\xb7\x4a\x60\x74\x38\x1b\x97\xfa\x4a\xa8\x50\x42\xe0\x66\xb1\x99\x50\x5d\x67\x8d\x22\xed\x34\x4b\x66\x5c\x4d\x45\x5d\x45\x9e\xf3\x14\xc6\xfe\xa7\xa0\x69\xf9\xf7\x71\x23\xc0\x27\x4e\x61\x91\x16\x86\x62\xec\xce\xa7\x10\xf6\x78\xab\x02\x0e\xee\xa0\x8e\x4b\xb8\x57\x92\x59\x2b\x99\xc8\xfa\x71\x84\x77\x77\x81\x0f\x41\xa1\x58\x63\xf2\x76\x2e\x2c\x4f\xb9\xe5\xbd\x25\x70\xbf\xe4\x81\xf5\x93\x92\x3a\x60\x39\x44\xc9\x1e\x74\xc6\x7a\x55\x52\x17\x32\xc6\x15\x00\x69\x30\xf3\xb3\x0f\xb8\x54\xd6\xad\x6b\x0a\x3a\x62\x5e\x36\xe8\x6a\x3c\xcb\xf4\x0d\x21\xd5\xf9\xd6\x50\x64\x89\x94\xa5\x15\xa8\x7d\xb5\x48\xeb\x12\x14\xef\x25\x66\xe2\x26\xba\xb7\x51\xbe\xac\x63\xff\x49\x33\x37\x7b\xa5\x82\x86\x67\x9d\x50\x56\x22\x87\xbe\x07\x82\xa0\xc1\xaf\x14\x6e\xd5\x85\x69\x80\x79\x9a\x0a\x6b\xea\xac\x4a\x3c\x4d\x9c\x88\xa4\xb3\x9c\x9c\x08\x70\xd4\xd0\xd4\x90\x1d\xbe\x5a\x53\xc4\x89\x33\x9a\x4e\x0b\x77\x7e\xad\x7d\x66\xfa\x0b\x1e\x21\xfd\xed\x4b\x9d\x76\x8f\x42\x2d\xf0\xb8\xd6\x0d\xd7\xd5\x26\x58\x79\x64\xc0\xc9\x83\x37\x40\x4c\xde\x34\x60\x32\xf0\x08\x98\xf1\xeb\xf6\xee\xd4\x5a\x33\x1d\x06\xb2\x36\x78\xdc\x10\x1e\x37\x7c\xda\xd5\x71\xdd\x3d\x6b\xd1\x5f\x1d\xb3\x17\x9b\x1d\xea\x21\x52\xe1\x44\xeb\x45\x2f\x81\x84\x05\x14\xa5\xd0\x2e\x9d\xbf\x94\x99\x11\xb2\x61\xa8\x9e\x56\x48\x27\x35\x9f\xb1\xbf\x34\x34\x2e\xd2\x6c\x83\x35\x8c\x55\x4c\x7b\xde\x3c\x1e\xd1\xc4\x7b\x38\xaf\xe6\xed\xfb\x0b\x8d\x81\xaa\xb7\xda\x6a\xf4\xd5\x52\x41\xfd\x76\xaa\x32\xf0\xf0\x87\x1a\x55\xb7\x98\x4b\x9d\x65\x9e\xbb\x1d\x2d\xe4\x85\xdc\x26\xe0\x0d\xc2\x68\xc9\x20\xb8\x21\x82\xbe\xaf\xc4\x4d\x50\xec\xb8\x41\xb8\x52\x1f\xab\x07\x57\x89\x4f\x38\x5b\xd5\x5e\xa8\xe8\x3a\x54\x73\xec\xfa\x71\x34\xb4\xe8\x5e\x60\x53\xf7\x20\x67\x01\x28\x3e\xce\x30\x23\x27\x28\x3e\xd0\x17\x9e\xdd\xf0\xb9\x81\x5d\x56\x5b\x6c\xe1\xf9\x84\xf5\x5e\x37\xfc\x5a\x4c\x3a\xf0\xc9\xc7\x57\x6f\xd1\xfc\xfe\xe2\xf9\x00\xb6\x22\x55\xfb\x24\xdd\xba\x99\x16\x14\xdc\x8b\x57\x7f\x69\x01\x90\x19\x09\x69\x51\x7d\xc4\x57\x1b\xdb\xf9\xf0\xfc\x14\x1a\xf6\x96\xdb\x14\xfe\xf0\x27\x7a\x08\x14\x8e\x85\xdb\x6f\x35\x44\x14\xac\xdd\xf8\xb7\x2b\xf2\xc6\xea\x45\xff\x13\xf0\x21\x51\xfc\xc5\xd7\x03\xbb\x03\xe1\xf0\xfc\x14\x9f\x38\x02\x4a\x5c\xae\xe6\xa4\x6b\xd9\x99\x2c\xd3\x61\xc1\x4b\x3b\x47\xe7\xc5\xa0\xf1\xb4\x50\x14\xd9\xc3\x70\xf4\x1a\x1a\xee\x42\xa1\x16\x5f\x8d\x39\x82\xe1\xf3\x81\x17\x8a\x9c\xdd\x3a\x33\x9b\x36\x22\x5d\x4b\x34\xfd\xd5\x18\x91\x98\x42\xc7\xfb\x2e\x1e\xc4\x88\xa4\xb1\x20\xfe\x54\xe7\xb2\x93\xf1\xa6\x99\xce\x82\xc7\x2c\xe8\xd0\xe4\x6f\xd2\x71\xdd\x58\xd0\xd9\xc0\xf8\x77\x2d\x0d\x98\x9c\xb8\x03\x4e\xab\x21\x55\xab\x07\xe7\x38\xe9\x7d\x3e\xef\x13\x0d\x79\xb7\x75\xd1\xfd\x19\x3f\x2b\x6e\x20\xec\x75\xb6\xa7\xb4\xc2\xfd\x8f\xf7\xee\x63\xda\xeb\x2d\xfe\x5d\xb8\x65\xc4\x7e\x99\x09\x15\x1f\x7e\xb1\x43\x7c\x10\x0e\x61\xa9\x52\x37\xf9\x70\x32\x82\x3f\xc0\x54\x49\x22\x44\xf0\x20\xc5\x74\xf1\xb5\x7c\xa2\x2e\xe7\xdc\x26\x33\x61\x98\xd1\x00\x3b\x6a\x2c\xcf\xb2\xda\x73\x43\xc3\xa5\x41\x8f\xf0\x5e\xf4\x48\xbd\x68\x14\x79\x93\x13\xab\xc8\x38\x79\x4a\x26\x95\x4a\x30\xb1\x4a\xda\xb9\xef\xc1\xf1\xa2\x2a\x05\xe6\xaa\x41\x87\x8e\x9c\xa0\xef\x36\x32\x3b\xc3\x60\x82\x80\x9d\xa3\x48\x6d\x9e\xfc\x84\xad\xe7\xa4\xe9\x98\x27\x57\x37\xbc\x4c\x0d\xd4\xaf\x73\x2b\x91\xe2\x70\xd0\x68\x76\x2f\xea\x83\x7b\x7a\x43\x53\xd8\x0f\xc6\xad\x11\x81\xca\xae\x7e\x0c\xe3\x95\xd5\x39\xb7\x32\x01\xb7\x8d\x9c\x44\x9e\xf8\x3c\x50\x40\x84\x48\x2a\x4a\x76\x38\x2b\xe8\x35\xc0\x82\x2b\xb1\xcc\xc2\xde\x68\x26\x73\xa7\x81\x71\xa0\x7e\x9e\x84\x6a\x75\x1f\x33\xf8\x50\x4f\x9d\x9a\xf9\x0b\x04\x6a\xa2\xbb\xd0\x21\xe4\x4c\x75\x03\xcd\x87\xa8\x40\x70\x87\x53\x59\xf6\x60\x41\x41\xa2\xdf\xb8\x35\xed\xfa\x1a\x2d\xd5\x81\x9b\x9e\x1b\xe1\xf4\x2e\xf3\xc1\x05\x6b\x46\xab\x7a\x24\xa7\x0a\x0b\x77\xa5\xf1\x2e\x04\xca\xc4\xde\x4b\x4b\x5d\x14\xe4\x0c\xcc\xf7\x17\x7b\x04\xb1\xb7\xf2\x5a\x18\x88\x3b\xfb\xdc\x6e\x37\x0c\x53\xa1\x44\xc9\x2d\x78\xf2\x09\x8e\x10\x76\xee\xe2\x23\x1a\x1b\x66\x84\xa0\x2c\xfb\xec\x0d\x11\xfc\x87\x85\x1b\x32\xc5\xef\xa4\x98\xa2\x67\x91\x74\xd3\xad\x46\xf9\xc1\x66\xb6\x1a\xe5\x56\xa3\x6c\x71\x6d\x35\xca\xc5\x6b\xab\x51\xc6\x57\x48\x46\xee\x57\x9b\xac\xab\x0b\xa2\xc4\x8f\x38\x95\xaa\xbe\xe1\x36\x97\xdf\xe9\x84\xbd\x16\x89\xbe\x16\x25\x1e\x22\x27\xef\x0a\xae\x9c\xae\xf4\x9c\xcb\xcc\x1d\x21\xfe\x28\xa9\xdd\x1b\xc0\xa3\xd3\x74\xb1\x47\x1e\xa5\x30\x1f\xb4\x59\x73\xea\x14\x21\x5d\xb8\xfb\x29\x90\x5f\x94\xe2\x5a\xea\xca\xf8\x84\xaf\xca\xa2\xb0\x30\x96\xf4\x99\x99\x9c\x06\xba\xbb\x90\x8e\x51\x8a\x44\x97\x69\x0d\x59\x65\x2c\xb7\x95\x69\xd6\x90\x26\xe8\xd3\xee\xcf\x9d\x19\xc6\x71\x83\x4e\xcf\x3e\xcf\x19\xcc\x98\xeb\x7d\xbf\xee\xbe\xc0\x4c\x3c\xfc\x70\x4c\xcb\xd0\x27\x07\xd6\x89\x89\x4e\xf5\xad\xac\x88\x96\x2b\x2d\xac\x7b\xcf\x61\x03\x8f\xe6\x00\xc9\xc3\x87\xa1\xd9\x61\x9d\x0b\xd8\x9a\x1f\x31\xbe\x7a\x9c\x4d\xd6\x3b\x70\x4a\x7c\x3d\xb8\xd4\xc1\xe6\xd5\x5b\xd5\x02\xfb\x24\x95\x0b\xac\xff\xea\x05\xf6\xe9\x2b\x18\x58\xa8\x28\xeb\x7f\xdf\xbf\xf6\x15\x6e\x0b\x3b\x9f\x8e\xa5\x0f\xed\xfc\x06\x94\x5a\x68\x47\x1a\xa6\x73\x69\xad\xf0\x09\x24\x61\x27\x83\xc3\x3f\xae\xf0\x21\x99\x03\xbe\x04\xcc\x12\x11\xef\x02\x87\x54\xa4\xab\x82\xc6\x79\x23\x0d\x18\x48\x5c\x39\xbb\x16\x11\x6d\x41\x76\x0c\x29\xdd\xd7\xdb\xea\x5b\x39\xd4\xbd\xdd\xad\x1c\x8a\xaf\xad\x1c\x62\xc0\xc6\x95\x41\xf1\x48\xaf\x8a\xb1\x6f\x94\xa0\x74\xf8\x58\x64\xec\xf7\x4a\x94\x73\xe6\x14\xdd\x3a\xcd\x14\xe8\xb6\x8c\x4c\x29\x51\x93\x1c\x93\x5d\xad\xcb\x0d\xd5\xf1\xc0\x71\x7a\xf2\xce\xd9\x09\x80\x80\xd0\xbb\xd4\x5f\x7c\x40\x13\xc8\x08\x67\x21\xcc\x4c\x6c\x1d\x60\x8e\x48\xc3\x5e\x70\xa6\xc2\xe1\xd9\x71\x9f\xa6\x7e\x1f\xe9\x03\xac\xbf\x14\x02\xb6\xe4\x92\xf9\xc0\x10\xe1\x50\x86\x6f\xe0\x60\x0b\x69\x1e\xc1\xd1\xc8\xae\xc4\x7c\x40\xd9\x54\xc4\xb5\xe8\x6f\xc6\xc4\xc4\x26\xe1\x4b\x37\xa0\xc0\xe6\xd5\xf3\x09\xd4\xa7\x6f\x10\xaf\xae\x04\x1f\xcd\xb6\xfc\xe0\xf6\x73\x28\xf6\x7c\xc8\xf6\x40\x04\x12\x5f\xb7\x91\x82\xe0\x6a\x05\x0e\x01\x5f\x2d\x15\x16\x28\x54\x88\x81\x84\xed\x67\x79\xb1\xbe\xdd\x53\x78\xf9\x69\xfc\x44\x83\x15\xb6\x60\xa3\x2c\xe7\x4a\xcc\x77\x0d\x61\x69\x68\x65\x66\xb2\xf0\x2c\x91\x20\x27\x69\x57\xb2\x9f\x21\xff\xcd\x37\x81\x12\xf1\x54\x0d\xd8\x99\xb6\xee\x3f\x27\x90\xd0\x8b\x31\x16\x2d\xcc\x99\xb6\xf0\xc9\x46\x0f\x37\xbe\xda\x27\x1a\x6c\x0a\xd1\x48\x08\xb1\x60\xea\x3a\xd4\xae\xfa\x34\x4f\x18\x54\xca\xe5\x09\x13\x23\x0d\x3b\x55\x4c\x97\x7e\x54\xad\x27\xbe\x32\xd4\x84\xf7\x5e\x47\xd1\xb0\x15\x6d\xd0\x64\xe8\xb2\x31\x17\x1f\x68\x2e\x04\xd6\xa4\xff\x06\xbc\xdb\x10\x89\x0c\xb9\xa9\x40\xbe\xc4\xad\x98\xca\x84\xe5\xa2\x9c\x02\xee\x4a\x32\xeb\x7b\x8a\xfb\x3a\x17\xf1\xea\xf1\x74\xc4\xab\xd7\x75\x08\x2a\xca\x0b\xc8\x3a\xfe\x34\xea\x0f\xb6\x8d\xc7\x75\xce\x0b\xb7\x04\xff\x8f\x3b\x95\x61\x15\xfc\x5f\x20\x77\x33\x23\x76\xc8\x8c\x54\xd3\x4c\x34\xbe\x23\x7f\x66\xdc\x8c\x6b\xc1\xd9\xaf\xbf\x57\xf2\x9a\x67\x02\xab\x04\xb8\x0a\xd4\x2b\x7a\xb2\xa4\x74\x0d\x88\xe1\xcd\xc9\xe5\x10\x83\xdf\xb9\x12\xf3\x9d\xc1\xd2\xb2\xdd\x39\x55\x3b\x35\x84\x53\x63\xa1\x06\xe5\x02\xc2\xb3\x3b\xf0\xdd\xce\xe7\xd1\xd3\x1e\x80\x19\xdb\xdb\x9a\x24\x97\xf3\x51\xc6\x8d\xe9\x03\x4d\x66\xa1\x20\x7c\xa1\xf5\x55\xc4\x12\x17\xd1\x3d\x75\x49\x38\x55\xa0\xf4\xee\x47\x87\x0a\xc8\xbe\xf2\x81\x7b\x18\xff\x6b\xe2\xb3\xee\x0a\x43\xb7\x12\x0a\x1c\x40\xd8\x7c\x85\x6c\x03\x51\xa1\x4e\xd3\xb9\x65\xc4\x7f\x86\x88\x88\x9e\xb0\xe7\x35\x61\x84\x34\xe0\xa2\x92\xbe\x66\x56\x69\xcb\xa4\x4a\xb2\x8a\x82\x21\xf0\x53\x70\x70\xf5\x63\xc0\xf6\x36\xbc\xbd\x2f\xec\xba\x59\xbf\xa2\x7d\x4a\xd1\x52\x21\xd4\x62\xf6\x07\xe4\xdb\x84\x6c\x0a\x1c\xed\x75\x8e\xd6\xa4\x55\xc9\x47\x93\xe8\x24\x69\xea\x97\xcf\xe5\xb8\x14\xec\x68\xc6\x95\x12\x59\x84\x22\x43\xce\x50\x6e\x2d\x4f\x66\x18\xb3\xe3\xcc\xed\xe3\x4c\xd8\x5d\x83\x04\xfd\x39\x4f\x66\x52\x05\x5c\x05\x15\xd0\x94\xea\xba\xb2\x35\x50\x03\x75\x35\x90\x7a\x64\x95\xd9\x25\x5a\x19\x5a\x77\x31\x9f\x4b\x93\x6d\xa6\x06\x28\x5f\xbc\xa7\x46\xea\xa7\x3d\x0f\x23\x8f\xe7\x32\x50\x9f\xc0\xbd\x1f\xe6\xab\xc9\x83\x43\x5b\xaa\x89\x28\x4b\x9c\xa1\xb1\xa0\x1f\x2c\x70\xcc\x8e\x88\xc4\x62\xa6\x6f\x58\xaa\xd9\x0d\xb0\xad\x5e\x3b\x05\x02\x52\x91\x8c\x57\x3d\xa2\x9e\x42\x62\x60\xa2\xf3\xa2\xd4\xb9\x34\xbe\xfc\x91\x96\xc7\xda\x00\x53\xb2\xaa\x35\xe6\x6c\x73\x16\xb3\x4a\x35\xc9\x1e\x9f\x1f\x31\xcb\xcb\xa9\xb0\xee\x19\x4c\x55\xf9\x58\x74\xc4\x85\x59\x37\x2a\x79\xaf\x2c\x20\xbb\x81\x06\xa4\x31\x6a\x1f\xe1\xf7\x60\xaf\xfd\xaf\x20\x81\x10\xd2\x14\x27\xba\xa4\x64\xcb\xf0\x25\xc1\xd0\xbb\x55\xf8\x33\x1d\x9c\x95\xb2\xa6\x23\x2a\x7c\x17\x7e\x10\x5c\x0a\xbf\xfc\x72\xd6\x0f\xac\xfb\x6e\xdd\xde\x6d\xab\xee\x46\x97\x59\x7a\x23\x53\x54\xce\x0c\xdb\x73\x37\xef\x77\x1b\x81\x35\xa2\xbc\x77\xde\xe9\x37\x37\x32\xed\x69\xf0\xa1\xa9\xe6\xa0\xfb\x3c\x6a\x37\xe8\x0c\x46\x5d\xa6\x42\x59\x27\x2c\x4b\xc3\xf6\xe0\x17\xfb\xec\x44\x62\x25\x3e\xfc\x1e\x40\x54\xf3\xb1\x54\x35\xca\x43\x3d\xa9\xee\xb8\x74\x72\xc3\x9b\xf7\x46\x58\xac\xa1\x86\x32\x64\x6d\x67\xcc\xc8\xbc\xca\x2c\x57\x42\x57\x26\x9b\x77\x5c\xda\x0f\x75\x62\x27\x99\x78\x87\x3b\xbc\xbb\xd2\x13\x9a\x6a\x2a\x3f\x90\x68\x5b\x03\xa7\x2c\x69\x3f\x75\x2a\x78\x7a\x10\x34\xa1\x00\x04\x20\xde\x89\x84\x6a\xc4\x8a\xac\x9a\xca\x56\x45\xc1\x5b\x1e\xc4\x56\xbf\xbe\x1b\x0f\x62\x4d\xf7\x56\x19\x51\x23\x97\x75\xe3\x21\xdf\x40\xda\xc2\xf5\xea\x97\x97\xab\x29\x0b\x53\x51\x08\x95\x02\x74\xfa\xf3\x7a\xff\x61\xe7\xd7\x36\xf6\x04\x59\xde\xcf\x59\xe1\xf1\xcf\x1b\xa7\x74\x94\x78\x3f\xd3\x59\x6a\x98\x78\x67\x4b\xee\x8e\x83\xdc\x09\xfe\xf0\x9b\x09\xe3\xaa\xab\x68\x7f\x2c\xc4\x5b\xec\x33\x69\xa0\xe9\x23\xd5\x40\x4d\xaf\x8c\x9c\xbb\x26\xe6\xe1\xac\x47\xaf\xf1\x71\xcf\xe4\x9c\x78\x80\x92\x74\x30\xcd\x3a\xb4\x15\x24\x9a\xf4\x94\x66\xfd\x4b\x37\x32\x4d\xb3\x82\x5a\x6f\xa1\x57\x6b\xdc\xac\x5b\x66\xcd\x87\xc5\xac\x39\x01\xb8\xa7\xee\xe0\xc7\xd4\xce\x82\xcf\x8e\x3e\x24\xb5\xf5\x2e\x3e\x3a\xda\x51\xd1\x99\x0c\x4c\x39\xd4\x10\xc1\x26\x30\xe3\x66\xa3\x2e\x8e\xa8\x94\x6a\x27\xcd\xd7\xcd\x3b\xc8\x2d\x37\xc2\x76\xf1\x24\x37\x15\xcc\xba\x3d\x27\x72\xe2\x95\x4f\x5f\x21\x7b\x27\x14\x7a\x7a\x08\x24\x36\xfc\x3b\xe9\xa2\xaa\x71\xa7\xd3\x42\xfd\xb8\x7b\x70\x64\x11\x32\xcb\xb0\x8d\xd4\xcd\x76\xc2\x6d\x47\x42\xfa\x0e\xa7\x31\xf5\xf6\xcd\x9b\xd3\xe3\x3e\x87\xd0\xb5\xe7\xb5\x55\xf8\x77\x73\x18\x69\x95\x02\x80\xae\xfc\xbd\x8a\x0d\x6d\x80\x6e\x0c\x03\x47\xf7\xaf\x63\x74\xa6\x89\xa8\xc3\x04\xc7\xd2\x5c\x75\x07\x38\x5f\x6a\xb2\xb9\xdd\x7f\x38\x3a\x61\xf4\xe9\x9d\xbc\xf3\xf7\x71\xcf\x77\x45\xc5\x9e\x26\xa2\x0e\xdc\xa5\xd2\x5c\xad\x01\x1c\xbd\xab\x0d\x5c\xa4\x67\xed\xea\x38\x37\x33\xd2\xb0\x68\xe1\x79\x18\xd5\x08\xdf\x77\xae\x2b\x76\x43\x30\x82\x64\x21\x5e\xca\xe2\x19\x3b\x51\xa6\x2a\x45\x9d\xa1\xb5\xd8\x94\xd3\xb7\xee\x6c\x2f\x02\x52\xa3\x79\xd6\x5b\x54\xa2\xef\x95\xfa\x58\xc2\x1c\x05\x2f\x2d\x18\x72\xfd\x2c\xa4\xd0\x9c\x97\xd3\xd1\x07\xea\x2e\x2b\xe9\x74\xe2\x8b\x2f\x06\x84\x29\x16\x80\xd3\xfd\x4d\x6e\xed\x44\x20\xa3\xf1\x6a\x79\x1e\x80\x7d\xd9\x41\x2a\xae\x0f\x4c\xca\x9f\x0e\xe0\x31\xbe\x64\xb0\xd9\x27\x6e\xd8\xce\xd3\x9d\x11\xbb\x90\xb9\xcc\x78\x99\xcd\x1b\x04\x67\xf5\x7d\xee\xd8\xf5\x0d\x42\x36\xcb\x93\x1d\xb6\xa7\x4b\x68\x39\xe1\x8a\x65\xc2\x63\x2e\xd0\xae\x9e\xa3\xdd\xb1\xbf\x19\x22\x92\x6d\x4c\xa4\x08\xa5\x65\x4f\x6b\x2d\xf5\x3a\x15\x9d\xf7\x0d\xd0\xda\xe3\xfa\xc0\x93\xca\x9d\x82\x23\xf6\x86\x8e\x2f\xd2\x0b\x70\x31\xc0\x66\xf6\x77\x6c\xd6\x64\x6d\x9e\x3f\xa4\x95\x67\x63\x39\x74\xb7\x69\x03\xdd\xd6\x7b\x32\x95\xf6\xb5\x28\x74\x0f\x3a\x1c\x36\xb4\x10\x5f\x90\xd6\x7d\xa0\x8d\x04\x7a\x1a\x6e\x19\x47\x91\x94\x54\x19\x77\x46\x1d\x46\x17\x46\xec\xf8\xe4\xfc\xf5\xc9\xd1\xe1\xe5\xc9\xf1\x33\xf6\x03\xb5\x24\x63\x3b\x60\xc4\x2e\x63\xdc\xe9\xa8\xa2\x8d\xc0\x7d\xc3\xb3\x06\x24\x62\xb9\xaa\x89\x33\x00\x87\x93\x2b\x76\xaa\xa4\xad\x29\xc3\xb0\x2e\x20\xd3\x8a\x32\xfd\xdd\xaf\x29\xba\x31\x95\x98\x8f\xaa\xa8\x31\xf7\x75\xb3\x35\xd8\xa1\x48\xb0\x13\xba\xd2\xca\x41\xb2\x66\xe5\xaf\x9e\x9e\x75\x18\xaa\x9e\x0b\xa7\x1f\x1b\x2b\xf0\x20\x79\x18\x08\x8c\x16\xd7\x9f\xe3\x61\x1b\x68\x1f\x3d\xb0\xae\x2e\x1b\xac\x8c\xa3\xd1\xee\x88\xb9\x63\x7c\x77\xb4\xeb\x55\xbe\x6c\x89\x3a\x34\x34\x1a\xe3\x97\x37\x17\xfc\x88\xb1\x57\xbe\x6c\x12\xc0\xa7\x56\xb3\x90\x22\xfe\x62\xc4\x39\xb9\xb0\x6d\x7c\xe9\x7e\x35\x8e\x1f\x4a\x80\xe7\x53\x79\x2d\x14\xbe\xd8\xfa\x24\xb5\xef\x6a\x2f\xd3\x18\xbf\x39\x59\xca\xaf\x5f\xac\xef\xdd\x50\xe2\xf4\xf4\x66\x24\xbe\xe8\xbd\x12\x9d\xe7\x88\xd0\x3d\x0b\x60\x32\x35\x1e\x4c\x90\x8e\x6b\xb1\xf2\x11\x97\x7c\xd2\x6a\x63\x2f\x9c\x0c\xbe\xa9\x05\xab\x3e\x7c\x4c\xe5\xcd\xaa\x36\xa7\xee\xcf\x63\x46\xc0\xf8\xc6\x83\xac\xd2\x31\x7b\x10\x1e\x7e\xf0\xfa\xe4\xf0\xf8\xe5\xc9\x28\x4f\x1f\xa0\x90\x16\x2a\x2d\xb4\x54\xd6\xb4\xb5\xf0\xdb\xf1\xa1\x77\x15\xef\xa1\xdb\xfd\xe8\x70\xa1\x39\xbf\x7f\xfc\x07\x11\xcb\x41\x2a\x2c\x97\x99\x89\x56\x97\xd5\x85\xce\xf4\x74\x35\x01\xda\x3d\x96\xcd\x9f\x10\x21\x77\xc8\x87\x6e\x3d\xae\xcf\xd8\x6d\xcf\xa3\xbc\x68\xe7\x22\x6f\xb2\x1b\xc8\x7a\xb4\x82\xdd\x08\x74\xc7\x8f\x60\xc0\x3e\xa3\x19\xb1\x34\x8a\xe8\xce\x01\xf1\xe6\x49\x28\x6a\x56\x87\x88\x5d\xfd\xae\xf6\xc5\x7a\x06\xbf\xad\x69\xe1\x24\x79\x5b\x1a\xff\xe6\xa8\xfb\x96\x9a\x07\x48\x51\x8a\x61\x80\xcd\x06\x7a\x6f\x5d\x46\x6a\x59\x7c\x9e\x78\x4f\xb0\xf7\x1b\xe3\x5d\xd9\x7c\xd1\x23\x5c\x6b\xf2\xc1\x11\x8f\x58\x84\x59\x36\xaf\xa9\x51\xc8\x1b\xc6\xa7\x08\x87\x5d\x52\x40\xae\x28\xe5\xb5\xcc\xc4\x14\x68\x8f\xa4\x9a\x46\x30\x4e\x31\xf0\x13\xd1\x20\x35\x83\x53\x2f\xdd\x5f\x11\xf5\x1e\xac\xac\xb3\x57\x97\xc0\xa0\x05\x29\x15\x9d\x0d\x4e\xf7\x40\xd8\xf3\xc3\xe1\x10\x5c\x7f\x7b\xff\xe3\x2c\x9f\x34\xdb\x67\xbf\x08\x7a\x8e\x06\x8a\xaf\x12\x68\xee\x67\x3a\xf0\x2d\x41\x5f\xeb\x91\x85\x05\x8d\x69\x7c\x74\xd7\x81\xbb\xd3\x69\xd4\x78\x94\x37\xee\x97\x02\x20\xbb\xeb\x3c\x83\x87\x68\x25\xad\xe9\x00\xed\x59\xda\xfb\x60\xd3\xaa\x3d\x12\xd2\x07\xfc\xb9\xc0\x99\x99\xe7\x99\x54\x57\x35\x46\xfc\x44\xbb\x75\x8c\xe5\xcc\x52\x5d\xf9\x5d\x53\x0a\x9e\xdd\x7e\x62\xb4\x59\xa3\x6b\x3b\x2d\x6c\x6f\xf1\x08\x88\x17\x38\x69\xf1\xa3\x17\x5e\x94\x00\x16\x8b\xfa\x9d\x9d\x07\x3d\x62\xd2\x24\x46\x76\x17\xef\xd0\x4c\x43\xb6\x2b\x76\x7a\x71\x74\x71\xfa\x59\xa3\x7e\xb7\x1d\xae\xd0\xbb\x07\x6d\x3d\xc8\xdf\xdb\x65\x55\x0d\x59\x56\xb5\xfd\x25\xba\x5e\xce\x75\x69\x79\xb6\x06\xc1\x99\xcc\x78\x71\x58\xd9\xd9\xb1\x34\x80\xd6\xd8\x8f\xfa\xb7\xd4\x6a\x54\xaf\x88\x3c\x74\x9e\x70\x43\xfa\xe5\x4b\xf7\x1d\xfd\x78\x78\xce\x78\xe5\xd6\xa3\x25\x8a\xa1\xb5\x25\xcb\xf9\xb7\xb8\xc0\x1a\xe8\x5e\x47\x86\xda\xfc\xc8\xb8\xf8\xbb\x36\x69\x54\x3e\x5f\xd5\xdb\x36\x1e\x0d\x27\x17\x4a\xfd\x47\x12\x83\x96\x4a\x5a\xc9\xad\x2e\x7b\x8b\x0d\x36\x5a\x0c\x0e\xc3\xca\x58\x9d\xd3\x2e\x3a\xf5\x77\x40\x42\x16\xe8\x6f\x4b\x3f\xaa\xbd\x89\x60\x7d\xc2\x98\x9f\x2a\x67\x2b\xf2\x44\x2c\x94\xd9\x0c\x80\xfa\x07\xdb\x96\xe1\x9e\x6f\xc9\x89\x0e\x28\xf6\xd9\xdf\x9f\x35\xc8\x31\x97\x18\x8c\xbd\x17\xb3\xa6\xc7\x5d\x9b\x57\x5a\xfe\xde\x8f\x68\x93\xbf\xab\x85\x78\x02\x0e\xd1\x7f\x55\x3c\xc3\xa1\x3d\x5b\xa7\xf3\xbd\x39\xa5\xfd\xbc\x71\x73\x95\xd0\xcb\xd7\x4b\xe2\x2c\x78\xdb\x2a\x83\x18\xfd\x38\x22\xb6\xe4\xca\xb8\x75\xd2\xf4\x67\xec\x52\x02\xc4\x2e\xdb\xb3\x49\xb1\xbf\xb6\x91\xea\xab\x1c\x36\xab\x54\xac\xac\xe2\xbb\x5f\xe2\xd2\x78\x11\xca\x61\xbb\xbd\xe6\xda\x93\x1c\x60\xb7\xf7\xe3\xb7\xa5\xb6\xc2\x3a\x8a\xc7\x0b\x15\x44\xf6\x42\x1a\xeb\x09\x84\xe1\x03\x69\x88\x6b\x0d\x6c\x81\x73\xa6\x4b\x26\x8b\x7f\xf2\x34\x2d\x9f\xa1\x1e\x41\xb6\x2a\xfc\xdb\x04\x38\x7c\xae\x42\xb6\xcd\x9e\x9d\x17\x44\xe2\x71\x79\x74\xce\x90\x28\xfc\x9b\xbf\x3d\x01\xbb\xe0\xab\x2f\xff\xf6\xa4\xe3\x42\x7c\xa8\x55\x85\xac\x6f\x9f\x68\xef\x99\x15\x8f\xa4\x8a\xa4\x51\x2d\xe2\xc6\x02\xb4\xdd\x0b\x2c\xce\x70\xe7\x24\x09\x4d\xdc\x08\x6e\x55\x86\xd3\xbb\x4f\x9d\x78\x5b\x75\xf1\x07\xaa\xba\x60\xa1\x1a\x1f\x05\x6b\x2f\x0b\x39\x6e\x10\x60\x75\x96\x05\x38\xca\xee\xf3\x87\x22\xbb\x5b\x8e\x6e\xdb\x95\xdc\x5c\xc1\x71\x8a\x9f\xa7\xce\xaf\xcb\x53\x8f\xcf\x2e\xfe\xf9\xe2\xf0\xfb\x93\x17\xf0\xae\x94\x15\xe8\x96\x27\x59\x42\x6d\x72\xd6\xef\xbe\xdc\xdb\x3b\xb7\xda\x0e\x69\x1f\x09\x06\x6a\x21\xb5\x40\xb1\xb3\xe7\x17\xf7\xcd\x2a\xe8\x6a\xce\xaa\x49\x87\xd1\x7b\x68\x71\x0d\x60\x5a\x17\xe5\x7a\x2a\xe7\x7b\x0e\x8a\x44\xb0\xf7\x0d\x3f\x8a\x5b\x43\xf8\x8e\x9d\x5d\x1d\x2d\xd7\x06\xdb\x38\x5d\xef\xc3\xf1\x6f\x37\x62\x38\x8a\xbd\x47\xbe\x3f\xeb\x68\x77\xd3\x21\xcb\xbe\x60\x1d\x76\xb1\x2d\xaf\x3e\x3a\x11\x86\x67\x47\xe9\x4e\x55\x77\x9e\x0a\x13\xd8\x98\x1f\xc1\x6a\x2d\x56\x51\x0f\x76\x3f\x1d\x56\x36\x4b\x1c\xdc\x9e\x7a\x29\xca\x2a\x68\xd4\x75\xdf\x46\xe0\xe9\x33\x32\x39\x39\xc2\x4c\xc1\x93\x5e\x09\xe1\xeb\x8f\xf0\x13\x80\xde\x7b\x88\x07\x0c\x74\x7c\x4d\xe5\x65\xe1\xd9\xfd\x6c\xc7\xd0\xdc\x22\xd2\xca\xbd\x56\x89\xa7\x2f\x2f\xb4\x47\xd2\x89\x21\x59\x36\x72\x09\xb1\x8d\x3b\x87\xc2\x31\xf4\x4b\x4b\x77\xc3\x3a\x5d\x0d\xc5\x4c\x5b\xad\x7a\xae\xa1\x5d\xd5\x68\x53\xb0\x9d\xc3\x1d\x47\x58\xe9\x9e\x89\x32\x92\xb7\x58\x41\x14\xc2\xea\xce\xf2\xf0\x47\xb7\x56\x3e\xc0\xde\x0c\xaf\x3f\x3c\x49\x54\xa4\xa7\xc7\x6b\x10\x42\x8f\x0d\xec\xe8\xbe\x61\xc2\xb5\x25\xca\xa6\x3d\x55\xee\xbb\x86\xfc\x98\x9f\x1e\x93\xb9\xe0\xcb\xf2\x0d\x6d\x2b\x76\xfb\xbe\x5a\x8b\x2a\xa5\x4b\x7b\xa3\xcb\xbe\xe0\xe3\x9a\xcd\x2d\x64\x61\xd2\x77\x4b\x60\x1c\x8f\x53\x8a\xe0\x5b\x3e\x78\x49\x72\x01\x92\x64\x81\x06\xf5\x36\x89\xf2\x29\x04\xca\xc3\x11\x24\x9f\x46\x71\xf9\xb4\x48\x5c\x6b\x33\x7f\xfd\xf6\xe8\x65\xb0\x7c\x63\xe4\x06\x75\x0b\xa5\x96\xbb\x1c\xdc\xcd\x91\xe4\x59\x8b\x9c\x2d\xb5\x93\x43\xed\xc4\x49\x53\xc4\xfa\x96\x30\x38\x88\xb4\x8d\x59\xe6\x66\x56\xab\x98\xf0\x91\xc0\xba\x06\x0c\x39\x13\x73\x5e\x10\x69\x7e\xaa\x6f\xd4\x0d\x2f\x53\x76\x78\x7e\xfa\xf9\xe5\x6a\xe7\x4a\x50\xdc\x0f\x5d\xb8\x05\x9a\xb5\xa0\x75\x7b\x90\x81\x0f\x49\x42\xee\x8f\xb1\xb4\x06\x53\xf9\x21\x19\xdf\xc6\xde\x28\x77\x4e\x85\x4c\x16\x27\xe9\x9c\x54\xa3\x96\x22\xb5\x4a\x31\x9d\x58\x9e\x79\x22\x66\x61\x6f\x84\x50\xec\xc9\x93\x27\x18\xa0\x78\xf2\x1f\xff\xf1\x1f\x0c\x58\x37\x53\x91\xc8\x7c\xf9\x46\xb8\xeb\xeb\xa7\x4f\x47\xec\x1f\x87\x2f\x5f\x30\x9e\x80\x2d\x87\xc8\xb7\xd8\x32\xcc\x67\xfc\x63\x33\x60\xff\xfb\xe2\xd5\x99\x3f\xbe\xcc\xc2\xb7\xb0\x5c\xc2\xeb\x8d\xd8\x71\x94\x7b\x1f\x07\x0f\xb8\x9d\xc1\x68\x28\x6d\x19\x9f\x4c\x70\xc1\x81\xe4\x96\xc6\x0b\x13\x8f\x3d\x27\xa7\x33\xcf\x44\xef\x96\x5a\x06\x45\x01\xd2\x75\x11\x02\x36\x1e\xc7\x11\x6b\x1c\xa0\xad\x70\x88\x40\x57\x06\x2c\x93\x57\x82\x4d\x0c\xf0\xd1\xd7\xc4\x29\xa5\x30\xce\x00\x4b\xb8\x72\xad\x63\x63\xf5\xcc\x18\xd1\x11\x1b\x73\xdd\x99\x13\x1d\x99\xcb\x9b\x21\x64\xda\xf3\x9e\x42\x8c\xb8\x01\x7d\x8d\x16\x8a\x0c\x37\x0b\x0f\x35\x93\xa1\xf1\xb6\xe7\xe1\x7d\x70\x51\x11\xfa\x61\x2d\x19\x79\xa6\xd5\x34\x5e\x83\xb5\xf6\xe1\x93\x29\xe7\x85\x68\x3b\x18\x3d\x11\xea\xf4\x43\x4f\x87\xc2\xfd\x25\x2f\xba\x31\x81\x34\x73\x74\x7d\x9b\x0d\x1c\x4a\x3e\xd6\x95\xf5\x39\x7b\xf4\x3d\xc0\xb7\x59\xed\x87\xbe\x53\x17\x7a\x63\x29\xea\x8f\xf7\xaf\x27\xd2\xad\x66\xce\x1c\x9c\xda\x4d\x95\x75\xc0\x04\x4f\x66\xec\x4a\xcc\x87\x78\x02\x14\x1c\xd0\x23\x60\xb4\x8f\xdd\x18\x37\x68\xf8\x83\xe7\x39\x75\xd6\x24\x4d\x85\x4f\xb0\x8c\xf4\x03\x8f\x3e\xe1\x0d\x2e\x43\x7a\x39\x51\x59\xa9\xc8\x43\xe9\xb9\x2b\x13\xad\x2c\xf1\x62\x06\xee\x2a\x48\x18\x5d\x00\x24\x70\x12\x46\xa4\xee\x67\xe6\x43\x4f\xae\xb3\x4a\xdd\x89\x42\xfa\x47\xa5\x96\x7e\x0d\x78\xee\x90\xd3\x6b\x04\x21\x23\x71\xcf\x89\x18\x65\xa6\xce\x64\x02\x15\x47\xee\x76\xba\xd7\x8f\x52\x18\x88\x06\x60\x82\x11\xb6\xa2\xa1\x81\x3c\x61\xf7\x6c\x61\x0c\x93\xf0\x86\x39\x2f\xaf\x84\x07\x1a\xe6\xd9\x88\x9d\xbb\x4e\x06\xb4\x79\xa4\x12\xbc\xc6\x02\x11\x27\x63\x62\x24\x08\xf7\x90\xdd\xd1\x68\x17\x8f\xca\x15\xb8\x10\x9d\x57\x4d\x9f\x2c\x72\xbd\xb1\xc7\x35\x96\xf2\x4b\x5e\x18\x64\xd3\x73\xa6\x05\x30\x56\x6a\xc0\x6d\xb1\x33\xaf\x4c\xf0\x8e\x10\xe2\xf1\xd5\x33\x8d\x59\xbf\x4c\xa8\xfd\xf1\xa0\x76\x88\xb5\x37\xaf\xbe\xf9\x4f\x7b\x64\x3f\xbd\x8d\xfb\x94\xd6\x10\x49\x92\xbe\x18\x19\x7b\xa7\xdc\xcc\x7b\x20\x36\xf3\x57\x33\x74\x04\xfa\x6d\x03\x4b\xfa\x4e\xb6\x08\x41\xa9\x67\xe2\x41\x19\x1f\xa7\x13\x10\xa9\xab\xb1\x6e\x62\xbb\xcc\x9f\x30\x6e\x04\xd6\x6f\x75\x74\x65\xd9\xf3\xd7\xa7\xa0\xa9\xef\x6e\x96\x2c\x5e\x5d\x92\x68\x16\xaf\xa6\x23\x23\x82\x95\x08\x47\x6d\x5c\x7d\x0c\x53\x65\x35\xb0\x75\xd6\xc2\x61\xc4\x5e\xd2\x51\x8c\x8b\x9c\x8f\x8d\xce\x2a\x1b\x90\x28\x56\x9c\xd3\xd0\xa8\xe7\xf6\x44\xd0\x26\x7f\x5b\x74\x6a\x83\xbe\x82\x47\x59\x3f\x07\x38\x5e\x3d\x0a\x9f\xae\x09\xb2\x78\xfd\xc1\xd2\x64\xf1\xea\x71\x16\xbc\xba\xd8\xf3\x4c\xf8\x66\x03\x7a\xa7\xaf\x88\x6c\x68\xb7\x90\x23\x6b\x0d\xaa\xce\x5e\x51\xc5\x1a\xca\xb6\x08\xd8\xf5\xd5\xdd\xab\x4b\xef\x45\x0e\xc6\xc3\xf3\xd3\x1e\xad\xd2\xa8\xd5\x5b\xec\xd2\xf8\x8e\xad\x65\x7a\x97\xab\x31\xc0\xa7\x68\x99\x3a\x95\xde\x3b\x90\x8e\xeb\x11\xa5\x90\x9e\x13\xca\x7f\x00\xd3\x66\xe9\xc5\x9f\xbb\xc3\x28\x2e\xe6\x6a\x32\x74\xa0\x33\xb8\x3e\xb6\x22\x56\x0f\x9f\xc3\x03\x22\xee\xf1\x9b\x41\x1b\x6a\xbc\xc0\xe8\x77\xa8\xd8\x59\xbc\x9a\xa7\xe8\x6b\x3f\x88\xec\x42\x64\xee\xd0\x63\x0b\x2e\x9b\x42\xa7\xcf\x90\xf3\x9b\x2b\xa5\x2d\xac\x1b\x33\x60\x19\xf0\x91\x0f\xd0\x15\xe3\x34\xd0\x28\xfb\xab\x8c\x82\xa6\x3d\xeb\x9c\xbd\x2d\x1e\xd6\xfb\x02\x62\xb0\x88\x60\xec\xce\xfb\x59\x49\xec\x13\xac\x26\x77\xd5\xaa\x4a\x9f\xb4\xfc\x8d\x75\x45\xed\xfb\x45\x64\x92\x99\xc8\x39\xf2\x91\xf8\x01\x72\xf2\xfa\xa6\x94\xd6\x0a\x44\x1d\x17\x65\x6e\x98\x9e\x0c\x1a\x71\xe3\x9d\xeb\xa7\x3b\x7d\xe9\xb3\xec\x53\x18\xd4\xcc\xef\xd0\xb6\x30\x60\xb7\x5d\xcd\xb8\x41\xc3\xb8\x70\xbb\x13\xac\xe9\x0c\x08\x92\xd4\x82\xc3\xd2\x29\x11\xd7\x38\xfe\x1b\x3d\x74\x9f\xce\x17\xd1\xd6\x07\x31\x08\x8a\xe9\xd6\x07\xb1\xf5\x41\xf4\xd1\xe2\x27\xf3\x41\x44\x07\xb7\x17\xa6\x2b\xfc\x11\x71\x21\x9e\x77\x4a\xd4\x50\x16\x11\x4c\xb4\x5b\xf2\xde\x1d\xa1\xcb\x66\xac\x60\x77\x34\xda\xdd\xf5\x4e\x0a\xda\x1f\x95\x9d\x0c\xbf\x61\x42\x25\x3a\xc5\x45\xe5\xda\x2f\x8d\x05\xa5\xb6\xb6\xca\xe3\xbe\xe4\xfe\x59\x71\xbc\x01\xda\xee\x77\x49\xf4\x28\xa1\x7c\x4a\xca\xf3\x4f\xaa\x82\xd5\x8a\x57\x80\x01\xa3\x01\x0c\x68\x89\xa4\x81\xd5\x29\x32\x99\xcc\x25\xe1\x13\x3a\x71\x21\x8c\x35\x6c\x0f\x3f\x1c\x25\x45\x35\xa0\x1b\x46\xb9\xc8\x75\x39\x1f\x84\x9b\xdc\x97\x8d\x5f\xd1\x1d\xfb\xa0\xb5\x25\x55\x59\x0a\x65\xb3\xf9\x1f\x57\x7f\xf3\x43\xbc\xc1\xea\x5b\x58\x15\x5d\xea\x3e\x56\x5d\xcd\x65\x59\x93\x08\x80\xf7\x2e\x8c\x36\x9c\x43\x54\x81\x31\xa8\x9d\x3f\xee\x53\xa1\xae\xd9\x35\x2f\x5b\x57\x60\xac\xba\x3e\x89\xc6\x96\xca\x6b\x69\x74\xeb\x1a\xb6\x95\x4d\xc6\x83\x77\x41\x87\x32\xfa\x88\x75\x65\x8b\xca\xd2\xe9\xe2\xf7\xb6\x87\xec\x0b\x7b\x7a\x41\xf1\x7d\xba\xd3\x63\xe7\x0a\x6e\xad\x28\xd5\x33\xf6\xdf\x7b\x6f\xbf\x78\x3f\xdc\xff\x6e\x6f\xef\xd7\x27\xc3\xff\xfc\xed\x8b\xbd\xb7\x23\xf8\xc7\x5f\xf6\xbf\xdb\x7f\xef\xff\xf8\x62\x7f\x7f\x6f\xef\xd7\x9f\x5e\xfe\x70\x79\x7e\xf2\x9b\xdc\x7f\xff\xab\xaa\xf2\x2b\xfc\xeb\xfd\xde\xaf\xe2\xe4\xb7\x3b\x36\xb2\xbf\xff\xdd\x9f\x7b\x7c\x09\xae\xe6\xaf\x7a\x13\xc1\x78\x0d\x3f\x89\x1a\xd1\x6c\xbb\xe7\xa5\xcb\xd8\xbb\x61\xed\xd1\x1e\x4a\x65\x87\xba\x1c\xe2\x43\x9e\x31\x5b\x56\x7d\x89\xae\xfa\xf8\xfb\x74\x32\xa6\x56\x62\x6a\x04\x4c\x6f\xd8\x6c\xa0\x10\xc1\xc4\xd4\x1e\x3d\xc3\xc4\x63\xbb\xda\x29\x4c\x5f\x6e\xfd\xc1\x77\xb9\x3e\x61\xa6\x12\xe1\xd9\xfc\xc1\xd3\x94\x2e\x88\x4d\x79\x9b\xa3\xb4\x74\x6d\x73\x94\x96\xaf\x6d\x8e\xd2\x3d\xaf\x6d\x8e\x92\xbf\xb6\x39\x4a\x5b\xff\x60\xf7\xeb\x0f\xee\x1f\xdc\xe6\x28\xdd\xf7\xda\xe6\x28\xb5\xbe\x1e\x50\x8e\x12\x2a\xf9\xab\x32\x95\x48\xcd\xaf\xd3\x94\x36\x36\x4b\xc9\xb8\xf5\x90\x88\xc3\x24\xd1\x95\xb2\x97\xfa\x4a\x74\x0c\xe4\x2e\xd8\xa4\x4b\xad\x03\x24\xe2\x2d\x36\xea\xf2\xcd\x1b\x69\xb0\xf6\xa5\x8f\xf6\xa0\x3f\xf6\xa7\x39\xf2\x2a\x95\xce\x46\xed\x79\xb3\xf8\x66\x63\x58\x6c\x95\x8a\xb4\xfe\x82\x44\x9a\x75\xf3\x3d\x62\x87\xac\x14\x89\x2c\xa4\x3b\x00\x00\x2b\x08\x3e\xc7\xed\x13\x58\x9c\xa5\x35\x22\x9b\x10\x93\xad\xaa\xcb\x9c\xcb\xc8\xfe\xa4\x13\x65\xe5\x63\x50\x87\xd0\x9e\x6b\x94\x99\x99\xae\xb2\x94\x95\xe2\x7f\xbc\xf2\x41\xbd\xb9\x8c\x5b\x88\x5d\xaa\xf0\x2a\xf5\x63\xa9\x71\x5e\x48\x02\x15\xdb\x24\x31\x28\xde\x15\xb2\x84\xcd\x76\x21\x12\xad\xd2\xbe\x3d\x24\x4b\xed\xd7\xba\x02\xc4\x85\x44\xca\xd2\x0a\x6f\x80\x72\x4c\x9e\xc9\x54\xda\x79\xc8\xe7\xc0\x6d\xef\xd4\x56\xe4\x0e\xa6\x85\x60\xea\x89\x60\xbc\x28\x4a\xcd\x93\x99\x30\xd1\xd3\x50\x09\x25\xa0\x8c\x50\xe5\x99\x55\x53\xa9\x50\x0f\x85\xdf\x38\x65\x25\x9b\xb3\x52\x5b\x9f\x9a\x76\xcb\x03\x2f\xa3\xc6\xe0\xe7\xa8\x71\xd8\x72\x0e\xf9\x6b\x3a\x6e\x02\x7b\x25\x27\xf1\x1f\x86\xe9\x2c\xf5\xd0\xac\xdf\x3c\x71\x8a\x7f\x42\xab\xd8\x1d\x02\x00\x9a\x69\x35\xcb\x9c\xf2\xe4\x0e\x86\xdb\x7f\xfc\xe5\x5f\xd9\x4c\x57\xa5\x19\xc5\x60\x7f\x4f\xe1\x33\xf4\x70\x78\xc3\xc1\xb2\x4c\x70\x63\xd9\xd3\x27\x2c\x97\xaa\x72\x27\x7e\x4f\x0b\xaf\x2f\x5d\x37\xd2\x72\xff\xf6\xd7\x8e\xad\xf5\xa3\xdf\xde\xaa\xd9\x16\xc8\x98\x47\xea\x2d\xed\x71\x04\xf4\x40\xd6\xcc\x05\x65\x97\x8e\xa4\x78\x16\x95\xd5\x6b\xde\xf9\xbf\x57\x7a\x3c\xb7\xdd\x21\x6c\xa8\x9d\x26\x76\xcd\x7f\xd1\x87\x77\x81\x8a\xad\x91\x62\x5b\x74\x65\xed\x1c\xdf\x53\x69\x6c\x2b\x86\xef\x1a\xf3\xa6\xc5\x8f\xbb\x1e\xe6\x53\x67\x1f\xf7\x52\x49\x0f\x2d\x79\x8b\xce\x7b\xa4\x93\x44\x18\x10\x45\x1e\x14\x0e\x9c\xbb\x78\x6f\xcb\x87\x6e\x28\xda\xcc\x2a\x10\x19\xbf\xf8\x7b\xe0\x2a\xed\x34\x58\x5d\x54\x7e\xbf\xb0\x7b\x1a\x2d\x6c\xac\x29\x23\x8c\x54\x53\xa4\x16\xcd\xab\xcc\xca\x22\xab\x47\xee\xb5\xff\x01\x1d\xc0\x71\xb4\x80\x47\xee\x69\x8e\xa0\x57\x88\x7e\x0e\x91\x95\xbd\xd0\x96\x50\x16\x19\x32\x4b\x77\x8e\x17\xbc\xe4\x61\xf8\x13\x9d\xe7\xdc\xec\x53\xe0\x81\x43\x16\x0c\xd1\x00\xb9\x5f\xf1\xac\xee\x71\x94\x75\xb0\xae\x85\x6b\x85\xe2\xaa\x75\xf8\xaf\x09\x38\x0f\x4d\x31\x7d\x13\x12\xed\x91\xe4\x7e\x61\xc5\x92\x42\xfc\x3d\x4f\xae\x84\x4a\xd9\x1b\xe3\x07\x2e\x9d\x2b\x9e\x13\x7e\x7c\x51\x6a\x64\x51\x17\xe9\xc2\xef\xcd\x80\xdc\x8e\x08\x7d\xe2\x01\xac\x50\xdf\x5a\xd7\x28\x56\xa6\x27\xf0\x60\xd7\xd0\xc7\xe4\x9d\x41\x97\x6e\x29\xaf\x13\xe1\x75\x47\xf7\xbb\x75\xbd\xfc\x75\x6b\xb4\x3a\xb6\x1a\x3a\x8a\x68\x4c\x71\x17\xc2\x91\x1e\x22\x97\x00\x13\xcf\x33\x27\xe2\xe6\x01\xf3\x67\x61\x81\x8d\xe7\xe0\xf7\x5a\x0b\xf2\x58\x39\xee\x8e\x29\xb5\x5b\x8e\xd3\xa6\x30\x7b\xcd\x53\x6d\xd8\xf7\x99\x4e\xae\xd8\xb1\x00\xa3\xe1\x53\x92\xef\x97\xe3\xf4\x61\x13\x67\xe6\x7c\xda\x2e\x63\x64\xc8\x72\xad\xa4\xd5\x65\x1b\x79\xbc\x41\x40\x81\x5b\x2a\xc3\xbb\x20\xa6\xbb\x7d\xf6\x58\x88\x0c\xdd\x92\xef\x67\xe9\x40\x53\xc1\x75\x02\x92\x07\x3f\x02\xa1\xda\x5a\x8e\xfc\x69\xa6\x6f\x86\x56\x0f\x2b\x23\x86\xb2\x75\x22\x54\xe7\x81\xba\x12\x73\xc8\x2a\xeb\x65\xa8\xa8\xb1\x86\xe5\x6e\x35\xf8\xd9\xe1\x73\xa7\xdf\xbd\xfe\xfe\xf8\x8d\x11\xe5\x28\xb6\x56\x0e\x84\x4d\x0e\x12\x51\xcc\x0e\xa8\x85\x07\x3f\xac\x5e\x6c\xf6\x33\xae\xbe\x35\x54\x04\x12\x9d\x65\x04\x30\xa6\x27\xec\x48\x14\xb3\xf0\xb8\xcd\x18\xb7\x87\xcc\x29\x57\x68\xdd\x0f\xdd\xd4\xae\x6b\xa9\x29\x36\xe0\x13\x94\x1a\xd1\xe2\x2f\xc7\xf7\x23\xf2\xde\xc4\xe5\xfe\x19\xd9\x59\xda\x50\xf1\x6d\xc4\xf0\x6e\x0e\xa5\xdf\x6e\x83\xd3\x2f\xae\x1f\x6a\x12\xf6\xf9\xec\xd4\x86\xd8\x3e\x9d\xa0\x31\x9a\x8a\x94\xe9\x6b\x51\x96\x32\x15\x86\x05\xb9\x1d\xfb\xa0\x64\xb6\x19\x23\xbf\xe5\x0e\x7c\x58\x09\x07\x9b\xe3\x7e\xd8\x05\xff\x43\x43\x88\xc3\x27\x4b\x42\x9c\xa7\xb9\x54\x9b\xb1\xda\x5b\x8e\x9b\x49\x78\x26\x4e\x5f\x75\xb6\xd6\xa9\x9d\xa6\xc1\x7e\x41\x1f\x46\x9c\x02\x1f\xc1\xd9\xff\x29\xac\x5d\xa6\x74\xda\x2e\x80\xb6\x66\xb3\x7b\xca\xad\xb8\x69\xa9\x08\x0d\x6b\x91\xdf\xf6\xf7\x60\x9e\x3d\x6c\xb3\x7d\x23\x98\x42\xa2\x5d\x8e\x90\xff\xeb\x52\xb2\x68\x3d\xf5\x13\x48\xc2\xb6\x62\x52\xb6\x45\x2a\x36\xbf\x67\x0f\xcf\x4f\xd9\x0f\x78\xfb\xfa\x58\x50\x4a\x6d\xd1\xe4\x39\xd6\x39\x97\xfd\x10\xa0\x2f\x36\xba\xc8\x87\x15\x0f\xc2\x79\xb8\x97\xd1\xcd\x4e\x29\xaa\xe1\x86\xab\x52\xa4\x8c\xfc\x29\x8f\x8c\xe2\x61\x49\x9d\x7e\x1c\x14\x0f\x9f\x8a\x25\x3b\x72\xcd\xfb\xfa\x9d\x5a\x8b\xf6\xcb\x09\x94\x88\x90\xeb\xc4\x8c\x50\x46\x42\x7a\x43\x94\x81\x07\xaa\x36\xa4\xa5\x87\x62\x1d\x54\xbb\x07\xec\x85\x9e\x4a\xe5\xa5\x98\xa6\xac\x9a\x09\x97\x59\xb7\xe1\xdc\xea\xc9\x7f\x30\x3d\xd9\x98\xec\x44\xf1\x71\xd6\x3e\x65\xb2\xb9\x09\x42\x73\xec\x79\xc6\xa7\x4c\xc0\x1f\x07\xa9\x34\xee\xbf\xec\xe2\xe2\x05\x04\x83\x2b\xe5\xed\x4b\x08\x73\xd2\xd9\x12\x4a\xa3\x51\xc8\xac\x4f\x2e\xa0\x10\xef\x8d\xc1\x23\x6a\x8f\x49\x95\xba\x57\x17\xa6\x91\x94\x4c\x77\x20\x57\x4a\xa8\xbb\xc3\xd4\xc7\xb1\x60\x97\x33\x99\x5c\x9d\x47\xf1\x5f\x5d\xba\xcf\x54\xf4\x51\x43\x49\x59\xfc\x6e\x5d\xa7\x11\xbd\xd6\x79\x5f\x0e\xb5\xa8\x3d\x7f\x52\x7b\x71\x7a\x41\x23\x08\xdf\x71\x63\x74\x22\xeb\xfc\x03\xf0\x44\xd7\xc7\x77\x0a\xc7\xf7\xfa\x46\x05\x14\xce\x7e\x06\x04\xf5\xdc\x15\x5a\x8b\x5f\x51\x74\x07\x37\xb1\x96\x22\x95\x1f\xb7\xb5\x0d\x02\xae\xf1\xde\x28\x4d\xeb\xe6\x96\x29\x4d\xbd\x99\xb9\x10\x22\xf7\x05\xaf\xb4\x80\xbc\xc9\x40\x1c\xda\xcb\x4b\x28\x50\x9b\x12\x99\xc9\x5a\x86\xae\x7d\x69\xfa\x2a\xf7\xdf\x42\x7e\x10\x7e\x46\x41\x73\x90\x3d\x85\x2e\xaa\x0c\x33\x6b\xbb\x33\xbb\xfa\x18\x23\x3e\x67\x0d\x41\xf4\x4d\x63\x76\xda\x8d\xcb\xf3\xee\x5f\xaf\xf8\x38\xf8\x9d\x22\xd3\xe2\xc9\xdf\xfe\xfa\xd7\x87\xce\xf8\xd4\xcd\x71\xb7\x6e\xca\xa7\x4e\xa1\xb7\x15\xd8\x0c\xa7\x5b\x6c\x86\x2d\x36\x43\xf3\x5a\x7b\x7c\xf8\xf3\xa3\x2f\xf4\x52\xdd\xd6\x47\x65\x5b\x57\x7c\x85\x8e\x55\x71\xfd\x54\xc4\x75\x46\x50\xf8\x1c\xb8\x09\x3d\xd5\x88\x75\xc7\x48\xd8\x22\x23\xfc\xb1\x90\x11\xfa\xab\x11\xeb\x0b\x05\xa1\x7b\x6d\xd8\x1f\x07\xf1\xa0\xb3\xd8\xe8\x5a\x57\xdf\xb9\x9a\xbe\x2f\xd2\x8f\xbe\xbc\xfb\xbd\x79\x18\x76\xeb\xf6\x56\xfa\x5b\x3c\xc4\x9b\x47\xd3\xdf\xdd\x35\x11\x58\xbe\xd5\x4e\xba\xac\xd1\x74\x66\x9d\x3d\x0f\xd8\x15\xdd\xea\xec\x5e\xe5\xc5\x7b\x75\xb1\x90\x20\x10\x3e\xde\xfc\xbc\x80\x6d\x80\xbc\x5b\x9a\xfa\xe3\x0a\x8f\x3e\x52\x06\xfc\x4f\x15\x1e\x35\x0d\xd4\x5c\xef\x75\x04\x01\x09\x2a\x9c\x1e\xc7\xcc\x34\xb5\x58\x38\x3c\x3f\x65\x49\x29\x00\xda\x81\x67\x66\xc4\x56\x68\x78\x3e\x80\x44\x1a\xa1\xd7\xec\xb8\xb5\x22\x2f\x6c\xd7\x95\xb7\x8d\x8e\xfe\xc1\xa2\xa3\x9f\x3c\x4a\x31\xab\x72\xae\x86\x4e\x5a\x40\x7c\xb4\x91\x77\xb2\x70\x1e\x8e\x18\xc9\x05\x54\x2b\xc0\x17\x0a\x25\xcd\x95\x92\xbf\x57\xa2\x76\x57\x04\xad\x63\x03\x82\x3b\xd0\x8f\x9e\xc7\x0e\x35\xaa\x05\x29\x92\xe8\xa5\x22\x2e\x1a\x90\x30\x8e\x5e\x60\x44\x6a\x59\xc3\xf5\x66\x67\x02\xb5\xb7\x73\x00\x49\xa8\xef\x6a\xda\x87\x68\x20\xf2\x2c\xd3\x37\xf8\xec\x58\x1f\x71\xf3\xe7\xfa\x42\xb8\x24\x63\xc1\x72\x59\x96\xba\xa4\x30\x52\xdc\x1d\x4c\x1f\x72\x76\xa6\x28\xd1\x60\x2b\x29\xe9\xe3\x42\x58\x9a\x6a\x58\x2a\x56\x33\xae\xb0\x80\xd3\xfd\xdb\x67\x5c\xc3\xb3\xbd\xbc\x1b\x8b\x19\xbf\x96\xba\x2a\xf1\xd7\x56\xb3\x1d\xfa\x0a\xce\xde\xb9\xae\x82\xef\xbc\x82\x0a\xad\xf0\x76\x66\xc5\x38\x9d\xd5\x5f\x82\x81\x9b\x6a\xef\x8e\x1c\x8a\x77\xd2\xd8\xe5\x77\xf1\x43\xe4\x29\x27\xd6\xb1\xf2\xae\x4d\xe1\x0e\xd8\x9f\x5b\xd7\xde\x36\xd7\x5b\xdc\x5a\x53\x53\xbd\xbe\x80\xaf\x3e\xa6\xa7\x12\x62\x0d\x96\xcc\xfb\x72\xb8\x87\x97\xc3\x8a\x6f\xd9\x92\xeb\x6a\x23\x15\xe5\xad\x92\xfc\xc1\x2b\x64\x59\x64\x32\x99\x9f\x1e\xf7\x9b\xb9\x81\x6d\xfa\xe3\xcf\x84\xac\x0d\xf7\x39\xfb\x9e\x1b\x91\xb2\x97\x5c\xf1\x29\x7a\x5d\xf6\x2e\xce\xbf\x7f\xb9\xef\x56\x11\x78\x75\x4e\x8f\x57\xa6\x76\x5c\xc4\x8d\x9f\xad\xab\xce\x9d\x2d\x0e\x5d\x6f\x6a\xc3\x52\xab\x2d\x87\x6f\x6d\x10\x00\x2c\xe8\x04\x5d\xe8\xd3\x56\xa8\x03\xe7\x8b\x20\x51\x98\xbe\xe1\xd1\xdf\xcc\xa2\xa8\xbe\xce\xd3\xab\x4f\x39\x00\x91\xdf\xfc\x43\x6f\x79\xb7\x18\xd8\x1d\xe2\x5c\x4d\x36\x12\x5b\x72\x2b\xa6\xf3\x63\x51\x64\x7a\xee\x16\xc0\x79\xe4\xc6\xc7\x5b\xc7\xa8\x36\x94\x63\x9e\xb0\xb2\xca\x04\x72\x0b\x2d\xc2\xae\x29\x21\xd2\x5a\xd2\x49\x65\x2c\x07\xd0\x35\x6c\xff\x83\x3d\xba\xf3\x61\x75\xd7\x63\x69\x88\xfd\xfc\xe8\x5d\x4d\x88\x4a\xb7\x4b\x3e\xf8\x93\xbb\x1f\x4c\xf0\xf8\x8f\xaf\xd9\xfb\xc4\x35\xef\x1c\xc1\x6c\xb2\x03\xc2\x2e\x7f\x5d\x65\xee\xf0\xc9\xd2\x05\x8a\x57\xd0\xd3\x68\x8e\x11\xed\x02\x64\x82\xeb\xfd\x80\x8d\x2b\xa7\xc4\x09\xd3\xf0\x71\x2f\x43\x7d\xde\xcc\x30\xa4\xed\x7e\xc4\x78\x51\x64\x12\x53\x98\x75\x49\x71\xe9\xc8\xa1\xb9\x7c\xdb\x5d\x44\xcb\x3d\x75\x99\xfb\xe9\x2e\x43\x76\x2d\xca\xf1\x5d\x70\x2a\xee\xab\x96\xf0\x42\x42\x1c\xe7\xce\x5a\x4c\x63\xe2\x0e\xcf\x4f\xf1\xd7\xab\x1c\xc7\xfe\x4b\x9c\x41\x9a\x1b\x1f\xde\x20\xce\x20\xb4\x5c\x02\xd2\xd2\xe1\xf9\x29\x42\x7b\x11\xd8\x52\xed\xfe\x70\x76\x02\xc7\x24\xc7\x1a\xe1\x91\x4f\x5d\x8b\x96\x69\x15\x1e\x2a\x54\x95\x0b\x04\x68\xaa\xc9\xc6\x9c\xf1\xa8\xe6\x75\xeb\xb5\xf7\xc4\xd9\x3a\xce\xf4\xd9\xd9\x89\x15\x61\x2c\x7d\x28\xa3\xfe\x80\x30\xd9\xf9\x4b\xe3\x2e\x27\x39\xea\x0e\xdf\xf5\xf8\xb9\x7f\x96\xc0\x3d\xb3\x02\xee\x7d\x9e\x29\xad\x5e\xd3\x50\xbd\x79\xfd\xa2\xdd\x42\x38\x6b\xb6\x41\xa0\x3e\x02\xf0\x0b\x0b\x5e\xda\xff\x8f\xbd\xe7\xe9\x6d\xdc\x56\xfe\xde\x4f\x41\xf8\x92\x4d\x10\x7b\xf1\x43\xdb\xdf\xa1\xb7\x3c\x27\xc5\x0b\x9a\x3f\x0b\x3b\x4d\x2f\x3d\x94\x91\x18\x9b\x88\x44\xfa\x91\x92\x13\x6f\xd1\xef\xfe\xc0\xe1\x90\x92\x6c\x89\xa2\x62\x67\x9b\x3c\xd4\x97\xdd\x48\xe4\x88\x1c\x0e\x87\xf3\x9f\x9c\x66\xa4\x54\x99\x73\x2b\xda\x1c\x01\x0c\xc5\x5b\xd2\x75\xad\xf0\xd1\x84\x90\x13\xbb\xfa\xb8\x38\x76\x8f\xdb\x0b\x7c\xd1\x14\x5c\x66\xd9\x29\x79\xe4\x70\x65\x7b\xc1\x56\xa4\xee\xd6\x9a\x73\x91\x18\x75\x50\x8c\xfd\x8d\x3c\x30\x22\xa7\x24\xfa\x8d\x0e\x5e\x53\x90\x99\x59\x96\x42\x31\x4c\xf8\x84\xd9\xf4\x09\x98\x2c\x8c\x16\x3b\xcd\x4a\x5d\x30\x35\x93\xe6\x40\xa9\x85\xed\x40\x61\x10\x5a\x7f\xfd\x2f\x2e\x52\x88\xd3\x9a\xc1\xe1\x93\x50\x41\x18\x07\x63\x90\x01\x09\xfe\x77\x43\x2c\x15\x51\x7e\xd2\x65\xb2\x34\x53\x1a\xad\x64\xaa\x47\x86\x15\x8d\xac\xc9\x50\x8f\x8e\xcd\x5f\xdb\x73\xb0\x51\x38\xb5\x7e\x9f\xe9\x8a\x8f\x8e\x4f\x09\x20\x08\x1c\x80\xb2\x58\x7e\x5c\x3a\x74\x73\x05\x1d\xfd\x55\x54\x38\xab\x43\x00\x1a\x14\x95\xab\xef\x79\xc9\x0b\xe6\xaf\x57\xb7\x96\x26\x5f\xe9\x66\x9b\xe1\x13\x72\x26\x08\xcb\x57\x05\x58\xaf\x49\xce\xa8\x73\x89\xb3\x35\x53\x9b\x62\x89\x95\x40\x1c\x03\xf9\xf0\x48\xdf\x0f\xe1\x5b\x77\xd7\x57\x44\x0e\x3b\x6c\x07\xb9\x47\x27\x47\xdb\x8c\xb4\x3a\x11\x3e\x2c\x2a\xe1\x88\x7e\x15\x1a\xef\x4d\xcf\x26\x0a\xed\x23\xcb\x2d\x3d\xff\xb8\xba\x42\xc7\x8a\xc5\xd5\x2f\x5c\xa4\xda\xdf\xa6\x88\x71\xdf\x88\xef\x56\x24\xc3\x08\x3f\x22\x82\x77\x45\xe0\x58\xb1\x35\x00\xde\x49\xfd\x5d\xa0\x82\x00\x50\x75\xb8\x96\x69\xfb\xd6\x69\xac\xef\x65\xad\xb1\x0f\x36\xa8\xec\x2e\x08\x0b\xc5\xdd\xcd\xaa\x55\x27\x08\x2f\x47\x00\xf5\x5d\x23\xa9\x0c\x0e\xc0\x27\x6b\x6f\xc0\x9a\x64\xeb\x9c\x93\xc7\x8c\x2e\x2a\x32\x02\xae\x67\x05\xad\xe9\xfc\xde\x4d\x41\x13\xde\x2e\xf2\xf6\xca\xc4\x7d\x52\xf0\xb8\xc2\x52\x67\x0b\xf3\x91\xd6\x97\xfd\xa2\xb0\x07\xde\x4d\x4d\x31\xce\xc6\x22\x68\xc8\xeb\xc2\xbf\xb3\xd9\xd1\x1a\x25\xb8\x82\x6d\x4e\x31\x85\xf8\x29\x90\x43\xe6\xf7\x0d\x32\xe9\x19\x6f\x07\xd1\x3e\xb1\xcd\xb3\x54\xed\xb5\xd8\x5f\x4d\x5f\xc1\x2f\x66\xf4\x81\x65\xfd\x1b\xe4\x9a\xae\xcc\xb4\xab\x60\x55\xab\xbd\xa3\xaf\xd3\xea\x0f\x36\xae\xcc\xc5\xf2\x49\xb5\xa0\x82\x7f\xb5\x11\xbe\x89\xd9\xc7\x52\x99\x3f\x3f\x59\x7f\x89\xd5\xfd\x33\x96\x14\xc7\x48\x7f\xad\x7c\xaf\x87\x40\x69\x9a\x72\x2b\x3d\x7c\xe9\xa1\xa5\x30\x12\xb8\x78\x7a\x0b\x9c\x07\x36\x56\x3f\xed\x87\x1d\xae\x11\xbc\xb9\x54\x81\x58\xac\x60\xff\x9c\x72\xbc\x99\xf7\xdd\x61\x85\xe5\x94\xbf\x76\x5a\xf6\xb7\x07\x5e\x73\x5a\x94\x8a\x17\xad\x07\x52\xb8\x23\x17\xbf\x94\x0f\x0c\x7d\xcc\x83\xbb\x0b\x08\x35\x3c\xfb\x72\x79\xd8\xe5\x68\xec\x70\xb0\x04\xe0\x00\x8d\xdc\x42\x4a\x41\xf3\x07\xbe\x28\x65\xa9\xb3\x4d\xdd\xb0\x49\xc1\x45\x3e\x21\xe4\xd2\x5a\x76\xc4\x51\x41\xa8\x90\x62\x93\x63\x53\x91\x64\x65\xca\x1a\x10\xc1\x93\xb8\x96\x3c\x25\xb4\x2c\x64\x4e\x0b\x9e\x90\x44\x32\x95\x80\xd7\xb1\x0e\xa9\xd4\x8c\xd0\x8e\xbe\x49\xa9\x0b\x99\x93\x9c\x2a\xbd\xa4\x59\xd6\xb5\xc6\x07\x38\xd5\x42\xe5\xcb\xc7\x30\xff\xce\x97\x6b\x3b\xea\x57\xd2\x77\x4f\xb5\xf6\x08\xfa\x36\x83\xdb\x0b\xc0\xba\x9b\x4a\x23\x60\x60\x9d\x80\xd6\x0a\x48\x3d\x0b\xd3\x87\x9d\xd0\xce\xed\x9d\x57\x80\x1b\x06\xfb\x42\xa0\x2f\x4b\x2f\x73\xba\x88\x10\x24\xaf\x8c\x76\x40\xc5\xc6\x75\xb3\xc5\x3a\xf5\x29\x91\x0a\x23\x4f\xfc\xdd\xea\xf8\xca\x17\x7c\x55\xe4\x16\x5c\x7a\x52\x61\x08\x38\x52\x29\x24\x06\x30\xf5\x28\x55\x6e\xe4\x3a\xae\xc8\x63\x29\xc0\xd0\xa6\x31\x62\x1c\x54\x12\xb4\xd5\xd0\x4c\x4b\xbf\x03\xc1\x47\x28\xdc\x20\x08\xd5\xe4\x99\x65\xd9\x84\x9c\x65\x19\x56\x11\xad\xd5\x8b\xa8\x72\xbe\xab\xb8\x84\x87\x0d\x49\xf9\x82\xe9\x82\x7c\x9a\xff\xfb\xec\x18\x4e\x6d\xb0\x63\x6c\x48\x41\x5d\xca\x5b\xd3\x3e\x03\xe7\x7f\x5a\x82\x9c\x90\xd0\x82\x66\x72\x61\x5d\xf3\x60\xeb\x15\x29\x59\x65\x74\x03\x57\x04\xac\xa8\x82\xa8\xd5\xc4\xda\x68\x88\x2a\x05\x14\x47\xfe\xa6\x27\x4e\x3f\x2b\x08\xd5\x2f\x1e\x03\x4d\xbe\x72\xab\xf7\x54\x89\x7d\xdb\xa3\x4c\xb1\x55\x46\x3b\xac\x0a\x0d\x8a\xbe\x6b\x24\x34\x1b\x31\x17\x54\x58\x29\x98\x87\x31\x21\x73\x4b\x3b\x39\x2d\x12\xeb\x17\xfd\x23\x67\x05\x4d\x69\x41\x27\x46\x17\xfc\xa3\x99\x5d\x27\xb3\xd4\x00\xea\x5e\xe8\x8e\x31\x5b\x79\xb1\xfd\x52\xfd\xe6\x2e\x34\x42\xad\x6f\x0e\xf2\xb9\xdb\x8f\x41\x33\xc6\x9e\xfc\x09\xa6\x7f\xf1\x62\x54\xb1\xa0\x1f\xae\x31\xd6\xed\x4e\x4d\x2b\x43\xd6\x9c\x09\x52\x6b\xce\xa0\xd4\xe4\x1d\xde\xa6\xe4\x9e\x80\x09\xf5\xec\xe6\xbc\xdb\xdc\xd5\x6f\x32\xe8\x31\x11\x34\x9d\x0b\x81\xe1\x39\x03\x33\xbe\x69\x7a\x18\x5c\x4a\x0d\x24\x21\xda\x04\x15\xea\x2a\xca\xb8\xc6\x76\xc1\x9a\xe9\x93\xb6\x5f\xb7\x7d\x24\xca\xc5\x13\xe3\xd8\xe9\xcb\x56\x1b\xfb\xc1\x76\x36\x8a\xf3\xf3\xf4\x66\x94\x75\x65\x8c\x59\xcc\x43\x82\x89\x33\x91\x7a\x64\xc7\xfa\xc5\x22\xed\x3b\x6e\xaa\x03\x06\xea\x97\xb2\x11\xbc\xf4\xc4\x36\x47\x1a\x33\x67\xa4\xd0\x4b\xbe\xb2\x29\x8f\xe8\x86\xc0\xd5\x25\xf7\x34\xe3\xa9\x07\x61\xa9\xfa\x52\x9c\x92\x1b\x59\x98\x7f\x2e\x5e\xb8\x2e\xac\xfa\x79\x2e\x99\xbe\x91\x05\x3c\x39\xc8\x54\xed\x10\x06\x4c\x14\x15\x60\x6b\xc9\x86\x7d\x55\x53\x93\xdd\x84\x2e\x91\xed\x39\xa4\x70\x4d\x2e\x85\x91\x08\x70\x46\x3e\x15\x58\x23\x08\x97\xc7\x22\xa4\x18\x83\x8d\xbb\x15\x06\x22\x42\xaa\x06\x1e\x02\xe0\x10\x94\x0d\x22\x84\x37\x5c\x3b\x26\xee\xcf\x6c\xea\xcc\x6e\x3c\x21\x39\x53\x0b\xf0\xda\x24\x3d\x5e\x8b\x58\x53\x64\x94\x01\xb2\x77\xad\x80\x65\x5e\x75\x1a\x2e\x76\x16\xa9\xd6\xde\xb2\xa5\xdc\x5a\x33\xfe\x34\xdc\x07\x30\xf5\x17\xe4\x83\xeb\x09\x39\x73\x57\xd5\xd4\xdf\xa1\xf7\xaa\x0e\xc6\x40\xe0\x9a\x18\x56\xb2\xa6\x19\xb3\x95\xfa\xa9\xf0\x39\x5b\xf2\x71\x87\xb1\x9f\x62\x5e\xb8\xd9\xb3\x5e\x64\x1a\x3d\xb1\xcd\xe8\x74\x67\x69\x47\x97\x62\x54\x25\xee\x35\x16\xd3\x33\x51\x90\xb6\x46\xf0\x6e\xf4\xfa\xb3\x20\xc8\x2c\xe3\xcd\x2b\xbd\xeb\xa6\x9f\x78\xbb\x0b\xbb\x55\xd8\xf8\xa4\x8f\x0d\x0a\xc1\x6d\xac\x48\x2e\x15\x98\x33\xcd\xd3\x7a\x89\x10\x23\xaa\x3e\xf1\xd5\xaa\xaa\xa8\x52\xae\x16\x8a\xa6\x8c\x2c\x14\x5d\x2d\x87\x8a\x25\x56\xb6\x69\x03\xff\x61\x04\xdd\x0e\xe4\x07\x34\xba\x60\xbf\x67\xf6\xb0\x94\xf2\x09\xd2\xe9\x80\x10\xde\xd0\xfe\xf0\x9b\xfd\xd6\x79\xf5\xcc\xa9\x92\x9a\xa4\xac\xa0\x3c\x83\x78\x90\xdb\xab\x6b\x8c\x18\x71\xe7\xb8\x1b\x65\x7b\xf0\xc5\x01\x14\x00\x9a\x62\x24\xd3\x8c\xad\x39\x7b\x46\xab\x44\x57\xac\xc7\x98\x2c\x98\x80\x00\x87\x40\x20\xd0\x98\x68\x9e\xb2\x0b\x48\xde\xed\x06\xb4\x87\xe1\xbc\x63\xcc\x7d\x9b\x37\xcc\xc1\x7b\xb9\x77\xc4\x29\xeb\xd5\xdf\x2f\x52\x05\x8a\x09\xc5\xe5\x12\xc7\xe5\x09\x63\x34\xfa\x4f\xe4\x87\x1f\xbe\xef\x6c\x94\xd3\x17\x9e\x97\xf9\x4f\xe4\xff\x7f\xfc\xf1\xfb\x1f\xbb\x9b\x71\x61\x9b\xfd\x5f\xf7\xfc\x70\xb7\x4d\x67\xe7\xef\x00\xdf\xa9\x8f\xc8\x0b\x3b\xe5\x22\x40\x3d\x52\x9e\x95\x0a\x63\x41\x23\x55\x84\x9f\xeb\x7d\xc0\xa1\x52\x25\x4f\x50\x07\xd1\x05\x8c\x61\x20\xd9\x23\x17\x4c\xc3\x25\x30\xa5\x50\x2c\x91\x0b\xc1\xbf\xb2\xd4\xdd\x01\x03\x81\x1d\x50\x2d\xde\x91\x38\x61\x22\xb5\x77\x71\x9a\x33\x6f\x49\x45\x9a\x85\x1c\xfe\x11\x33\xad\xef\xe0\xbd\x50\x06\x27\xcf\x20\x84\x5d\x57\x3d\xb6\xd0\x05\x37\x8a\xa2\xfb\xc9\x9e\x68\x16\x6d\x7b\xcd\xd4\x32\xc6\x79\x40\xb1\x6e\x19\xe3\x8e\xde\x67\x55\x56\x78\xf6\x9f\x92\xa9\x0d\x24\x8a\x54\x82\x7d\x2d\x98\xec\xae\xaa\x43\xe0\xa6\x81\x12\x95\x2d\x04\xb3\xa5\x0b\x57\x42\x4c\x15\xee\xb1\xf5\x6d\xe8\xc3\xac\xfb\xdc\x39\x92\xc8\x19\x11\x65\x96\x75\x35\x15\x32\xe4\x72\xaa\xe3\xae\x47\x95\x8c\xd3\xf1\x62\xcd\x02\x2d\x98\xfe\xa6\xc6\x81\xfa\xc4\x0f\x24\xca\xbf\x6f\x73\x41\x7d\xc2\x51\x71\xa1\xf1\x31\xa1\x71\xe5\x6e\x22\xcc\x08\xf6\x37\x24\x68\x34\xb2\x48\xcd\x5b\x1a\x16\xec\x6f\x50\x7c\x4e\x9c\x91\xa1\x65\xe8\xef\xce\xd4\xf0\x8a\xc9\xc7\x98\x1d\x5a\xa6\xfe\x8f\xf1\x61\x07\xe1\xb1\xd1\x50\x03\x22\xa1\x22\x57\x32\xc2\x28\x61\x7f\xff\x98\x26\x06\x9d\x44\x11\x8c\x79\x98\x99\x22\x7a\x55\x15\xe3\x62\x2d\x6d\xb1\xe8\x41\x32\xdc\x6c\xa7\xe3\x96\x28\xf7\x0c\x9c\x15\x65\x39\x2f\xfc\xd6\x45\x5a\xa3\xd0\x92\x52\xf7\x1b\xbb\xc3\x33\x08\xe7\x8f\x1c\x44\x07\x69\xce\xbc\xcc\xd8\x6f\xbc\x58\xde\xba\xe2\xf0\x48\xd5\x45\xb9\xca\x60\xb2\xb5\x17\x86\x84\x66\x95\x64\x78\x69\xaf\x23\x63\x89\xcc\x73\x26\x52\x1b\x44\x94\xd3\x27\x46\xaa\x2b\x2f\x8d\x8c\x07\x62\x30\x80\x63\x2f\x2b\x2a\x2a\x39\x71\x6d\x78\x79\x88\xa2\x22\xe9\x29\xf6\xac\x8d\x4e\xcc\x08\x27\x64\xd4\x32\x2a\x1a\x89\x17\xe4\x81\x65\x12\x52\xb9\x6d\xa4\xa8\x8d\x65\x76\xb9\x0c\x86\x25\xe3\x53\x3c\xf5\xb0\x70\x24\x13\x8b\xaa\x1e\x95\xce\xe0\x72\x5a\xe4\xc0\x52\xb0\x09\x99\xa1\x08\x13\x27\x15\xc5\xb0\xd3\x48\x56\x1a\x7d\x20\x56\xb5\x18\x06\x63\xd6\xf5\xab\xe3\x76\xed\x9e\xc5\x60\xd7\x35\xfe\x5f\xc6\xaf\xbf\xb8\x61\x18\x7a\x9b\x5b\xba\x3a\x15\x3c\x6e\xb7\x98\x57\x62\xaf\x3e\x06\x53\xdd\x98\x4c\x67\x17\x67\x77\x17\xa7\xe4\xd7\x2f\xe7\xf0\xef\xf9\xc5\xd5\x85\xf9\x77\x7a\x7b\x73\x73\x31\xbd\x33\x72\xc4\x89\x2d\x41\x6f\xd4\x38\x83\x5d\x73\x1e\xc9\x26\xb7\xa0\x62\x43\x1e\xcb\xc2\xb0\x83\xea\x63\x8d\x51\x50\x6b\x03\xa0\x69\x6a\x54\xc6\x0f\xb7\x86\xed\x08\xdf\x36\x9b\xd4\xef\xde\xb0\x55\xfb\x31\xe1\xaa\x5f\x4c\x8a\x26\x92\xe8\xac\x83\xc6\x90\x47\xaf\x4c\x37\xf8\x5d\x90\x9f\xa5\x22\x78\x59\x19\xdc\x5e\x99\xea\x23\x4c\xea\x30\xff\x9f\xd8\x47\x9f\x33\xb9\x38\xf2\xb9\x1e\x8c\x64\x72\x41\x74\xf9\xe0\x73\x70\xe0\x34\x85\xd6\x27\xae\x59\x23\x75\xe1\xd4\x27\xe2\xd4\x7a\x79\xe0\x8d\x3e\xf5\x06\x75\xb8\x9f\xe1\x86\xb1\x46\x4b\xf3\x60\x1b\xe0\xc9\xe7\xf6\x11\x38\xc1\x89\xab\xad\x1e\xbf\x0b\x43\xae\xcf\x3c\x4b\x13\xaa\xd2\x1d\x9a\x85\xc3\xcd\x2e\x39\x60\xcf\x96\xdd\xb5\xb7\x41\x57\xc0\xb1\x58\x86\x5c\x33\x95\xd1\x95\x8d\x10\x87\xba\xc7\x10\x7a\x04\x1f\x39\x67\x2b\x06\x79\x50\xee\xb6\x72\x26\x92\x4c\x42\x5d\x0e\x7b\x32\x9e\x36\xa7\x6e\x43\x91\x5c\xf1\x42\x97\x8d\xe7\x77\xc8\xe8\xdd\xb2\x39\x08\x33\x1e\x44\xbd\x36\x30\xb9\xb3\xb8\x8b\xcf\xdb\xb0\x4a\xa3\x97\x7c\x19\x19\x61\x96\xd9\xe8\x94\x8c\x7c\xfd\x92\x14\xa5\xe4\xd1\xc9\xa8\x6a\x50\xcf\x53\x02\x21\x19\x5d\x42\x63\xf8\x4e\x3d\x23\x12\x16\xd8\x39\xae\xfc\xa7\xab\x1a\x34\xe6\x68\x43\x23\x16\x8c\xa1\x09\x68\xd2\x18\xc8\xce\x57\xab\x14\xbb\xde\x2f\x9a\xe1\xd7\xba\x17\x90\xd2\x6e\x53\xf5\x10\x39\x8a\x99\xd5\x70\x01\x69\xf3\x06\xf1\x78\xc7\x5b\xbd\x48\x0e\x57\x64\x45\x95\x51\x45\x5c\xcb\xe6\x35\x67\x27\xbd\x97\x9c\x45\x10\x41\xcd\xbf\x12\x29\xb5\xcf\x7d\x8f\x69\x46\xb5\x6e\xb1\xbc\x02\x23\x30\x80\x09\xb3\x90\x09\x75\xce\x27\xa8\x61\xbd\xa4\xeb\x40\x91\x83\x88\x41\x17\x54\x2d\x58\x11\xf6\x8c\x50\xb1\xb9\x0d\x96\x45\x1b\x47\x17\x62\x1d\xc7\xed\xa6\x97\x71\x55\x84\x6b\xcc\x45\x31\x96\x6a\x6c\xbb\xfc\x44\x0a\x55\x76\xf9\xb8\x0a\x9e\x33\x59\x16\x73\x96\x48\xd1\x9e\xd1\x80\xed\x0e\xe6\xea\x19\x90\xe6\x81\xde\xc6\x33\x27\x46\xd4\x0b\x19\x3a\xc5\xac\x92\x31\x9c\x87\xb1\x59\x8a\xe5\xf6\xea\x7a\x9f\xc5\x26\x90\x0a\x1d\x5e\xc9\x7b\x64\xfb\x62\xe1\x47\x8a\x23\x0f\x76\xbb\x2e\x8b\xe1\x9d\xa6\xde\x73\x15\x6e\x8d\xc8\x08\x97\xd3\xe8\x9c\xbf\x2e\x68\x51\xee\x50\x43\x63\x6d\x90\x59\xce\x6d\x4a\x19\xca\xf4\x73\xe8\x57\x37\xf2\xed\xd6\x10\xb0\x75\x49\xa0\x9d\x0b\x56\x9c\x10\xec\x68\xf6\x67\xa1\x28\xb7\x0a\x24\x4d\x8a\x12\x72\x93\x69\x81\x81\x8d\x58\x44\xe7\xbb\xb6\x69\xb4\xaa\x8c\x21\x35\x31\x61\xaa\xd0\x57\x54\x17\xbf\xae\x52\xda\x91\xbd\xb4\x15\xb0\xa8\x0b\xd8\x30\x56\xb0\x7e\x16\x2c\x35\x1c\x1e\x51\x60\xe1\x91\x67\xc3\x7a\x4b\x0b\x71\xa8\x27\xbf\xda\x40\xa6\xfb\xd8\x7c\xaa\x7d\xd4\x33\x69\x70\x72\xd6\xca\x80\x9a\xa1\x1a\x7d\xa3\x35\xc7\x89\x02\x68\x44\xb0\x97\x36\x8d\x7b\xff\x11\x67\x8c\x8a\xf6\x70\xf9\x2d\x8a\x82\x76\xc3\x69\x08\x3f\x40\x9e\x97\xdc\x88\xac\x36\xcb\x4b\x13\x27\x42\xa5\x2c\x63\x1d\xc9\x5e\x7b\x86\x92\xe2\x17\xce\xf1\x03\x51\x61\x4e\x5f\x9a\x7d\xbc\x41\x1f\x85\x70\x4c\x9e\xa8\x84\x65\x94\x1e\xbc\xd6\xb4\x3d\x2b\x10\x5f\x1e\x32\x99\x3c\xd9\xa2\x62\x90\xcf\xcf\xbf\x32\xe5\xe2\xce\xab\x0b\xc5\xf0\x96\xab\x85\xbb\xc1\xd3\xe1\xcd\x5d\x69\x04\x50\x0c\x6c\x83\x40\x0f\x5f\xaa\xca\xb2\x58\x0a\xcc\x9e\xfb\x36\xa1\xab\x4e\x51\x81\x78\xfd\x86\xe7\x60\x57\x67\xb1\xf5\x47\xa0\xe6\x21\xaa\x8c\x34\xc7\xec\x96\xcf\xbf\x74\x67\x82\x1c\x34\x1c\x35\x94\x8f\x62\x5b\x00\xfa\x44\x12\x2c\x57\x13\xcc\x5c\x89\xb5\x7c\xf5\x64\xa8\x90\x78\x21\xdd\x0f\x39\x06\xda\x41\x83\x0b\x0f\xee\xed\xeb\x4c\x03\xa8\x7e\x43\x7c\x78\xb1\xc5\x56\x07\x79\x99\xc4\x90\xa2\x98\xcd\xe2\x21\x5e\xed\xc0\x24\x4f\xeb\x89\x7f\x94\xaa\x53\x81\x39\xdc\xe0\xc3\xf9\x4c\xbd\x80\x8c\xf4\xd9\x1d\xbb\xb6\x9b\xbc\x63\xb8\x97\xef\x72\x4a\x28\x59\x72\x5d\x48\x85\xae\x35\xb8\x90\x4c\x51\xb8\x30\xb5\x3d\x06\xec\x30\xd1\x70\x53\x3f\x04\x42\x57\x2b\x46\xfd\x5d\x45\x78\x36\xc1\x65\x43\x8a\x25\x52\xa5\xad\x03\x73\xda\x7d\xab\x2c\xd5\xfa\xf9\x03\xe4\x66\x66\x54\x17\x77\x7e\x0c\x46\x40\x88\xe4\xc6\x4d\xf1\x07\xa7\x58\xcd\xc6\x95\x73\x91\xa2\x7a\x29\x09\x15\xd6\xaa\xb1\x9f\x0c\xde\x2f\x64\x54\x73\xb3\xd2\xdc\xab\xe6\xf5\xec\x25\xb7\xda\x14\xbf\xcd\xc8\x73\xa6\x75\x30\xd1\x68\x2b\x48\x03\xea\x02\x13\x5f\x17\x18\xbb\xbb\xc3\xde\x0a\x08\x36\x1c\xd3\x55\xee\xda\x74\x93\x1a\x01\x31\xc1\x1a\x14\xfc\xb6\xda\x6b\xc9\x56\x4b\xaa\x63\x27\xe3\x77\x91\x0f\xf1\x8d\xde\x0e\x91\xa3\x51\x8c\xea\x50\xaa\xe4\x16\x6e\x1f\x14\x67\x8f\x64\x4a\x73\x96\x4d\xa9\x3e\x24\x72\x81\x03\x4c\x08\x9b\x2c\x26\xe4\x68\x56\xf3\xb6\xde\xc8\xe2\x3a\x74\x6f\x43\x4f\x75\x80\x98\x1d\xfd\xa6\x7b\x79\x6f\x25\xa1\x7f\xe7\xee\xb9\x67\xf7\x1e\x61\x60\x87\xbe\x8b\xbd\x19\xce\xf7\xed\xda\x8f\xcd\x9d\x58\x2a\xb0\xf8\x25\xaf\xdd\x91\x3d\xc9\x8c\x5d\xbb\xf0\x3d\xef\xbf\x9e\x29\x79\x10\xf3\x56\x93\xc9\xce\xec\xee\x1a\x9a\x2b\x98\xfd\xeb\x01\x76\x50\xf2\xdb\x8c\x74\x3a\xbf\x3f\xa4\xd8\xf2\xf7\x26\xdb\xe3\x02\x76\xbe\x0f\xc8\xe5\xe3\xf0\x29\xbc\x6f\x22\x7f\x0a\x8e\x16\x43\x01\xdf\x32\x00\xe3\xdc\x7d\x15\x6d\x1d\xbe\x5a\x2f\xfc\xf5\x88\xb7\xa2\x61\x9b\x06\x7d\x7c\x82\xfb\xe7\xd8\xda\x5e\xfa\x08\x09\x1f\x8c\x08\xa6\xcd\xa6\x38\x0e\x7c\x3e\x52\xa1\x8a\x53\xa6\xfa\x15\xdd\x5e\x25\x96\xf4\x2f\xad\x6b\x14\x5a\x60\xfb\x8b\xd5\xd9\x22\x74\xe2\x01\xca\x5a\xbf\xc6\x33\x00\x58\xaf\xf8\x37\x10\x5e\xbb\x01\x77\xfb\xb7\x55\x1d\xd8\x74\x99\x01\x93\xb6\x8e\xe1\xc4\x70\xe0\x04\x6a\x46\x5b\xde\x8d\xec\xa9\x69\xbf\x9d\x6d\xf3\x40\x08\x37\x6c\x52\xf8\xa1\xa6\x55\x96\xfc\x70\x38\xef\xad\xa0\x11\x0d\xef\x1d\x94\x03\xe9\x25\xa0\xb7\x2d\x54\x60\x7f\x7d\x54\xf7\xf7\xd3\x5b\x4c\x41\xa6\x20\x8d\xbd\x51\x65\x16\xcd\xd4\x9a\xa5\x0d\x4f\x1d\xd6\x6e\x6f\x3e\xab\xf9\x6d\x2b\xf8\x88\x76\xf2\xe7\x5f\xdf\xfd\x37\x00\x00\xff\xff\x61\xf0\xd9\xb1\x48\xda\x07\x00") func operatorsCoreosCom_clusterserviceversionsYamlBytes() ([]byte, error) { return bindataRead( @@ -125,7 +125,7 @@ func operatorsCoreosCom_clusterserviceversionsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_installplansYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4b\x93\xdb\x36\x12\xbe\xcf\xaf\xe8\x9a\x1c\x9c\x54\x59\x9a\x24\x7b\x49\xe9\xe6\x9d\x6c\xb6\x66\x37\x0f\x97\x67\xe2\x4b\x36\x87\x16\xd9\x12\x91\x01\x01\x04\x0f\xc9\xda\x54\xfe\xfb\x56\x03\x7c\x4a\x24\x45\x8d\x27\x8e\x6b\x2b\xbc\xd8\x43\x36\x80\x7e\xf7\xd7\x00\x84\x46\xbc\x25\xeb\x84\x56\x2b\x40\x23\xe8\x9d\x27\xc5\x7f\xb9\xe5\xe3\x57\x6e\x29\xf4\xcd\xee\x8b\xab\x47\xa1\xf2\x15\xdc\x06\xe7\x75\xf9\x86\x9c\x0e\x36\xa3\xaf\x69\x23\x94\xf0\x42\xab\xab\x92\x3c\xe6\xe8\x71\x75\x05\x80\x4a\x69\x8f\xfc\xda\xf1\x9f\x00\x99\x56\xde\x6a\x29\xc9\x2e\xb6\xa4\x96\x8f\x61\x4d\xeb\x20\x64\x4e\x36\x4e\x5e\x2f\xbd\xfb\x7c\xf9\xd5\xf2\xf3\x2b\x80\xcc\x52\x1c\xfe\x20\x4a\x72\x1e\x4b\xb3\x02\x15\xa4\xbc\x02\x50\x58\xd2\x0a\x84\x72\x1e\xa5\x34\x12\x95\x5b\x6a\x43\x16\xbd\xb6\x6e\x99\x69\x4b\x9a\xff\x29\xaf\x9c\xa1\x8c\xd7\xde\x5a\x1d\xcc\x0a\x06\x69\xd2\x6c\x35\x8b\xe8\x69\xab\xad\xa8\xff\x06\x58\x80\x96\x65\xfc\x7f\x12\xfd\x2e\x2d\xfa\x5a\xa2\x8a\x6f\xa5\x70\xfe\xdf\xc7\x5f\xbe\x15\xce\xc7\xaf\x46\x06\x8b\xb2\xcf\x6a\xfc\xe0\x0a\x6d\xfd\xf7\xed\xc2\xbc\x90\x30\xe9\x93\x50\xdb\x20\xd1\xf6\x46\x5d\x01\xb8\x4c\x1b\x5a\x41\x1c\x64\x30\xa3\xfc\x0a\xa0\x52\x5a\x35\xc9\x02\x30\xcf\xa3\x21\x50\xbe\xb6\x42\x79\xb2\xb7\x5a\x86\x52\x35\x8b\x30\x4d\x4e\x2e\xb3\xc2\xf8\xa8\xec\x87\x82\x60\x23\xac\xf3\x70\x7b\xff\x16\x84\x02\x5f\x50\x94\x09\xf4\x06\x32\x19\x9c\x27\x7b\x4f\x76\x27\x32\xaa\x7c\x23\xae\xdf\x4c\x07\xf0\x8b\xd3\xea\x35\xfa\x62\x05\x4b\x56\xf7\x72\x7c\xd0\x4f\x9f\xff\xdc\x19\x97\x6c\x78\x7b\xff\xb6\xf3\xce\x1f\x58\x42\xe7\xad\x50\xdb\x29\x8e\xd1\x18\xab\x77\x28\xa1\xd4\x39\x4d\xf0\x52\xd3\x9d\x2c\xfb\xea\xf4\xc3\xc8\xda\xc3\x53\x46\xe5\x0f\x4d\xd9\xfb\x90\xa6\x5c\x6b\x2d\xa9\xf2\x96\x9a\x78\xf7\x05\x4a\x53\xe0\x17\xd5\x4b\x97\x15\x54\x62\x6b\x24\x6d\x48\xbd\x7a\x7d\xf7\xf6\x6f\xf7\x47\x1f\xa0\xaf\x8b\x8e\xcb\x41\xce\x51\x48\x2e\x1a\xb0\x72\x9c\x18\x3d\x6c\x48\x04\x47\xd1\xa2\x6d\x04\x9c\xb0\xa9\xd7\xbf\x50\xe6\x3b\xaf\x2d\xfd\x1a\x84\xa5\xbc\xbb\x3a\x6b\xa4\x8e\xf1\xa3\xd7\xac\x9d\xce\x2b\x63\x79\x2d\xdf\x89\xa4\xf4\x74\x92\x4c\xef\xfd\x91\x64\x2f\x58\xfc\x44\xd7\x93\xac\x72\x78\xca\x2b\x9d\xb1\x50\xbe\x10\x0e\x2c\x19\x4b\x8e\x94\x6f\x85\x56\x95\x4c\x4b\x60\x67\x24\xeb\x38\xea\x82\xcc\x39\x11\xed\xc8\x7a\xb0\x94\xe9\xad\x12\xff\x6d\x66\x73\xe0\x75\x8a\x00\xf4\xe4\x3c\xc4\x10\x52\x28\x61\x87\x32\xd0\x4b\x40\x95\x43\x89\x07\xb0\xc4\xf3\x42\x50\x9d\x19\x22\x89\x5b\xc2\x77\xda\xb2\x01\x36\x7a\x05\x85\xf7\xc6\xad\x6e\x6e\xb6\xc2\xd7\x29\x34\xd3\x65\x19\x94\xf0\x87\x9b\x98\x0d\xc5\x3a\xb0\x35\x6e\x72\xda\x91\xbc\x71\x62\xbb\x40\x9b\x15\xc2\x53\xe6\x83\xa5\x1b\x34\x62\x11\x99\x55\x31\x8d\x2e\xcb\xfc\x13\x5b\x25\x5d\xf7\xe2\x48\x7d\x83\xfe\x0b\x75\xde\x9a\xd4\x35\xe7\x2f\x10\x8e\xdd\x24\x0e\x4f\xb2\xb4\x2a\xe5\x57\xac\x95\x37\xff\xb8\x7f\x80\x9a\x81\xa4\xf6\xa4\xe1\x96\xd4\xb5\xca\x66\x45\x09\xb5\x21\x9b\x28\x37\x56\x97\x71\x16\x52\xb9\xd1\x42\xf9\xf8\x47\x26\x05\x29\x0f\x2e\xac\x4b\xe1\x5d\xf4\x39\x72\x9e\xed\xb0\x84\xdb\x58\x41\x60\x4d\x10\x4c\x8e\x9e\xf2\x25\xdc\x29\xb8\xc5\x92\xe4\x2d\x3a\xfa\xc3\x55\xcd\x1a\x75\x0b\x56\xdf\x7c\x65\x77\x0b\xe0\xe9\x80\x93\x18\x03\xa8\x4b\xd4\xa8\x75\x3a\x31\x7e\x6f\x28\x6b\xa2\xa1\x89\xe9\x57\xc6\x48\x91\x25\xb7\x6f\xbc\x83\x1d\x79\xdd\x24\x82\x5e\x56\x9a\x64\x67\x2c\xec\x21\x95\x97\xd3\xb4\xd9\xff\x74\xb2\x10\x7f\x9a\x55\x46\x60\x22\x67\x40\xcc\x1b\x69\xe9\xd3\x2f\x47\xfa\xaa\x53\x3b\x3b\x34\x7b\x58\x70\x64\xdb\x82\x61\xb4\x14\xd9\x01\x36\xda\x72\x7e\xe8\xe8\x76\x09\x77\x1e\xca\xe0\xa2\xbf\x69\x45\xac\xd9\xeb\x57\xc1\xeb\x12\xbd\xc8\xae\x41\x5b\xb8\xfe\x0e\x55\x40\x79\xbd\x1c\x60\x61\xd4\x21\x5a\xde\x87\x54\x3a\x5c\x23\xda\x67\x5c\x75\xe3\x73\xa1\xb5\x78\x18\xf8\x2a\x3c\x95\x83\xc3\xce\x70\xbf\x25\xc5\x45\x63\x20\x63\xb7\x43\x39\x51\x6e\xc9\x9e\x7c\x4f\xde\x38\x3e\x6e\x64\xc9\x34\xac\x41\x3a\x17\x8d\x77\x1e\x7d\x38\x91\xb3\xe7\x22\xd7\xdd\x98\x8a\xe4\x9d\x04\x56\x15\xd0\x8d\xb6\x65\x8a\x29\x5c\xeb\x90\x92\x55\x9a\x9a\x3d\xc3\x79\x32\xae\x09\x15\x0e\xb6\x4c\x97\x46\x92\xef\xd7\xde\x25\xfc\x47\x41\xb5\x02\xa7\x43\x6f\x51\xc8\x38\x15\x66\x3e\xa0\x8c\x33\x52\x55\xa1\x0f\xce\x53\xb9\xbc\x7e\x9e\x48\xcd\xd0\xa3\xd4\xdb\xfb\x94\x0d\x06\x08\x4c\x81\x8e\x2e\x89\x3f\xef\x49\x05\xce\xc2\x95\x33\xbe\xca\x32\x1d\x94\x7f\x43\x9b\xf3\x21\x39\x3e\x16\x2c\x6d\xc8\x92\xca\xaa\xfa\xee\x12\x01\x60\xa2\x00\x5f\xa0\xe7\x48\x0e\x2e\xa9\x39\xd7\x09\x07\xe7\x0d\x94\xa9\x15\x3e\x1e\x95\x83\xca\x3b\x27\x2f\x4c\x62\x95\x61\x31\x5f\xdf\xd5\xf8\x24\xc1\x12\xaa\xa5\xf3\x43\xcc\xc1\xb9\x28\xe0\x67\x23\x48\xe6\x11\x7f\xce\xe1\xe0\xc5\x5d\xa5\xd0\x58\xc5\xbd\x06\x04\x23\x28\xa3\x1e\x1c\x8a\x0a\x23\xcc\xab\x97\x5c\xf0\x2c\x55\xdf\x5e\xa6\x5a\x5d\xc1\x80\x16\x2e\x79\x14\x0a\x90\x71\x81\xc8\xe1\x5f\xf7\x3f\x7c\x7f\xf3\x4f\x9d\x78\x63\x4b\x91\x73\xc9\x93\x4b\x52\xfe\x25\xb8\x90\x15\x80\x8e\x59\x63\xf7\x64\xff\xa7\x65\x89\x4a\x6c\xc8\xf9\x65\x35\x1b\x59\xf7\xd3\x97\x3f\x2f\xe1\x1b\x6d\x81\xde\x21\x07\xcf\x4b\x10\x49\x6b\x0d\xa8\xa8\x5c\x23\xa6\x72\x16\xa6\x19\x0b\x7b\xe1\x8b\xc8\x92\xd1\x79\xc5\xf4\x3e\x32\xeb\xf1\x91\xf3\x77\x62\x36\x70\x2f\xf3\x48\x2b\xb8\x4e\xad\x49\xb3\xf4\x6f\x0c\xc3\x7f\xbf\x86\x4f\xf7\x05\x59\x82\x6b\xfe\xf3\x3a\x2d\xd8\x60\x40\x7e\x57\xdb\xb1\x5d\x38\x3a\xa4\xb7\x62\xbb\xa5\x18\xf9\x0c\x68\x18\x34\x7c\xc6\x15\x42\x6c\x40\xe9\x0e\x71\x9c\x82\xf5\x69\x28\x13\x1b\x41\xf9\x09\x23\x3f\x7d\xf9\xf3\x35\x7c\xda\x97\x0b\x84\xca\xe9\x1d\x7c\x99\xda\x31\xe1\x58\xc6\xcf\x96\xf0\x10\x2d\x73\x50\x1e\xdf\xf1\x9c\x59\xa1\x1d\x29\xd0\x4a\x1e\x98\xe3\x02\x77\x04\x4e\x97\x04\x7b\x92\x72\x91\x50\x42\x0e\x7b\x3c\xb0\x0c\xb5\x2a\xd9\xaa\x08\x06\xad\x3f\x42\xc8\x0f\x3f\x7c\xfd\xc3\x2a\xad\xc6\x66\xdb\x2a\x5e\x82\xd1\xd7\x46\x30\xfe\x65\xe0\x9b\x50\x5c\xb4\x39\x33\x12\x92\x91\x38\xf5\x15\xa8\xb6\x54\x37\x8f\x9b\xc0\x78\x6a\x79\x8c\x98\x66\x7b\xfc\x10\x5c\x1d\x76\xf6\x08\x5b\x8f\x03\xed\x4f\x04\x85\xb3\x45\x8c\x3d\xe0\x2c\x11\xbf\xef\xf8\xe0\xa4\x88\x8f\x61\x4d\x56\x91\xa7\x28\x65\xae\x33\xc7\x02\x66\x64\xbc\xbb\xd1\x3b\x4e\xaa\xb4\xbf\xd9\x6b\xfb\x28\xd4\x76\xc1\x4e\xb6\x48\x96\x77\x37\x71\xf7\xe3\xe6\x93\xf8\xcf\x7b\x49\x34\x5a\xaa\x87\xc5\x8a\xe4\x1f\x42\x36\x5e\xc7\xdd\x3c\x59\xb4\x1a\x52\x5f\x52\x09\x5e\xdc\xa7\x80\xcf\x8e\x47\x73\xb8\xec\x0b\x91\x15\x75\xd3\xda\xc9\x70\x25\xe6\x29\x05\xa2\x3a\xfc\xe1\x6e\xcc\x0a\x0c\x96\xd7\x3e\x2c\xaa\x7d\xb9\x05\xaa\x9c\xff\xef\x84\xf3\xfc\xfe\xc9\x1a\x0b\x62\x66\x00\xff\x78\xf7\xf5\x87\x71\xee\x20\x9e\x18\xad\xeb\xa0\x72\x49\xdf\x6a\xfd\x18\xcc\x20\x48\xe8\x09\xf4\xf7\x2e\x75\xdd\x7f\x54\x5d\x9a\x50\x0b\x63\xf5\xd6\x72\xad\xec\x74\xb9\x60\x82\x4c\xe9\x35\x28\x83\xd9\x23\x6e\xa9\x5a\x34\x96\x11\xee\x8d\xab\x72\x54\xb5\x02\xe3\x30\xe7\x09\xb8\x7f\x94\xfb\xb4\x1b\x50\xf1\x39\xc2\x66\x5d\x17\x99\xc7\x88\x60\x2b\xbe\xcf\xf3\x7b\x16\x98\x4d\x61\xdb\xf4\x1c\x21\xdc\x37\xb4\x19\x25\x14\x39\xfb\xfd\x46\x0c\xb4\x27\x35\x89\x41\x5f\x8c\x7e\xb4\x64\x24\x0e\x81\x68\x98\x01\x21\xe1\x84\xcf\x31\xba\x23\x6b\xdc\x1e\x0d\xab\x2d\x52\x27\x8c\x4a\xcb\x3d\xb2\xf8\xa6\xb2\x02\x8b\x04\x7b\x74\x31\x03\xc9\x1d\xe5\x71\x03\x66\x0c\x87\xce\xb0\xc8\x3c\x69\x61\x16\x6c\x1e\x90\xf7\x09\xe0\xb9\xcb\xf8\x44\x3a\x4a\xcf\x59\x20\x3d\xc0\xd3\x5f\x70\xfa\x2f\x38\xfd\x91\xc3\xe9\x8b\x62\x60\x0a\x5a\x0f\xb9\xff\xc7\x0a\xb0\x2f\x12\x7a\x0a\x6c\x0f\x09\xfd\x91\x40\xee\x8b\x65\x9c\x84\xdf\x63\x82\x7e\x24\x20\xfc\x22\x61\x67\x02\xf2\x21\x91\xff\x9f\x61\xf9\x45\x3a\x9c\x80\xe8\x43\x7a\xfb\x28\x80\xfa\x6c\x01\x33\xad\xd2\x29\xf8\x04\x4a\xe9\x63\xad\x66\xc0\xf1\x3e\x30\x33\x8d\xb2\xb7\x4f\xdb\x85\xc9\xe7\xe0\xd4\x18\x24\x4f\xcf\x04\x30\xef\x4e\x72\x06\x93\x9d\xc7\xca\xe9\x59\x54\xdb\xd7\x67\x88\x78\xcd\x09\x92\x79\x08\x10\x40\xa2\xf3\x0f\x16\x95\x13\xf5\x0d\x8e\x69\xfa\x23\x8b\x7c\x8b\xdc\x76\x88\xb2\xe9\x32\x92\x7d\xc0\x37\x53\x56\x80\x36\x1e\xd5\x54\xfb\xf2\x8c\x69\x94\xf6\xc5\x58\xd3\xd1\x3e\x33\xa3\x84\x9f\x74\x0e\xb0\x82\x1c\x3d\x2d\x98\xa3\xb3\x62\xff\x18\x0f\x2b\x9f\x4d\x64\xc6\xf0\xc6\xea\x35\xe5\x7f\x9a\x54\x25\x39\x87\xdb\xcb\xc4\x79\x05\x45\x28\x51\x81\x25\xcc\x71\x2d\xa9\x9e\x84\xd1\x58\x3c\xad\x54\x5b\xc8\xc9\xa3\x90\xae\x73\xc2\xd2\xda\xf7\xd9\x84\xb5\x84\xee\x5c\x95\x80\xd3\x2b\x26\x69\x58\x3c\x28\xec\xd9\xe3\x85\x8b\x46\xfe\x23\x38\x1d\x3e\xb9\x9a\xe4\xf4\xbe\x39\x91\xea\x31\xf9\xb2\x3e\xc1\x7c\xb0\x81\x5e\xc2\x37\x28\x1d\xbd\x84\x1f\xd5\xa3\xd2\xfb\xe7\xe3\x37\x12\x5e\xa4\xd7\x83\x89\x5c\x35\x7c\x3e\x03\x2b\x6d\x77\x3f\x33\xd9\xdf\x35\x03\xea\x1d\x9a\xaa\x43\x5f\x04\x25\x7e\x0d\xfd\x46\xa5\x39\x64\xfa\xf4\xb8\x85\xb9\xbd\x7f\x1b\x9d\x23\xb5\xdb\x2e\x35\x32\x75\x6b\x77\x7b\xff\xd6\x7d\x76\xa6\x36\x4c\x4a\x65\x26\x1b\xd5\x9e\x3c\xdc\xd3\x1e\xb5\x5a\x52\x67\x9d\xab\x3f\xed\xb6\x8c\x09\x52\x2e\xe1\xce\xbf\x70\xcc\x83\xc8\x50\xca\x03\x77\x2d\xa2\xe4\xc0\x6c\x50\xcf\xb9\xaa\x36\xcd\xf9\x8c\x02\x71\x12\x6c\xb4\xd9\x50\xe6\xc5\x8e\x3a\xc3\x6b\x45\xa7\x0d\x27\xca\x2b\x39\xde\x8b\xb9\x7a\x2b\x67\x26\x6b\x6f\x2a\xf2\xda\x51\xba\xf6\x6f\xb5\x5a\x4d\x9a\x7a\xcd\xe8\x34\x8a\x60\xa3\x83\xca\x01\x7d\x34\xcf\x13\x79\xee\x9f\xe1\x7e\xb8\x03\xff\x69\xfc\xf4\x3c\x9b\x8d\x9d\x13\xf8\x06\x7d\x4d\x81\xaf\x36\xc9\xd1\x3b\xca\x42\xe7\x8e\x57\xf7\x0e\xc7\xd3\xf6\x1a\xcf\xbb\xec\x25\x68\x66\x56\xfa\x9c\x5b\x7f\xe7\xe2\x89\x67\x5d\xf4\x6c\xb9\x9f\x15\x69\xd3\x55\x77\x18\x7f\xbf\x49\x45\x37\x6e\x75\x66\x58\x92\xcc\xd0\x51\x7e\x5c\x8b\x13\x18\x9f\x53\x80\x67\x30\x7a\xae\xe8\xce\x98\x62\xba\x0e\x9e\x75\xfb\x58\x15\x13\xd5\xba\xbe\x05\xd1\xb4\x1b\x3d\xff\xe6\x7c\x82\x90\x91\x8d\x45\x26\x5d\xa2\x43\xd6\xd5\xbe\xd0\x4f\xce\x8c\x13\xd6\xee\xb1\xfe\x5d\x8d\xdf\x78\xc1\x88\xed\x16\x27\xd8\xae\xaa\x7f\x2d\xb6\xa3\xbc\x77\x95\x26\x16\xc9\x12\x0f\xf1\x6a\x5a\x69\xb4\xf5\x98\x0e\x38\x82\xca\xc9\x3a\x8f\x2a\xe7\xb1\xfb\xe2\x10\xd5\x60\x58\xe6\x02\x1d\x08\xef\x20\xf5\xc5\xbe\x32\xd8\xc5\x77\xb0\xe2\x7d\x97\xb3\x42\x76\x94\xfd\x9a\x07\x34\x10\xa1\xb7\x78\xaa\xab\x3d\xc3\x4c\x5a\x61\x9a\x31\x89\x13\x17\xab\xde\x37\xcf\xde\x7b\x32\xc7\x79\xb5\x23\x84\x8a\x70\x7c\x27\xf2\x74\x19\x89\x0c\x08\xf5\x3c\x49\xf5\xfc\x01\x4e\x3a\x98\x18\x0f\xab\x45\xb3\x4b\x33\x4a\x30\xd1\xd1\x9e\x4f\xea\xda\xa4\x9b\xf2\xe7\x62\x7f\xec\x6e\x5e\x7a\x1a\x29\xde\x33\x5d\x8e\xdf\x94\x4b\xcf\x89\x55\xeb\x5f\x5f\x4c\x58\xb7\x73\x57\x37\xde\x06\xf5\xb6\x42\x52\x87\x59\x36\x86\xb9\x5b\x10\x73\x36\x20\x16\xe9\x47\x18\x93\x14\x8f\x42\x9d\xde\x1f\xed\x12\x30\x00\x9b\x24\x68\x2f\x0e\xce\x24\x8b\x1b\x93\x93\xb4\xd5\xa1\xd4\x7b\x9e\x89\xa5\x5f\xa0\x7c\x98\x4d\xfc\x99\x13\xd5\x47\x48\xcf\x32\xd9\xf9\x5d\xf6\x99\x13\xb5\xa6\x79\xe6\xe9\x66\xec\x8f\xcf\x9c\x73\x37\x67\xe3\xf9\x19\xa0\xc7\x49\xc8\x57\xdd\xfe\x44\x4d\x32\x68\xbd\xc8\x82\x44\xdb\xc6\x7e\x4c\xf2\x27\xbf\x5b\xba\x98\x67\xe7\xd1\xfa\x31\x14\x7a\xbc\x29\x91\x28\x6b\x4e\xe3\xae\xd6\xbe\x20\xd5\x1c\xfe\xa5\x9f\x81\xc1\x9a\xb6\x5c\x3c\x8d\x91\x87\xfa\x37\x06\xed\x0d\x76\x29\x9c\x8f\xf8\xa1\xc5\x02\x73\xaf\x42\x8c\xaa\x7d\x0c\x02\x3b\xb2\x3b\xca\x57\xe0\x6d\x68\x5e\x79\x6d\x19\x17\xf5\xde\x85\x75\xc3\x5f\xab\x86\xca\x8e\xf0\xdb\xef\x57\xff\x0b\x00\x00\xff\xff\xae\xb2\xfa\x2c\x43\x37\x00\x00") +var _operatorsCoreosCom_installplansYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4b\x93\x1b\xb7\x11\xbe\xef\xaf\xe8\x5a\x1f\x64\x57\x89\x5c\xdb\xb9\x24\xbc\x29\xeb\x38\xb5\x89\x1f\x2a\xed\x5a\x17\xc7\x87\xe6\x4c\x93\x03\x2f\x06\x80\xf1\x20\xc5\xb8\xfc\xdf\x53\x0d\xcc\x93\x9c\x19\x0e\x57\x6b\x59\x95\xf2\x5c\xa4\x9d\x69\x00\xfd\xee\xaf\x01\x10\x8d\x78\x4b\xd6\x09\xad\x56\x80\x46\xd0\x3b\x4f\x8a\xff\x72\xcb\xc7\xbf\xba\xa5\xd0\x37\xbb\x2f\xae\x1e\x85\xca\x57\x70\x1b\x9c\xd7\xe5\x1b\x72\x3a\xd8\x8c\xbe\xa2\x8d\x50\xc2\x0b\xad\xae\x4a\xf2\x98\xa3\xc7\xd5\x15\x00\x2a\xa5\x3d\xf2\x6b\xc7\x7f\x02\x64\x5a\x79\xab\xa5\x24\xbb\xd8\x92\x5a\x3e\x86\x35\xad\x83\x90\x39\xd9\x38\x79\xbd\xf4\xee\xf3\xe5\xdf\x96\x9f\x5f\x01\x64\x96\xe2\xf0\x07\x51\x92\xf3\x58\x9a\x15\xa8\x20\xe5\x15\x80\xc2\x92\x56\x20\x94\xf3\x28\xa5\x91\xa8\xdc\x52\x1b\xb2\xe8\xb5\x75\xcb\x4c\x5b\xd2\xfc\x4f\x79\xe5\x0c\x65\xbc\xf6\xd6\xea\x60\x56\x30\x48\x93\x66\xab\x59\x44\x4f\x5b\x6d\x45\xfd\x37\xc0\x02\xb4\x2c\xe3\xff\x93\xe8\x77\x69\xd1\xd7\x12\x55\x7c\x2b\x85\xf3\xff\x3e\xfe\xf2\x8d\x70\x3e\x7e\x35\x32\x58\x94\x7d\x56\xe3\x07\x57\x68\xeb\xbf\x6b\x17\xe6\x85\x84\x49\x9f\x84\xda\x06\x89\xb6\x37\xea\x0a\xc0\x65\xda\xd0\x0a\xe2\x20\x83\x19\xe5\x57\x00\x95\xd2\xaa\x49\x16\x80\x79\x1e\x0d\x81\xf2\xb5\x15\xca\x93\xbd\xd5\x32\x94\xaa\x59\x84\x69\x72\x72\x99\x15\xc6\x47\x65\x3f\x14\x04\x1b\x61\x9d\x87\xdb\xfb\xb7\x20\x14\xf8\x82\xa2\x4c\xa0\x37\x90\xc9\xe0\x3c\xd9\x7b\xb2\x3b\x91\x51\xe5\x1b\x71\xfd\x66\x3a\x80\x9f\x9d\x56\xaf\xd1\x17\x2b\x58\xb2\xba\x97\xe3\x83\x7e\xfc\xfc\xa7\xce\xb8\x64\xc3\xdb\xfb\xb7\x9d\x77\xfe\xc0\x12\x3a\x6f\x85\xda\x4e\x71\x8c\xc6\x58\xbd\x43\x09\xa5\xce\x69\x82\x97\x9a\xee\x64\xd9\x57\xa7\x1f\x46\xd6\x1e\x9e\x32\x2a\x7f\x68\xca\xde\x87\x34\xe5\x5a\x6b\x49\x95\xb7\xd4\xc4\xbb\x2f\x50\x9a\x02\xbf\xa8\x5e\xba\xac\xa0\x12\x5b\x23\x69\x43\xea\xd5\xeb\xbb\xb7\x7f\xb9\x3f\xfa\x00\x7d\x5d\x74\x5c\x0e\x72\x8e\x42\x72\xd1\x80\x95\xe3\xc4\xe8\x61\x43\x22\x38\x8a\x16\x6d\x23\xe0\x84\x4d\xbd\xfe\x99\x32\xdf\x79\x6d\xe9\x97\x20\x2c\xe5\xdd\xd5\x59\x23\x75\x8c\x1f\xbd\x66\xed\x74\x5e\x19\xcb\x6b\xf9\x4e\x24\xa5\xa7\x93\x64\x7a\xef\x8f\x24\x7b\xc1\xe2\x27\xba\x9e\x64\x95\xc3\x53\x5e\xe9\x8c\x85\xf2\x85\x70\x60\xc9\x58\x72\xa4\x7c\x2b\xb4\xaa\x64\x5a\x02\x3b\x23\x59\xc7\x51\x17\x64\xce\x89\x68\x47\xd6\x83\xa5\x4c\x6f\x95\xf8\x6f\x33\x9b\x03\xaf\x53\x04\xa0\x27\xe7\x21\x86\x90\x42\x09\x3b\x94\x81\x5e\x02\xaa\x1c\x4a\x3c\x80\x25\x9e\x17\x82\xea\xcc\x10\x49\xdc\x12\xbe\xd5\x96\x0d\xb0\xd1\x2b\x28\xbc\x37\x6e\x75\x73\xb3\x15\xbe\x4e\xa1\x99\x2e\xcb\xa0\x84\x3f\xdc\xc4\x6c\x28\xd6\x81\xad\x71\x93\xd3\x8e\xe4\x8d\x13\xdb\x05\xda\xac\x10\x9e\x32\x1f\x2c\xdd\xa0\x11\x8b\xc8\xac\x8a\x69\x74\x59\xe6\x9f\xd8\x2a\xe9\xba\x17\x47\xea\x1b\xf4\x5f\xa8\xf3\xd6\xa4\xae\x39\x7f\x81\x70\xec\x26\x71\x78\x92\xa5\x55\x29\xbf\x62\xad\xbc\xf9\xc7\xfd\x03\xd4\x0c\x24\xb5\x27\x0d\xb7\xa4\xae\x55\x36\x2b\x4a\xa8\x0d\xd9\x44\xb9\xb1\xba\x8c\xb3\x90\xca\x8d\x16\xca\xc7\x3f\x32\x29\x48\x79\x70\x61\x5d\x0a\xef\xa2\xcf\x91\xf3\x6c\x87\x25\xdc\xc6\x0a\x02\x6b\x82\x60\x72\xf4\x94\x2f\xe1\x4e\xc1\x2d\x96\x24\x6f\xd1\xd1\xef\xae\x6a\xd6\xa8\x5b\xb0\xfa\xe6\x2b\xbb\x5b\x00\x4f\x07\x9c\xc4\x18\x40\x5d\xa2\x46\xad\xd3\x89\xf1\x7b\x43\x59\x13\x0d\x4d\x4c\xbf\x32\x46\x8a\x2c\xb9\x7d\xe3\x1d\xec\xc8\xeb\x26\x11\xf4\xb2\xd2\x24\x3b\x63\x61\x0f\xa9\xbc\x9c\xa6\xcd\xfe\xa7\x93\x85\xf8\xd3\xac\x32\x02\x13\x39\x03\x62\xde\x48\x4b\x9f\x7e\x39\xd2\x57\x9d\xda\xd9\xa1\xd9\xc3\x82\x23\xdb\x16\x0c\xa3\xa5\xc8\x0e\xb0\xd1\x96\xf3\x43\x47\xb7\x4b\xb8\xf3\x50\x06\x17\xfd\x4d\x2b\x62\xcd\x5e\xbf\x0a\x5e\x97\xe8\x45\x76\x0d\xda\xc2\xf5\xb7\xa8\x02\xca\xeb\xe5\x00\x0b\xa3\x0e\xd1\xf2\x3e\xa4\xd2\xe1\x1a\xd1\x3e\xe3\xaa\x1b\x9f\x0b\xad\xc5\xc3\xc0\x57\xe1\xa9\x1c\x1c\x76\x86\xfb\x2d\x29\x2e\x1a\x03\x19\xbb\x1d\xca\x89\x72\x4b\xf6\xe4\x7b\xf2\xc6\xf1\x71\x23\x4b\xa6\x61\x0d\xd2\xb9\x68\xbc\xf3\xe8\xc3\x89\x9c\x3d\x17\xb9\xee\xc6\x54\x24\xef\x24\xb0\xaa\x80\x6e\xb4\x2d\x53\x4c\xe1\x5a\x87\x94\xac\xd2\xd4\xec\x19\xce\x93\x71\x4d\xa8\x70\xb0\x65\xba\x34\x92\x7c\xbf\xf6\x2e\xe1\x3f\x0a\xaa\x15\x38\x1d\x7a\x8b\x42\xc6\xa9\x30\xf3\x01\x65\x9c\x91\xaa\x0a\x7d\x70\x9e\xca\xe5\xf5\xf3\x44\x6a\x86\x1e\xa5\xde\xde\xa7\x6c\x30\x40\x60\x0a\x74\x74\x49\xfc\x79\x4f\x2a\x70\x16\xae\x9c\xf1\x55\x96\xe9\xa0\xfc\x1b\xda\x9c\x0f\xc9\xf1\xb1\x60\x69\x43\x96\x54\x56\xd5\x77\x97\x08\x00\x13\x05\xf8\x02\x3d\x47\x72\x70\x49\xcd\xb9\x4e\x38\x38\x6f\xa0\x4c\xad\xf0\xf1\xa8\x1c\x54\xde\x39\x79\x61\x12\xab\x0c\x8b\xf9\xfa\xae\xc6\x27\x09\x96\x50\x2d\x9d\x1f\x62\x0e\xce\x45\x01\x3f\x1b\x41\x32\x8f\xf8\x73\x0e\x07\x2f\xee\x2a\x85\xc6\x2a\xee\x35\x20\x18\x41\x19\xf5\xe0\x50\x54\x18\x61\x5e\xbd\xe4\x82\x67\xa9\xfa\xf6\x32\xd5\xea\x0a\x06\xb4\x70\xc9\xa3\x50\x80\x8c\x0b\x44\x0e\xff\xba\xff\xfe\xbb\x9b\x7f\xea\xc4\x1b\x5b\x8a\x9c\x4b\x9e\x5c\x92\xf2\x2f\xc1\x85\xac\x00\x74\xcc\x1a\xbb\x27\xfb\x3f\x2d\x4b\x54\x62\x43\xce\x2f\xab\xd9\xc8\xba\x1f\xbf\xfc\x69\x09\x5f\x6b\x0b\xf4\x0e\x39\x78\x5e\x82\x48\x5a\x6b\x40\x45\xe5\x1a\x31\x95\xb3\x30\xcd\x58\xd8\x0b\x5f\x44\x96\x8c\xce\x2b\xa6\xf7\x91\x59\x8f\x8f\x9c\xbf\x13\xb3\x81\x7b\x99\x47\x5a\xc1\x75\x6a\x4d\x9a\xa5\x7f\x65\x18\xfe\xdb\x35\x7c\xba\x2f\xc8\x12\x5c\xf3\x9f\xd7\x69\xc1\x06\x03\xf2\xbb\xda\x8e\xed\xc2\xd1\x21\xbd\x15\xdb\x2d\xc5\xc8\x67\x40\xc3\xa0\xe1\x33\xae\x10\x62\x03\x4a\x77\x88\xe3\x14\xac\x4f\x43\x99\xd8\x08\xca\x4f\x18\xf9\xf1\xcb\x9f\xae\xe1\xd3\xbe\x5c\x20\x54\x4e\xef\xe0\xcb\xd4\x8e\x09\xc7\x32\x7e\xb6\x84\x87\x68\x99\x83\xf2\xf8\x8e\xe7\xcc\x0a\xed\x48\x81\x56\xf2\xc0\x1c\x17\xb8\x23\x70\xba\x24\xd8\x93\x94\x8b\x84\x12\x72\xd8\xe3\x81\x65\xa8\x55\xc9\x56\x45\x30\x68\xfd\x11\x42\x7e\xf8\xfe\xab\xef\x57\x69\x35\x36\xdb\x56\xf1\x12\x8c\xbe\x36\x82\xf1\x2f\x03\xdf\x84\xe2\xa2\xcd\x99\x91\x90\x8c\xc4\xa9\xaf\x40\xb5\xa5\xba\x79\xdc\x04\xc6\x53\xcb\x63\xc4\x34\xdb\xe3\x87\xe0\xea\xb0\xb3\x47\xd8\x7a\x1c\x68\x7f\x20\x28\x9c\x2d\x62\xec\x01\x67\x89\xf8\x5d\xc7\x07\x27\x45\x7c\x0c\x6b\xb2\x8a\x3c\x45\x29\x73\x9d\x39\x16\x30\x23\xe3\xdd\x8d\xde\x71\x52\xa5\xfd\xcd\x5e\xdb\x47\xa1\xb6\x0b\x76\xb2\x45\xb2\xbc\xbb\x89\xbb\x1f\x37\x9f\xc4\x7f\xde\x4b\xa2\xd1\x52\x3d\x2c\x56\x24\xff\x10\xb2\xf1\x3a\xee\xe6\xc9\xa2\xd5\x90\xfa\x92\x4a\xf0\xe2\x3e\x05\x7c\x76\x3c\x9a\xc3\x65\x5f\x88\xac\xa8\x9b\xd6\x4e\x86\x2b\x31\x4f\x29\x10\xd5\xe1\x77\x77\x63\x56\x60\xb0\xbc\xf6\x61\x51\xed\xcb\x2d\x50\xe5\xfc\x7f\x27\x9c\xe7\xf7\x4f\xd6\x58\x10\x33\x03\xf8\x87\xbb\xaf\x3e\x8c\x73\x07\xf1\xc4\x68\x5d\x07\x95\x4b\xfa\x46\xeb\xc7\x60\x06\x41\x42\x4f\xa0\xbf\x77\xa9\xeb\xfe\xa3\xea\xd2\x84\x5a\x18\xab\xb7\x96\x6b\x65\xa7\xcb\x05\x13\x64\x4a\xaf\x41\x19\xcc\x1e\x71\x4b\xd5\xa2\xb1\x8c\x70\x6f\x5c\x95\xa3\xaa\x15\x18\x87\x39\x4f\xc0\xfd\xa3\xdc\xa7\xdd\x80\x8a\xcf\x11\x36\xeb\xba\xc8\x3c\x46\x04\x5b\xf1\x7d\x9e\xdf\xb3\xc0\x6c\x0a\xdb\xa6\xe7\x08\xe1\xbe\xa1\xcd\x28\xa1\xc8\xd9\xef\x37\x62\xa0\x3d\xa9\x49\x0c\xfa\x62\xf4\xa3\x25\x23\x71\x08\x44\xc3\x0c\x08\x09\x27\x7c\x8e\xd1\x1d\x59\xe3\xf6\x68\x58\x6d\x91\x3a\x61\x54\x5a\xee\x91\xc5\x37\x95\x15\x58\x24\xd8\xa3\x8b\x19\x48\xee\x28\x8f\x1b\x30\x63\x38\x74\x86\x45\xe6\x49\x0b\xb3\x60\xf3\x80\xbc\x4f\x00\xcf\x5d\xc6\x27\xd2\x51\x7a\xce\x02\xe9\x01\x9e\xfe\x84\xd3\x7f\xc2\xe9\x8f\x1c\x4e\x5f\x14\x03\x53\xd0\x7a\xc8\xfd\x3f\x56\x80\x7d\x91\xd0\x53\x60\x7b\x48\xe8\x8f\x04\x72\x5f\x2c\xe3\x24\xfc\x1e\x13\xf4\x23\x01\xe1\x17\x09\x3b\x13\x90\x0f\x89\xfc\xff\x0c\xcb\x2f\xd2\xe1\x04\x44\x1f\xd2\xdb\x47\x01\xd4\x67\x0b\x98\x69\x95\x4e\xc1\x27\x50\x4a\x1f\x6b\x35\x03\x8e\xf7\x81\x99\x69\x94\xbd\x7d\xda\x2e\x4c\x3e\x07\xa7\xc6\x20\x79\x7a\x26\x80\x79\x77\x92\x33\x98\xec\x3c\x56\x4e\xcf\xa2\xda\xbe\x3e\x43\xc4\x6b\x4e\x90\xcc\x43\x80\x00\x12\x9d\x7f\xb0\xa8\x9c\xa8\x6f\x70\x4c\xd3\x1f\x59\xe4\x1b\xe4\xb6\x43\x94\x4d\x97\x91\xec\x03\xbe\x99\xb2\x02\xb4\xf1\xa8\xa6\xda\x97\x67\x4c\xa3\xb4\x2f\xc6\x9a\x8e\xf6\x99\x19\x25\xfc\xa4\x73\x80\x15\xe4\xe8\x69\xc1\x1c\x9d\x15\xfb\x87\x78\x58\xf9\x6c\x22\x33\x86\x37\x56\xaf\x29\xff\xc3\xa4\x2a\xc9\x39\xdc\x5e\x26\xce\x2b\x28\x42\x89\x0a\x2c\x61\x8e\x6b\x49\xf5\x24\x8c\xc6\xe2\x69\xa5\xda\x42\x4e\x1e\x85\x74\x9d\x13\x96\xd6\xbe\xcf\x26\xac\x25\x74\xe7\xaa\x04\x9c\x5e\x31\x49\xc3\xe2\x41\x61\xcf\x1e\x2f\x5c\x34\xf2\xef\xc1\xe9\xf0\xc9\xd5\x24\xa7\xf7\xcd\x89\x54\x8f\xc9\x97\xf5\x09\xe6\x83\x0d\xf4\x12\xbe\x46\xe9\xe8\x25\xfc\xa0\x1e\x95\xde\x3f\x1f\xbf\x91\xf0\x22\xbd\x1e\x4c\xe4\xaa\xe1\xf3\x19\x58\x69\xbb\xfb\x99\xc9\xfe\xae\x19\x50\xef\xd0\x54\x1d\xfa\x22\x28\xf1\x4b\xe8\x37\x2a\xcd\x21\xd3\xa7\xc7\x2d\xcc\xed\xfd\xdb\xe8\x1c\xa9\xdd\x76\xa9\x91\xa9\x5b\xbb\xdb\xfb\xb7\xee\xb3\x33\xb5\x61\x52\x2a\x33\xd9\xa8\xf6\xe4\xe1\x9e\xf6\xa8\xd5\x92\x3a\xeb\x5c\xfd\x69\xb7\x65\x4c\x90\x72\x09\x77\xfe\x85\x63\x1e\x44\x86\x52\x1e\xb8\x6b\x11\x25\x07\x66\x83\x7a\xce\x55\xb5\x69\xce\x67\x14\x88\x93\x60\xa3\xcd\x86\x32\x2f\x76\xd4\x19\x5e\x2b\x3a\x6d\x38\x51\x5e\xc9\xf1\x5e\xcc\xd5\x5b\x39\x33\x59\x7b\x53\x91\xd7\x8e\xd2\xb5\x7f\xab\xd5\x6a\xd2\xd4\x6b\x46\xa7\x51\x04\x1b\x1d\x54\x0e\xe8\xa3\x79\x9e\xc8\x73\xff\x0c\xf7\xc3\x1d\xf8\x4f\xe3\xa7\xe7\xd9\x6c\xec\x9c\xc0\x37\xe8\x6b\x0a\x7c\xb5\x49\x8e\xde\x51\x16\x3a\x77\xbc\xba\x77\x38\x9e\xb6\xd7\x78\xde\x65\x2f\x41\x33\xb3\xd2\xe7\xdc\xfa\x3b\x17\x4f\x3c\xeb\xa2\x67\xcb\xfd\xac\x48\x9b\xae\xba\xc3\xf8\xfb\x4d\x2a\xba\x71\xab\x33\xc3\x92\x64\x86\x8e\xf2\xe3\x5a\x9c\xc0\xf8\x9c\x02\x3c\x83\xd1\x73\x45\x77\xc6\x14\xd3\x75\xf0\xac\xdb\xc7\xaa\x98\xa8\xd6\xf5\x2d\x88\xa6\xdd\xe8\xf9\x37\xe7\x13\x84\x8c\x6c\x2c\x32\xe9\x12\x1d\xb2\xae\xf6\x85\x7e\x72\x66\x9c\xb0\x76\x8f\xf5\x6f\x6b\xfc\xc6\x0b\x46\x6c\xb7\x38\xc1\x76\x55\xfd\x6b\xb1\x1d\xe5\xbd\xab\x34\xb1\x48\x96\x78\x88\x57\xd3\x4a\xa3\xad\xc7\x74\xc0\x11\x54\x4e\xd6\x79\x54\x39\x8f\xdd\x17\x87\xa8\x06\xc3\x32\x17\xe8\x40\x78\x07\xa9\x2f\xf6\x95\xc1\x2e\xbe\x83\x15\xef\xbb\x9c\x15\xb2\xa3\xec\xd7\x3c\xa0\x81\x08\xbd\xc5\x53\x5d\xed\x19\x66\xd2\x0a\xd3\x8c\x49\x9c\xb8\x58\xf5\xbe\x79\xf6\xde\x93\x39\xce\xab\x1d\x21\x54\x84\xe3\x3b\x91\xa7\xcb\x48\x64\x40\xa8\xe7\x49\xaa\xe7\x0f\x70\xd2\xc1\xc4\x78\x58\x2d\x9a\x5d\x9a\x51\x82\x89\x8e\xf6\x7c\x52\xd7\x26\xdd\x94\x3f\x17\xfb\x63\x77\xf3\xd2\xd3\x48\xf1\x9e\xe9\x72\xfc\xa6\x5c\x7a\x4e\xac\x5a\xff\xfa\x62\xc2\xba\x9d\xbb\xba\xf1\x36\xa8\xb7\x15\x92\x3a\xcc\xb2\x31\xcc\xdd\x82\x98\xb3\x01\xb1\x48\x3f\xc2\x98\xa4\x78\x14\xea\xf4\xfe\x68\x97\x80\x01\xd8\x24\x41\x7b\x71\x70\x26\x59\xdc\x98\x9c\xa4\xad\x0e\xa5\xde\xf3\x4c\x2c\xfd\x02\xe5\xc3\x6c\xe2\xcf\x9c\xa8\x3e\x42\x7a\x96\xc9\xce\xef\xb2\xcf\x9c\xa8\x35\xcd\x33\x4f\x37\x63\x7f\x7c\xe6\x9c\xbb\x39\x1b\xcf\xcf\x00\x3d\x4e\x42\xbe\xea\xf6\x27\x6a\x92\x41\xeb\x45\x16\x24\xda\x36\xf6\x63\x92\x3f\xf9\xdd\xd2\xc5\x3c\x3b\x8f\xd6\x8f\xa1\xd0\xe3\x4d\x89\x44\x59\x73\x1a\x77\xb5\xf6\x05\xa9\xe6\xf0\x2f\xfd\x0c\x0c\xd6\xb4\xe5\xe2\x69\x8c\x3c\xd4\xbf\x31\x68\x6f\xb0\x4b\xe1\x7c\xc4\x0f\x2d\x16\x98\x7b\x15\x62\x54\xed\x63\x10\xd8\x91\xdd\x51\xbe\x02\x6f\x43\xf3\xca\x6b\xcb\xb8\xa8\xf7\x2e\xac\x1b\xfe\x5a\x35\x54\x76\x84\x5f\x7f\xbb\xfa\x5f\x00\x00\x00\xff\xff\xa9\xc5\x05\x0b\x43\x37\x00\x00") func operatorsCoreosCom_installplansYamlBytes() ([]byte, error) { return bindataRead( @@ -145,7 +145,7 @@ func operatorsCoreosCom_installplansYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_olmconfigsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x6f\x6f\xdb\x46\xd2\x7f\xef\x4f\x31\xd0\xf3\x00\xb1\x73\x12\x15\x27\x87\x5c\x4a\x20\x08\x02\xe5\x5c\x04\x89\xaf\x41\xec\xcb\x01\x67\xf9\xae\x43\x72\x44\x6d\x43\xee\xb2\xbb\xb3\xb6\xd5\xa2\xdf\xfd\x30\xbb\x24\x45\xc9\xa2\x63\xa0\xad\xde\x58\x9a\x9d\x9d\x9d\xbf\xbf\x99\x31\x36\xea\x0b\x59\xa7\x8c\x4e\x01\x1b\x45\x77\x4c\x5a\x7e\xb9\xe4\xeb\x2b\x97\x28\x33\xbf\x39\x3d\xfa\xaa\x74\x91\xc2\xc2\x3b\x36\xf5\x67\x72\xc6\xdb\x9c\xde\xd1\x4a\x69\xc5\xca\xe8\xa3\x9a\x18\x0b\x64\x4c\x8f\x00\x50\x6b\xc3\x28\x64\x27\x3f\x01\x72\xa3\xd9\x9a\xaa\x22\x3b\x2b\x49\x27\x5f\x7d\x46\x99\x57\x55\x41\x36\x08\xef\x9e\xbe\x79\x96\xbc\x4a\x9e\x1d\x01\xe4\x96\xc2\xf5\x4b\x55\x93\x63\xac\x9b\x14\xb4\xaf\xaa\x23\x00\x8d\x35\xa5\x60\xaa\x3a\x37\x7a\xa5\x4a\x97\x98\x86\x2c\xb2\xb1\x2e\xc9\x8d\x25\x23\x7f\xea\x23\xd7\x50\x2e\x2f\x97\xd6\xf8\x26\x85\x83\x3c\x51\x56\xa7\x20\x32\x95\xc6\xaa\xee\x37\xc0\x4c\x1e\x09\xdf\xa3\xe1\x3f\x7c\x3c\x5f\x84\x27\x03\xad\x52\x8e\x3f\xec\xd2\x3f\x2a\xc7\xe1\xac\xa9\xbc\xc5\x6a\xa8\x64\x20\x3b\xa5\x4b\x5f\xa1\x1d\x1c\x1c\x01\xb8\xdc\x34\x94\xc2\xa2\xf2\x8e\xc9\x1e\x01\xb4\xce\x68\xf5\x98\xb5\x06\xdf\x9c\xb6\x6a\xb9\x7c\x4d\x35\x76\x4a\x82\x98\xa6\xdf\x7e\x7a\xff\xe5\xc5\xc5\xde\x01\x40\x41\x2e\xb7\xaa\xe1\xe0\xda\x5e\x4d\x50\x0e\x10\x6c\x1b\x40\xf9\xd2\x18\xed\x54\x56\x11\xac\x8c\x85\xa8\x98\xb7\x4a\x97\x72\x27\x19\xc8\xe3\x8d\x68\x6a\xb2\x9f\x28\xe7\x01\xd9\xd2\xcf\x5e\x59\x2a\x86\x4f\x8b\xe2\x5d\x42\x0c\xc8\x8d\x95\x48\xf0\xc0\xcb\xf1\x33\x48\xbf\x1d\xfa\x9e\x0d\x4f\xc4\xd0\xc8\x07\x85\x64\x1e\x39\xe0\x35\x75\x2e\xa3\xa2\xf5\x0e\x98\x15\xf0\x5a\x39\xb0\xd4\x58\x72\xa4\x63\x2e\x0a\x19\x75\x6b\x40\x02\x17\x64\xe5\x22\xb8\xb5\xf1\x55\x21\x86\xdf\x90\x65\xb0\x94\x9b\x52\xab\x5f\x7a\x69\x0e\xd8\x84\x67\x2a\x64\x72\x0c\x4a\x33\x59\x8d\x15\xdc\x60\xe5\x69\x0a\xa8\x0b\xa8\x71\x03\x96\x44\x2e\x78\x3d\x90\x10\x58\x5c\x02\xe7\xc6\x12\x28\xbd\x32\x29\xac\x99\x1b\x97\xce\xe7\xa5\xe2\xae\xb8\x72\x53\xd7\x5e\x2b\xde\xcc\x43\x9d\xa8\xcc\x4b\xae\xce\x0b\xba\xa1\x6a\xee\x54\x39\x43\x9b\xaf\x15\x53\xce\xde\xd2\x1c\x1b\x35\x0b\xca\xea\x50\x60\x49\x5d\xfc\x5f\x17\x4d\xf7\x64\xcf\x7d\x31\x64\x8e\x25\x9c\x3b\x47\x21\xa7\x1f\xf4\xb5\x64\x77\xcc\x95\x78\x3d\xda\xb2\x75\xa9\x90\xc4\x2b\x9f\xff\x7e\x71\xb9\x4d\xa7\xe0\xf6\xe8\xe1\x2d\xab\xdb\x3a\x5b\x1c\xa5\xf4\x8a\x6c\xe4\x5c\x59\x53\x07\x29\xa4\x8b\xc6\x28\xcd\xe1\x47\x5e\x29\xd2\x0c\xce\x67\xb5\x62\x17\x12\x8c\x1c\x4b\x1c\x12\x58\x04\x6c\x81\x8c\xc0\x37\x05\x32\x15\x09\xbc\xd7\xb0\xc0\x9a\xaa\x05\x3a\xfa\xd3\x5d\x2d\x1e\x75\x33\x71\xdf\xe3\x9d\x3d\x84\xc6\xfb\x17\xee\x15\x14\x40\x07\x5f\xa3\xd1\xe9\xab\xf9\xa2\xa1\x5c\xa2\x24\x6e\x93\x5b\xa1\x86\x51\x0f\xca\xbd\x0b\x4d\xf2\xd8\xc7\xc7\xcb\x54\x3e\x2b\x42\x71\xcd\x81\x93\x3d\x15\xcf\x5a\xc6\x80\xfd\xa8\x74\xd4\x51\x70\x53\xea\xb0\x83\x19\x14\xdc\xf9\xe1\xe3\x79\x2f\x77\x5f\xcd\x6f\xa8\xfa\x2d\x75\x83\x5a\xca\xc9\x33\x0b\xd3\x28\x2a\x16\x17\x5f\x46\xd8\xf6\xf4\x7f\xb7\x7f\x4b\xdc\xec\x1d\x15\x02\x07\xad\x48\xd1\xfc\x89\x83\x49\x64\x82\xc5\xc5\x97\x49\x67\x48\x08\x44\xdf\x77\x40\x69\xc7\x58\x55\x54\x00\x76\x39\x1e\x00\x3f\xe2\xff\x14\x6e\xd7\x64\x09\x70\x97\x5c\xf4\x02\xe4\x6d\xa3\xa5\xbc\x90\x61\x8d\x0e\x32\x22\x3d\x10\xaa\x74\x08\x7a\xcb\xfd\xbd\x74\xbd\xc8\xcb\x68\x4b\x62\x07\x58\x55\xb1\xdd\x35\x98\x0b\x20\xfd\x6b\x4d\x1a\x2c\x91\x16\x33\x8a\x69\x08\xc1\xad\xaa\x2a\x81\x3f\xe9\xbd\x14\x94\x1c\x18\xe6\x26\xc1\x22\xc2\x7c\x3d\xa6\xe4\xa1\xd0\x6d\xc3\x97\x19\x53\x11\xea\xdd\x3c\x67\x64\x7f\x2f\x1c\x23\x99\x1e\x78\xfb\x5c\x8f\xbf\xfe\xec\x6c\xcf\x8d\x2e\xd4\x60\x8e\x39\x24\x14\xad\xc5\xcd\x81\x53\xc5\x54\x8f\x65\xe4\xd0\xc2\xc9\xa2\x7b\x64\x5b\x2a\x05\x31\xaa\x2a\xda\x27\x71\x47\xa9\x6d\x8e\x7d\x8d\x20\xf7\xd6\x06\x80\x64\x09\x54\xd7\xec\xde\x7e\x7a\x0f\xdd\x5c\x96\xc0\x6c\x36\x83\x4b\x21\x3b\xb6\x3e\x67\xf1\x9b\x34\x2e\x5d\x50\x11\xa4\x16\xca\x86\x6e\xe5\x44\xb8\xf8\x30\x98\xd1\x65\xe7\x4a\x51\x55\x40\x83\xbc\x86\x24\xba\x3a\xd9\xba\x22\x01\x38\x93\x54\xb8\xc3\xba\xa9\x68\x1a\xdc\x00\x67\xc6\xb4\x11\x8a\x0f\xfe\x0a\xf3\x39\x7c\xee\x3b\x40\x90\x6a\x32\x47\xf6\x26\xce\x85\xa1\x19\xc3\xca\x98\x27\x6e\xd7\x9e\x44\x2e\x7e\xd0\xe6\x56\x1f\x7a\x3a\xbc\x85\x96\x52\x58\x4e\xde\xde\xa0\xaa\x24\x7f\x97\x93\x29\x2c\x27\x9f\xac\x29\x2d\x39\x19\xb3\x84\x20\x6d\x79\x39\x79\x47\xa5\xc5\x82\x8a\xe5\x44\xc4\xfe\xa5\x41\xce\xd7\xe7\x64\x4b\xfa\x40\x9b\xd7\x41\x58\x4f\xbe\x60\x2b\x43\xe0\xe6\x75\x2d\xe7\x81\x2e\x68\x75\xb9\x69\xe8\x75\x8d\x4d\x4f\x38\xc7\xa6\xbf\xdc\x87\xce\xc1\xd5\xb5\xc0\xfc\xcd\x69\xb2\x0d\xe7\x8f\x3f\x39\xa3\xd3\xe5\x64\xab\xff\xd4\xd4\x92\x16\x0d\x6f\x96\x13\xd8\x79\x35\x5d\x4e\xc2\xbb\x1d\xbd\x53\x32\x5d\x4e\xe4\x25\x21\x5b\xc3\x26\xf3\xab\x74\x39\xc9\x36\x4c\x6e\x7a\x3a\xb5\xd4\x4c\xa5\xaa\x5f\x6f\x5f\x58\x4e\x7e\x84\xa5\x16\x65\x0d\xaf\xc9\xc6\x48\x3a\xf8\x6d\x72\x30\x11\xbf\x81\xac\x63\xc3\xdd\xf6\x33\x83\x0a\x1d\x5f\x5a\xd4\x4e\x75\x03\xfb\x28\x6b\x4d\xce\x61\x39\x7e\x6e\x09\x9d\xd1\xa3\xc7\x31\x1b\x46\x8f\xc5\x96\x83\x87\xdf\xea\x0f\x70\xc0\x86\x31\xce\xbd\xda\xbd\x7f\xb1\x03\x28\x39\x01\x16\x42\xa8\xd8\x3e\x27\xb8\xe7\x96\x42\x94\xf1\x47\xea\xbb\x85\x33\x36\x80\x3a\xc4\x2d\x69\x8b\x37\xce\xa6\x19\x49\x83\xd0\x41\x94\xd7\x05\xd9\x6a\x23\xe3\xd7\x56\x6a\xbe\x46\x5d\xca\x2c\x04\xef\x57\x11\xf8\x95\x03\x99\x93\xbe\x4a\x21\x4d\xe5\xa2\x06\xef\xba\x99\x2d\xe8\xd5\x4b\x14\xe0\x88\x05\xdf\x8a\x09\x63\x5f\x9e\x53\xc3\x52\x5d\x63\xb0\xfe\xc0\xc0\x33\xfc\xac\x8c\xad\x91\x53\x90\x61\x6d\xc6\xe3\xe9\xd1\x26\xc7\x23\x1d\xdf\x72\xc7\x01\x75\xed\x6b\x94\x6e\x86\x45\x68\xca\xfd\x99\x2e\x54\x8e\x61\x50\xed\xf0\x14\x33\xe3\x23\xc2\x6d\xe3\xd0\xba\x5a\x26\xd3\x8c\x04\x09\x43\x7d\xb6\x66\xfd\x4e\xe3\x6b\xbc\xfb\x48\xba\xe4\x75\x0a\x2f\x9e\xff\xed\xe5\xab\x11\xc6\x08\x8c\x54\x7c\x4f\x5a\x5a\xe9\x81\x3d\x68\xc4\x0d\xf7\x2f\x0e\xa6\xee\x60\x67\xd2\x0d\x9f\x49\xb9\xe5\x89\xa3\xc1\x4e\x5e\xde\xa2\x03\x47\x0c\x19\xca\x88\xe3\x1b\xf1\x8b\xa0\x7c\x98\x31\x74\x4e\x53\x50\xab\xc3\xc2\x54\x0f\xe0\xd5\x06\x4e\x9f\x4f\x21\x6b\x5d\x7c\x1f\xbe\xaf\xee\xae\x93\x03\x2a\x2b\x07\xdf\x4d\xf7\xf4\x91\x81\xc7\x87\x8e\x27\x89\x03\xb7\x8a\xd7\x61\x57\x95\xa6\xd5\xee\x63\x07\xda\x20\xf5\xfa\x7e\x2b\x70\xd2\x0c\xcb\xb0\x70\x1f\xfe\x74\x69\xab\x34\xbf\xfc\xeb\x78\x7c\x95\x56\xb5\xaf\x53\x78\x36\xc2\x12\x21\xed\x91\xd1\x8c\xcc\xdb\x29\x00\x05\xba\x4a\x8b\x75\x8d\xac\x72\x50\x85\xec\x21\x2b\x45\x76\x98\xda\x62\x74\x7b\x51\xfa\xfa\x8e\x17\x9f\xb8\x16\x87\x06\xc9\xfe\xc9\x9a\xc2\xe7\xb2\x8b\x99\x55\x58\x19\xd4\x4a\xe5\x43\x80\x92\x05\x27\x54\x43\x5c\xb1\x81\xee\xc4\xe9\xfd\x32\x1b\xf7\x5d\x42\xad\x74\xe9\xda\x27\x65\x93\x13\x00\x89\x5d\xf7\x76\x4d\xa1\xf5\x84\xd5\xbc\xbd\x63\x83\x56\x4e\x15\x64\x65\x06\x86\xd2\xa3\x45\xcd\x44\x85\xc0\x8f\x94\x60\xcb\x3b\x80\x3c\xdc\xae\x75\x5d\x35\xc6\x52\x8d\x60\x25\x2a\xb6\xab\x60\xa8\xd8\x3f\xae\x54\x4f\x9f\x3d\x7f\x30\xe4\x3d\xdf\x28\x53\x83\xcc\x64\x75\x0a\xff\xb9\x7a\x3b\xfb\x37\xce\x7e\xb9\x3e\x6e\xbf\x3c\x9b\x7d\xf7\xdf\x69\x7a\xfd\x74\xf0\xf3\xfa\xe4\xcd\xff\x8f\x48\x3a\x3c\x20\x8f\xa4\x4f\xdb\x44\xba\x21\xb1\x8b\xe8\x34\x74\x18\xb3\x82\x4b\xeb\x69\x0a\x67\x58\x39\x9a\xc2\x3f\x75\x68\x0d\xbf\xd3\x69\xa4\x7d\x3d\xae\x9d\x74\xe5\x89\xbc\x7a\x78\xf8\xe8\x59\x82\x4a\x0f\xf3\xb4\xea\x3e\xb4\x61\x3c\xce\x49\x61\x6c\x8b\x0b\x68\x87\x34\x83\x7f\x1f\x40\x40\x3c\x19\x4b\x93\x76\xbc\x4d\x72\x53\xcf\x07\xff\x5e\x90\xb9\xfa\x1c\xf5\x06\xb6\xb0\x16\x87\xd2\xfd\x4c\x77\x2c\xd8\x84\xb9\x35\xce\xf5\x6b\x89\x83\x4a\x7d\x25\xe8\x27\xd7\x08\x96\x19\xe5\x18\x06\x71\x9b\x29\xb6\x68\x37\x83\xbd\x03\x72\xd4\xe1\xbf\x1d\x8e\x56\xbe\x82\x63\x47\x04\x89\x36\x05\xdd\x47\xd7\x93\x88\xa1\x98\xa9\x4a\xf1\x26\xac\xa9\x24\x7b\x76\xa5\xda\xf9\xbf\x6e\x8c\x65\xd4\x1c\xcb\xcd\x52\x49\x77\xa0\x18\x6a\x99\x37\x29\xac\x56\xc7\x85\x76\xa7\xa7\xcf\x5f\x5c\xf8\xac\x30\x35\x2a\x7d\x56\xf3\xfc\xe4\xcd\xf1\xcf\x1e\x2b\x41\x9e\xe2\x1f\x58\xd3\x59\xcd\x27\x7f\x5c\x5b\x3c\x7d\xf9\x88\x2a\x3a\xbe\x8a\xb5\x72\x7d\x7c\x35\x6b\xbf\x3d\xed\x48\x27\x6f\x8e\x97\xc9\x83\xe7\x27\x4f\xc5\x86\x41\x05\x5e\x5f\xcd\xb6\xe5\x97\x5c\x3f\x3d\x79\x33\x38\x3b\xe9\x8a\x31\xf6\xa9\x14\xd8\xfa\x6e\x68\x71\x6c\xac\x0c\x29\x3b\x34\x9f\xf5\xe1\xdd\x26\x61\x5b\xb9\xf0\xeb\x6f\x47\xff\x0b\x00\x00\xff\xff\x65\x57\xc7\x70\x5d\x17\x00\x00") +var _operatorsCoreosCom_olmconfigsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\x6f\x6f\xdb\x46\xd2\x7f\xef\x4f\x31\xd0\xf3\x00\xb1\x73\x12\x15\x27\x87\x5c\x43\x20\x08\x02\xe5\x5c\x04\x89\xaf\x41\xec\xcb\x01\x67\xf9\xae\x43\x72\x44\x6d\x43\xee\xb2\xbb\xb3\xb6\xd5\xa2\xdf\xfd\x30\xbb\x24\x45\xc9\xa2\x63\xa0\xad\xde\x58\x9a\x9d\x9d\x9d\xbf\xbf\x99\x31\x36\xea\x0b\x59\xa7\x8c\x4e\x01\x1b\x45\x77\x4c\x5a\x7e\xb9\xe4\xeb\x77\x2e\x51\x66\x7e\x73\x7a\xf4\x55\xe9\x22\x85\x85\x77\x6c\xea\xcf\xe4\x8c\xb7\x39\xbd\xa3\x95\xd2\x8a\x95\xd1\x47\x35\x31\x16\xc8\x98\x1e\x01\xa0\xd6\x86\x51\xc8\x4e\x7e\x02\xe4\x46\xb3\x35\x55\x45\x76\x56\x92\x4e\xbe\xfa\x8c\x32\xaf\xaa\x82\x6c\x10\xde\x3d\x7d\xf3\x2c\x79\x95\x3c\x3b\x02\xc8\x2d\x85\xeb\x97\xaa\x26\xc7\x58\x37\x29\x68\x5f\x55\x47\x00\x1a\x6b\x4a\xc1\x54\x75\x6e\xf4\x4a\x95\x2e\x31\x0d\x59\x64\x63\x5d\x92\x1b\x4b\x46\xfe\xd4\x47\xae\xa1\x5c\x5e\x2e\xad\xf1\x4d\x0a\x07\x79\xa2\xac\x4e\x41\x64\x2a\x8d\x55\xdd\x6f\x80\x99\x3c\x12\xbe\x47\xc3\x7f\xf8\x78\xbe\x08\x4f\x06\x5a\xa5\x1c\x7f\xd8\xa5\x7f\x54\x8e\xc3\x59\x53\x79\x8b\xd5\x50\xc9\x40\x76\x4a\x97\xbe\x42\x3b\x38\x38\x02\x70\xb9\x69\x28\x85\x45\xe5\x1d\x93\x3d\x02\x68\x9d\xd1\xea\x31\x6b\x0d\xbe\x39\x6d\xd5\x72\xf9\x9a\x6a\xec\x94\x04\x31\x4d\xbf\xfd\xf4\xfe\xcb\x8b\x8b\xbd\x03\x80\x82\x5c\x6e\x55\xc3\xc1\xb5\xbd\x9a\xa0\x1c\x20\xd8\x36\x80\xf2\xa5\x31\xda\xa9\xac\x22\x58\x19\x0b\x51\x31\x6f\x95\x2e\xe5\x4e\x32\x90\xc7\x1b\xd1\xd4\x64\x3f\x51\xce\x03\xb2\xa5\x9f\xbd\xb2\x54\x0c\x9f\x16\xc5\xbb\x84\x18\x90\x1b\x2b\x91\xe0\x81\x97\xe3\x67\x90\x7e\x3b\xf4\x3d\x1b\x9e\x88\xa1\x91\x0f\x0a\xc9\x3c\x72\xc0\x6b\xea\x5c\x46\x45\xeb\x1d\x30\x2b\xe0\xb5\x72\x60\xa9\xb1\xe4\x48\xc7\x5c\x14\x32\xea\xd6\x80\x04\x2e\xc8\xca\x45\x70\x6b\xe3\xab\x42\x0c\xbf\x21\xcb\x60\x29\x37\xa5\x56\xbf\xf4\xd2\x1c\xb0\x09\xcf\x54\xc8\xe4\x18\x94\x66\xb2\x1a\x2b\xb8\xc1\xca\xd3\x14\x50\x17\x50\xe3\x06\x2c\x89\x5c\xf0\x7a\x20\x21\xb0\xb8\x04\xce\x8d\x25\x50\x7a\x65\x52\x58\x33\x37\x2e\x9d\xcf\x4b\xc5\x5d\x71\xe5\xa6\xae\xbd\x56\xbc\x99\x87\x3a\x51\x99\x97\x5c\x9d\x17\x74\x43\xd5\xdc\xa9\x72\x86\x36\x5f\x2b\xa6\x9c\xbd\xa5\x39\x36\x6a\x16\x94\xd5\xa1\xc0\x92\xba\xf8\xbf\x2e\x9a\xee\xc9\x9e\xfb\x62\xc8\x1c\x4b\x38\x77\x8e\x42\x4e\x3f\xe8\x6b\xc9\xee\x98\x2b\xf1\x7a\xb4\x65\xeb\x52\x21\x89\x57\x3e\xff\xfd\xe2\x72\x9b\x4e\xc1\xed\xd1\xc3\x5b\x56\xb7\x75\xb6\x38\x4a\xe9\x15\xd9\xc8\xb9\xb2\xa6\x0e\x52\x48\x17\x8d\x51\x9a\xc3\x8f\xbc\x52\xa4\x19\x9c\xcf\x6a\xc5\x2e\x24\x18\x39\x96\x38\x24\xb0\x08\xd8\x02\x19\x81\x6f\x0a\x64\x2a\x12\x78\xaf\x61\x81\x35\x55\x0b\x74\xf4\xa7\xbb\x5a\x3c\xea\x66\xe2\xbe\xc7\x3b\x7b\x08\x8d\xf7\x2f\xdc\x2b\x28\x80\x0e\xbe\x46\xa3\xd3\x57\xf3\x45\x43\xb9\x44\x49\xdc\x26\xb7\x42\x0d\xa3\x1e\x94\x7b\x17\x9a\xe4\xb1\x8f\x8f\x97\xa9\x7c\x56\x84\xe2\x9a\x03\x27\x7b\x2a\x9e\xb5\x8c\x01\xfb\x51\xe9\xa8\xa3\xe0\xa6\xd4\x61\x07\x33\x28\xb8\xf3\xc3\xc7\xf3\x5e\xee\xbe\x9a\xdf\x50\xf5\x5b\xea\x06\xb5\x94\x93\x67\x16\xa6\x51\x54\x2c\x2e\xbe\x8c\xb0\xed\xe9\xff\x6e\xff\x96\xb8\xd9\x3b\x2a\x04\x0e\x5a\x91\xa2\xf9\x13\x07\x93\xc8\x04\x8b\x8b\x2f\x93\xce\x90\x10\x88\xbe\xef\x80\xd2\x8e\xb1\xaa\xa8\x00\xec\x72\x3c\x00\x7e\xc4\xff\x29\xdc\xae\xc9\x12\xe0\x2e\xb9\xe8\x05\xc8\xdb\x46\x4b\x79\x21\xc3\x1a\x1d\x64\x44\x7a\x20\x54\xe9\x10\xf4\x96\xfb\x7b\xe9\x7a\x91\x97\xd1\x96\xc4\x0e\xb0\xaa\x62\xbb\x6b\x30\x17\x40\xfa\xd7\x9a\x34\x58\x22\x2d\x66\x14\xd3\x10\x82\x5b\x55\x55\x02\x7f\xd2\x7b\x29\x28\x39\x30\xcc\x4d\x82\x45\x84\xf9\x7a\x4c\xc9\x43\xa1\xdb\x86\x2f\x33\xa6\x22\xd4\xbb\x79\xce\xc8\xfe\x5e\x38\x46\x32\x3d\xf0\xf6\xb9\x1e\x7f\xfd\xd9\xd9\x9e\x1b\x5d\xa8\xc1\x1c\x73\x48\x28\x5a\x8b\x9b\x03\xa7\x8a\xa9\x1e\xcb\xc8\xa1\x85\x93\x45\xf7\xc8\xb6\x54\x0a\x62\x54\x55\xb4\x4f\xe2\x8e\x52\xdb\x1c\xfb\x1a\x41\xee\xad\x0d\x00\xc9\x12\xa8\xae\xd9\xbd\xfd\xf4\x1e\xba\xb9\x2c\x81\xd9\x6c\x06\x97\x42\x76\x6c\x7d\xce\xe2\x37\x69\x5c\xba\xa0\x22\x48\x2d\x94\x0d\xdd\xca\x89\x70\xf1\x61\x30\xa3\xcb\xce\x95\xa2\xaa\x80\x06\x79\x0d\x49\x74\x75\xb2\x75\x45\x02\x70\x26\xa9\x70\x87\x75\x53\xd1\x14\x96\x3a\x78\x02\xce\x8c\x69\x83\x14\xdf\xfc\x15\xe6\x73\xf8\xdc\x37\x81\x20\xd8\x64\x8e\xec\x4d\x1c\x0d\x43\x3f\x86\x95\x31\x4f\xdc\xae\x49\x89\x5c\xfc\xa0\xcd\xad\x3e\xf4\x7a\x78\x0b\x2d\xa5\xb0\x9c\xbc\xbd\x41\x55\x49\x0a\x2f\x27\x53\x58\x4e\x3e\x59\x53\x5a\x72\x32\x69\x09\x41\x3a\xf3\x72\xf2\x8e\x4a\x8b\x05\x15\xcb\x89\x88\xfd\x4b\x83\x9c\xaf\xcf\xc9\x96\xf4\x81\x36\xaf\x83\xb0\x9e\x7c\xc1\x56\xe6\xc0\xcd\xeb\x5a\xce\x03\x5d\x00\xeb\x72\xd3\xd0\xeb\x1a\x9b\x9e\x70\x8e\x4d\x7f\xb9\x8f\x9e\x83\xab\x6b\x41\xfa\x9b\xd3\x64\x1b\xd1\x1f\x7f\x72\x46\xa7\xcb\xc9\x56\xff\xa9\xa9\x25\x33\x1a\xde\x2c\x27\xb0\xf3\x6a\xba\x9c\x84\x77\x3b\x7a\xa7\x64\xba\x9c\xc8\x4b\x42\xb6\x86\x4d\xe6\x57\xe9\x72\x92\x6d\x98\xdc\xf4\x74\x6a\xa9\x99\x4a\x61\xbf\xde\xbe\xb0\x9c\xfc\x28\x31\x99\xcf\xc1\xf0\x9a\x6c\x0c\xa6\x83\xdf\x26\x07\x73\xf1\x1b\xe0\x3a\x36\xdf\x6d\x3f\x33\xa8\xd0\xf1\xa5\x45\xed\x54\x37\xb3\x8f\xb2\xd6\xe4\x1c\x96\xe3\xe7\x96\xd0\x19\x3d\x7a\x1c\xb3\x61\xf4\x58\x6c\x39\x78\xf8\xad\x16\x01\x07\x6c\x18\xe3\xdc\x2b\xdf\xfb\x17\x3b\x8c\x92\x13\x60\x21\x84\xa2\xed\x73\x82\x7b\x6e\xa9\x45\x99\x80\xa4\xc4\x5b\x44\x63\x03\xa8\x43\xdc\x92\xb6\x7e\xe3\x78\x9a\x91\xf4\x08\x1d\x44\x79\x5d\x90\xad\x36\x32\x81\x6d\xa5\xe6\x6b\xd4\xa5\x8c\x43\xf0\x7e\x15\xb1\x5f\x39\x90\x51\xe9\xab\x14\xd2\x54\x2e\x6a\xf0\xae\x1b\xdb\x82\x5e\xbd\x44\xc1\x8e\x58\xf3\xad\x98\x30\xf9\xe5\x39\x35\x2c\xd5\x35\x86\xec\x0f\xcc\x3c\xc3\xcf\xca\xd8\x1a\x39\x05\x99\xd7\x66\x3c\x9e\x1e\x6d\x72\x3c\xd2\xf1\x2d\x77\x9c\x51\xd7\xbe\x46\x69\x68\x58\x84\xbe\xdc\x9f\xe9\x42\xe5\x18\x66\xd5\x0e\x52\x31\x33\x3e\x82\xdc\x36\x0e\xad\xab\x65\x38\xcd\x48\xc0\x30\xd4\x67\x6b\xd6\xef\x34\xbe\xc6\xbb\x8f\xa4\x4b\x5e\xa7\xf0\xe2\xf9\xdf\x5e\x7e\x37\xc2\x18\x81\x91\x8a\xef\x49\x4b\x37\x3d\xb0\x0a\x8d\xb8\xe1\xfe\xc5\xc1\xe0\x1d\xec\x4c\xba\xf9\x33\x29\xb7\x3c\x71\x3a\xd8\xc9\xcb\x5b\x74\xe0\x88\x21\x43\x99\x72\x7c\x23\x7e\x11\xa0\x0f\x63\x86\xce\x69\x0a\x6a\x75\x58\x98\xea\x01\xbc\xda\xc0\xe9\xf3\x29\x64\xad\x8b\xef\xc3\xf7\xd5\xdd\x75\x72\x40\x65\xe5\xe0\xd5\x74\x4f\x1f\x99\x79\x7c\x68\x7a\x92\x38\x70\xab\x78\x1d\xd6\x55\xe9\x5b\xed\x4a\x76\xa0\x13\x52\xaf\xef\xb7\x02\x27\xfd\xb0\x0c\x3b\xf7\xe1\x4f\x97\xb6\x4a\xf3\xcb\xbf\x8e\xc7\x57\x69\x55\xfb\x3a\x85\x67\x23\x2c\x11\xd2\x1e\x19\xcd\xc8\xbc\x1d\x04\x50\xa0\xab\xb4\x58\xd7\xc8\x2a\x07\x55\xc8\x2a\xb2\x52\x64\x87\xa9\x2d\x46\xb7\x17\xa5\xb5\xef\x78\xf1\x89\x6b\x71\x68\x90\xec\x9f\xac\x29\x7c\x2e\xeb\x98\x59\x85\xad\x41\xad\x54\x3e\x04\x28\xd9\x71\x42\x35\xc4\x2d\x1b\xe8\x4e\x9c\xde\xef\xb3\x71\xe5\x25\xd4\x4a\x97\xae\x7d\x52\x96\x39\x01\x90\xd8\x75\x6f\xd7\x14\x5a\x4f\xd8\xce\xdb\x3b\x36\x68\xe5\x54\x41\x56\xc6\x60\x28\x3d\x5a\xd4\x4c\x54\x08\xfc\x48\x09\xb6\xbc\x03\xc8\xc3\xed\x66\xd7\x55\x63\x2c\xd5\x08\x56\xa2\x62\xbb\x0d\x86\x8a\xfd\xe3\x4a\xf5\xf4\xd9\xf3\x07\x43\xde\xf3\x8d\x32\x35\xc8\x4c\x56\xa7\xf0\x9f\xab\xb7\xb3\x7f\xe3\xec\x97\xeb\xe3\xf6\xcb\xb3\xd9\xab\xff\x4e\xd3\xeb\xa7\x83\x9f\xd7\x27\x6f\xfe\x7f\x44\xd2\xe1\x19\x79\x24\x7d\xda\x26\xd2\xcd\x89\x5d\x44\xa7\xa1\xc3\x98\x15\x5c\x5a\x4f\x53\x38\xc3\xca\xd1\x14\xfe\xa9\x43\x6b\xf8\x9d\x4e\x23\xed\xeb\x71\xed\xa4\x2b\x4f\xe4\xd5\xc3\xc3\x47\xcf\x12\x54\x7a\x98\xa7\x55\xf7\xa1\x25\xe3\x71\x4e\x0a\x63\x5b\xdc\x41\x3b\xa4\x19\xfc\x07\x01\x02\xe2\xc9\x58\x9a\xb4\x13\x6e\x92\x9b\x7a\x3e\xf8\x0f\x83\x8c\xd6\xe7\xa8\x37\xb0\x85\xb5\x38\x94\xee\x67\xba\x63\xc1\x26\xcc\xad\x71\xae\xdf\x4c\x1c\x54\xea\x2b\x41\x3f\xb9\x46\xb0\xcc\x28\xc7\x30\x8b\xdb\x4c\xb1\x45\xbb\x19\xac\x1e\x90\xa3\x0e\xff\xf0\x70\xb4\xf2\x15\x1c\x3b\x22\x48\xb4\x29\xe8\x3e\xba\x9e\x44\x0c\xc5\x4c\x55\x8a\x37\x61\x53\x25\x59\xb5\x2b\xd5\xae\x00\x75\x63\x2c\xa3\xe6\x58\x6e\x96\x4a\xba\x03\xc5\x50\xcb\xbc\x49\x61\xbb\x3a\x2e\xb4\x3b\x3d\x7d\xfe\xe2\xc2\x67\x85\xa9\x51\xe9\xb3\x9a\xe7\x27\x6f\x8e\x7f\xf6\x58\x09\xf2\x14\xff\xc0\x9a\xce\x6a\x3e\xf9\xe3\xda\xe2\xe9\xcb\x47\x54\xd1\xf1\x55\xac\x95\xeb\xe3\xab\x59\xfb\xed\x69\x47\x3a\x79\x73\xbc\x4c\x1e\x3c\x3f\x79\x2a\x36\x0c\x2a\xf0\xfa\x6a\xb6\x2d\xbf\xe4\xfa\xe9\xc9\x9b\xc1\xd9\x49\x57\x8c\xb1\x4f\xa5\xc0\xd6\x77\x43\x8b\x63\x63\x65\x48\xd9\xa1\xf9\xac\x0f\xef\x36\x09\xdb\xca\x85\x5f\x7f\x3b\xfa\x5f\x00\x00\x00\xff\xff\x1e\x16\x84\x1b\x60\x17\x00\x00") func operatorsCoreosCom_olmconfigsYamlBytes() ([]byte, error) { return bindataRead( @@ -165,7 +165,7 @@ func operatorsCoreosCom_olmconfigsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorconditionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\xdd\x6f\x1b\xb9\x11\x7f\xf7\x5f\x31\x50\x0b\xc4\x4e\xa5\x55\x9c\x2b\xae\x39\x01\x41\x10\xe4\x9a\x22\x48\x7c\x09\x62\xf7\x1e\x6a\xb9\xcd\xec\x72\x24\xf1\xb2\x4b\xee\x91\x5c\xd9\xba\xc3\xfd\xef\xc5\x90\xfb\x25\x69\xa5\xf8\x90\x34\x68\x0b\xf2\xc5\x12\x3f\x86\xc3\xf9\xfe\xd1\x14\x96\xf2\x47\x32\x56\x6a\x35\x03\x2c\x25\xdd\x39\x52\xfc\xcd\x26\x1f\x9f\xd8\x44\xea\xe9\xfa\xfc\xe4\xa3\x54\x62\x06\x2f\x2a\xeb\x74\xf1\x9e\xac\xae\x4c\x46\xdf\xd3\x42\x2a\xe9\xa4\x56\x27\x05\x39\x14\xe8\x70\x76\x02\x80\x4a\x69\x87\xdc\x6d\xf9\x2b\x40\xa6\x95\x33\x3a\xcf\xc9\x4c\x96\xa4\x92\x8f\x55\x4a\x69\x25\x73\x41\xc6\x13\x6f\xb6\x5e\x3f\x4a\x9e\x24\x8f\x4e\x00\x32\x43\x7e\xf9\x95\x2c\xc8\x3a\x2c\xca\x19\xa8\x2a\xcf\x4f\x00\x14\x16\x34\x03\x5d\x92\x41\xa7\x4d\xa6\x95\xf0\xdb\xdb\xa4\xe9\xb2\x49\xa6\x0d\x69\xfe\x53\x9c\xd8\x92\x32\xe6\x60\x69\x74\x55\x76\xcb\xb6\xe6\x04\x9a\x0d\xa3\xe8\x68\xa9\x8d\x6c\xbe\x03\x4c\x40\xe7\x85\xff\x1c\x04\xf0\xb6\xa6\xf1\xa2\xd9\xda\x8f\xe5\xd2\xba\xd7\xc3\xe3\x6f\xa4\x75\x7e\x4e\x99\x57\x06\xf3\x21\xe6\xfd\xb0\x5d\x69\xe3\x7e\xe8\x58\xe1\xad\xb3\xad\x4d\xac\x54\xcb\x2a\x47\x33\x40\xe2\x04\xc0\x66\xba\xa4\x19\x78\x0a\x25\x66\x24\x4e\x00\x6a\xc9\xd6\x14\x27\xb5\xf4\xd6\xe7\xf5\x06\x36\x5b\x51\x81\xcd\x76\xc0\x64\xd5\xf3\x77\xaf\x7e\xfc\xe6\x72\x67\x00\x40\x90\xcd\x8c\x2c\x9d\xd7\xd3\xde\x19\x41\x5a\xc0\xda\x36\xa0\x31\x0e\xd0\x0b\x70\x9b\x92\xe0\xc3\xde\xfc\x0f\x70\xbb\x92\xd9\x8a\x97\x55\x96\x04\x38\xcd\x47\x5d\xd3\x06\xa4\x5a\x68\x53\x78\xe5\x73\xef\xdb\x37\x17\x80\xa9\xae\x1c\xb8\x15\x81\x75\xe8\x3c\x59\x54\xad\x08\x92\x1e\x93\xbc\xdb\x0c\x74\xfa\x13\x65\xae\xd7\x6d\xe8\xe7\x4a\x1a\x12\xfd\xf3\xb0\x34\x1a\x93\xed\x75\x97\x86\xe9\xba\x9e\xfe\x43\xeb\x39\xc8\x56\xff\x8e\x60\x1e\xb0\xf4\xc2\x3c\x10\xec\x1b\x64\x3d\xe3\xb5\x1e\x48\xd4\x22\xf7\xa2\x59\x49\x0b\x86\x4a\x43\x96\x54\xf0\x96\xe6\x68\xfe\x00\x09\x5c\x92\xe1\x85\x6c\x19\x55\x2e\x82\x84\x8c\x03\x43\x99\x5e\x2a\xf9\x4b\x4b\xcd\xb2\xa4\x78\x9b\x1c\x1d\x59\x07\x52\x39\x32\x0a\x73\x58\x63\x5e\xd1\x18\x50\x09\x28\x70\x03\x86\x98\x2e\x54\xaa\x47\xc1\x4f\xb1\x09\x5c\x68\x43\x5e\xf8\x33\x58\x39\x57\xda\xd9\x74\xba\x94\xae\x71\xff\x4c\x17\x45\xa5\xa4\xdb\x4c\xbd\x27\xcb\xb4\x62\x2f\x9a\x0a\x5a\x53\x3e\xb5\x72\x39\x41\x93\xad\xa4\xa3\xcc\x55\x86\xa6\x58\xca\x89\x67\x56\x05\xd7\x2c\xc4\x1f\x4c\x6d\x13\xf6\xc1\x8e\xf8\x82\xca\xac\x33\x52\x2d\xb7\x86\xbc\xb7\x1d\x95\x35\xfb\x5b\x30\xbc\xb0\x3c\x9c\xa5\x13\x29\x77\xb1\x54\xde\xff\xf5\xf2\x0a\x1a\x06\x82\xd8\x83\x84\xbb\xa9\xb6\x13\x36\x0b\x4a\xaa\x05\x99\x30\x73\x61\x74\xe1\xa9\x90\x12\xa5\x96\x2a\x18\x62\x96\x4b\x52\x0e\x6c\x95\x16\xd2\x59\x6f\x60\x64\x1d\xeb\x21\x81\x17\x3e\xfa\x41\x4a\x50\x95\x02\x1d\x89\x04\x5e\x29\x78\x81\x05\xe5\x2f\xd0\xd2\x7f\x5c\xd4\x2c\x51\x3b\x61\xf1\xdd\x5f\xd8\xfd\xe0\xbd\xbf\x60\xcf\xa1\x00\x9a\xc0\x7a\x50\x3b\x7b\x2e\x7f\x59\x52\x06\x98\xe7\xfa\x96\x35\x96\xe5\x95\x75\x64\x00\x45\x21\xd5\x01\xf7\x3f\xee\xf7\x75\x74\x18\x43\xa9\x1d\x9f\x1e\xf3\x7c\x03\x7a\x4d\xc6\x48\xc1\x9a\x0f\x6b\x0c\x95\xda\x38\x12\x90\x6e\x3c\xa5\xa1\xa8\x71\xf4\xa0\x87\x43\x42\x38\x72\x99\xeb\x4d\xc1\x16\xb4\x3f\xd8\x50\x45\x63\x70\x33\x30\x2a\x1d\x15\x83\xcb\x8e\x28\x8a\x5b\x7d\xc8\x21\x7e\x3e\x63\xcb\x2d\xed\x8d\xba\xc8\xce\x56\x88\x52\x59\x10\xe4\x50\xe6\x16\x16\xda\x80\x56\x04\xc8\x36\xe0\x42\x24\x23\xc8\x2a\x63\xbc\x4b\x34\xaa\xf2\xde\xf3\xfc\xdd\xab\x36\x1d\x24\x30\x99\x4c\xe0\x8a\xbb\xad\x33\x55\xe6\xd8\x77\x39\x54\x29\x41\xc2\x53\x15\xd2\xf8\xf8\x64\x99\x38\xeb\xda\x1f\x03\x30\x18\xc1\x42\x52\x2e\xa0\x44\xb7\x82\x84\x77\xa9\x38\x7d\xb7\xe9\x1f\xe0\xa5\x36\x40\x77\x58\x94\x39\x8d\x43\xde\x79\xa9\xf5\xa5\x9f\x58\x6f\xf8\x2b\x4c\xa7\xf0\xbe\xf5\xf9\x60\x10\xa9\x25\xb3\x0e\xb5\x8a\xb7\x30\x58\x68\xfd\xc0\x6e\x9f\x27\xe1\x85\xaf\x95\xbe\x55\x43\x5b\xfb\xbd\xd0\xd0\x0c\xe6\xa3\xe7\x6b\x94\x39\xa6\x39\xcd\x47\x63\x98\x8f\xde\x19\xbd\x34\x64\x39\x71\x73\x07\x07\xe2\xf9\xe8\x7b\x5a\x1a\x14\x24\xe6\x23\x26\xfb\xa7\x12\x5d\xb6\xba\x20\xb3\xa4\xd7\xb4\x79\xea\x89\xb5\xdd\x97\xce\x70\x41\xb2\x79\x5a\xf0\xb8\xef\xe7\x4a\xe3\x6a\x53\xd2\xd3\x02\xcb\xb6\xe3\x02\xcb\x76\x71\xab\x3a\x0b\xd7\x37\xec\xd8\xeb\xf3\xa4\x53\xe7\x87\x9f\xac\x56\xb3\xf9\xa8\xe3\x7f\xac\x0b\x36\x8b\xd2\x6d\xe6\x23\xd8\xda\x75\x36\x1f\xf9\x7d\x9b\xfe\x86\xc9\xd9\x7c\xc4\x3b\x71\xb7\xd1\x4e\xa7\xd5\x62\x36\x1f\xa5\x1b\x47\x76\x7c\x3e\x36\x54\x8e\xb9\xcc\x78\xda\xed\x30\x1f\x7d\x80\xb9\x62\x66\xb5\x5b\x91\x09\x9a\xb4\xf0\xdb\xe8\x88\xed\x0f\xba\x62\x68\xc3\xe9\xbc\x6b\x9c\xd8\xad\xc5\x25\x1d\x1c\x37\x84\xb6\xae\xa9\x86\x86\x83\x8a\x0f\x0e\x33\x83\x83\x83\xc7\x22\x45\x68\x39\x5a\x77\x65\x50\x59\xd9\x54\xb7\x87\x66\xee\x38\xe4\xfe\x42\xf6\x9e\x90\xf3\xad\x03\xc7\x1d\xde\x0d\x5b\x45\xbb\x76\x36\x7b\x17\x67\x31\x76\xda\x70\x34\x8e\x9d\xa8\xbc\x32\x92\xda\x23\x43\x89\x91\x12\xdc\xae\x48\x79\x52\x95\x12\x64\xf2\x0d\xc7\xd2\x8e\x6a\xb6\x42\xb5\xe4\x94\x06\xaf\xd8\xc5\xd1\x3b\x31\xa7\xbb\x8f\xec\x1d\x63\x5e\xa8\xa0\xb2\x4d\xea\xf5\x7c\xb5\x14\x39\x1a\x04\x2f\xae\xc9\xf8\xec\x9d\x65\x54\x3a\x76\x99\xdd\x98\xdc\xb5\xa3\xe1\xb0\x69\x21\x71\xcc\x80\x73\xee\x84\x37\x3e\x30\xb3\x36\x8e\x7b\x0a\xbe\x9e\x1d\xea\x8c\x55\x55\xa0\x62\xeb\x11\xcc\x6f\x37\xa6\x84\xcc\xd0\xd7\x1b\x4d\x90\xec\x72\x57\xa7\x87\x5a\xd4\x5c\x60\xa4\xc4\xe1\xcd\x3b\x5d\x7d\xac\xcf\x3c\x7c\x81\x77\x6f\x48\x2d\xdd\x6a\x06\xdf\x3c\xfe\xcb\xb7\x4f\x0e\x4c\x0c\xd1\x8e\xc4\xdf\x48\x71\x1e\x1c\x28\x67\x0f\x88\x61\x7f\x61\xaf\x78\xf2\xe7\x4c\x9a\x1a\x22\x59\x76\x73\xbc\x85\x6c\xdb\xe5\x2d\x5a\xb0\xe4\x20\x45\x2e\xfc\xab\x92\xe5\xc2\xa1\x5b\x2a\xeb\x50\x65\x34\x06\xb9\x18\x26\x26\xdb\xa8\x9c\x6f\xe0\xfc\xf1\x18\xd2\x5a\xc4\xfb\x31\xf9\xfa\xee\x26\x19\x60\x59\x5a\xf8\x6e\xbc\xc3\x0f\x57\x83\x95\x4f\x63\x6c\x38\x70\x2b\xdd\x8a\x8b\x45\x9f\xdb\xea\xb2\x7a\x20\xb7\x51\xcb\xef\xa7\x14\xc7\x19\x6e\x49\xe6\x93\x66\x2b\x95\xfb\xf6\xcf\x87\xf5\x2b\x95\x2c\xaa\x62\x06\x8f\x0e\x4c\x09\x21\xed\x9e\xda\x0c\x93\xbb\xd4\x8e\x1c\xba\x96\x06\x0b\xae\xbc\x32\x90\x82\x0b\xaa\x85\x24\xd3\x37\x6d\x3e\x74\xbd\x90\x93\xf5\x96\x14\x1f\xd8\x3a\x0e\xf5\x8c\xfd\x9d\xd1\xa2\xca\xb8\xa4\xd6\x0b\x5f\x2f\xca\x85\xcc\xfa\x01\x8a\xeb\x54\xef\x0d\x01\x29\x01\xdd\xb1\xd0\x5b\x4c\x12\x60\x0b\xa1\x92\x6a\x69\xeb\x2d\xb9\x20\xe7\x00\x12\x52\xe9\xed\x8a\x7c\x3e\xf1\x08\xab\x5e\x63\x3c\x57\x56\x0a\x32\x24\x00\x61\x59\xa1\x41\xe5\x88\x04\x87\x1f\x76\xc1\x7a\x6e\x2f\xe4\x61\x57\x9d\x37\xde\x18\x5c\x35\x04\x2b\x66\xb1\xae\xe8\xbd\xc7\x7e\x39\x57\x3d\x7f\xf4\xf8\xa8\xca\xdb\x79\x07\x27\x95\xe8\x18\xeb\xcd\xe0\x9f\xd7\xcf\x27\xff\xc0\xc9\x2f\x37\xa7\xf5\x87\x47\x93\xef\xfe\x35\x9e\xdd\x3c\xec\x7d\xbd\x39\x7b\xf6\xc7\x03\x94\x82\x07\xdd\xd3\x7c\xea\x24\xd2\x54\x7e\x8d\x46\xc7\x3e\xc3\xe8\x05\x5c\x19\x46\x9d\x2f\x31\xb7\x34\x86\xbf\x2b\x9f\x1a\x3e\x53\x68\xa4\xaa\xe2\x30\x77\x9c\x95\x47\xbc\xeb\x70\x45\xd1\x4e\xf1\x2c\x1d\x9f\x53\xb3\x7b\x60\x8e\xe7\xf5\x7e\x42\xf2\xb5\x98\x5e\xf4\x23\x4d\x0f\x05\x82\x8f\x78\x5c\x6b\x26\x75\xcd\x9a\x64\xba\x98\xf6\x50\x22\x17\xcb\x17\xa8\x36\xd0\x85\xb5\x50\x69\xee\x5a\xba\x65\xf8\x03\x98\x19\x6d\x6d\x0b\x73\x2d\xe4\xf2\x23\x41\x5b\x8e\x86\x60\x99\x52\x86\xbe\xba\x36\xa9\x74\x06\xcd\xa6\xe3\xce\x42\x86\xca\x83\x56\x4b\x8b\x2a\x87\x53\x4b\x04\x89\xd2\x82\xf6\xa3\xeb\x59\x88\xa1\x98\xca\x5c\xba\x0d\x47\x49\x41\x99\x56\x8b\x5c\xd6\x45\x7d\xc1\xa0\x0b\x95\x0b\xee\x66\x68\x49\x77\x20\x1d\x14\x5c\x44\x92\xe5\x29\xa7\x42\xd9\xf3\xf3\xc7\xdf\x5c\x56\xa9\xd0\x05\x4a\xf5\xb2\x70\xd3\xb3\x67\xa7\x3f\x57\x98\x73\xe4\x11\x3f\x60\x41\x2f\x0b\x77\xf6\xe5\xd2\xe2\xf9\xb7\xf7\xf0\xa2\xd3\xeb\xe0\x2b\x37\xa7\xd7\x93\xfa\xd3\xc3\xa6\xeb\xec\xd9\xe9\x3c\x39\x3a\x7e\xf6\x90\xcf\xd0\xf3\xc0\x9b\xeb\x49\xe7\x7e\xc9\xcd\xc3\xb3\x67\xbd\xb1\xb3\x7d\x67\xe4\x8c\x25\x33\x7a\x9e\x65\xba\xfa\x6a\x98\x72\xd8\xf7\x3f\x81\xe6\x43\x08\x68\xf0\xfc\x36\x2c\x1f\xc0\xf2\xd2\xd9\x3a\x7d\x06\xd8\x1e\x2c\xa3\x0e\x24\x1c\x60\x9d\x41\x99\x07\xb3\xca\x5c\x85\x79\x0f\xf3\x83\xdd\x58\x47\xc5\x17\x82\xec\x9d\x19\x47\xf8\x1c\xe1\x73\x84\xcf\x7b\x6d\x32\x00\x36\x23\xd2\x8e\x48\xbb\x6b\x11\x69\x47\xa4\x1d\x91\xf6\xbd\xb4\x19\x91\x76\x44\xda\xdb\x2d\x22\xed\x7a\x4e\x44\xda\x11\x69\x7f\x6d\xa4\x1d\xf2\xd4\x0c\x9c\xa9\x9a\xa2\xc5\x3a\x6d\xb8\x48\x81\x05\x9b\x6c\xd3\x59\xa5\xad\x7e\x3b\x2b\xac\x5d\x17\x7e\xfd\x6d\xfb\x39\xcd\xe3\xf8\x9c\x26\x3e\xa7\x89\xcf\x69\xe2\x73\x9a\xa6\x7d\xed\xe7\x34\xdb\xd7\x6f\xe1\xcd\xcb\xd6\x75\x9b\xb7\xd9\xd2\xe8\xb5\x14\x64\x77\x1e\xdf\xf8\x3a\x7c\x27\xcb\x14\xa8\xaa\xfe\x83\x1a\xfa\x3a\xcf\x69\xe2\xdd\x5c\xbc\x9b\x8b\x77\x73\xf1\x6e\xae\xd7\xe2\xdd\x5c\xdb\xe2\xdd\x5c\xbc\x9b\x8b\x77\x73\xf1\x6e\x2e\xde\xcd\xed\xb6\x78\x37\x17\x5a\xbc\x9b\x8b\x77\x73\x03\xed\x7f\xe3\x6e\xae\x6f\x41\xf1\x57\x15\x11\x7a\x46\xe8\xf9\x5f\x06\x3d\x23\x9e\x8c\x78\x32\xe2\xc9\x81\x16\xf1\x64\xc4\x93\x11\x4f\x46\x3c\xb9\xd7\x22\x9e\xac\xe7\x44\x3c\x19\xf1\x64\xfc\x55\xc5\xef\xfc\x55\xc5\xdb\x37\x17\xbd\x97\x1c\xe1\x85\x47\xcf\xb2\x56\xb8\x26\x48\x89\x54\x5b\x46\xc4\xff\xc2\x46\x28\x1c\xa1\x70\xfc\x2f\x2c\x44\xd4\x1c\x51\x73\x44\xcd\x11\x35\xef\x2a\x2e\xa2\xe6\x88\x9a\xb7\x55\x19\x51\xf3\xef\x17\x5a\x44\xcd\x11\x35\x0f\xa8\xe2\xff\x03\x35\x1f\xfb\x85\x44\xbf\xef\x53\x3f\x90\xf8\x77\x00\x00\x00\xff\xff\x79\xf0\xdc\xa4\x52\x56\x00\x00") +var _operatorsCoreosCom_operatorconditionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x5f\x6f\x1b\xb9\x11\x7f\xf7\xa7\x18\xa8\x05\x62\xa7\xd2\x2a\x4e\x8a\xf4\x22\x20\x08\x82\x5c\x53\x04\x89\x2f\x41\xec\xde\x43\x2d\xb7\x99\x5d\x8e\x24\x9e\x77\xc9\x3d\x92\x2b\x5b\x77\xb8\xef\x5e\x0c\xb9\xff\x64\xad\x14\x1f\x92\x06\x6d\x41\xbe\x58\x22\x87\x43\x72\xfe\xff\x68\x0a\x4b\xf9\x23\x19\x2b\xb5\x9a\x01\x96\x92\x6e\x1d\x29\xfe\x66\x93\xeb\xef\x6c\x22\xf5\x74\x7d\x7a\x74\x2d\x95\x98\xc1\xab\xca\x3a\x5d\x7c\x24\xab\x2b\x93\xd1\xf7\xb4\x90\x4a\x3a\xa9\xd5\x51\x41\x0e\x05\x3a\x9c\x1d\x01\xa0\x52\xda\x21\x77\x5b\xfe\x0a\x90\x69\xe5\x8c\xce\x73\x32\x93\x25\xa9\xe4\xba\x4a\x29\xad\x64\x2e\xc8\x78\xe6\xcd\xd2\xeb\x47\xc9\xb3\xe4\xd1\x11\x40\x66\xc8\x4f\xbf\x90\x05\x59\x87\x45\x39\x03\x55\xe5\xf9\x11\x80\xc2\x82\x66\xa0\x4b\x32\xe8\xb4\xc9\xb4\x12\x7e\x79\x9b\x34\x5d\x36\xc9\xb4\x21\xcd\x7f\x8a\x23\x5b\x52\xc6\x3b\x58\x1a\x5d\x95\xdd\xb4\x2d\x9a\xc0\xb3\xd9\x28\x3a\x5a\x6a\x23\x9b\xef\x00\x13\xd0\x79\xe1\x3f\x07\x01\xbc\xaf\x79\xbc\x6a\x96\xf6\x63\xb9\xb4\xee\xed\xf0\xf8\x3b\x69\x9d\xa7\x29\xf3\xca\x60\x3e\xb4\x79\x3f\x6c\x57\xda\xb8\x1f\xba\xad\xf0\xd2\xd9\xd6\x22\x56\xaa\x65\x95\xa3\x19\x60\x71\x04\x60\x33\x5d\xd2\x0c\x3c\x87\x12\x33\x12\x47\x00\xb5\x64\x6b\x8e\x93\x5a\x7a\xeb\xd3\x7a\x01\x9b\xad\xa8\xc0\x66\x39\x60\xb6\xea\xe5\x87\x37\x3f\x3e\x39\xbf\x33\x00\x20\xc8\x66\x46\x96\xce\xeb\x69\xe7\x8c\x20\x2d\x60\x6d\x1b\xd0\x18\x07\xe8\x05\xb8\x4d\x49\xf0\x69\x87\xfe\x13\xdc\xac\x64\xb6\xe2\x69\x95\x25\x01\x4e\xf3\x51\xd7\xb4\x01\xa9\x16\xda\x14\x5e\xf9\xdc\xfb\xfe\xdd\x19\x60\xaa\x2b\x07\x6e\x45\x60\x1d\x3a\xcf\x16\x55\x2b\x82\xa4\xb7\x49\x5e\x6d\x06\x3a\xfd\x89\x32\xd7\xeb\x36\xf4\x73\x25\x0d\x89\xfe\x79\x58\x1a\x8d\xc9\xf6\xba\x4b\xc3\x7c\x5d\x4f\xff\xa1\xf5\x1c\x64\xab\xff\x8e\x60\x1e\xb0\xf4\x02\x1d\x08\xf6\x0d\xb2\x7e\xe3\xb5\x1e\x48\xd4\x22\xf7\xa2\x59\x49\x0b\x86\x4a\x43\x96\x54\xf0\x96\xe6\x68\xfe\x00\x09\x9c\x93\xe1\x89\x6c\x19\x55\x2e\x82\x84\x8c\x03\x43\x99\x5e\x2a\xf9\x4b\xcb\xcd\xb2\xa4\x78\x99\x1c\x1d\x59\x07\x52\x39\x32\x0a\x73\x58\x63\x5e\xd1\x18\x50\x09\x28\x70\x03\x86\x98\x2f\x54\xaa\xc7\xc1\x93\xd8\x04\xce\xb4\x21\x2f\xfc\x19\xac\x9c\x2b\xed\x6c\x3a\x5d\x4a\xd7\xb8\x7f\xa6\x8b\xa2\x52\xd2\x6d\xa6\xde\x93\x65\x5a\xb1\x17\x4d\x05\xad\x29\x9f\x5a\xb9\x9c\xa0\xc9\x56\xd2\x51\xe6\x2a\x43\x53\x2c\xe5\xc4\x6f\x56\x05\xd7\x2c\xc4\x1f\x4c\x6d\x13\xf6\xc1\x1d\xf1\x05\x95\x59\x67\xa4\x5a\x6e\x0d\x79\x6f\x3b\x28\x6b\xf6\xb7\x60\x78\x61\x7a\x38\x4b\x27\x52\xee\x62\xa9\x7c\xfc\xeb\xf9\x05\x34\x1b\x08\x62\x0f\x12\xee\x48\x6d\x27\x6c\x16\x94\x54\x0b\x32\x81\x72\x61\x74\xe1\xb9\x90\x12\xa5\x96\x2a\x18\x62\x96\x4b\x52\x0e\x6c\x95\x16\xd2\x59\x6f\x60\x64\x1d\xeb\x21\x81\x57\x3e\xfa\x41\x4a\x50\x95\x02\x1d\x89\x04\xde\x28\x78\x85\x05\xe5\xaf\xd0\xd2\x7f\x5c\xd4\x2c\x51\x3b\x61\xf1\xdd\x5f\xd8\xfd\xe0\xbd\x3b\x61\xc7\xa1\x00\x9a\xc0\xba\x57\x3b\x3b\x2e\x7f\x5e\x52\x06\x98\xe7\xfa\x86\x35\x96\xe5\x95\x75\x64\x00\x45\x21\xd5\x1e\xf7\x3f\xec\xf7\x75\x74\x18\x43\xa9\x1d\x9f\x1e\xf3\x7c\x03\x7a\x4d\xc6\x48\xc1\x9a\x0f\x73\x0c\x95\xda\x38\x12\x90\x6e\x3c\xa7\xa1\xa8\x71\xf0\xa0\xfb\x43\x42\x38\x72\x99\xeb\x4d\xc1\x16\xb4\x3b\xd8\x70\x45\x63\x70\x33\x30\x2a\x1d\x15\x83\xd3\x0e\x28\x8a\x5b\x7d\xc8\xa1\xfd\x7c\xc1\x92\x5b\xda\x1b\x75\x91\x9d\xad\x10\xa5\xb2\x20\xc8\xa1\xcc\x2d\x2c\xb4\x01\xad\x08\x90\x6d\xc0\x85\x48\x46\x90\x55\xc6\x78\x97\x68\x54\xe5\xbd\xe7\xe5\x87\x37\x6d\x3a\x48\x60\x32\x99\xc0\x05\x77\x5b\x67\xaa\xcc\xb1\xef\x72\xa8\x52\x82\x84\xe7\x2a\xa4\xf1\xf1\xc9\x32\x73\xd6\xb5\x3f\x06\x60\x30\x82\x85\xa4\x5c\x40\x89\x6e\x05\x09\xaf\x52\x71\xfa\x6e\xd3\x3f\xc0\x6b\x6d\x80\x6e\xb1\x28\x73\x1a\xc3\x5c\x85\xd4\xf3\x5a\xeb\x73\x4f\x5b\xaf\xf9\x2b\x4c\xa7\xf0\xb1\x75\xfb\x60\x13\xa9\x25\xb3\x0e\xe5\x8a\x37\x32\x58\x68\xfd\xc0\x6e\x1f\x29\xe1\x89\x6f\x95\xbe\x51\x43\xab\xfb\xb5\xd0\xd0\x0c\xe6\xa3\x97\x6b\x94\x39\xa6\x39\xcd\x47\x63\x98\x8f\x3e\x18\xbd\x34\x64\x39\x77\x73\x07\xc7\xe2\xf9\xe8\x7b\x5a\x1a\x14\x24\xe6\x23\x66\xfb\xa7\x12\x5d\xb6\x3a\x23\xb3\xa4\xb7\xb4\x79\xee\x99\xb5\xdd\xe7\xce\x70\x4d\xb2\x79\x5e\xf0\xb8\xef\xe7\x62\xe3\x62\x53\xd2\xf3\x02\xcb\xb6\xe3\x0c\xcb\x76\x72\xab\x3d\x0b\x97\x57\xec\xdb\xeb\xd3\xa4\xd3\xe8\xa7\x9f\xac\x56\xb3\xf9\xa8\xdb\xff\x58\x17\x6c\x19\xa5\xdb\xcc\x47\xb0\xb5\xea\x6c\x3e\xf2\xeb\x36\xfd\xcd\x26\x67\xf3\x11\xaf\xc4\xdd\x46\x3b\x9d\x56\x8b\xd9\x7c\x94\x6e\x1c\xd9\xf1\xe9\xd8\x50\x39\xe6\x4a\xe3\x79\xb7\xc2\x7c\xf4\x89\x75\x32\x9d\x82\x76\x2b\x32\x41\x99\x16\x7e\x1b\x1d\x30\xff\x41\x6f\x0c\x6d\x38\xa3\x77\x8d\x73\xbb\xb5\xb8\xa4\xbd\xe3\x86\xd0\xd6\x65\xd5\xd0\x70\x50\xf1\xde\x61\xde\xe0\xe0\xe0\xa1\x60\x11\x5a\x8e\xd6\x5d\x18\x54\x56\x36\x05\xee\x3e\xca\x3b\x3e\xb9\x3b\x91\x1d\x28\xa4\x7d\xeb\xc0\x71\x87\xf7\xc4\x56\xd1\xae\xa5\x66\x07\xe3\x44\xc6\x7e\x1b\x8e\xc6\xe1\x13\x95\x57\x46\x52\x3b\x65\xa8\x32\x52\x82\x9b\x15\x29\xcf\xaa\x52\x82\x4c\xbe\xe1\x70\xda\x71\xcd\x56\xa8\x96\x9c\xd5\xe0\x0d\x7b\x39\x7a\x3f\xe6\x8c\x77\xcd\xde\x31\xe6\x89\x0a\x2a\xdb\x64\x5f\xbf\xaf\x96\x23\x07\x84\xe0\xc8\x35\x1b\x9f\xc0\xb3\x8c\x4a\xc7\x2e\x73\x37\x2c\x77\xed\x60\x44\x6c\x5a\xc8\x1d\x33\xe0\xb4\x3b\xe1\x85\xf7\x50\xd6\xc6\x71\x4f\xc1\xd7\xd4\xa1\xd4\x58\x55\x05\x2a\xb6\x1e\xc1\xfb\xed\xc6\x94\x90\x19\xfa\x92\xa3\x89\x93\x5d\xfa\xea\xf4\x50\x8b\x9a\x6b\x8c\x94\x38\xc2\x79\xa7\xab\x8f\xf5\x85\x87\x2f\xf0\xf6\x1d\xa9\xa5\x5b\xcd\xe0\xc9\xe3\xbf\x3c\xfd\x6e\x0f\x61\x88\x76\x24\xfe\x46\x8a\x53\xe1\x40\x45\xbb\x47\x0c\xbb\x13\x7b\xf5\x93\x3f\x67\xd2\x94\x11\xc9\xb2\xa3\xf1\x16\xb2\x6d\x97\x37\x68\xc1\x92\x83\x14\xb9\xf6\xaf\x4a\x96\x0b\x47\x6f\xa9\xac\x43\x95\xd1\x18\xe4\x62\x98\x99\x6c\xa3\x72\xbe\x81\xd3\xc7\x63\x48\x6b\x11\xef\xc6\xe4\xcb\xdb\xab\x64\x60\xcb\xd2\xc2\xb3\xf1\x9d\xfd\x70\x41\x58\xf9\x4c\xc6\x86\x03\x37\xd2\xad\xb8\x5e\xf4\xe9\xad\xae\xac\x07\xd2\x1b\xb5\xfb\xfd\x9c\xe2\x38\xc9\x2d\xc9\x7c\xd6\x6c\xa5\x72\x4f\xff\xbc\x5f\xbf\x52\xc9\xa2\x2a\x66\xf0\x68\x0f\x49\x08\x69\xf7\xd4\x66\x20\xee\xb2\x3b\x72\xe8\x5a\x1a\x2c\xb8\xf8\xca\x40\x0a\xae\xa9\x16\x92\x4c\xdf\xb4\xf9\xd0\xf5\x44\xce\xd7\x5b\x52\x7c\x60\xeb\x38\xd4\x33\xf6\x0f\x46\x8b\x2a\xe3\xaa\x5a\x2f\x7c\xc9\x28\x17\x32\xeb\x07\x28\x2e\x55\xbd\x37\x04\xb0\x04\x74\xcb\x42\x6f\x61\x49\x40\x2e\x84\x4a\xaa\xa5\xad\x97\xe4\x9a\x9c\x03\x48\x48\xa5\x37\x2b\xf2\xf9\xc4\x83\xac\x7a\x8e\xf1\xbb\xb2\x52\x90\x21\x01\x08\xcb\x0a\x0d\x2a\x47\x24\x38\xfc\xb0\x0b\xd6\xb4\xbd\x90\x87\x5d\x81\xde\x78\x63\x70\xd5\x10\xac\x78\x8b\x75\x51\xef\x3d\xf6\xeb\xb9\xea\xe9\xa3\xc7\x07\x55\xde\xd2\xed\x25\x2a\xd1\x31\xdc\x9b\xc1\x3f\x2f\x5f\x4e\xfe\x81\x93\x5f\xae\x8e\xeb\x0f\x8f\x26\xcf\xfe\x35\x9e\x5d\x3d\xec\x7d\xbd\x3a\x79\xf1\xc7\x3d\x9c\x82\x07\xdd\xd3\x7c\xea\x24\xd2\x14\x7f\x8d\x46\xc7\x3e\xc3\xe8\x05\x5c\x18\x06\x9e\xaf\x31\xb7\x34\x86\xbf\x2b\x9f\x1a\xbe\x50\x68\xa4\xaa\x62\xff\xee\x38\x2b\x8f\x78\xd5\xe1\x8a\xa2\x25\xf1\x5b\x3a\x4c\x53\x6f\x77\x0f\x8d\xdf\xeb\xfd\x84\xe4\x6b\x31\xbd\xe8\x47\x9a\x1e\x10\x04\x1f\xf1\xb8\xd6\x4c\xea\xb2\x35\xc9\x74\x31\xed\x01\x45\xae\x97\xcf\x50\x6d\xa0\x0b\x6b\xa1\xd2\xbc\x6b\xe9\x96\x11\x10\x60\x66\xb4\xb5\x2d\xd2\xb5\x90\xcb\x6b\x82\xb6\x1c\x0d\xc1\x32\xa5\x0c\x7d\x81\x6d\x52\xe9\x0c\x9a\x4d\xb7\x3b\x0b\x19\x2a\x8f\x5b\x2d\x2d\xaa\x1c\x8e\x2d\x11\x24\x4a\x0b\xda\x8d\xae\x27\x21\x86\x62\x2a\x73\xe9\x36\x1c\x25\x05\x65\x5a\x2d\x72\x59\xd7\xf5\x05\xe3\x2e\x54\x2e\xb8\x9b\xa1\x25\xdd\x82\x74\x50\x70\x11\x49\x96\x49\x8e\x85\xb2\xa7\xa7\x8f\x9f\x9c\x57\xa9\xd0\x05\x4a\xf5\xba\x70\xd3\x93\x17\xc7\x3f\x57\x98\x73\xe4\x11\x3f\x60\x41\xaf\x0b\x77\xf2\xf5\xd2\xe2\xe9\xd3\x7b\x78\xd1\xf1\x65\xf0\x95\xab\xe3\xcb\x49\xfd\xe9\x61\xd3\x75\xf2\xe2\x78\x9e\x1c\x1c\x3f\x79\xc8\x67\xe8\x79\xe0\xd5\xe5\xa4\x73\xbf\xe4\xea\xe1\xc9\x8b\xde\xd8\xc9\xae\x33\x72\xc6\x92\x19\xbd\xcc\x32\x5d\x7d\x33\x58\x39\xec\xfb\x9f\x01\xf4\x21\x04\x34\x90\x7e\x1b\x99\x0f\xc0\x79\xe9\x6c\x9d\x3e\x03\x72\x0f\x96\x51\x07\x12\x0e\xb0\xce\xa0\xcc\x83\x59\x65\xae\xc2\xbc\x07\xfb\xc1\x6e\xac\xa3\xe2\x2b\xa1\xf6\xce\x8c\x23\x82\x8e\x08\x3a\x22\xe8\xa1\x36\x19\xc0\x9b\x11\x6c\x47\xb0\xdd\xb5\x08\xb6\x23\xd8\x8e\x60\xfb\x5e\xda\x8c\x60\x3b\x82\xed\xed\x16\xc1\x76\x4d\x13\xc1\x76\x04\xdb\xdf\x1a\x6c\x87\x3c\x35\x03\x67\xaa\xa6\x68\xb1\x4e\x1b\x2e\x52\x60\xc1\x26\xdb\x74\x56\x69\xab\xdf\xce\x0a\x6b\xd7\x85\x5f\x7f\xdb\x7e\x54\xf3\x38\x3e\xaa\x89\x8f\x6a\xe2\xa3\x9a\xf8\xa8\xa6\x69\xdf\xfa\x51\xcd\xf6\x0d\x5c\x78\xf9\xb2\x75\xe3\xe6\x6d\xb6\x34\x7a\x2d\x05\xd9\x3b\x4f\x70\x7c\x1d\x7e\x27\xcb\x14\xa8\xaa\xfe\xb3\x1a\xfa\x36\x8f\x6a\xe2\xf5\x5c\xbc\x9e\x8b\xd7\x73\xf1\x7a\x6e\xbb\xc5\xeb\xb9\xb6\xc5\xeb\xb9\x78\x3d\x17\xaf\xe7\xe2\xf5\x5c\xbc\x9e\xbb\xdb\xe2\xf5\x5c\x68\xf1\x7a\x2e\x5e\xcf\x0d\xb4\xff\x8d\xeb\xb9\xbe\x05\xc5\x9f\x57\x44\xf4\x19\xd1\xe7\x7f\x1f\xfa\x8c\x90\x32\x42\xca\x08\x29\x07\x5a\x84\x94\x11\x52\x46\x48\x19\x21\xe5\x4e\x8b\x90\xb2\xa6\x89\x90\x32\x42\xca\xf8\xf3\x8a\xdf\xf9\xf3\x8a\xf7\xef\xce\x7a\xef\x39\xc2\x3b\x8f\x9e\x65\xad\x70\x4d\x90\x12\xa9\xb6\x8c\x88\xff\x8b\x8d\x68\x38\xa2\xe1\xf8\xbf\xd8\xba\x45\xe0\x1c\x81\x73\x04\xce\x11\x38\x6f\x29\x2e\x02\xe7\x08\x9c\xb7\x55\x19\x81\xf3\xef\x17\x5a\x04\xce\x11\x38\x0f\xa8\xe2\xff\x03\x38\x1f\xfa\xa9\x44\xbf\xef\x73\xbf\x94\xf8\x77\x00\x00\x00\xff\xff\x0a\x10\x91\x5e\x61\x56\x00\x00") func operatorsCoreosCom_operatorconditionsYamlBytes() ([]byte, error) { return bindataRead( @@ -185,7 +185,7 @@ func operatorsCoreosCom_operatorconditionsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorgroupsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x79\x6f\x23\x37\x96\xff\xbf\x3f\xc5\x83\x66\x81\xb6\xb3\x3a\xda\x9d\x45\x36\x23\x20\x08\x8c\xee\x74\xe0\x4d\xb7\xdb\x68\xbb\xb3\xc0\x5a\xde\x1d\xaa\xea\x55\x89\x63\x16\x59\x43\xb2\x24\x6b\x82\x7c\xf7\xc5\x7b\x64\x1d\xba\xe5\x1c\xb3\x93\x85\xea\x1f\x5b\x3c\xdf\xc1\xf7\x7b\x07\x29\x4a\xf9\x23\x5a\x27\x8d\x1e\x83\x28\x25\x3e\x79\xd4\xf4\xcb\x0d\x1f\xbf\x76\x43\x69\x46\xf3\x8b\x17\x8f\x52\xa7\x63\x78\x53\x39\x6f\x8a\x4f\xe8\x4c\x65\x13\x7c\x8b\x99\xd4\xd2\x4b\xa3\x5f\x14\xe8\x45\x2a\xbc\x18\xbf\x00\x10\x5a\x1b\x2f\xa8\xd9\xd1\x4f\x80\xc4\x68\x6f\x8d\x52\x68\x07\x39\xea\xe1\x63\x35\xc5\x69\x25\x55\x8a\x96\x17\xaf\xb7\x9e\xbf\x1a\x7e\x3d\x7c\xf5\x02\x20\xb1\xc8\xd3\xef\x64\x81\xce\x8b\xa2\x1c\x83\xae\x94\x7a\x01\xa0\x45\x81\x63\x30\x25\x5a\xe1\x8d\xcd\xad\xa9\x4a\x37\xac\x7f\xba\x61\x62\x2c\x1a\xfa\x53\xbc\x70\x25\x26\xb4\x3b\x8f\x69\xa7\xac\x8c\x09\xeb\xd5\x44\x0a\x8f\xb9\xb1\xb2\xfe\x0d\x30\x00\xa3\x0a\xfe\x3f\x30\xff\x31\xae\xf1\x3d\x2d\xc9\xed\x4a\x3a\xff\xc3\x66\xdf\x7b\xe9\x3c\xf7\x97\xaa\xb2\x42\xad\x13\xcc\x5d\x6e\x66\xac\xbf\x6e\xb7\xe7\xed\xf2\xd0\x25\x75\x5e\x29\x61\xd7\xe6\xbd\x00\x70\x89\x29\x71\x0c\x3c\xad\x14\x09\xa6\x2f\x00\xa2\xf8\xe2\x32\x83\x28\xa2\xf9\x45\x5c\xd5\x25\x33\x2c\x44\xbd\x07\xd0\x92\xfa\xf2\xe6\xea\xc7\x2f\x6f\xd7\x3a\x00\x52\x74\x89\x95\xa5\x67\x65\xac\x30\x04\xd2\x81\x9f\x21\x54\x5a\x7a\x30\x19\x14\x95\xf2\xd2\xa3\x16\x3a\x59\x42\x66\x2c\x7c\x7c\xff\x01\x0a\xa1\x45\x8e\x69\x47\xd4\x70\xe5\x49\xf7\xce\x5b\x21\x75\x58\x41\x6a\xe7\x85\x52\xac\x5e\x5a\xa9\x19\x0c\x52\x83\xf4\x2e\x68\x84\x78\x03\x6f\x40\x00\xa9\x51\x66\x12\x53\x70\xc8\x5b\x7b\x61\x73\xf4\xed\x30\x37\xec\x70\xe0\x97\x24\x1e\x33\xfd\x2b\x26\xbe\xd3\x6c\xf1\x6f\x95\xb4\x98\x76\x99\x25\x51\xd5\x87\xb6\xd3\x5c\x5a\xa2\xc8\x77\x4e\x41\xf8\x3a\x26\xb2\xd2\xbe\x26\xb5\x97\x24\xda\x30\x0e\x52\xb2\x0e\x0c\x6c\x47\x25\x11\x1b\x2c\x76\xe6\x64\x26\x1d\x58\x2c\x2d\x3a\xd4\xbe\x91\x88\xd0\x91\x81\x21\xdc\xa2\xa5\x89\x74\x56\x2a\x95\x92\x28\xe7\x68\x3d\x58\x4c\x4c\xae\xe5\xdf\x9b\xd5\x1c\xc9\x8a\xb6\x51\xc2\xa3\xf3\x20\xb5\x47\xab\x85\x82\xb9\x50\x15\xf6\x41\xe8\x14\x0a\xb1\x04\x8b\xb4\x2e\x54\xba\xb3\x02\x0f\x71\x43\xf8\x60\x2c\x69\x27\x33\x63\x98\x79\x5f\xba\xf1\x68\x94\x4b\x5f\x03\x40\x62\x8a\x82\x94\xbf\x1c\xb1\x2d\xcb\x69\x45\x3a\x1b\xa5\x38\x47\x35\x72\x32\x1f\x08\x9b\xcc\xa4\xc7\xc4\x57\x16\x47\xa2\x94\x03\x26\x56\x33\x08\x0c\x8b\xf4\x4f\x36\x42\x86\x7b\xb9\x26\xbe\xa0\x32\xe7\xad\xd4\xf9\x4a\x17\xdb\xdc\x5e\x59\x93\xe5\xd1\xc9\x14\x71\x7a\xe0\xa5\x15\x29\x35\x91\x54\x3e\x7d\x77\x7b\x07\x35\x01\x41\xec\x41\xc2\xed\x50\xd7\x0a\x9b\x04\x25\x75\x86\x36\x8c\xcc\xac\x29\x78\x15\xd4\x69\x69\xa4\xf6\xfc\x23\x51\x12\xb5\x07\x57\x4d\x0b\x3a\xb4\x74\xc0\xd0\x79\xd2\xc3\x10\xde\x30\xfe\xc1\x14\xa1\x2a\x53\xe1\x31\x1d\xc2\x95\x86\x37\xa2\x40\xf5\x46\x38\xfc\xdd\x45\x4d\x12\x75\x03\x12\xdf\xf1\xc2\xee\xc2\xf7\xe6\x84\x0d\x83\x02\xa8\xe1\x75\xa7\x76\x56\xf0\xe3\xb6\xc4\xa4\xc6\x10\x9a\xc9\x98\x21\xf4\x1a\xc8\xd4\x2a\x1a\x1e\x4b\x04\x6d\x99\x89\x4a\xf9\x75\x4a\x00\xaa\x32\xb7\x22\xc5\x5b\x6f\x09\xd6\x97\x63\x78\x1b\x46\xae\x0d\xdc\x65\xee\xcc\x22\x2a\x4c\xbc\xb1\x9b\x3d\x6b\xac\xde\xc6\x81\x71\x46\x60\x73\x85\xb5\x97\x6e\x3f\x6e\x1d\xc1\xe9\x21\x6a\xe9\x2b\x84\x4f\x66\xdf\x3d\xd1\x99\xee\xb8\x84\x03\xd4\xaf\x4f\x0a\x16\x45\x9e\x8d\xd0\x48\x89\x29\xaa\x46\x14\x35\x92\x16\xc1\x64\xee\x66\xb8\xd2\x02\xc2\x22\x5c\x5e\xbf\xc5\x74\x1b\x73\x2d\x83\xc2\x5a\xb1\xdc\x31\x42\x7a\x2c\x76\x12\xbe\x46\xfa\xe5\x1e\xf2\x22\x30\xd4\x3d\x7e\x26\xd8\x17\x79\xf6\x44\x01\xf4\xfa\x20\xe0\x11\x97\x01\x1f\x09\x76\xa3\xca\xc2\x60\x8b\x8c\xa6\xac\xcc\x47\x5c\xf2\xa0\x08\x96\x3b\xa9\x3b\xa0\xbf\xf0\x6d\xf7\x46\xab\xdf\x80\xb6\xdc\xdb\x5f\x13\xbb\x73\xd0\xa1\xc3\x12\xbe\x47\x5c\xee\xeb\x5e\x13\x38\xc9\x21\x9a\x71\x90\x3c\x35\xb0\xb4\xd8\xb2\x6b\x61\x8b\xb2\x54\x12\x19\x0d\xf7\xae\xbd\x13\x8e\x56\xbf\x9a\xd5\x67\x10\xda\xa8\xb2\x45\xf8\xa0\xec\x97\x2e\x28\x96\x4e\xfa\x4c\x96\x31\xc8\x08\xa1\x45\xed\x0a\x7f\x14\x4a\x76\xc2\x18\x3e\xd5\x57\xba\x0f\xd7\xc6\xd3\x9f\xef\x9e\x24\x41\x3d\x9d\x87\xb7\x06\xdd\xb5\xf1\xdc\xf2\x9b\xb0\x1a\x48\x78\x06\xa3\x61\x02\x1f\x76\x1d\xec\x8a\x38\xe9\xfa\x43\x0a\xc3\x32\xd6\x4f\x23\x14\xe9\xc8\x23\x19\x5b\x73\xc4\x11\x4a\x58\x28\x2c\x51\x54\x8e\x1d\x98\x36\x7a\x80\x45\xe9\x97\x5b\xd7\x88\x82\x30\x76\x45\x0e\x7b\x96\x8b\x4b\xdd\x91\x5f\x0d\x3d\x21\x02\x52\x14\xca\x42\x5a\x31\xd1\xec\xcd\x09\xb4\x65\x02\x05\xda\x1c\xa1\x24\x84\x3a\x46\xbc\xfb\x70\x25\x7c\x07\xd0\xe5\x48\x5d\x31\x64\xbe\x27\x03\x78\x06\xc4\x86\xf1\x01\x96\x0a\x51\x92\x9a\x7e\x22\xf4\x61\x49\xfd\x0c\xa5\x90\x14\x31\x5f\x72\xf4\xaf\x70\xa5\x4f\x6a\x96\x69\x77\x19\x5a\x41\x3a\x20\x28\x99\x0b\x45\x78\x47\x27\x59\x03\xaa\x80\x7e\x14\xa4\xaf\x01\x7b\x1f\x16\x33\xe3\x02\x98\x65\x12\x15\xc7\x4e\xbd\x47\x5c\xf6\xfa\x1b\xaa\xed\x5d\xe9\x5e\xc0\xc5\x0d\x65\x36\x20\x6a\xb4\x5a\x42\x8f\xfb\x7a\xbf\xdc\x17\xec\x05\x4b\x91\xa6\x9c\x5e\x0a\x75\x73\x04\x9a\xed\xd5\x9b\x43\x3b\x97\x09\x5e\x26\x89\xa9\x34\x27\x5e\x47\xf8\xf5\xf5\x29\x35\xf8\x89\xb4\x90\x7a\x25\x37\xe1\x91\x20\xc2\x50\x58\xcc\x64\x32\x83\x85\x54\x8a\xc3\x40\x87\x29\xa9\x27\xc5\x52\x99\x65\x23\xe7\x33\x77\x1e\x34\x4b\xf1\x68\x2d\x7b\xce\xf4\x76\x87\x06\xbb\x98\xa3\xf4\x21\xb9\xb1\x66\x2e\x53\x4c\x2f\x6f\xae\xb6\x4a\x69\x95\x39\x9e\x02\x1e\x95\x72\x9c\xbe\x51\xcc\xea\x4d\x8c\x59\xb7\x86\x30\x65\x67\xfd\x4e\x92\xbf\x93\xd8\xa9\x31\x0a\xc5\x66\x7f\x08\x85\x9a\x24\xf6\x30\xad\x77\x6b\x13\x22\xdc\xe1\x53\xa9\x64\x22\x7d\x8d\xdf\x6d\x6c\xc5\xf9\x10\x4f\x62\xe0\x92\x1c\x0d\x38\xf4\xfd\x36\x56\x93\x0e\x64\xae\x8d\xdd\x7e\x3e\xf7\xe3\xc9\x1e\x14\x39\x80\x1d\x4f\x83\xc7\x6a\x8a\x56\xa3\x47\x37\xa0\x18\x6b\x10\x27\xe0\xa6\x09\xac\x87\xb0\x87\xa4\xd4\xfb\xbc\x3a\x61\x25\x01\x8d\x8b\xd5\xd8\x1a\xb2\xf6\x95\xe4\x9b\x46\x35\x12\x64\x7b\xb6\xc8\x46\x9c\x54\xd6\xa2\xf6\x6a\x09\x7e\x61\xc0\x55\x65\x69\xac\xc7\x74\x7d\x49\x32\x4d\x98\xe8\x3a\xd0\x1e\xf3\xa1\x62\x13\x60\xa0\x10\x4a\x99\x05\x24\xaa\x72\x1e\x6d\xb4\xac\x98\x29\xb3\xba\x0a\x33\xc7\x3a\x8d\x0d\x2e\x81\x9c\x41\x39\x13\x0e\xdb\x1c\xcc\x55\x49\x82\x98\x62\x1a\x3a\xa2\x2b\xc1\x2c\xc3\xc4\xcb\x39\xaa\x25\x14\x28\xb8\xd2\x20\x7c\xbb\x3f\x9d\xec\xb0\x7d\xcb\xf0\xda\x8e\x1a\x9f\x7c\x9d\xa4\x83\xe4\x24\x7c\xb5\x52\x61\x1b\x76\x67\xc2\x41\x26\xa4\xa2\xbc\x6e\xa2\xe1\x0e\x93\xd9\x8d\xc5\xb9\xc4\xc5\x67\xed\x44\x86\xef\x84\x54\xef\x8c\x5d\x08\x9b\x76\x64\xf0\x7b\xb0\x4f\x54\x35\x7d\x81\xa4\x5a\x2e\x97\x0d\x70\xaa\x65\xbf\xa5\x22\x47\x4d\x02\x20\x7e\x17\x35\x83\x37\x8a\x24\xb6\x98\xa1\x26\xd7\x5b\x4d\x9b\x13\x05\x16\x33\xb4\xa8\xc9\x9e\x44\xbd\x7e\x67\x52\xe3\x1e\x12\xe1\x85\x32\x39\x4b\x66\x8a\xa8\xeb\xbc\x17\x16\xd2\xcf\x40\xf0\x66\xb5\xf4\x32\x0e\xaf\x11\x90\x42\x05\x62\x31\xda\x6e\xa7\x68\x34\xd1\xf0\x9f\x97\x9f\xae\xaf\xae\xbf\x1f\xb3\x57\xd9\x27\xe1\xcd\x73\x2d\x1d\x54\x3c\xaa\x53\xf5\x70\x95\xf2\x74\xc4\x2b\x8d\x4f\x25\x26\x44\xda\x14\x67\x62\x2e\xc9\x06\x6c\xac\x87\xcc\xd1\x8a\xa9\x42\xa0\x34\x18\x94\x71\xb4\x8e\x42\xe7\x60\x69\x2a\x98\x89\x39\x42\x8a\x58\x42\xa5\x53\xb4\xce\x0b\x9d\x12\xf5\x26\x8b\x91\xef\x2a\x13\x30\x45\xea\xad\x2b\x62\x1b\xd6\xd5\x7b\x2e\xc0\xb7\x99\xee\x8e\x44\x96\x3e\xd4\x55\xb1\x1d\x95\x06\x7b\x66\x51\xef\x3e\x11\xaf\xa6\xfd\x5e\xf8\x6a\x03\xfa\xf6\x24\xfe\x3c\xbe\x49\xfd\xc3\xaf\x6d\xc9\xff\xa7\xe7\xe7\xfe\xbb\xf3\xa8\x01\x28\xe1\xfc\xe7\x70\x0a\x9f\x91\xf1\x27\x46\x07\xb3\x39\xec\x92\xde\x34\x43\xd7\x63\xef\x6d\x9e\xb3\x5d\xf8\x37\x75\x36\xab\xf0\xdf\x90\xd4\x86\x68\x29\x7a\x21\x55\x90\xb8\xd1\x08\x82\x42\x16\x5f\x53\x19\x81\x9d\xd5\x82\x4d\x45\xf2\xf2\xe6\x0a\x1a\x6d\xc0\x60\x30\x08\x20\xeb\xbc\xad\x12\xf6\xa3\x52\x7b\xd4\x04\x42\xb4\x6a\x2a\x2d\x97\x14\x1d\x2d\xde\xca\x21\x66\x84\x21\xcc\x2c\x85\x9f\xc1\x30\x28\x7f\xd8\x11\x05\xc0\x3b\x63\x01\x9f\x44\x51\x2a\xec\xb3\x18\xe0\x9d\x31\xf1\xcc\x84\x0d\x7f\x82\xd1\x08\x3e\xb5\x49\x1c\x07\xaa\x53\x8a\xb7\x42\x0e\xc7\x15\x53\xc8\x8c\x21\x29\x77\xf9\x19\xd2\xc4\x1f\xb4\x59\xe8\x6d\x5b\xf3\x5e\xc2\xe2\x18\x26\xbd\xcb\xb9\x90\x8a\x4c\x7f\xd2\xeb\xc3\xa4\x77\x63\x4d\xce\x21\xb3\xce\x27\x31\x06\x9e\xf4\xde\x22\xc3\x4c\x3a\xe9\xd1\xb2\xff\xca\x19\xc9\x07\x4a\x4e\x7e\xc0\xe5\x37\xbc\x58\xd3\x5c\xbb\xdf\x6f\x42\xf2\x42\xed\xe4\xe8\xef\x96\x25\x7e\x43\x51\x7b\xdd\xf0\x41\x94\xcd\xe4\xce\x69\xba\x7f\x28\xd0\x8b\xf9\xc5\xb0\x55\xe7\x5f\xfe\xea\x8c\x1e\x4f\x7a\x2d\xfd\x7d\x53\xd0\xb1\x28\xfd\x72\xd2\x83\x95\x5d\xc7\x93\x1e\xef\x5b\xb7\xd7\x44\x8e\x27\x3d\xda\x89\x9a\xad\xf1\x66\x5a\x65\xe3\x49\x6f\xba\xf4\xe8\xfa\x17\x7d\x8b\x65\x9f\xc0\xe9\x9b\x76\x87\x49\xef\x2f\x04\xc4\xa3\x11\x18\x3f\x43\x1b\x34\xe9\xe0\xe7\x6d\xc8\x75\x44\x28\x7f\xa8\xe6\x11\x2c\xf6\xce\x0a\xed\x64\x7d\xf3\xb3\x73\x68\x81\xce\x89\x7c\x77\xbf\x45\xe1\xb6\x86\xa5\xa1\x3b\x9c\x86\x9d\xdd\xc4\xcb\xd6\xce\xc3\x05\x95\x4d\x1e\x8e\x2c\x64\x6d\x4e\x6c\xcb\x2c\xce\x83\xa7\x06\xb6\xd8\xe6\x4c\xf8\x66\x34\x19\x22\x05\x01\x64\xdf\x11\x60\x39\x15\x64\xbd\xc5\x08\x29\x5e\x20\x4c\x31\xf8\xf9\x70\x95\x93\xa2\x55\x4b\x72\x53\xed\xaa\xc9\x4c\xe8\x9c\x02\x9b\x90\xee\x0b\xb6\x77\x0a\x9f\x1e\xc9\x90\x38\x4d\xd4\x50\xb9\xba\xb0\xce\x74\x35\x2b\x12\x70\x04\x83\x8f\xcb\x30\x32\x26\x09\x96\x9e\xac\xeb\x50\xd5\xec\x40\x6d\x24\x33\xb6\x10\x7e\x4c\xee\x19\x07\x7e\xf7\xf1\x88\x87\xe3\x48\xc1\xc7\xd1\x21\x2b\x9f\x55\x85\xa0\xa8\x47\xa4\x1c\x08\x34\x7d\x3a\x95\x89\xe0\x60\xa5\xc6\x53\x31\x35\x55\x40\xb8\x56\x0f\x51\xd4\x14\x71\x4c\x91\xd3\x13\xb2\xcf\xc8\xd6\xaf\x64\xbe\x10\x4f\xef\x51\xe7\x7e\x36\x86\x2f\x5f\xff\xfb\x57\x5f\xef\x18\x18\x80\x11\xd3\xef\x43\x98\xb7\xe5\xb2\x6a\x87\x18\x36\x27\x76\x0b\x67\xc4\xe7\xb0\xbe\x21\x18\xe6\xed\x98\xa6\xf2\xd7\x9e\xa0\x85\xe0\x44\x0b\xa6\xc2\x71\x8a\x40\x72\x21\x94\xe7\xb8\x51\x27\xd8\xa7\xe8\x7a\xeb\x62\xd2\x75\x32\x8d\x8b\xd7\x7d\x98\x46\x11\x6f\xc2\xf7\xfd\xd3\xc3\x70\x0b\xc9\xd2\xc1\x9f\xfb\x6b\xf4\x50\x6e\x5d\xb1\xc7\xe3\xb4\x96\x23\x52\x8b\xc1\x0d\xc6\x70\x7b\x8b\x1b\xc4\x86\xde\x43\x8a\x23\x67\x98\xe3\xee\x2a\x6c\x7d\x6c\xa5\xf6\x5f\xfd\xdb\x6e\xfd\x4a\x2d\x8b\xaa\x18\xc3\xab\x1d\x43\x02\xa4\x1d\xa9\xcd\x30\xb8\x8d\x02\x04\x41\x57\x6e\x45\x51\x70\xca\x2f\x53\xd4\x5e\x66\x12\x6d\xf7\x68\x87\xc4\x83\x27\xd6\x31\x7a\x23\xc5\x97\x2e\xe2\x50\xe7\xb0\xdf\x58\x93\x56\x09\x5a\xf6\xc0\xb1\x12\x92\x74\x01\x6a\x59\x62\xb0\x86\x90\x86\x42\x13\x7a\xd7\xd5\x24\x0a\xcf\x51\x68\xa9\x73\x17\xb7\x94\x2e\x00\x48\xf0\xba\x8b\x19\xb2\xeb\x59\xa9\x40\x31\x55\x4e\xa6\x68\x31\x05\x01\x79\x25\xac\xd0\x1e\x31\x25\xf8\x09\x55\xa8\x70\x0b\xd8\x42\x9e\x68\xef\xde\x6a\x6b\x0c\xa6\x1a\xc0\x8a\x48\x8c\xf7\x75\xa1\x3e\xf9\x9b\x99\xea\xc5\xab\xd7\x7b\x55\xde\x8c\xdb\x5d\xc3\x17\xde\xa3\xd5\x63\xf8\xef\xfb\xcb\xc1\x7f\x89\xc1\xdf\x1f\xce\xe2\x3f\xaf\x06\x7f\xfe\x9f\xfe\xf8\xe1\x8b\xce\xcf\x87\xf3\x6f\xff\x65\xc7\x4a\xdb\xc3\xf6\x1d\xc7\x27\x3a\x91\x3a\x48\xac\x35\xda\x67\x0f\x63\x32\xb8\xb3\x15\xf6\xe1\x9d\x50\x0e\xfb\xf0\x59\xb3\x6b\xf8\x95\x42\xdb\x9d\xb9\x84\x6f\x00\x3d\xda\x75\x7b\xf0\xd1\x0c\x61\x92\xf6\x8f\x89\xe4\xee\xab\x48\x1e\x27\x24\x0e\xdb\x4c\xd6\x45\x9a\xce\x1d\x2f\x30\xe2\x51\x58\x3a\x8c\xe1\xed\x30\x31\xc5\xa8\x73\x07\x4c\x71\xf5\x07\xa1\x97\xd0\xc2\x5a\x08\x4a\xd7\x4f\xba\xf3\x84\x4d\x22\xb1\x94\x91\x36\xb7\xe8\xa0\xe4\x23\x42\x13\xb9\x06\xb0\x9c\x62\x22\x38\x10\xb7\x53\xe9\xad\xb0\xcb\x4e\xde\x01\x89\xd0\xb1\x16\x99\x55\x0a\xce\x1c\x22\x0c\xb5\x49\x71\x13\x5d\xcf\x03\x86\x8a\xa9\x54\xd2\x2f\x43\xe1\x32\x31\x3a\x53\x32\xc6\xff\x45\x69\xac\x17\xda\xd7\x45\xdf\x1c\x9f\x40\xfa\x50\x6f\x0e\xc5\xb9\xb3\x54\xbb\x8b\x8b\xd7\x5f\xde\x56\xd3\xd4\x14\x42\xea\x77\x85\x1f\x9d\x7f\x7b\xf6\xb7\x4a\x28\xae\x98\x5e\x8b\x02\xdf\x15\xfe\xfc\xb7\x73\x8b\x17\x5f\x1d\x61\x45\x67\xf7\xc1\x56\x1e\xce\xee\x07\xf1\xbf\x2f\xea\xa6\xf3\x6f\xcf\x26\xc3\xbd\xfd\xe7\x5f\x10\x0f\x1d\x0b\x7c\xb8\x1f\xb4\xe6\x37\x7c\xf8\xe2\xfc\xdb\x4e\xdf\xf9\xa6\x31\x76\xb2\xd2\x83\x09\xe6\xfb\x76\x6c\x88\x4e\x7c\xfd\x18\xaa\xb6\xcc\xd5\xd0\x70\x3d\xe5\x8c\x56\x4c\xfe\x38\x2e\xf3\xec\xaa\xf2\x31\x41\x97\x3e\xbe\x8a\xbb\x5a\xbf\xed\x94\x4d\x36\xae\xc6\x1b\x0f\xb4\xc2\xd4\x3f\x6b\x9d\x76\xf5\x66\xe1\x13\x66\xcf\xbc\x58\xf8\x84\x59\xb7\xd4\x16\x04\xb3\x7a\x9f\x10\x9f\xab\x34\x17\x0e\xbf\xc3\xdb\x81\xdd\x0f\x9c\xb6\xb2\x40\xc1\x7e\x5d\x2f\x8d\xe7\x31\xf2\xb0\xf3\x22\xf4\xa0\x49\xb3\x3f\xbe\x11\x7e\x76\x14\x05\x2f\xaf\xa2\xd8\xf8\xd6\x90\xef\x71\x4b\x89\x09\xae\xbc\xa1\xe2\x38\x0e\x45\x1a\x1b\x29\xf0\xb1\x18\xfb\xfa\x21\xe2\x88\x77\xa5\xed\x1b\x2b\x0a\x9a\x40\x10\x10\xcb\x14\xfe\xe3\xf6\xe3\xf5\xe8\x7b\x13\x63\x05\xca\x66\x5c\xb0\x2d\xbe\xe5\xea\x83\xab\x92\x19\x08\x47\xa4\x51\x7e\x7b\xcb\xa5\x87\x42\x68\x99\xa1\xf3\xc3\xb8\x1a\x5a\x77\xff\xfa\x61\xb8\x5a\xee\x90\xf1\x42\xb5\x7e\x89\x14\x0f\x00\xdb\x06\x31\xd3\xcc\xe5\xa0\x95\x49\x2a\x4d\x1a\x89\x5e\x30\xb1\x5e\x3c\x22\x98\x48\x6c\x85\xec\x14\xc6\xd0\xa3\x63\xd2\xd9\xfa\x27\x32\xac\x9f\x7b\x70\xb6\xe0\x92\x7e\x8f\x7e\xf6\xc2\x86\xcd\xc3\x31\x6a\xeb\x78\xfc\xb8\x71\x88\xef\xad\xcc\x73\x0e\xb7\xb8\x6e\x3b\x47\xed\xcf\xd9\xbf\x65\xa0\x4d\x67\xb0\x8e\xf7\x63\xed\xad\xd8\x3a\x21\xf7\xaf\x1f\x7a\x70\xb6\xca\x17\x85\xa0\xf8\x04\xaf\x9b\x9b\xb0\xd2\xa4\xe7\x75\xd6\xba\xd4\x5e\x3c\x71\x62\x30\x33\x0e\x75\xb8\x48\xf0\x26\x54\x63\x9d\xa1\xe4\x13\x95\x1a\x84\x00\x33\x85\x45\x28\xc0\xd5\xa2\x0c\x97\xc9\xa5\xb0\x7e\xed\x59\xdd\xdd\xc7\xb7\x1f\xc7\x61\x37\x52\x5b\xae\xeb\x2c\x37\x93\x5a\xa8\x58\xd6\x6e\xe2\x43\x22\xa4\x0a\x4a\xf2\x26\xa6\xb6\x75\x45\x37\xab\x7c\x65\x71\xb8\xfe\xcc\xea\xe8\x13\xbf\xed\x8d\xdb\xf6\xc3\xce\x6f\xdd\xd6\x0d\xed\xff\xf0\x25\xd9\xd1\x2c\xea\x1d\x37\xad\x9b\x2c\x5e\x77\xce\xe0\x5e\x16\x5b\x68\x26\x2e\x53\x93\x38\x62\x30\xc1\xd2\xbb\x91\x99\x13\x74\xe2\x62\xb4\x30\xf6\x51\xea\x7c\x40\x87\x6c\x10\x34\xef\x46\xec\x62\x46\x7f\xe2\x3f\xbf\x8a\x23\xf6\x53\xc7\xb3\x15\x1e\xb4\xfe\x03\x78\x63\xf7\x39\xfa\xc5\xac\xd5\xf1\xe5\x73\x3c\xc1\xcb\xdb\x3a\xf9\x5b\x9b\x4d\xe6\x12\x2e\xc2\xe3\x4b\xd7\x0e\xc2\x15\x22\x0d\x10\x28\xf4\xf2\x77\x3f\xc6\x24\x40\xce\xf1\x93\xe5\x20\x3e\x45\x1f\x08\x9d\x0e\x9a\xf8\x3a\x59\xfe\x62\x89\x55\xf2\x48\x03\xfe\x7c\xf5\xf6\x1f\x73\xb8\x2b\xf9\x2c\x6b\x0d\x55\x94\x31\x78\x5b\xd5\xd1\x9d\xf3\xc6\x8a\x1c\x57\xdb\xaa\x69\x93\x7c\xb4\x0c\xc7\xbc\x12\x7e\xfa\x99\x9b\xda\xc7\xe7\x42\x95\x33\xf1\xba\x9e\x7b\x7a\x82\x7e\x7a\x82\x7e\x7a\x82\x7e\x7a\x82\xbe\x57\xd8\x7f\xd4\x27\xe8\xa7\x27\xe4\xa7\x27\xe4\xa7\x27\xe4\xbb\xbb\x4f\x4f\xc8\x4f\x4f\xc8\x4f\x4f\xc8\xd7\xbf\xd3\x13\xf2\xd3\x13\xf2\xd3\x13\xf2\xd3\x13\xf2\x2d\xdf\x4e\x35\xfd\xff\x7e\x7c\x79\xba\x1c\xfb\x63\x5c\x8e\x9d\xae\xbb\x4e\xd7\x5d\xa7\xeb\xae\xd3\x75\xd7\x2f\x38\xf1\xa7\xeb\xae\xd3\x75\xd7\xe9\xba\xeb\x74\xdd\xf5\x4f\x7a\xdd\x95\x09\xe5\x8e\xbe\xef\xfa\xdf\x00\x00\x00\xff\xff\x25\xf1\x04\x48\x34\x4b\x00\x00") +var _operatorsCoreosCom_operatorgroupsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x79\x6f\x23\x37\x96\xff\xbf\x3f\xc5\x83\x66\x81\xb6\xb3\x3a\xda\x9d\x45\x76\x22\x20\x08\x8c\xee\x74\xe0\x4d\xb7\xdb\x68\xbb\xb3\xc0\x5a\xde\x1d\xaa\xea\x55\x89\x63\x16\x59\x43\xb2\x24\x6b\x82\x7c\xf7\xc5\x7b\x64\x1d\xba\xe5\x1c\xb3\x93\x85\xea\x1f\x5b\x3c\xdf\xc1\xf7\x7b\x07\x29\x4a\xf9\x23\x5a\x27\x8d\x1e\x83\x28\x25\x3e\x79\xd4\xf4\xcb\x0d\x1f\xff\xec\x86\xd2\x8c\xe6\x17\x2f\x1e\xa5\x4e\xc7\xf0\xa6\x72\xde\x14\x9f\xd0\x99\xca\x26\xf8\x16\x33\xa9\xa5\x97\x46\xbf\x28\xd0\x8b\x54\x78\x31\x7e\x01\x20\xb4\x36\x5e\x50\xb3\xa3\x9f\x00\x89\xd1\xde\x1a\xa5\xd0\x0e\x72\xd4\xc3\xc7\x6a\x8a\xd3\x4a\xaa\x14\x2d\x2f\x5e\x6f\x3d\x7f\x35\xfc\x7a\xf8\xea\x05\x40\x62\x91\xa7\xdf\xc9\x02\x9d\x17\x45\x39\x06\x5d\x29\xf5\x02\x40\x8b\x02\xc7\x60\x4a\xb4\xc2\x1b\x9b\x5b\x53\x95\x6e\x58\xff\x74\xc3\xc4\x58\x34\xf4\xa7\x78\xe1\x4a\x4c\x68\x77\x1e\xd3\x4e\x59\x19\x13\xd6\xab\x89\x14\x1e\x73\x63\x65\xfd\x1b\x60\x00\x46\x15\xfc\x7f\x60\xfe\x63\x5c\xe3\x7b\x5a\x92\xdb\x95\x74\xfe\x87\xcd\xbe\xf7\xd2\x79\xee\x2f\x55\x65\x85\x5a\x27\x98\xbb\xdc\xcc\x58\x7f\xdd\x6e\xcf\xdb\xe5\xa1\x4b\xea\xbc\x52\xc2\xae\xcd\x7b\x01\xe0\x12\x53\xe2\x18\x78\x5a\x29\x12\x4c\x5f\x00\x44\xf1\xc5\x65\x06\x51\x44\xf3\x8b\xb8\xaa\x4b\x66\x58\x88\x7a\x0f\xa0\x25\xf5\xe5\xcd\xd5\x8f\x5f\xde\xae\x75\x00\xa4\xe8\x12\x2b\x4b\xcf\xca\x58\x61\x08\xa4\x03\x3f\x43\xa8\xb4\xf4\x60\x32\x28\x2a\xe5\xa5\x47\x2d\x74\xb2\x84\xcc\x58\xf8\xf8\xfe\x03\x14\x42\x8b\x1c\xd3\x8e\xa8\xe1\xca\x93\xee\x9d\xb7\x42\xea\xb0\x82\xd4\xce\x0b\xa5\x58\xbd\xb4\x52\x33\x18\xa4\x06\xe9\x5d\xd0\x08\xf1\x06\xde\x80\x00\x52\xa3\xcc\x24\xa6\xe0\x90\xb7\xf6\xc2\xe6\xe8\xdb\x61\x6e\xd8\xe1\xc0\x2f\x49\x3c\x66\xfa\x57\x4c\x7c\xa7\xd9\xe2\xdf\x2a\x69\x31\xed\x32\x4b\xa2\xaa\x0f\x6d\xa7\xb9\xb4\x44\x91\xef\x9c\x82\xf0\x75\x4c\x64\xa5\x7d\x4d\x6a\x2f\x49\xb4\x61\x1c\xa4\x64\x1d\x18\xd8\x8e\x4a\x22\x36\x58\xec\xcc\xc9\x4c\x3a\xb0\x58\x5a\x74\xa8\x7d\x23\x11\xa1\x23\x03\x43\xb8\x45\x4b\x13\xe9\xac\x54\x2a\x25\x51\xce\xd1\x7a\xb0\x98\x98\x5c\xcb\xbf\x37\xab\x39\x92\x15\x6d\xa3\x84\x47\xe7\x41\x6a\x8f\x56\x0b\x05\x73\xa1\x2a\xec\x83\xd0\x29\x14\x62\x09\x16\x69\x5d\xa8\x74\x67\x05\x1e\xe2\x86\xf0\xc1\x58\xd2\x4e\x66\xc6\x30\xf3\xbe\x74\xe3\xd1\x28\x97\xbe\x06\x80\xc4\x14\x05\x29\x7f\x39\x62\x5b\x96\xd3\x8a\x74\x36\x4a\x71\x8e\x6a\xe4\x64\x3e\x10\x36\x99\x49\x8f\x89\xaf\x2c\x8e\x44\x29\x07\x4c\xac\x66\x10\x18\x16\xe9\x9f\x6c\x84\x0c\xf7\x72\x4d\x7c\x41\x65\xce\x5b\xa9\xf3\x95\x2e\xb6\xb9\xbd\xb2\x26\xcb\xa3\x93\x29\xe2\xf4\xc0\x4b\x2b\x52\x6a\x22\xa9\x7c\xfa\xee\xf6\x0e\x6a\x02\x82\xd8\x83\x84\xdb\xa1\xae\x15\x36\x09\x4a\xea\x0c\x6d\x18\x99\x59\x53\xf0\x2a\xa8\xd3\xd2\x48\xed\xf9\x47\xa2\x24\x6a\x0f\xae\x9a\x16\x74\x68\xe9\x80\xa1\xf3\xa4\x87\x21\xbc\x61\xfc\x83\x29\x42\x55\xa6\xc2\x63\x3a\x84\x2b\x0d\x6f\x44\x81\xea\x8d\x70\xf8\xbb\x8b\x9a\x24\xea\x06\x24\xbe\xe3\x85\xdd\x85\xef\xcd\x09\x1b\x06\x05\x50\xc3\xeb\x4e\xed\xac\xe0\xc7\x6d\x89\x49\x8d\x21\x34\x93\x31\x43\xe8\x35\x90\xa9\x55\x34\x3c\x96\x08\xda\x32\x13\x95\xf2\xeb\x94\x00\x54\x65\x6e\x45\x8a\xb7\xde\x12\xac\x2f\xc7\xf0\x36\x8c\x5c\x1b\xb8\xcb\xdc\x99\x45\x54\x98\x78\x63\x37\x7b\xd6\x58\xbd\x8d\x03\xe3\x8c\xc0\xe6\x0a\x6b\x2f\xdd\x7e\xdc\x3a\x82\xd3\x43\xd4\xd2\x57\x08\x9f\xcc\xbe\x7b\xa2\x33\xdd\x71\x09\x07\xa8\x5f\x9f\x14\x2c\x8a\x3c\x1b\xa1\x91\x12\x53\x54\x8d\x28\x6a\x24\x2d\x82\xc9\xdc\xcd\x70\xa5\x05\x84\x45\xb8\xbc\x7e\x8b\xe9\x36\xe6\x5a\x06\x85\xb5\x62\xb9\x63\x84\xf4\x58\xec\x24\x7c\x8d\xf4\xcb\x3d\xe4\x45\x60\xa8\x7b\xfc\x4c\xb0\x2f\xf2\xec\x89\x02\xe8\xf5\x41\xc0\x23\x2e\x03\x3e\x12\xec\x46\x95\x85\xc1\x16\x19\x4d\x59\x99\x8f\xb8\xe4\x41\x11\x2c\x77\x52\x77\x40\x7f\xe1\xdb\xee\x8d\x56\xbf\x01\x6d\xb9\xb7\xbf\x26\x76\xe7\xa0\x43\x87\x25\x7c\x8f\xb8\xdc\xd7\xbd\x26\x70\x92\x43\x34\xe3\x20\x79\x6a\x60\x69\xb1\x65\xd7\xc2\x16\x65\xa9\x24\x32\x1a\xee\x5d\x7b\x27\x1c\xad\x7e\x35\xab\xcf\x20\xb4\x51\x65\x8b\xf0\x41\xd9\x2f\x5d\x50\x2c\x9d\xf4\x99\x2c\x63\x90\x11\x42\x8b\xda\x15\xfe\x28\x94\xec\x84\x31\x7c\xaa\xaf\x74\x1f\xae\x8d\xa7\x3f\xdf\x3d\x49\x82\x7a\x3a\x0f\x6f\x0d\xba\x6b\xe3\xb9\xe5\x37\x61\x35\x90\xf0\x0c\x46\xc3\x04\x3e\xec\x3a\xd8\x15\x71\xd2\xf5\x87\x14\x86\x65\xac\x9f\x46\x28\xd2\x91\x47\x32\xb6\xe6\x88\x23\x94\xb0\x50\x58\xa2\xa8\x1c\x3b\x30\x6d\xf4\x00\x8b\xd2\x2f\xb7\xae\x11\x05\x61\xec\x8a\x1c\xf6\x2c\x17\x97\xba\x23\xbf\x1a\x7a\x42\x04\xa4\x28\x94\x85\xb4\x62\xa2\xd9\x9b\x13\x68\xcb\x04\x0a\xb4\x39\x42\x49\x08\x75\x8c\x78\xf7\xe1\x4a\xf8\x0e\xa0\xcb\x91\xba\x62\xc8\x7c\x4f\x06\xf0\x0c\x88\x0d\xe3\x03\x2c\x15\xa2\x24\x35\xfd\x44\xe8\xc3\x92\xfa\x19\x4a\x21\x29\x62\xbe\xe4\xe8\x5f\xe1\x4a\x9f\xd4\x2c\xd3\xee\x32\xb4\x82\x74\x40\x50\x32\x17\x8a\xf0\x8e\x4e\xb2\x06\x54\x01\xfd\x28\x48\x5f\x03\xf6\x3e\x2c\x66\xc6\x05\x30\xcb\x24\x2a\x8e\x9d\x7a\x8f\xb8\xec\xf5\x37\x54\xdb\xbb\xd2\xbd\x80\x8b\x1b\xca\x6c\x40\xd4\x68\xb5\x84\x1e\xf7\xf5\x7e\xb9\x2f\xd8\x0b\x96\x22\x4d\x39\xbd\x14\xea\xe6\x08\x34\xdb\xab\x37\x87\x76\x2e\x13\xbc\x4c\x12\x53\x69\x4e\xbc\x8e\xf0\xeb\xeb\x53\x6a\xf0\x13\x69\x21\xf5\x4a\x6e\xc2\x23\x41\x84\xa1\xb0\x98\xc9\x64\x06\x0b\xa9\x14\x87\x81\x0e\x53\x52\x4f\x8a\xa5\x32\xcb\x46\xce\x67\xee\x3c\x68\x96\xe2\xd1\x5a\xf6\x9c\xe9\xed\x0e\x0d\x76\x31\x47\xe9\x43\x72\x63\xcd\x5c\xa6\x98\x5e\xde\x5c\x6d\x95\xd2\x2a\x73\x3c\x05\x3c\x2a\xe5\x38\x7d\xa3\x98\xd5\x9b\x18\xb3\x6e\x0d\x61\xca\xce\xfa\x9d\x24\x7f\x27\xb1\x53\x63\x14\x8a\xcd\xfe\x10\x0a\x35\x49\xec\x61\x5a\xef\xd6\x26\x44\xb8\xc3\xa7\x52\xc9\x44\xfa\x1a\xbf\xdb\xd8\x8a\xf3\x21\x9e\xc4\xc0\x25\x39\x1a\x70\xe8\xfb\x6d\xac\x26\x1d\xc8\x5c\x1b\xbb\xfd\x7c\xee\xc7\x93\x3d\x28\x72\x00\x3b\x9e\x06\x8f\xd5\x14\xad\x46\x8f\x6e\x40\x31\xd6\x20\x4e\xc0\x4d\x13\x58\x0f\x61\x0f\x49\xa9\xf7\x79\x75\xc2\x4a\x02\x1a\x17\xab\xb1\x35\x64\xed\x2b\xc9\x37\x8d\x6a\x24\xc8\xf6\x6c\x91\x8d\x38\xa9\xac\x45\xed\xd5\x12\xfc\xc2\x80\xab\xca\xd2\x58\x8f\xe9\xfa\x92\x64\x9a\x30\xd1\x75\xa0\x3d\xe6\x43\xc5\x26\xc0\x40\x21\x94\x32\x0b\x48\x54\xe5\x3c\xda\x68\x59\x31\x53\x66\x75\x15\x66\x8e\x75\x1a\x1b\x5c\x02\x39\x83\x72\x26\x1c\xb6\x39\x98\xab\x92\x04\x31\xc5\x34\x74\x44\x57\x82\x59\x86\x89\x97\x73\x54\x4b\x28\x50\x70\xa5\x41\xf8\x76\x7f\x3a\xd9\x61\xfb\x96\xe1\xb5\x1d\x35\x3e\xf9\x3a\x49\x07\xc9\x49\xf8\x6a\xa5\xc2\x36\xec\xce\x84\x83\x4c\x48\x45\x79\xdd\x44\xc3\x1d\x26\xb3\x1b\x8b\x73\x89\x8b\xcf\xda\x89\x0c\xdf\x09\xa9\xde\x19\xbb\x10\x36\xed\xc8\xe0\xf7\x60\x9f\xa8\x6a\xfa\x02\x49\xb5\x5c\x2e\x1b\xe0\x54\xcb\x7e\x4b\x45\x8e\x9a\x04\x40\xfc\x2e\x6a\x06\x6f\x14\x49\x6c\x31\x43\x4d\xae\xb7\x9a\x36\x27\x0a\x2c\x66\x68\x51\x93\x3d\x89\x7a\xfd\xce\xa4\xc6\x3d\x24\xc2\x0b\x65\x72\x96\xcc\x14\x51\xd7\x79\x2f\x2c\xa4\x9f\x81\xe0\xcd\x6a\xe9\x65\x1c\x5e\x23\x20\x85\x0a\xc4\x62\xb4\xdd\x4e\xd1\x68\xa2\xe1\x3f\x2f\x3f\x5d\x5f\x5d\x7f\x3f\x66\xaf\xb2\x4f\xc2\x9b\xe7\x5a\x3a\xa8\x78\x54\xa7\xea\xe1\x2a\xe5\xe9\x88\x57\x1a\x9f\x4a\x4c\x88\xb4\x29\xce\xc4\x5c\x92\x0d\xd8\x58\x0f\x99\xa3\x15\x53\x85\x40\x69\x30\x28\xe3\x68\x1d\x85\xce\xc1\xd2\x54\x30\x13\x73\x84\x14\xb1\x84\x4a\xa7\x68\x9d\x17\x3a\x25\xea\x4d\x16\x23\xdf\x55\x26\x60\x8a\xd4\x5b\x57\xc4\x36\xac\xab\xf7\x5c\x80\x6f\x33\xdd\x1d\x89\x2c\x7d\xa8\xab\x62\x3b\x2a\x0d\xf6\xcc\xa2\xde\x7d\x22\x5e\x4d\xfb\xbd\xf0\xd5\x06\xf4\xed\x49\xfc\x79\x7c\x93\xfa\x87\x5f\xdb\x92\xff\x4f\xcf\xcf\xfd\x77\xe7\x51\x03\x50\xc2\xf9\xcf\xe1\x14\x3e\x23\xe3\x4f\x8c\x0e\x66\x73\xd8\x25\xbd\x69\x86\xae\xc7\xde\xdb\x3c\x67\xbb\xf0\x6f\xea\x6c\x56\xe1\xbf\x21\xa9\x0d\xd1\x52\xf4\x42\xaa\x20\x71\xa3\x11\x04\x85\x2c\xbe\xa6\x32\x02\x3b\xab\x05\x9b\x8a\xe4\xe5\xcd\x15\x34\xda\x80\xc1\x60\x10\x40\xd6\x79\x5b\x25\xec\x47\xa5\xf6\xa8\x09\x84\x68\xd5\x54\x5a\x2e\x29\x3a\x5a\xbc\x95\x43\xcc\x08\x43\x98\x59\x0a\x3f\x83\x61\x50\xfe\xb0\x23\x0a\x80\x77\xc6\x02\x3e\x89\xa2\x54\xd8\x27\xbb\x27\x49\xc0\x3b\x63\xe2\xb1\x09\x7b\xfe\x04\xa3\x11\x7c\x6a\xf3\x38\x8e\x55\xa7\x14\x72\x85\x34\x8e\x8b\xa6\x90\x19\x43\x82\xee\xb2\x34\xa4\x89\x3f\x68\xb3\xd0\xdb\x76\xe7\xbd\x84\xc5\x31\x4c\x7a\x97\x73\x21\x15\x59\xff\xa4\xd7\x87\x49\xef\xc6\x9a\x9c\xa3\x66\x9d\x4f\x62\x18\x3c\xe9\xbd\x45\x46\x9a\x74\xd2\xa3\x65\xff\x95\x93\x92\x0f\x94\x9f\xfc\x80\xcb\x6f\x78\xb1\xa6\xb9\xf6\xc0\xdf\x84\xfc\x85\xda\xc9\xd7\xdf\x2d\x4b\xfc\x86\x02\xf7\xba\xe1\x83\x28\x9b\xc9\x9d\x03\x75\xff\x50\xa0\x17\xf3\x8b\x61\xab\xd1\xbf\xfc\xd5\x19\x3d\x9e\xf4\x5a\xfa\xfb\xa6\xa0\x93\x51\xfa\xe5\xa4\x07\x2b\xbb\x8e\x27\x3d\xde\xb7\x6e\xaf\x89\x1c\x4f\x7a\xb4\x13\x35\x5b\xe3\xcd\xb4\xca\xc6\x93\xde\x74\xe9\xd1\xf5\x2f\xfa\x16\xcb\x3e\xe1\xd3\x37\xed\x0e\x93\xde\x5f\x48\x27\xa3\x11\x18\x3f\x43\x1b\x94\xe9\xe0\xe7\x6d\xe0\x75\x44\x34\x7f\xa8\xec\x11\x8c\xf6\xce\x0a\xed\x64\x7d\xf9\xb3\x73\x68\x81\xce\x89\x7c\x77\xbf\x45\xe1\xb6\x46\xa6\xa1\x3b\x9c\x86\x9d\xdd\xc4\xcb\xd6\xce\xc3\x35\x95\x4d\x1e\x8e\xac\x65\x6d\x4e\x6c\x2b\x2d\xce\x83\xa7\x06\x36\xda\xe6\x4c\xf8\x66\x34\xd9\x22\xc5\x01\x64\xe2\x11\x63\x39\x1b\x64\xbd\xc5\x20\x29\xde\x21\x4c\x31\xb8\xfa\x70\x9b\x93\xa2\x55\x4b\xf2\x54\xed\xaa\xc9\x4c\xe8\x9c\x62\x9b\x90\xf1\x0b\x36\x79\x8a\xa0\x1e\xc9\x90\x38\x53\xd4\x50\xb9\xba\xb6\xce\x74\x35\x2b\x12\x76\x04\x9b\x8f\xcb\x30\x38\x26\x09\x96\x9e\xac\xeb\x50\xe1\xec\x40\x79\x24\x33\xb6\x10\x7e\x4c\x1e\x1a\x07\x7e\xf7\xf1\x88\x87\xe3\x48\xc1\xc7\xd1\x21\x31\x9f\x55\x85\xa0\xc0\x47\xa4\x1c\x0b\x34\x7d\x3a\x95\x89\xe0\x78\xa5\x86\x54\x31\x35\x55\x00\xb9\x56\x0f\x51\xd4\x14\x74\x4c\x91\x33\x14\xb2\xcf\xc8\xd6\xaf\x64\xbe\x10\x4f\xef\x51\xe7\x7e\x36\x86\x2f\x5f\xff\xfb\x57\x7f\xde\x31\x30\x00\x23\xa6\xdf\x87\x48\x6f\xcb\x7d\xd5\x0e\x31\x6c\x4e\xec\xd6\xce\x88\xcf\x61\x7d\x49\x30\xcc\xdb\x31\x4d\xf1\xaf\x3d\x41\x0b\xc1\xb9\x16\x4c\x85\xe3\x2c\x81\xe4\x42\x40\xcf\xa1\xa3\x4e\xb0\x4f\x01\xf6\xd6\xc5\xa4\xeb\x24\x1b\x17\xaf\xfb\x30\x8d\x22\xde\x84\xef\xfb\xa7\x87\xe1\x16\x92\xa5\x83\xaf\xfb\x6b\xf4\x50\x7a\x5d\xb1\xd3\xe3\xcc\x96\x83\x52\x8b\xc1\x13\xc6\x88\x7b\x8b\x27\xc4\x86\xde\x43\x8a\x23\x7f\x98\xe3\xee\x42\x6c\x7d\x6c\xa5\xf6\x5f\xfd\xdb\x6e\xfd\x4a\x2d\x8b\xaa\x18\xc3\xab\x1d\x43\x02\xa4\x1d\xa9\xcd\x30\xb8\x0d\x04\x04\x41\x57\x6e\x45\x51\x70\xd6\x2f\x53\xd4\x5e\x66\x12\x6d\xf7\x68\x87\xdc\x83\x27\xd6\x61\x7a\x23\xc5\x97\x2e\xe2\x50\xe7\xb0\xdf\x58\x93\x56\x09\x5a\xf6\xc0\xb1\x18\x92\x74\x01\x6a\x59\x62\xb0\x86\x90\x89\x42\x13\x7d\xd7\x05\x25\x8a\xd0\x51\x68\xa9\x73\x17\xb7\x94\x2e\x00\x48\xf0\xba\x8b\x19\xb2\xeb\x59\x29\x42\x31\x55\x4e\xa6\x68\x31\x05\x01\x79\x25\xac\xd0\x1e\x31\x25\xf8\x09\x85\xa8\x70\x11\xd8\x42\x9e\x68\xaf\xdf\x6a\x6b\x0c\xa6\x1a\xc0\x8a\x48\x8c\x57\x76\xa1\x44\xf9\x9b\x99\xea\xc5\xab\xd7\x7b\x55\xde\x8c\xdb\x5d\xc6\x17\xde\xa3\xd5\x63\xf8\xef\xfb\xcb\xc1\x7f\x89\xc1\xdf\x1f\xce\xe2\x3f\xaf\x06\x5f\xff\x4f\x7f\xfc\xf0\x45\xe7\xe7\xc3\xf9\xb7\xff\xb2\x63\xa5\xed\x91\xfb\x8e\xe3\x13\x9d\x48\x1d\x27\xd6\x1a\xed\xb3\x87\x31\x19\xdc\xd9\x0a\xfb\xf0\x4e\x28\x87\x7d\xf8\xac\xd9\x35\xfc\x4a\xa1\xed\x4e\x5e\xc2\x37\x80\x1e\xed\xba\x3d\xf8\x68\x86\x30\x49\xfb\xc7\x44\x72\xf7\x15\x25\x8f\x13\x12\x87\x6d\x26\xeb\x22\x4d\xe7\x9a\x17\x18\xf1\x28\x2c\x1d\xc6\x08\x77\x98\x98\x62\xd4\xb9\x06\xa6\xd0\xfa\x83\xd0\x4b\x68\x61\x2d\x04\xa5\xeb\x27\xdd\x79\xc2\x26\x91\x58\x4a\x4a\x9b\x8b\x74\x50\xf2\x11\xa1\x89\x5c\x03\x58\x4e\x31\x11\x1c\x8b\xdb\xa9\xf4\x56\xd8\x65\x27\xf5\x80\x44\xe8\x58\x8e\xcc\x2a\x05\x67\x0e\x11\x86\xda\xa4\xb8\x89\xae\xe7\x01\x43\xc5\x54\x2a\xe9\x97\xa1\x76\x99\x18\x9d\x29\x19\x53\x80\xa2\x34\xd6\x0b\xed\xeb\xba\x6f\x8e\x4f\x20\x7d\x28\x39\x87\xfa\xdc\x59\xaa\xdd\xc5\xc5\xeb\x2f\x6f\xab\x69\x6a\x0a\x21\xf5\xbb\xc2\x8f\xce\xbf\x3d\xfb\x5b\x25\x14\x17\x4d\xaf\x45\x81\xef\x0a\x7f\xfe\xdb\xb9\xc5\x8b\xaf\x8e\xb0\xa2\xb3\xfb\x60\x2b\x0f\x67\xf7\x83\xf8\xdf\x17\x75\xd3\xf9\xb7\x67\x93\xe1\xde\xfe\xf3\x2f\x88\x87\x8e\x05\x3e\xdc\x0f\x5a\xf3\x1b\x3e\x7c\x71\xfe\x6d\xa7\xef\x7c\xd3\x18\x3b\x89\xe9\xc1\x1c\xf3\x7d\x3b\x36\x44\x27\xbe\x7e\x0f\x55\x5b\xe6\x6a\x68\xb8\x9e\x75\x46\x2b\x26\x7f\x1c\x97\x79\x76\x61\xf9\x98\xa0\x4b\x1f\x5f\xc8\x5d\x2d\xe1\x76\x2a\x27\x1b\xb7\xe3\x8d\x07\x5a\x61\xea\x9f\xb5\x54\xbb\x7a\xb9\xf0\x09\xb3\x67\xde\x2d\x7c\xc2\xac\x5b\x6d\x0b\x82\x59\xbd\x52\x88\x2f\x56\x9a\x3b\x87\xdf\xe1\xf9\xc0\xee\x37\x4e\x5b\x59\xa0\x60\xbf\x2e\x99\xc6\xf3\x18\x79\xd8\x79\x17\x7a\xd0\xa4\xd9\x1f\xdf\x08\x3f\x3b\x8a\x82\x97\x57\x51\x6c\x7c\x71\xc8\x57\xb9\xa5\xc4\x04\x57\x9e\x51\x71\x1c\x87\x22\x8d\x8d\x14\xf8\x58\x8c\x7d\xfd\x10\x71\xc4\xeb\xd2\xf6\x99\x15\x05\x4d\x20\x08\x88\x65\x0a\xff\x71\xfb\xf1\x7a\xf4\xbd\x89\xb1\x02\x65\x33\x2e\xd8\x16\x5f\x74\xf5\xc1\x55\xc9\x0c\x84\x23\xd2\x28\xbf\xbd\xe5\xd2\x43\x21\xb4\xcc\xd0\xf9\x61\x5c\x0d\xad\xbb\x7f\xfd\x30\x5c\xad\x78\xc8\x78\xa7\x5a\x3f\x46\x8a\x07\x80\x6d\x83\x98\x69\xe6\x72\xd0\xca\x24\x95\x26\x8d\x44\x2f\x98\x58\x2f\x1e\x11\x4c\x24\xb6\x42\x76\x0a\x63\xe8\xd1\x31\xe9\x6c\xfd\x13\x19\xd6\xcf\x3d\x38\x5b\x70\x55\xbf\x47\x3f\x7b\x61\xc3\xe6\xed\x18\xb5\x75\x3c\x7e\xdc\x38\xc4\xf7\x56\xe6\x39\x87\x5b\x5c\xba\x9d\xa3\xf6\xe7\xec\xdf\x32\xd0\xa6\x33\x58\xc7\x2b\xb2\xf6\x62\x6c\x9d\x90\xfb\xd7\x0f\x3d\x38\x5b\xe5\x8b\x42\x50\x7c\x82\xd7\xcd\x65\x58\x69\xd2\xf3\x3a\x6b\x5d\x6a\x2f\x9e\x38\x31\x98\x19\x87\x3a\xdc\x25\x78\x13\x0a\xb2\xce\x50\xf2\x89\x4a\x0d\x42\x80\x99\xc2\x22\xd4\xe0\x6a\x51\x86\xfb\xe4\x52\x58\xbf\xf6\xb2\xee\xee\xe3\xdb\x8f\xe3\xb0\x1b\xa9\x2d\xd7\x75\x96\x9b\x49\x2d\x54\xac\x6c\x37\xf1\x21\x11\x52\x05\x25\x79\x13\x53\xdb\xba\xa8\x9b\x55\xbe\xb2\x38\x5c\x7f\x69\x75\xf4\x89\xdf\xf6\xcc\x6d\xfb\x61\xe7\xe7\x6e\xeb\x86\xf6\x7f\xf8\x98\xec\x68\x16\xf5\x8e\xcb\xd6\x4d\x16\xaf\x3b\x67\x70\x2f\x8b\x2d\x34\x13\x97\xa9\x49\x1c\x31\x98\x60\xe9\xdd\xc8\xcc\x09\x3a\x71\x31\x5a\x18\xfb\x28\x75\x3e\xa0\x43\x36\x08\x9a\x77\x23\x76\x31\xa3\x3f\xf1\x9f\x5f\xc5\x11\xfb\xa9\xe3\xd9\x0a\x6f\x5a\xff\x01\xbc\xb1\xfb\x1c\xfd\x62\xd6\xea\xf8\xf2\x39\x9e\xe0\xe5\x6d\x9d\xfc\xad\xcd\x26\x73\x09\x77\xe1\xf1\xb1\x6b\x07\xe1\x0a\x91\x06\x08\x14\x7a\xf9\xbb\x1f\x63\x12\x20\xe7\xf8\xc9\x72\x10\x5f\xa3\x0f\x84\x4e\x07\x4d\x7c\x9d\x2c\x7f\xb1\xc4\x2a\x79\xa4\x01\x7f\xbe\x7a\xfb\x8f\x39\xdc\x95\x7c\x96\xb5\x86\x2a\xca\x18\xbc\xad\xea\xe8\xce\x79\x63\x45\x8e\xab\x6d\xd5\xb4\x49\x3e\x5a\x86\x63\x5e\x09\x3f\xfd\xcc\x4d\xed\xfb\x73\xa1\xca\x99\x78\x5d\xcf\x3d\xbd\x42\x3f\xbd\x42\x3f\xbd\x42\x3f\xbd\x42\xdf\x2b\xec\x3f\xea\x2b\xf4\xd3\x2b\xf2\xd3\x2b\xf2\xd3\x2b\xf2\xdd\xdd\xa7\x57\xe4\xa7\x57\xe4\xa7\x57\xe4\xeb\xdf\xe9\x15\xf9\xe9\x15\xf9\xe9\x15\xf9\xe9\x15\xf9\x96\x6f\xa7\x9a\xfe\x7f\xbf\xbf\x3c\x5d\x8e\xfd\x31\x2e\xc7\x4e\xd7\x5d\xa7\xeb\xae\xd3\x75\xd7\xe9\xba\xeb\x17\x9c\xf8\xd3\x75\xd7\xe9\xba\xeb\x74\xdd\x75\xba\xee\xfa\x27\xbd\xee\xca\x84\x72\x47\xdf\x77\xfd\x6f\x00\x00\x00\xff\xff\x43\xb0\x74\xb5\x37\x4b\x00\x00") func operatorsCoreosCom_operatorgroupsYamlBytes() ([]byte, error) { return bindataRead( @@ -205,7 +205,7 @@ func operatorsCoreosCom_operatorgroupsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_operatorsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\xcd\x72\xe3\x36\x12\xbe\xfb\x29\xba\x94\x83\x93\x2a\xfd\x24\xb3\x97\x94\x6e\x2e\x7b\xb2\xe5\xdd\xac\x67\x6a\xec\x99\x4b\x2a\x87\x16\xd9\x12\xb1\x02\x01\x06\x0d\x4a\xd6\x4e\xcd\xbb\x6f\x35\x00\x4a\xa4\x24\x4b\xd4\xac\x27\x1b\x5c\x24\x82\x40\xa3\x7f\xbf\xee\x06\xb1\x52\x9f\xc8\xb1\xb2\x66\x0a\x58\x29\x7a\xf6\x64\xe4\x89\xc7\xcb\x9f\x79\xac\xec\x64\xf5\xd3\xd5\x52\x99\x7c\x0a\xb7\x35\x7b\x5b\x7e\x20\xb6\xb5\xcb\xe8\x8e\xe6\xca\x28\xaf\xac\xb9\x2a\xc9\x63\x8e\x1e\xa7\x57\x00\x68\x8c\xf5\x28\xd3\x2c\x8f\x00\x99\x35\xde\x59\xad\xc9\x8d\x16\x64\xc6\xcb\x7a\x46\xb3\x5a\xe9\x9c\x5c\x20\xde\x1c\xbd\xfa\x71\xfc\xf3\xf8\xc7\x2b\x80\xcc\x51\xd8\xfe\xa4\x4a\x62\x8f\x65\x35\x05\x53\x6b\x7d\x05\x60\xb0\xa4\x29\xd8\x8a\x1c\x7a\xeb\x78\xbc\xfb\x97\x59\x47\x56\x7e\xca\x2b\xae\x28\x93\x83\x17\xce\xd6\x55\x7b\x75\x6b\x4d\x24\xd5\xf0\x87\x9e\x16\xd6\xa9\xe6\x19\x60\x04\x56\x97\xe1\x7f\x94\xfb\x5d\xa2\x11\xa6\xb4\x62\xff\xcf\xce\xf4\xaf\x8a\x7d\x78\x55\xe9\xda\xa1\x6e\x9d\x19\x66\x59\x99\x45\xad\xd1\xed\xe6\xaf\x00\x38\xb3\x15\x4d\xe1\x56\xd7\xec\x49\x26\x92\x1e\x12\x0f\xa3\x24\xeb\xea\xa7\xc4\x12\x67\x05\x95\xd8\x30\x08\x42\xca\xdc\xbc\xbf\xff\xf4\xb7\xc7\xbd\x17\x00\x39\x71\xe6\x54\xe5\x83\x56\x1b\x1e\xc1\x51\xe5\x88\xc9\x78\x06\x84\x2c\x1e\xbb\x65\x68\xdc\xda\xee\x37\xc2\x98\x9d\xfd\x9b\x32\xdf\x9a\xae\x9c\x2c\xf6\x2d\x2d\xc5\xd1\xf2\x9e\xce\xfc\x1e\x1f\xd7\xc2\x6c\x5c\x07\xb9\x38\x0e\x31\xf8\x82\x1a\xb1\x29\x4f\x12\x82\x9d\x83\x2f\x14\xef\xf8\x0d\xbe\x20\xd3\x68\x12\x57\x63\x78\x24\x27\x1b\x81\x0b\x5b\xeb\x5c\x3c\x6c\x45\xce\x83\xa3\xcc\x2e\x8c\xfa\xcf\x96\x1a\x83\xb7\xe1\x18\x8d\x9e\xd8\x83\x32\x9e\x9c\x41\x0d\x2b\xd4\x35\x0d\x01\x4d\x0e\x25\x6e\xc0\x91\xd0\x85\xda\xb4\x28\x84\x25\x3c\x86\x7f\x59\x47\xa0\xcc\xdc\x4e\xa1\xf0\xbe\xe2\xe9\x64\xb2\x50\xbe\x89\x8d\xcc\x96\x65\x6d\x94\xdf\x4c\x82\x9b\xab\x59\x2d\x76\x9f\xe4\xb4\x22\x3d\x61\xb5\x18\xa1\xcb\x0a\xe5\x29\xf3\xb5\xa3\x09\x56\x6a\x14\x98\x35\x21\x3e\xc6\x65\xfe\x9d\x4b\xd1\xc4\xd7\x7b\xea\x8b\x76\x60\xef\x94\x59\x74\x5e\x05\x9f\x3c\xa9\x6b\x71\x4f\x50\x62\xe8\xb8\x3d\xca\xb2\x53\xa9\x4c\x89\x56\x3e\xbc\x7d\x7c\x82\x86\x81\xa8\xf6\xa8\xe1\x96\xb7\xec\x94\x2d\x8a\x52\x66\x4e\x2e\xae\x9c\x3b\x5b\x06\x2a\x64\xf2\xca\x2a\xe3\xc3\x43\xa6\x15\x19\x0f\x5c\xcf\x4a\xe5\xc5\x8a\x7f\xd4\xc4\x5e\xec\x30\x86\xdb\x00\x0d\x30\x23\xa8\xab\x1c\x3d\xe5\x63\xb8\x37\x70\x8b\x25\xe9\x5b\x64\xfa\xe6\xaa\x16\x8d\xf2\x48\xd4\xd7\x5f\xd9\x6d\x64\x3b\xdc\x70\x10\x25\x00\x0d\xfc\xbc\x68\x9d\x26\x22\x1f\x2b\xca\x3a\xa1\x90\x13\x2b\x27\xae\xeb\xd1\x93\x38\x7c\x07\x76\xfa\x1c\xed\xd1\xd7\xdc\xef\xf0\xb0\xb4\x73\xbc\x9d\xb1\x18\xba\x75\x3e\x9a\x1d\x7c\x48\xa4\x88\x41\x33\x5b\x56\xd6\x88\x63\xf4\xe5\xea\x65\xe8\x80\x90\x1c\x1a\x7a\x87\xef\xf6\x78\xbf\xdd\x2e\x4d\xf3\x33\xe2\xad\xf7\x8a\x0c\xe8\x23\x39\xa6\x28\xd0\x11\x70\xeb\xc1\xad\x0c\x71\x5b\xb1\xc5\x31\x9e\x04\x9c\x35\xce\x48\x3f\x92\xa6\xec\xd0\x3c\xe7\x24\x96\xd1\xd9\x7f\x7c\xc9\x9e\xf0\xbf\xb6\x77\xc4\xd8\x0e\x44\xe0\x8f\x9a\xdc\x06\xec\x8a\x9c\x84\x3b\x79\x31\xdc\x4e\x29\x35\x53\x2e\x18\xc8\x61\x67\x47\x2d\xd7\x27\x8c\xd9\x53\x4d\x7d\x44\x95\x51\xa2\xcf\x8a\xb7\xcf\x02\x29\xad\x1c\xd7\x43\xea\xfd\x8d\x49\x70\xc5\x41\xcc\xa8\x00\x6e\x94\x92\x8c\x56\x46\xd4\x7a\x2a\xa8\x33\x03\xe8\x08\x6e\x1e\xee\x28\x3f\xe6\x0f\x5d\x81\xd1\x39\xdc\x9c\x58\xa5\x3c\x95\x27\x85\xd8\x13\xe3\xe6\x04\xab\x09\xa7\x9b\x37\xc9\x8b\x8d\x47\x65\x38\xe5\xa0\x21\x20\x2c\x69\x13\xd3\x95\x64\xc1\x26\x28\xc3\x62\x47\x21\xb9\x05\xdb\x2e\x69\x13\x16\xa5\xdc\x75\x92\xc3\x1e\xb6\x8d\xe3\x74\x30\xec\xc6\x48\x8e\x3f\xbb\xc6\x1e\x07\xb5\xee\xe8\xe3\x54\x71\x2c\x69\x73\x6e\xc9\x9e\x31\x44\x47\x8a\x53\x55\x20\x56\x91\x89\xa0\x49\x99\xda\x1a\x02\xab\x4a\x2b\x0a\x89\xeb\x2c\xfd\x17\xb3\xc7\xe1\x68\xc4\xbf\x90\x69\x7b\xb4\x8c\x5b\xd2\xe6\x9a\xa3\x03\x48\x74\x14\xaa\x92\x58\xdf\xc2\x40\x53\xc1\x7c\x42\xad\xf2\x5d\x51\x1a\x22\xe1\xde\x0c\xe1\xc1\x7a\xf9\x79\xfb\xac\x24\x43\x8b\xdf\xdc\x59\xe2\x07\xeb\xc3\xcc\xab\x8a\x1d\x59\xb9\x50\xe8\xb8\x29\x04\x88\x89\x31\x29\x52\xb5\x4b\x1a\x1e\xc3\xfd\xbc\x83\x6a\xb2\xfa\xde\x80\x75\x8d\x74\xa1\xc8\x8c\x84\x22\x89\xb2\xe6\x50\x83\x18\x6b\x46\x54\x56\x7e\x73\x94\x46\x52\x8a\x75\x1d\x9d\x9c\x20\x97\x48\x3d\x49\x69\x14\xdf\xc4\x22\x56\x63\x46\x39\xe4\x75\x60\x3a\x14\x64\xd2\x6e\xa8\x0c\x4a\x72\x0b\x82\x4a\x10\xae\xaf\xaa\xcf\xe1\x52\x1c\x3d\xd0\xa9\x4d\xf4\x8c\xfd\x02\x04\x87\xec\x73\x21\x6c\xc7\x3d\x11\xde\x4a\xac\xc4\x74\x9f\x05\xc5\x82\xf6\xbe\x40\x85\xca\xf1\x18\x6e\x42\x7b\xa4\xa9\xf3\x4e\x99\xa0\xe7\x36\x19\xa1\xa0\x18\x04\x8a\x56\xa8\x05\x37\xc5\xd3\x0d\x90\x8e\x28\x6a\xe7\x07\xc9\x62\x08\xeb\x42\x6a\x01\x89\xef\xb9\x22\x1d\x4a\xe2\xc1\x92\x36\x83\xe1\x81\xb9\x07\xf7\x66\x10\xf1\xf5\xc0\xc0\x5b\x30\xb6\x46\x6f\x60\x10\xde\x0d\xfe\xb7\xfc\x72\x16\x74\x31\xcf\x43\x63\x8d\xfa\x7d\x4f\x24\x3c\x6b\x4b\x47\xf3\x17\x49\x74\x8c\xf7\x81\xe6\x51\x98\x56\x39\x31\x27\x47\x26\x14\x59\xf6\xc5\x1a\x62\x57\x75\x0c\x13\x8a\x52\x0e\x6b\xe5\x8b\x6e\xed\xf2\x92\x76\xce\x7b\xf8\x19\xbf\xee\x0a\xa1\xb2\xe2\x43\xc3\x76\xf4\xc1\xad\x14\x11\x23\x1b\x6e\x87\x40\xc6\xa9\xac\x68\x98\x95\x22\x37\x16\xd2\x62\xf9\x68\x86\x13\x99\xb4\x97\x41\xfb\xa5\xb3\x97\x3b\xe9\x13\x82\xde\xbc\xbf\x6f\x7a\xe8\xd8\x3a\x53\x23\xe8\x19\x00\xef\x09\xde\x3b\x1d\x5c\xc0\xd4\xed\x76\x53\x3b\x5f\xb5\xfa\xf0\x6d\x8b\x11\x5a\xc6\xc6\x83\xfa\x30\x7c\x1e\x02\x7b\xc1\xdf\x71\x76\x77\xdc\xb6\x99\xc5\x15\x2a\x8d\x33\xdd\xb4\x48\x31\xd9\xa6\x06\x69\xcb\xfc\x75\x74\x1b\x3a\x87\xe5\xbd\xcb\xae\xfe\x85\x97\x94\x55\xd1\x65\x7b\x2c\x94\xf3\xcf\x2c\xeb\x5f\x7d\x49\x27\xc3\xfe\xc9\xa1\x61\xd5\x5c\xd9\xf5\xc9\x3c\x7b\xad\x0d\x7b\xf0\xaa\xa4\xe4\x0d\x8d\x31\xfc\x96\x2c\xe5\xf1\xb6\xc1\x1a\x6a\x62\x33\xa0\xbf\xf5\x05\xbd\x08\x28\xed\x71\x41\xa5\x22\x63\x6e\x5d\x89\x7e\x0a\x39\x7a\x1a\x09\x67\xbd\xd4\xf0\x31\x5c\x6a\xbc\xaa\x0a\xd6\xc8\x62\x8d\x19\xe5\x7f\x05\x21\x4b\x62\xc6\xc5\xe5\xd2\xdd\x40\x51\x97\x28\xd1\x85\x79\x88\xa3\x44\x08\x94\xc9\x55\x86\xe1\x3a\x2a\x27\x8f\x4a\x33\xe0\xcc\xd6\x31\xfa\x76\xe6\x7f\x75\x0b\x3b\x42\x3e\x87\xb2\x47\xe4\x88\x29\x5f\xb6\x8a\xf2\xba\xa6\xba\xe6\xe0\x03\xdf\x92\xeb\xe3\xd7\x3b\x67\xb9\x4e\x57\x3d\x5b\xb0\x4d\x0c\x0f\x43\x34\xd9\x39\x3c\xb9\x9a\x86\xf0\x0b\x6a\xa6\x21\x7c\x34\x4b\x63\xd7\xaf\xcf\x7b\x58\x7c\xb1\xbe\x37\x55\xe0\x70\xcb\xf3\x2b\xb2\x15\x0a\xc2\xf7\xe8\x8b\x0b\xd2\xda\xf5\x7d\xaa\x85\x42\x2d\x1f\xaa\x88\x4a\x51\x46\x9d\xcb\x69\x50\x86\x3d\x61\x9e\x26\xc9\x78\xe5\x28\xbd\x1b\xc6\x9b\xd3\xd4\xc1\xec\x2e\xaf\xa5\xbe\x04\x94\xb2\x53\xe5\xf0\x8f\xc7\x77\x0f\x93\xbf\xdb\x54\xb2\x62\x96\x11\xa7\xd4\x22\x75\xe6\x10\xb8\xce\x0a\x40\x6e\xae\x0b\x1f\x43\xd2\x29\xd1\xa8\x39\xb1\x1f\x27\x6a\xe4\xf8\xb7\x37\xbf\x8f\xe1\x17\xeb\x80\x9e\xb1\xac\x34\x0d\x41\xa5\x36\xa7\xb9\xe2\x6d\x95\x47\x41\x98\xed\xde\x50\x09\x05\x96\x2a\x9b\x27\xa6\xd7\x81\x59\x8f\x4b\x02\x9b\x98\xad\x09\xb4\x5a\xd2\x14\x06\x5c\x51\xd6\x3a\xfa\xb3\xc1\x92\xbe\x0c\xe0\xfb\x75\x41\x8e\x60\x20\x8f\x83\x78\xe0\xb6\x84\x94\xb9\x96\x53\xa6\x83\x63\x1f\xee\xd4\x62\x41\x8e\x62\x31\x4e\x2b\x32\xfe\x07\xe9\xc4\xd4\x1c\x8c\x6d\x2d\x0e\x24\x44\x9f\x15\x65\x6a\xae\x28\x3f\x60\xe4\xb7\x37\xbf\x0f\xe0\xfb\xae\x5c\x82\x3a\xf4\x0c\x6f\x62\x97\xa1\x58\x64\xfc\x21\x35\x6e\xbc\x31\x1e\x9f\x85\x66\x26\xad\x83\x89\x35\xbf\xb7\x50\xe0\x8a\x80\x6d\x49\xb0\x26\xad\x47\xf1\xde\x34\x87\x75\x6c\x49\x1b\x55\xc6\x16\xaf\x42\xe7\xf7\xbe\x57\x3c\xbd\xbb\x7b\x37\x8d\xa7\x89\xd9\x16\x46\x8e\x30\xd6\xc3\x5c\x19\xd4\xa9\xef\x50\xbc\x6b\x53\xb8\x8e\x46\xf2\x16\xb2\x02\x4d\xc0\xca\xa0\x8d\x79\xed\x6b\x47\xe3\xfd\xfb\xeb\xaf\x8a\x81\x63\x1f\x12\x4e\xb9\x7f\xf8\xac\xb0\x5f\x64\xfe\x1f\x2f\xed\xbf\x4a\xe8\xf0\x5d\xed\x02\xa1\x1f\x5a\x7e\x7a\x52\xe8\x65\x3d\x23\x67\xc8\x53\x90\x3b\xb7\x19\x8b\xc8\x19\x55\x9e\x27\x76\x45\x6e\xa5\x68\x3d\x59\x5b\xb7\x54\x66\x31\x12\x47\x1c\x45\xef\xe0\x49\xf8\x16\x39\xf9\x2e\xfc\xbc\x9a\x8c\x5c\x61\x76\xb1\xa0\x61\xd3\x9f\x21\xad\x9c\xc3\x93\x57\x11\xb6\x69\xe4\x2e\xef\x9d\xae\x1f\x23\x70\x64\xfb\x34\x24\xec\xd6\x85\xca\x8a\xe6\x53\x64\x0b\x29\x4b\xcc\x23\x94\xa2\xd9\x7c\x73\xe7\x17\x95\xd6\x4e\xce\xde\x8c\xd2\x67\xf4\x11\x9a\x5c\xfe\xb3\x62\x2f\xf3\xaf\xa2\xc3\x5a\x5d\x04\x04\x1f\xef\xef\xfe\x9c\x90\xa8\xd5\x57\x44\x7d\xfc\x8c\x35\x05\xef\xea\xa6\xa6\x65\x6f\x9d\x54\xae\x9d\xb9\x7a\xb6\xbd\xb1\xd8\x09\x9f\x8a\x2c\xf8\xfc\xe5\xea\xbf\x01\x00\x00\xff\xff\x7e\x2b\xf8\xdd\x18\x21\x00\x00") +var _operatorsCoreosCom_operatorsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x5f\x73\xe3\xb6\x11\x7f\xf7\xa7\xd8\x51\x1e\x9c\xcc\xe8\x4f\x72\x7d\x69\xf5\xe6\xb1\x2f\x1d\xb7\xa9\xef\xe6\xec\xbb\x97\x4c\x1e\x56\xe4\x4a\x44\x05\x02\x0c\x16\x94\xac\xde\xdc\x77\xef\x2c\x00\x4a\xa4\x24\x4b\xd4\xd5\x97\x06\x2f\x12\x41\x60\xb1\x7f\x7f\xbb\x0b\x62\xa5\x3e\x91\x63\x65\xcd\x14\xb0\x52\xf4\xec\xc9\xc8\x13\x8f\x97\x7f\xe5\xb1\xb2\x93\xd5\x4f\x57\x4b\x65\xf2\x29\xdc\xd6\xec\x6d\xf9\x81\xd8\xd6\x2e\xa3\x3b\x9a\x2b\xa3\xbc\xb2\xe6\xaa\x24\x8f\x39\x7a\x9c\x5e\x01\xa0\x31\xd6\xa3\x4c\xb3\x3c\x02\x64\xd6\x78\x67\xb5\x26\x37\x5a\x90\x19\x2f\xeb\x19\xcd\x6a\xa5\x73\x72\x81\x78\x73\xf4\xea\xc7\xf1\xdf\xc6\x3f\x5e\x01\x64\x8e\xc2\xf6\x27\x55\x12\x7b\x2c\xab\x29\x98\x5a\xeb\x2b\x00\x83\x25\x4d\xc1\x56\xe4\xd0\x5b\xc7\xe3\xdd\xbf\xcc\x3a\xb2\xf2\x53\x5e\x71\x45\x99\x1c\xbc\x70\xb6\xae\xda\xab\x5b\x6b\x22\xa9\x86\x3f\xf4\xb4\xb0\x4e\x35\xcf\x00\x23\xb0\xba\x0c\xff\xa3\xdc\xef\x12\x8d\x30\xa5\x15\xfb\x7f\x76\xa6\x7f\x51\xec\xc3\xab\x4a\xd7\x0e\x75\xeb\xcc\x30\xcb\xca\x2c\x6a\x8d\x6e\x37\x7f\x05\xc0\x99\xad\x68\x0a\xb7\xba\x66\x4f\x32\x91\xf4\x90\x78\x18\x25\x59\x57\x3f\x25\x96\x38\x2b\xa8\xc4\x86\x41\x10\x52\xe6\xe6\xfd\xfd\xa7\xbf\x3c\xee\xbd\x00\xc8\x89\x33\xa7\x2a\x1f\xb4\xda\xf0\x08\x8e\x2a\x47\x4c\xc6\x33\x20\x64\xf1\xd8\x2d\x43\xe3\xd6\x76\xbf\x11\xc6\xec\xec\xdf\x94\xf9\xd6\x74\xe5\x64\xb1\x6f\x69\x29\x8e\x96\xf7\x74\xe6\xf7\xf8\xb8\x16\x66\xe3\x3a\xc8\xc5\x71\x88\xc1\x17\xd4\x88\x4d\x79\x92\x10\xec\x1c\x7c\xa1\x78\xc7\x6f\xf0\x05\x99\x46\x93\xb8\x1a\xc3\x23\x39\xd9\x08\x5c\xd8\x5a\xe7\xe2\x61\x2b\x72\x1e\x1c\x65\x76\x61\xd4\x7f\xb6\xd4\x18\xbc\x0d\xc7\x68\xf4\xc4\x1e\x94\xf1\xe4\x0c\x6a\x58\xa1\xae\x69\x08\x68\x72\x28\x71\x03\x8e\x84\x2e\xd4\xa6\x45\x21\x2c\xe1\x31\xfc\xcb\x3a\x02\x65\xe6\x76\x0a\x85\xf7\x15\x4f\x27\x93\x85\xf2\x4d\x6c\x64\xb6\x2c\x6b\xa3\xfc\x66\x12\xdc\x5c\xcd\x6a\xb1\xfb\x24\xa7\x15\xe9\x09\xab\xc5\x08\x5d\x56\x28\x4f\x99\xaf\x1d\x4d\xb0\x52\xa3\xc0\xac\x09\xf1\x31\x2e\xf3\xef\x5c\x8a\x26\xbe\xde\x53\x5f\xb4\x03\x7b\xa7\xcc\xa2\xf3\x2a\xf8\xe4\x49\x5d\x8b\x7b\x82\x12\x43\xc7\xed\x51\x96\x9d\x4a\x65\x4a\xb4\xf2\xe1\xed\xe3\x13\x34\x0c\x44\xb5\x47\x0d\xb7\xbc\x65\xa7\x6c\x51\x94\x32\x73\x72\x71\xe5\xdc\xd9\x32\x50\x21\x93\x57\x56\x19\x1f\x1e\x32\xad\xc8\x78\xe0\x7a\x56\x2a\x2f\x56\xfc\xbd\x26\xf6\x62\x87\x31\xdc\x06\x68\x80\x19\x41\x5d\xe5\xe8\x29\x1f\xc3\xbd\x81\x5b\x2c\x49\xdf\x22\xd3\x37\x57\xb5\x68\x94\x47\xa2\xbe\xfe\xca\x6e\x23\xdb\xe1\x86\x83\x28\x01\x68\xe0\xe7\x45\xeb\x34\x11\xf9\x58\x51\xd6\x09\x85\x9c\x58\x39\x71\x5d\x8f\x9e\xc4\xe1\x3b\xb0\xd3\xe7\x68\x8f\xbe\xe6\x7e\x87\x87\xa5\x9d\xe3\xed\x8c\xc5\xd0\xad\xf3\xd1\xec\xe0\x43\x22\x45\x0c\x9a\xd9\xb2\xb2\x46\x1c\xa3\x2f\x57\x2f\x43\x07\x84\xe4\xd0\xd0\x3b\x7c\xb7\xc7\xfb\xed\x76\x69\x9a\x9f\x11\x6f\xbd\x57\x64\x40\x1f\xc9\x31\x45\x81\x8e\x80\x5b\x0f\x6e\x65\x88\xdb\x8a\x2d\x8e\xf1\x24\xe0\xac\x71\x46\xfa\x91\x34\x65\x87\xe6\x39\x27\xb1\x8c\xce\xfe\xe3\x4b\xf6\x84\xff\xa5\xbd\x23\xc6\x76\x20\x02\xbf\xd7\xe4\x36\x60\x57\xe4\x24\xdc\xc9\x8b\xe1\x76\x4a\xa9\x99\x72\xc1\x40\x0e\x3b\x3b\x6a\xb9\x3e\x61\xcc\x9e\x6a\xea\x23\xaa\x8c\x12\x7d\x56\xbc\x7d\x16\x48\x69\xe5\xb8\x1e\x52\xef\x6f\x4c\x82\x2b\x0e\x62\x46\x05\x70\xa3\x94\x64\xb4\x32\xa2\xd6\x53\x41\x9d\x19\x40\x47\x70\xf3\x70\x47\xf9\x31\x7f\xe8\x0a\x8c\xce\xe1\xe6\xc4\x2a\xe5\xa9\x3c\x29\xc4\x9e\x18\x37\x27\x58\x4d\x38\xdd\xbc\x49\x5e\x6c\x3c\x2a\xc3\x29\x07\x0d\x01\x61\x49\x9b\x98\xae\x24\x0b\x36\x41\x19\x16\x3b\x0a\xc9\x2d\xd8\x76\x49\x9b\xb0\x28\xe5\xae\x93\x1c\xf6\xb0\x6d\x1c\xa7\x83\x61\x37\x46\x72\xfc\xd9\x35\xf6\x38\xa8\x75\x47\x1f\xa7\x8a\x63\x49\x9b\x73\x4b\xf6\x8c\x21\x3a\x52\x9c\xaa\x02\xb1\x8a\x4c\x04\x4d\xca\xd4\xd6\x10\x58\x55\x5a\x51\x48\x5c\x67\xe9\xbf\x98\x3d\x0e\x47\x23\xfe\x85\x4c\xdb\xa3\x65\xdc\x92\x36\xd7\x1c\x1d\x40\xa2\xa3\x50\x95\xc4\xfa\x16\x06\x9a\x0a\xe6\x13\x6a\x95\xef\x8a\xd2\x10\x09\xf7\x66\x08\x0f\xd6\xcb\xcf\xdb\x67\x25\x19\x5a\xfc\xe6\xce\x12\x3f\x58\x1f\x66\x5e\x55\xec\xc8\xca\x85\x42\xc7\x4d\x21\x40\x4c\x8c\x49\x91\xaa\x5d\xd2\xf0\x18\xee\xe7\x1d\x54\x93\xd5\xf7\x06\xac\x6b\xa4\x0b\x45\x66\x24\x14\x49\x94\x35\x87\x1a\xc4\x58\x33\xa2\xb2\xf2\x9b\xa3\x34\x92\x52\xac\xeb\xe8\xe4\x04\xb9\x44\xea\x49\x4a\xa3\xf8\x26\x16\xb1\x1a\x33\xca\x21\xaf\x03\xd3\xa1\x20\x93\x76\x43\x65\x50\x92\x5b\x10\x54\x82\x70\x7d\x55\x7d\x0e\x97\xe2\xe8\x81\x4e\x6d\xa2\x67\xec\x17\x20\x38\x64\x9f\x0b\x61\x3b\xee\x89\xf0\x56\x62\x25\xa6\xfb\x2c\x28\x16\xb4\xf7\x05\x2a\x54\x8e\xc7\x70\x13\xda\x23\x4d\x9d\x77\xca\x04\x3d\xb7\xc9\x08\x05\xc5\x20\x50\xb4\x42\x2d\xb8\x29\x9e\x6e\x80\x74\x44\x51\x3b\x3f\x48\x16\x43\x58\x17\x52\x0b\x48\x7c\xcf\x15\xe9\x50\x12\x0f\x96\xb4\x19\x0c\x0f\xcc\x3d\xb8\x37\x83\x88\xaf\x07\x06\xde\x82\xb1\x35\x7a\x03\x83\xf0\x6e\xf0\xbf\xe5\x97\xb3\xa0\x8b\x79\x1e\x1a\x6b\xd4\xef\x7b\x22\xe1\x59\x5b\x3a\x9a\xbf\x48\xa2\x63\xbc\x0f\x34\x8f\xc2\xb4\xca\x89\x39\x39\x32\xa1\xc8\xb2\x2f\xd6\x10\xbb\xaa\x63\x98\x50\x94\x72\x58\x2b\x5f\x74\x6b\x97\x97\xb4\x73\xde\xc3\xcf\xf8\x75\x57\x08\x95\x15\x1f\x1a\xb6\xa3\x0f\x6e\xa5\x88\x18\xd9\x70\x3b\x04\x32\x4e\x65\x45\xc3\xac\x14\xb9\xb1\x90\x16\xcb\x47\x33\x9c\xc8\xa4\xbd\x0c\xda\x2f\x9d\xbd\xdc\x49\x9f\x10\xf4\xe6\xfd\x7d\xd3\x43\xc7\xd6\x99\x1a\x41\xcf\x00\x78\x4f\xf0\xde\xe9\xe0\x02\xa6\x6e\xb7\x9b\xda\xf9\xaa\xd5\x87\x6f\x5b\x8c\xd0\x32\x36\x1e\xd4\x87\xe1\xf3\x10\xd8\x0b\xfe\x8e\xb3\xbb\xe3\xb6\xcd\x2c\xae\x50\x69\x9c\xe9\xa6\x45\x8a\xc9\x36\x35\x48\x5b\xe6\xaf\xa3\xdb\xd0\x39\x2c\xef\x5d\x76\xf5\x2f\xbc\xa4\xac\x8a\x2e\xdb\x63\xa1\x9c\x7f\x66\x59\xff\xea\x4b\x3a\x19\xf6\x4f\x0e\x0d\xab\xe6\xca\xae\x4f\xe6\xd9\x6b\x6d\xd8\x83\x57\x25\x25\x6f\x68\x8c\xe1\xb7\x64\x29\x8f\xb7\x0d\xd6\x50\x13\x9b\x01\xfd\xad\x2f\xe8\x45\x40\x69\x8f\x0b\x2a\x15\x19\x73\xeb\x4a\xf4\x53\xc8\xd1\xd3\x48\x38\xeb\xa5\x86\x8f\xe1\x52\xe3\x55\x55\xb0\x46\x16\x6b\xcc\x28\xff\x33\x08\x59\x12\x33\x2e\x2e\x97\xee\x06\x8a\xba\x44\x89\x2e\xcc\x43\x1c\x25\x42\xa0\x4c\xae\x32\x0c\xd7\x51\x39\x79\x54\x9a\x01\x67\xb6\x8e\xd1\xb7\x33\xff\xab\x5b\xd8\x11\xf2\x39\x94\x3d\x22\x47\x4c\xf9\xb2\x55\x94\xd7\x35\xd5\x35\x07\x1f\xf8\x96\x5c\x1f\xbf\xde\x39\xcb\x75\xba\xea\xd9\x82\x6d\x62\x78\x18\xa2\xc9\xce\xe1\xc9\xd5\x34\x84\x9f\x51\x33\x0d\xe1\xa3\x59\x1a\xbb\x7e\x7d\xde\xc3\xe2\x8b\xf5\xbd\xa9\x02\x87\x5b\x9e\x5f\x91\xad\x50\x10\xbe\x47\x5f\x5c\x90\xd6\xae\xef\x53\x2d\x14\x6a\xf9\x50\x45\x54\x8a\x32\xea\x5c\x4e\x83\x32\xec\x09\xf3\x34\x49\xc6\x2b\x47\xe9\xdd\x30\xde\x9c\xa6\x0e\x66\x77\x79\x2d\xf5\x25\xa0\x94\x9d\x2a\x87\x7f\x3c\xbe\x7b\x98\xfc\xdd\xa6\x92\x15\xb3\x8c\x38\xa5\x16\xa9\x33\x87\xc0\x75\x56\x00\x72\x73\x5d\xf8\x18\x92\x4e\x89\x46\xcd\x89\xfd\x38\x51\x23\xc7\xbf\xbe\xf9\x6d\x0c\x3f\x5b\x07\xf4\x8c\x65\xa5\x69\x08\x2a\xb5\x39\xcd\x15\x6f\xab\x3c\x0a\xc2\x6c\xf7\x86\x4a\x28\xb0\x54\xd9\x3c\x31\xbd\x0e\xcc\x7a\x5c\x12\xd8\xc4\x6c\x4d\xa0\xd5\x92\xa6\x30\xe0\x8a\xb2\xd6\xd1\x9f\x0d\x96\xf4\x65\x00\xdf\xaf\x0b\x72\x04\x03\x79\x1c\xc4\x03\xb7\x25\xa4\xcc\xb5\x9c\x32\x1d\x1c\xfb\x70\xa7\x16\x0b\x72\x14\x8b\x71\x5a\x91\xf1\x3f\x48\x27\xa6\xe6\x60\x6c\x6b\x71\x20\x21\xfa\xac\x28\x53\x73\x45\xf9\x01\x23\xbf\xbe\xf9\x6d\x00\xdf\x77\xe5\x12\xd4\xa1\x67\x78\x13\xbb\x0c\xc5\x22\xe3\x0f\xa9\x71\xe3\x8d\xf1\xf8\x2c\x34\x33\x69\x1d\x4c\xac\xf9\xbd\x85\x02\x57\x04\x6c\x4b\x82\x35\x69\x3d\x8a\xf7\xa6\x39\xac\x63\x4b\xda\xa8\x32\xb6\x78\x15\x3a\xbf\xf7\xbd\xe2\xe9\xdd\xdd\xbb\x69\x3c\x4d\xcc\xb6\x30\x72\x84\xb1\x1e\xe6\xca\xa0\x4e\x7d\x87\xe2\x5d\x9b\xc2\x75\x34\x92\xb7\x90\x15\x68\x02\x56\x06\x6d\xcc\x6b\x5f\x3b\x1a\xef\xdf\x5f\x7f\x55\x0c\x1c\xfb\x90\x70\xca\xfd\xc3\x67\x85\xfd\x22\xf3\xff\x78\x69\xff\x55\x42\x87\xef\x6a\x17\x08\xfd\xd0\xf2\xd3\x93\x42\x2f\xeb\x19\x39\x43\x9e\x82\xdc\xb9\xcd\x58\x44\xce\xa8\xf2\x3c\xb1\x2b\x72\x2b\x45\xeb\xc9\xda\xba\xa5\x32\x8b\x91\x38\xe2\x28\x7a\x07\x4f\xc2\xb7\xc8\xc9\x77\xe1\xe7\xd5\x64\xe4\x0a\xb3\x8b\x05\x0d\x9b\xfe\x08\x69\xe5\x1c\x9e\xbc\x8a\xb0\x4d\x23\x77\x79\xef\x74\xfd\x18\x81\x23\xdb\xa7\x21\x61\xb7\x2e\x54\x56\x34\x9f\x22\x5b\x48\x59\x62\x1e\xa1\x14\xcd\xe6\x9b\x3b\xbf\xa8\xb4\x76\x72\xf6\x66\x94\x3e\xa3\x8f\xd0\xe4\xf2\x9f\x15\x7b\x99\x7f\x15\x1d\xd6\xea\x22\x20\xf8\x78\x7f\xf7\xc7\x84\x44\xad\xbe\x22\xea\xe3\x67\xac\x29\x78\x57\x37\x35\x2d\x7b\xeb\xa4\x72\xed\xcc\xd5\xb3\xed\x8d\xc5\x4e\xf8\x54\x64\xc1\xe7\x2f\x57\xff\x0d\x00\x00\xff\xff\x08\x9c\x4f\xa3\x18\x21\x00\x00") func operatorsCoreosCom_operatorsYamlBytes() ([]byte, error) { return bindataRead( @@ -225,7 +225,7 @@ func operatorsCoreosCom_operatorsYaml() (*asset, error) { return a, nil } -var _operatorsCoreosCom_subscriptionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x7b\x73\xe3\xb8\x95\x38\xfa\xff\x7c\x0a\x94\x93\x2a\xdb\x59\x49\xee\xce\xe6\x97\xe4\xf6\xa6\xb2\xe5\xb1\xdd\x13\xff\xa6\xbb\xc7\xdb\x76\xcf\xd4\xde\x6c\xee\x06\x22\x21\x09\x31\x09\x70\x00\x50\x6e\xe5\xf1\xdd\x6f\xe1\x1c\x00\x04\xa9\x17\x29\xc9\x8f\x9e\x21\xff\x98\x69\x53\x00\x08\x1c\x1c\x9c\x17\xce\x83\x16\xfc\x7b\xa6\x34\x97\xe2\x0d\xa1\x05\x67\x9f\x0d\x13\xf6\x2f\x3d\xba\xff\xbd\x1e\x71\x79\x36\x7f\xfd\xd5\x3d\x17\xe9\x1b\x72\x51\x6a\x23\xf3\x8f\x4c\xcb\x52\x25\xec\x92\x4d\xb8\xe0\x86\x4b\xf1\x55\xce\x0c\x4d\xa9\xa1\x6f\xbe\x22\x84\x0a\x21\x0d\xb5\xaf\xb5\xfd\x93\x90\x44\x0a\xa3\x64\x96\x31\x35\x9c\x32\x31\xba\x2f\xc7\x6c\x5c\xf2\x2c\x65\x0a\x06\xf7\x9f\x9e\xbf\x1a\xfd\x7e\xf4\xea\x2b\x42\x12\xc5\xa0\xfb\x1d\xcf\x99\x36\x34\x2f\xde\x10\x51\x66\xd9\x57\x84\x08\x9a\xb3\x37\x44\x97\x63\x9d\x28\x5e\xc0\x27\x46\xb2\x60\x8a\x1a\xa9\xf4\x28\x91\x8a\x49\xfb\xbf\xfc\x2b\x5d\xb0\xc4\x7e\x7c\xaa\x64\x59\xbc\x21\x2b\xdb\xe0\x70\x7e\x8e\xd4\xb0\xa9\x54\xdc\xff\x4d\xc8\x90\xc8\x2c\x87\x7f\xe3\xda\x6f\xa3\xaf\xc2\xeb\x8c\x6b\xf3\xed\xd2\x4f\xef\xb8\x36\xf0\x73\x91\x95\x8a\x66\x8d\xd9\xc2\x2f\x7a\x26\x95\xf9\x50\x7d\xdb\x7e\x4b\x97\xe3\xf8\xdf\xae\x21\x17\xd3\x32\xa3\xaa\x3e\xc8\x57\x84\xe8\x44\x16\xec\x0d\x81\x31\x0a\x9a\xb0\xf4\x2b\x42\x1c\x1c\xdd\x98\x43\x42\xd3\x14\xf6\x86\x66\x37\x8a\x0b\xc3\xd4\x85\xcc\xca\x5c\x84\x6f\xda\x36\x29\x0b\xa3\xbe\x21\x77\x33\x46\x0a\x9a\xdc\xd3\x29\xf3\xdf\x1b\xb3\x94\x18\x19\x3a\x10\xf2\x37\x2d\xc5\x0d\x35\xb3\x37\x64\x64\x41\x3c\xb2\x10\x8c\x7e\xc6\xfd\xb9\xc1\x41\xa2\xf7\x66\x61\xa7\xab\x8d\xe2\x62\xba\xe9\xf3\x09\x35\x34\x93\x53\x82\xf8\x45\x26\x52\x11\x33\x63\xc4\x7e\x8a\x4f\x38\x4b\xfd\xfc\x36\xcc\x08\xbb\x2e\xcd\xe9\xb6\xf9\xba\xf5\x94\x66\x54\x08\x96\x11\x39\x21\x65\x91\x52\xc3\x34\x31\xb2\x82\xcf\x66\xf0\xb8\xce\x4b\xb3\xb9\x58\x7a\xbf\x62\x3a\xd8\x74\xfe\x9a\x66\xc5\x8c\xbe\x76\x2f\x75\x32\x63\x39\xad\xf6\x50\x16\x4c\x9c\xdf\x5c\x7f\xff\xef\xb7\x8d\x1f\x48\x7d\x29\x31\x8a\x92\x7b\xc6\x0a\x5d\x1d\x0a\x52\x16\x76\x4d\x76\x71\x64\xbc\x20\x46\xd1\xe4\x9e\x8b\x29\x2c\x7d\x8a\xeb\xbd\xc0\x8d\xd1\xa3\xa5\x29\xcb\xf1\xdf\x58\x62\xa2\xd7\x8a\xfd\x58\x72\xc5\xd2\x78\x2a\x16\xb2\x9e\x44\x34\x5e\x5b\x38\x45\xaf\x0a\x65\xa7\x65\xa2\x73\x88\x4f\x44\xa3\x6a\xef\x1b\xcb\x3c\xb6\xb0\xc0\x76\x24\xb5\xe4\xc9\x4e\x7f\xc6\xfc\xe1\x60\xa9\x03\xa0\xdd\x4e\x33\xe3\x9a\x28\x56\x28\xa6\x99\x40\x82\x65\x5f\x53\xe1\xd6\x34\x22\xb7\x4c\xd9\x8e\xf6\xc0\x96\x59\x6a\xe9\xd8\x9c\x29\x43\x14\x4b\xe4\x54\xf0\xbf\x87\xd1\x00\x44\xf6\x33\x99\xc5\x0f\x43\xe0\xb8\x09\x9a\x91\x39\xcd\x4a\x36\x20\x54\xa4\x24\xa7\x0b\xa2\x98\x1d\x97\x94\x22\x1a\x01\x9a\xe8\x11\x79\x2f\x15\x23\x5c\x4c\xe4\x1b\x32\x33\xa6\xd0\x6f\xce\xce\xa6\xdc\x78\x0a\x9c\xc8\x3c\x2f\x05\x37\x8b\x33\x20\xa6\x7c\x5c\xda\x8d\x3b\x4b\xd9\x9c\x65\x67\x9a\x4f\x87\x54\x25\x33\x6e\x58\x62\x4a\xc5\xce\x68\xc1\x87\x30\x59\x81\x24\x32\x4f\x7f\xa1\x1c\xcd\xd6\xc7\x0d\xf0\xad\x3c\x07\xc4\x53\xbd\x8d\xb0\xb6\xc4\x8f\x70\x4d\xa8\xeb\x8e\x6b\xa9\x40\x6a\x5f\x59\xa8\x7c\xbc\xba\xbd\x23\x7e\x02\x08\x76\x84\x70\xd5\x54\x57\xc0\xb6\x80\xe2\x62\xc2\x14\xb6\x9c\x28\x99\xc3\x28\x4c\xa4\x85\xe4\xc2\xc0\x1f\x49\xc6\x99\x30\xf6\x18\xe6\xdc\x68\xc0\x39\xa6\x8d\xdd\x87\x11\xb9\x00\x06\x44\xc6\xcc\x1d\xd8\x74\x44\xae\x05\xb9\xa0\x39\xcb\x2e\xa8\x66\x8f\x0e\x6a\x0b\x51\x3d\xb4\xe0\x6b\x0f\xec\x98\x7f\x2e\x77\x58\x3a\x63\x84\x78\x06\xb7\x76\x77\xe2\x03\x7f\x5b\xb0\x24\x1c\x07\x2a\xc8\x79\x51\x64\x3c\x41\x8c\x37\x33\x6a\x48\x42\x85\x85\x17\x17\xda\xd0\x2c\x03\x76\xd2\x6a\x16\xeb\x4e\x3b\x81\xa3\xdd\x60\x0e\xfe\xf5\x12\x85\xae\xff\x10\x98\x5a\xa3\xc5\x3a\xca\x60\x1f\x47\x67\x97\x7f\xd8\x00\x72\x82\x92\xc9\x84\x4f\x57\x75\x5b\x0b\xcb\x0b\xe8\x02\x32\x0d\xe5\x42\xbb\x21\x4a\x85\xd0\xac\x38\x95\xe5\x5d\xb4\xc6\xb7\x47\x6b\x67\xb7\x12\xb2\xdb\xd6\x6c\x1f\x3a\x01\x09\x6c\xb1\xfa\xd7\xc6\x2a\xae\x27\xd5\xf4\x06\x44\xce\x99\x52\x3c\x75\xf4\xb1\x90\xe9\xb1\x06\x6a\x96\x96\x19\xd0\x7e\x29\xb4\x51\x94\xc3\xd1\x14\x3c\xb3\x2b\x19\x52\x83\xe7\x81\x69\xf2\xc0\xb3\x8c\xfc\x4a\x48\xf3\xab\x30\x12\x0c\x24\x15\x9f\xf2\x40\xfa\x34\xe1\xc2\x8f\x0f\x1c\xd1\xb1\x74\xa9\x59\x63\xc0\x11\xf9\xa4\x19\x61\x79\x61\x16\x9e\x38\x9c\xfc\xe3\x5f\xa7\x96\xb0\x32\x45\x75\x34\x70\xad\x9f\x27\x9f\x6b\xd6\xbf\x05\xbc\x6d\x40\x6c\x1f\x21\x53\x76\xbe\x05\xd4\x4b\xe0\xbe\x64\x28\x21\x68\xe8\x1e\xb6\x2a\x06\xb2\x2a\x33\xa6\x83\x94\x63\x61\xb4\x61\xf0\x16\x6b\x69\xbb\x1e\x6c\xc7\x26\x4c\x29\x96\x5e\x96\xf6\x68\xdc\x86\x59\x5d\x4f\x85\x0c\xaf\xaf\x3e\xb3\xa4\x34\x2b\xb8\xee\xc6\xa5\x5b\xb9\xc9\x2d\x93\x29\x44\x15\xfc\x1c\x88\x4e\xee\x07\xbb\x5e\x60\x9c\x16\x3c\x1a\xe9\x90\xa6\x86\xeb\xc9\x02\xc0\x11\x00\xc6\x3e\x5b\x26\x01\xb2\x6d\x74\xbe\xac\xa0\x02\xfc\x81\xb3\x2c\x1d\x90\x71\x69\x08\x37\xc0\x3c\x92\x99\xb4\xf8\x45\x11\xee\x30\xee\x9c\x4b\x60\xcd\x44\x0a\x8b\x49\x24\xb7\x1c\x00\x44\x00\x16\x0f\x3f\x82\x99\x57\xdd\xb8\x26\xb9\xd4\xa6\x82\x95\x7d\x03\x58\x2e\x18\x79\xe0\x66\x06\x7f\x4c\xad\xba\x62\xd9\xbe\x2e\x73\x3b\xe8\x03\xe3\xd3\x99\xd1\x03\xc2\x47\x6c\x04\xbb\xcb\x68\x32\x8b\x86\xcd\x19\x33\x9a\xd0\x2c\xf3\x53\x88\x51\x02\xe9\x69\x6e\x79\x22\x39\x09\x4c\xd3\x31\xb8\x41\xa0\xb7\xcd\x5d\x5b\x09\xae\x01\x61\x26\x19\x9d\x0e\x48\x22\xf3\xc2\x9e\x16\x0a\x73\x1c\x2f\x08\x37\x56\xf6\x43\x06\xad\x64\x39\xc5\x95\xb0\xcc\x7d\xd8\x4b\x47\x00\x5c\x10\x5f\xac\x36\x21\xa6\xe4\x08\x17\x77\xe4\x05\x1e\x3b\x1c\xc7\x45\xc0\xfa\x72\x6a\x92\x99\xa3\x29\x89\x54\x8a\xe9\x42\x0a\xe8\x09\xbf\x5c\x55\x73\xfb\x8f\xd0\xe9\x44\x9f\x56\xc0\x9c\xf1\xe9\xcc\xc3\x92\x2a\xa4\x29\xf5\x3d\xd8\x74\x46\xaa\x73\x42\x95\xa2\x8b\x2d\x2d\xb9\x61\xf9\x96\x53\xb2\x84\xda\xe7\xc2\x11\xa9\x0a\x27\xa2\xdd\x33\x4c\xe5\x01\x06\xb0\xc1\x70\x5c\x35\xae\x8f\xe7\x96\xed\x72\xe3\x30\x84\xbc\x22\x27\x80\x22\xdc\x1c\x6b\x40\xd7\xa1\x2c\x4e\x47\xe4\x1c\xb4\xdd\x16\x1f\x10\x32\x8c\xef\x06\xb2\x1f\xd5\xb2\x1a\x6b\xeb\xda\x5a\x12\x15\x7c\xd6\xf3\xfa\xe5\x67\xe8\xe6\xcf\xc4\x0a\x56\xbf\xaa\x39\xc2\x64\x6b\xd3\xb6\xe4\xcd\xb7\xf6\x73\x68\xd3\xba\xb9\xd5\x88\xd2\x9a\x65\x2c\x31\x96\x46\x33\x95\x0f\x08\xd5\x5a\x26\xdc\x8a\x95\x15\xd2\xd6\x31\x1d\x57\xb2\x1d\xf6\xa4\x2b\xfc\x49\xe7\xf5\xdb\xa7\x79\xf0\xda\xf6\x5b\x82\x46\xc6\xb5\xb1\x94\xa1\x0e\x95\x1a\xc1\x1a\x2f\xe0\xd7\x63\x4d\x32\x3a\x66\xd9\x5a\xbe\xbc\xfc\xb4\x3f\xb5\xd5\xd3\xf2\xfc\xae\x5d\xd0\xda\x85\x38\xa5\x26\x6c\x3c\x88\xc8\x5e\xe0\x43\x89\x63\x40\x28\xb9\x67\x0b\xd4\xed\xac\xca\xe8\x94\x69\x6c\xac\x18\xb2\x1b\x8b\x1c\xf7\x6c\x01\x8d\x36\x4b\x2a\xeb\x61\xd2\x01\x39\xf0\xe9\x72\x4c\xab\x67\x68\x27\xda\xb1\x87\x5f\x74\x87\x6e\xdd\xf1\x17\x9f\x7b\xb6\x51\xf2\x5a\xf5\x2c\x89\x24\x80\x93\xb0\x1f\xb0\x49\xc0\xbf\xfc\x1e\x53\xab\x12\x81\xad\xa3\xcb\x0e\x91\x6d\x0a\xc6\xa6\xc7\x43\x6f\xaf\x75\x7d\x0c\x1a\x34\x22\xe4\xb1\x46\xe4\xb3\x27\x7d\xc6\xc1\xae\x63\x31\x19\x0e\xae\x37\x35\x7c\x4f\x33\x9e\x46\xe6\x1f\xcb\x67\xaf\xc5\x80\x7c\x90\xc6\xfe\xef\xea\x33\xd7\x56\x7c\xb9\x94\x4c\x7f\x90\x06\xfe\x1c\x91\x6f\x0c\xe2\xfa\xbb\x96\x94\xed\x00\x00\xc2\xf9\xee\x05\x9e\x73\x81\x34\xc5\x2e\x3f\x36\x52\xe8\x91\x55\x87\x40\x94\xf3\x07\x97\x6b\x72\x2d\xac\x70\xe8\xc0\x00\x66\x23\x54\x62\x70\x88\xbc\xd4\x60\x55\x10\x52\x0c\x41\x06\x58\x39\x06\x42\xcf\x8e\x13\xc3\x6f\xc3\x70\xeb\x87\xfa\xc6\xd8\x61\xde\xad\xed\x3c\xa3\x73\x10\xe9\xb8\x98\x66\x41\x78\x1b\x90\x87\x19\x4f\x66\x28\x75\x83\x4e\x6f\x98\x2a\x14\xb3\x0c\x8b\x82\xf6\x6f\xdf\x4c\x99\xb2\xc2\x2e\xf7\xe3\xa1\x25\x2c\xa3\x09\x4b\x49\x0a\xa2\x25\x5a\x75\xa8\x61\x53\x9e\x90\x9c\xa9\x29\x23\x85\xe5\x24\xbb\xed\x7e\x37\xc2\x8e\x4f\x67\xf2\x1e\x7f\xb0\x13\xba\x01\x8b\x7c\x6b\x65\xdd\x27\xe2\x8e\x20\x57\xf7\xdc\xb1\xe7\x8e\x8d\xa7\xe7\x8e\xe1\xe9\xb9\xe3\x96\xa7\xe7\x8e\x3d\x77\x7c\x74\xee\x88\xba\xec\x0e\xca\xf3\x0f\x68\xe2\x68\x6a\xcb\xc0\x69\xfd\xbd\x50\x5d\x6d\xb6\xfc\xe6\xd6\x11\x9c\x3b\x50\xb5\x9d\xed\x58\x51\x31\x65\xe4\xf5\xf0\xf5\xab\x57\x5d\x94\x6a\xb7\x91\xad\x7a\x4c\xa4\xca\xa9\x81\x3e\xff\xfe\xeb\x8d\x3d\xd6\xd9\xdf\x0e\x60\x35\x75\x38\x1e\x0c\x79\x35\xd9\x61\x8d\xe1\x13\xa8\x93\x90\x86\xe4\xcc\x10\x6a\x6a\xa6\x22\x9e\xb3\x81\x37\x2c\x23\xc2\xbb\x6b\x31\x6f\x81\x4d\x89\x14\xce\x8e\x67\x81\x3f\xda\x6d\x06\x09\xa3\x9a\x59\x4a\x3a\x66\x61\x16\x32\xb7\x5f\xe5\xc2\xf8\xe3\x62\xa7\xc0\x3c\x54\xc8\x09\x1b\x4d\x47\x24\x2d\xa1\x1b\x15\xee\x9e\xee\x14\x67\xab\x17\xda\xb0\x1c\x2c\xb9\x52\xc1\xff\xec\xb4\x8d\x5a\xc0\x5d\xc0\x9c\x09\x53\xd2\x2c\x5b\x10\x36\xe7\x89\x09\xeb\x83\x6b\x42\x6e\xd0\xd8\xde\xce\x44\xd8\x4a\x74\x68\x2f\x2e\x0c\x97\x30\x58\x6f\xe9\xd3\x85\xdb\x2f\x8d\xdd\xe6\x4c\x36\x78\x21\xae\x64\xb4\x56\x58\x35\x76\x5c\xb4\x81\xc3\x3f\x01\xb9\xbe\xfb\xb8\xdd\xe4\x4a\x3a\x53\xb2\x0e\xd4\xab\x29\x96\x96\x59\x66\x11\x03\xad\xb0\xcb\x0b\x58\x61\x1d\xc5\x25\xd5\x90\x19\x0d\xef\x68\x62\x3e\xff\x70\x69\xa1\x62\xdb\xdc\xc9\x42\x66\x72\xba\x88\x21\x0d\x2b\x03\xdb\xad\xeb\x8b\xb7\x7a\x28\x34\x58\xf4\xfb\xd0\xd8\x9a\xde\xf2\xd7\x5b\xfe\x7a\xdd\x66\xe9\xe9\x75\x9b\xf0\xf4\xba\xcd\x96\xa7\xd7\x6d\x7a\xdd\xa6\xb7\xfc\x91\x9e\x3b\x6e\x80\x49\xcf\x1d\x49\xcf\x1d\xd7\xae\xab\xe7\x8e\x1b\xc1\xd3\x73\xc7\x9e\x3b\xae\x7a\x0a\x99\xee\xe1\xe8\x58\xc8\x74\x83\x9f\x23\x5a\x7d\x12\x39\xcc\x64\x42\x8d\x73\x04\xb7\x5d\x9c\x9d\x4f\xd3\x1c\x0d\x51\x03\xf2\x77\x29\x18\x3a\xaf\xd9\xbd\x01\x73\x92\x34\x33\xa6\x6c\xf3\x13\x7d\xba\xd1\xb1\xa9\xf7\x93\xec\xfd\x24\x5f\xbc\x9f\xe4\x8c\x6a\xdc\x57\x24\x4a\xeb\xdd\x26\xa3\x03\x79\xc7\x54\xfe\x85\x7a\x4d\x5a\x74\x71\xdb\x0d\x21\x36\xd5\x96\xe2\xca\x53\x77\x5f\xc0\xd2\x9b\xfa\x7a\x9d\xbc\x0c\x8b\xa2\x69\xca\x52\x52\x30\x35\x44\x14\x91\x64\xc2\x45\xba\x62\xad\x1e\x3e\xcf\xea\xfd\x58\x5f\xc7\x33\xba\x40\xd6\x27\xb2\x83\xcd\x35\x36\x1c\xd7\x28\xfc\x8b\x70\x88\xec\x2a\xd5\x0f\x89\x71\x46\xde\x6f\x5b\xca\xf5\xdd\x45\x73\x10\xa8\xbd\x49\x78\x77\xbd\x12\xc4\xf2\x1f\x4b\xa6\x16\x10\x63\x51\x09\xac\x21\x98\xcb\xdd\x91\x71\x4d\x12\xaa\x91\x53\x74\x55\x2d\x3b\xaa\x51\xbb\xe9\x29\xbb\x5b\xa2\x49\x13\x2e\xcd\xa1\x50\x27\xf5\x3a\x38\xc2\x6c\xa5\x12\xbe\xe2\x16\xa0\xb2\xfe\x77\x9a\xcf\xae\xa2\xdb\x4e\x82\xdb\x4a\xa4\x78\xc1\xca\x39\xd9\x5d\x41\x27\x3b\x2b\xe9\x64\x27\x45\x9d\xec\xaa\xac\x93\x3d\x14\x76\xb2\x9b\xd2\x4e\x9a\xa8\x60\x77\xc8\x49\x59\x8f\xa3\xbf\x93\x7d\x54\x54\xb2\x87\x1e\x4f\x9a\x4b\x0d\x68\xaa\x1e\x4b\xa9\x07\x5c\xaf\xe9\xf5\x4f\x0d\xac\xdd\x74\x7a\xd2\x04\x95\x8f\xba\x03\x85\xf6\x0b\xd1\xf0\x9f\x44\xdd\x26\x7b\xa9\xdc\x64\x77\xb5\x9b\xec\x8e\x19\xc0\xea\xde\xc1\x75\xea\xbe\x0c\x13\x47\x41\x16\x91\xd3\xc2\x22\xc5\x3f\x2c\x27\x80\x7d\xf9\x17\x29\x28\x57\xda\xca\x77\xce\x66\x12\xff\xe6\xb4\xf3\x78\x18\x3b\x02\xd7\xc4\x92\xea\x39\xcd\x2c\xef\x41\x3f\x0e\xa7\x17\xd9\xd1\x9b\x6c\x7a\x40\x1e\x20\xea\xd3\x52\x29\xd4\x96\xb8\x26\x47\xf7\x6c\x71\x34\x58\x42\xa4\xa3\x6b\x71\x84\x3c\x6a\x09\x75\x02\x43\x93\x22\x5b\x90\x23\xf8\xed\xe8\xd0\x9c\x7d\x07\xc6\x15\x27\xdb\xd8\x95\x2f\xec\x80\x25\xc2\xc7\x4a\x1f\x5e\xd8\x44\x2e\x82\x17\x1b\xfe\x2b\xba\x62\x30\xe0\x6a\x11\x31\x97\xe0\x35\x02\x38\x06\xef\x53\xaf\xfc\x96\xc2\xa5\x56\x00\xdd\xb5\x1a\x0c\x99\xd4\xb2\x4b\x93\xdb\x78\x29\x98\x06\xc1\x8e\x05\x13\x51\xd4\x19\xda\x8e\xd0\x1d\xa4\xe2\x76\x22\x6d\x3a\x88\x54\x3d\x40\x46\xcc\x19\x15\x9a\x1c\x79\xdb\xd3\xb1\xae\x5a\x1c\x8d\xaa\xe8\xbe\x30\x22\x04\x21\xc7\x11\x7d\xd5\x80\xbd\xa4\xdd\x4b\xda\xbd\xa4\xdd\xa1\x57\x2f\x69\xaf\x7f\x7a\x49\xbb\xc3\xd3\x4b\xda\xbd\xa4\xbd\xe9\xc3\xbd\xa4\xdd\x4b\xda\xdb\x3f\xbe\x9b\xa4\xbd\xab\x9f\x50\x2c\xf7\xba\xcb\x39\xcc\x9c\x45\x0d\x4f\x2a\x1f\x22\xdf\x0a\xff\x75\x58\x79\x3b\x96\xa5\x57\x4b\xdb\xb1\x44\xbe\xa4\x5b\x8c\xb6\x88\xd6\x41\xf8\x5e\xea\xb9\x59\xea\x7e\x59\xbe\x50\x3b\xe0\x46\x74\xa1\xb0\x23\x72\xdc\xf9\xab\x70\x97\x69\x6e\xcc\xaa\x7b\xf2\x94\x9c\xf8\x1b\x97\x53\x0b\x7c\x21\x4d\xfd\x47\x61\xf8\xb0\x6a\x11\xee\x60\xe0\x7a\xb1\x16\x6f\x53\xbb\x96\x08\xb7\xee\xe1\xa6\xb8\xda\x4f\x4b\x42\x98\xaa\xcd\x81\x6b\x97\x40\x0c\xbc\x25\x54\x29\x84\x1d\x55\x0a\x7f\x7d\x8c\x34\x07\x13\xc0\x39\xcc\x43\x61\x09\xe6\x03\x12\x53\x05\xa5\xe8\xbe\x93\x1a\xcc\xb9\xe7\x5c\xf9\xa5\x70\x37\xa2\xf6\x8d\xbf\xf5\xf5\x48\x09\x2b\xe2\xe1\xeb\x23\x72\x05\x78\x18\x0f\xcc\x35\xc0\x87\x66\x99\x7c\xe8\x42\x92\x9e\x2a\x2c\xea\xa1\x73\x58\x54\xe3\xfe\xae\x8f\x8a\xfa\x99\x44\x45\xc1\x8f\x78\x84\x0e\x1e\x1e\x45\x7e\x98\x31\xc0\x22\xc5\x00\x54\x79\x99\x19\x5e\x54\xbe\x52\x1a\x3f\x95\xa1\x94\x39\x71\x9e\x27\x75\xbc\xb4\x5f\xa3\xc9\xac\x89\x9f\x30\x1e\xf8\x56\x69\x38\xb4\xce\xbb\x83\x66\x99\x8b\x29\xf2\x22\x29\xba\xb0\xf0\xe7\xf6\x4c\xb8\xf4\x59\x11\xbd\x36\x03\x44\xe6\xc4\xd2\xc2\x6c\xe1\x32\xd5\x6d\x20\xa2\xa8\x14\xcd\x99\x67\xbd\x53\x3e\x67\xa2\xa2\xa4\x27\xfa\xf4\xd4\xf3\xf0\x83\x52\xf8\x47\xa1\xd0\x7f\x88\x28\xe9\x1f\xdb\xd0\x68\x58\x50\xa0\xd2\x15\xf8\x2a\x1a\xfd\x9c\x2e\x18\x5d\xee\xf9\xbb\xd9\x18\x76\xb8\xdf\x7f\xc2\xbb\xfd\x2f\x27\xb2\xec\x99\x2d\x8c\xcf\xe1\x5b\xff\xe2\xad\x8a\xbd\x73\x7d\xf5\xec\xeb\x5c\xff\xe8\x96\xc3\xe7\xf5\xb1\xff\x02\xac\x85\xcf\xe9\x63\xdf\x5b\x08\x37\x6e\xca\x4b\x73\x7d\xaf\x3f\x3b\x59\x04\x7b\x6b\xe0\xce\x5c\xb8\x23\xc3\xd9\xd7\x0a\xd8\x11\x23\x76\xbc\x67\xef\xef\xd8\x9f\xe6\x8e\xbd\x97\x78\x5b\x3e\xbd\xc4\xbb\x16\x28\xbd\xc4\x4b\x7a\x89\x77\xdb\xf2\x7a\x89\x77\x23\x78\x7a\x89\x77\xe3\xa6\xf4\x12\x6f\x2f\xf1\x92\x2f\x4d\xe2\xdd\x25\x4b\x57\x7f\xd7\xbd\xd7\x5d\x77\x57\x6a\xd1\x89\x46\x74\xc4\x83\xce\x77\xdb\xfd\xbd\xf6\x4b\xb9\xd7\x6e\x1d\xf0\x2f\x0c\xdf\x37\xe8\x3f\xde\xab\x75\x91\xff\x74\x2e\x79\x4a\x8a\xd2\xb8\x78\xea\x3e\xfa\xff\x10\xd1\xff\x35\xc8\xf7\x29\x00\x5a\xa5\x00\x58\x07\xb3\x3e\x0f\x40\x9f\x07\xe0\xc0\x97\xd0\x7d\x1e\x80\x3e\x0f\x40\x9f\x07\xc0\x3f\x7d\x74\x12\xe9\xa3\x93\x5a\x3d\x7d\x74\xd2\xfa\xa7\x8f\x4e\x7a\xb1\xd6\x57\xd2\x47\x27\xbd\x6c\x4b\x2c\xe9\xa3\x93\x7a\xeb\x6c\xcb\x8d\xfa\x02\xa3\x93\xfa\x3c\x00\x2f\xd5\x47\x81\xf4\x92\x76\x2f\x69\xf7\x92\x76\x2f\x69\x6f\x7e\x7a\x49\xbb\xc3\xd3\x4b\xda\xbd\xa4\xbd\xe9\xc3\xbd\xa4\xdd\x4b\xda\xdb\x3f\xde\xe7\x01\xf8\x82\x7c\x23\x48\x9f\x07\xa0\xf7\x97\xe8\xf3\x00\xfc\x7c\xf3\x00\xd4\xee\xee\x9f\x2f\x19\x40\xf7\x69\xf4\x19\x01\xfa\x8c\x00\x7d\x46\x80\x3e\x23\x80\x7f\xfa\x8c\x00\xf8\xbc\x24\x5b\x63\x1f\x1f\xb5\x16\x28\x7d\x7c\x14\xe9\xe3\xa3\xb6\x2d\xef\x0b\xb0\x1b\xf6\xf1\x51\x2f\xd0\x56\xd8\xc7\x47\xf5\x76\xc1\xe6\xe6\x7c\x21\xf1\x51\x7d\x46\x80\x97\x78\xdb\xde\x4b\xbc\x2d\x9f\x5e\xe2\x5d\x0b\x94\x5e\xe2\x25\xbd\xc4\xbb\x6d\x79\xbd\xc4\xbb\x11\x3c\xbd\xc4\xbb\x71\x53\x7a\x89\xb7\x97\x78\xc9\x97\x26\xf1\xf6\x19\x01\xfa\x8c\x00\x7d\x46\x80\x2f\xf1\x86\x7b\xeb\x4e\x33\x31\x5f\xb7\xa7\xb5\x5d\xbc\x12\xf3\xba\x9e\xc2\xc4\x9c\x2b\x29\x80\x02\xcf\xa9\xe2\x74\x9c\xc1\x49\x05\x89\xc7\xc1\xdf\xd1\x4f\xa6\x46\xe4\x82\x0a\x77\xd1\x8a\x37\x99\x6b\xe7\xbf\x1d\xf1\xb7\xa0\x7a\x73\xda\xdf\xd3\xba\xa8\x26\x56\x4e\x9d\xb8\x06\x76\xea\x94\x5c\x84\x89\xaf\xfd\x4c\x2b\x02\xde\x46\x3f\x18\x02\x72\xae\x6d\xd0\x4e\x8a\xb7\x43\x6c\x3e\x9b\x35\xb0\x7c\xa0\x79\x15\xe2\xbf\x02\x1a\x23\xf2\xde\x49\x48\x94\x5c\xfc\xef\xf5\xe5\xd5\x87\xbb\xeb\xb7\xd7\x57\x1f\x37\x23\x5d\x4b\xb2\x02\x07\xa9\xc3\x64\x8f\xbf\xf7\x7b\x04\x61\xde\x4c\x58\x0a\xfc\xcb\x93\xef\xcf\x3f\xfe\xef\x87\xf3\xf7\x57\xa7\xc0\x7e\xd9\xe7\x82\x8a\x94\xa5\xa4\xd4\x9e\x24\x14\x8a\xcd\xb9\x2c\x75\xb6\x08\xc7\x7b\x35\xd2\x36\xb1\xd5\x29\x9a\x0b\xa2\x99\x9a\xf3\x64\x35\x88\x50\x8a\xa5\x15\x02\x25\x01\xc3\x15\xd3\x32\x9b\xb3\x14\x65\x8d\x30\x69\xff\x1d\x2e\x8a\xd2\x78\x89\x18\x5c\x10\xec\xa9\x10\xc9\x8c\x8a\x29\x4b\x47\xe4\x52\x96\x76\xbc\x5f\xfe\x12\x16\xa6\x58\x5a\x26\xc8\xeb\xa8\x17\x98\x7e\x39\xf0\x94\xc4\xd2\x02\x8d\x69\x14\x74\x42\x0b\xbf\xf4\x18\x3a\x7a\x21\x0c\xfd\xfc\x06\xef\xe0\x8f\x7e\x19\xfd\x74\xe4\x53\x50\x48\xfb\x09\xa4\x47\x38\xab\x0c\xb2\x1f\x64\xe4\x28\x6e\x3d\x22\x57\xf6\x1b\x2c\x8d\xf7\x01\x5d\x28\xd8\x9c\x29\x90\xa7\xdd\x2e\x0c\x88\x62\x53\xaa\xd2\x8c\x69\x70\x1e\x78\x98\x31\x48\xe7\x81\x12\x96\x03\x18\x0b\xd2\xba\x90\x66\x44\x2e\xd9\x84\x96\x99\x01\x1a\x72\x74\x34\x3a\x3e\x18\xaa\xbd\x55\x72\x4b\xf0\x7b\x0d\xdd\x6e\x31\xa9\xc4\x44\xaa\xb5\xc7\xe3\xd8\x99\x26\x6a\x64\x4d\x5b\x4e\xe2\x34\x3d\x4f\xab\x51\xbf\x68\xb1\x92\x16\x82\x60\x7b\x75\x3e\x91\x62\xc2\xa7\xef\x69\xf1\x2d\x5b\x7c\x64\x93\x8e\xde\x10\xc8\x44\x9d\x4e\x0b\x0c\xcc\x92\x43\x1c\x70\x3b\xd3\x79\xc4\xbb\xfc\x36\x46\x93\x6e\x36\x8f\xd6\x96\x8e\xa5\x94\x16\xc8\xf4\x1d\xfb\x3e\x60\x72\x9e\xea\xd9\x4e\xd1\x57\x4e\xee\x38\x26\xed\xee\x9c\x9a\x11\x79\x2f\xc1\x25\x67\x22\xdf\x90\x99\x31\x85\x7e\x73\x76\x76\x5f\x8e\x99\x12\xcc\x30\x3d\xe2\xf2\x2c\x95\x89\x3e\x4b\xa4\x48\x58\x61\xf4\x99\x9c\x5b\xca\xc7\x1e\xce\x1e\xa4\xba\xe7\x62\x3a\xb4\x92\xce\x10\x77\x55\x9f\x81\x30\x75\xf6\x0b\x94\xd8\xef\xbe\xbb\xfc\xee\x0d\x39\x4f\x53\x97\xb1\xa7\xd4\x6c\x52\x66\x2e\x7b\xc7\x88\xd0\x82\x7f\xcf\x94\x55\xca\x06\xe4\x9e\x8b\x74\x40\x4a\x9e\xfe\xe7\xe6\xc3\xbd\x23\xc4\x64\x81\xba\xd1\x0e\x50\xbb\x05\x41\x71\x51\xa3\x53\x01\xe9\x2d\x85\xe2\x46\xc3\x9e\x7b\xc3\x81\x63\x28\x1d\x96\x31\x96\x32\x63\x54\x6c\xe9\x01\x60\xeb\x7e\x66\x8f\xab\x43\x8b\x5a\x8e\x43\x80\x42\xa6\x6f\x88\x2e\x8b\x42\x2a\xa3\x49\xce\x0c\x4d\xa9\xa1\x23\xbb\x73\x83\xfa\x9f\x20\x1c\x0f\xc8\x5f\xc3\x4b\x90\x70\xf5\x9f\x8f\x8f\xff\xf0\xed\xd5\x7f\xff\xf1\xf8\xf8\x2f\x7f\x8d\x7f\x05\xb2\x87\xa6\xae\x7a\x13\x2b\x72\x8f\xac\xb8\xfb\x01\xbe\x01\x7f\x3a\x36\x7a\x9e\x24\xb2\x14\xc6\xfd\x60\xa8\x29\xf5\x68\x26\xb5\xb9\xbe\x09\x7f\x16\x32\x6d\xfe\xa5\xb7\x70\x02\xf2\xb8\x44\x07\xc0\x79\x43\xcd\xec\xc0\xa4\xa7\x3a\x17\x3b\xa0\xab\xeb\x19\x67\x48\xca\x29\xfc\xf3\xad\x9f\xae\xe5\x40\x0f\x8a\x1b\xc3\x04\xc8\x1d\xe0\x77\x27\x27\x03\x8b\xb9\x15\x9b\x9d\xbf\xee\xa4\x8e\xb6\x3e\x8a\x01\x6a\x3b\x2c\x0e\x66\xef\x56\x86\xc8\x1c\x08\xed\xb2\x5e\x77\x7e\x73\x4d\xe6\x08\x8d\x83\x2f\xc4\x7b\x61\xbd\xdd\xfb\x4c\x86\x4c\x55\x6e\x59\x41\xd2\x7c\x83\x96\xa5\xe0\xef\x45\x32\x9e\x73\x67\x00\x76\x59\xad\x34\x39\xc1\x97\xa3\xa4\x28\x07\xae\xc1\x28\x67\xb9\x54\x8b\xf0\x27\x2b\x66\x2c\xb7\x12\xdb\x50\x1b\xa9\xe8\x94\x0d\x42\x77\xec\x16\xfe\xc2\x8e\xb5\x0f\x2c\xf7\x46\x91\x3a\x29\x95\x65\x1e\xd9\xc2\x53\x10\x96\x3e\xef\x59\xf4\x60\x3a\xf0\x51\x0c\xbb\xf1\x61\x47\x96\x1b\xb4\x45\x64\xda\x61\x55\x20\x43\xce\x65\x56\xe6\x4c\x0f\x02\x7b\x42\x69\x5d\xcc\xad\x34\xa9\x1f\x85\x11\xa6\x7c\xce\xf5\x4e\xf7\xd3\xb7\xc1\x52\x07\x26\xb2\xd2\x58\x4d\x05\x9d\xc1\xa3\x8c\x70\x52\x83\x0e\x10\x7c\x14\x6b\x24\xe5\xf5\x51\xbb\xdb\x57\x6a\x0c\x53\xe2\x0d\xf9\xff\x4e\xfe\xe7\xdf\xfe\x39\x3c\xfd\xcf\x93\x93\x3f\xbf\x1a\xfe\x3f\x7f\xf9\xb7\x93\xff\x19\xc1\x3f\x7e\x75\xfa\x9f\xa7\xff\xf4\x7f\xfc\xdb\xe9\xe9\xc9\xc9\x9f\xbf\x7d\xff\xcd\xdd\xcd\xd5\x5f\xf8\xe9\x3f\xff\x2c\xca\xfc\x1e\xff\xfa\xe7\xc9\x9f\xd9\xd5\x5f\x5a\x0e\x72\x7a\xfa\x9f\xbf\x6c\x35\x3d\x2a\x16\xdf\xb5\x38\xf0\xf8\x0c\x77\xf0\xb0\xaf\x7a\x75\x30\xd0\x7f\x1e\x56\x42\xdb\x90\x0b\x33\x94\x6a\x88\xdd\xdf\x10\xa3\xca\xed\x07\xa3\x22\x6a\xbb\xe0\xb9\x4f\x07\xf6\xa6\x22\x68\x81\x34\x1f\x1c\x91\x35\x4b\x14\x33\x87\xd2\x60\x70\x34\xcf\x3f\x1a\x26\xd9\x5e\xa9\xa9\x94\x9a\x60\x97\x04\x78\x55\x9c\x77\xa2\x64\x3e\x22\x91\x59\x68\x0e\x37\x99\xae\xdd\x3d\xdb\xa2\xe5\xfa\xa7\x57\x82\xbe\x2c\x25\xe8\x16\xf7\xf7\xd1\x35\x20\x26\xe6\x9b\xcc\x34\x4d\x9b\xee\x5b\x08\x65\x89\xcd\xd1\x5e\x80\x32\x92\x14\xb2\x28\x33\x6a\xd6\x98\xed\x56\xd8\xa6\x1d\xee\x57\xb7\x00\x76\xa3\xc1\x0e\xec\xa8\x5c\xbe\xda\x18\x4a\xce\xb3\x8c\x70\x81\x27\x01\x06\xf0\xd6\x3c\xc5\x50\x5e\x22\x14\x0d\xce\x73\x3b\x85\x07\x17\x70\x13\x19\x1a\xb9\xb6\xba\x8e\x32\x60\xf1\x87\x80\x1c\xa4\x59\xce\x34\xc6\x45\x15\x96\x13\xb8\x6d\xb8\xa5\x5c\x99\x7f\x31\xa3\xda\xf8\x69\xc3\x6c\x0c\xbd\x07\x53\x68\xc2\x52\x26\x12\x06\x2e\x08\x25\xab\xd6\x3a\xb6\xc2\x20\x98\xf7\x61\x0c\x4a\xd2\xb2\xc8\x78\x62\xe1\x67\x67\xb2\x7a\x8c\xeb\x3c\x2f\x0d\x18\x8a\x9f\xca\x8a\x6f\x77\xfc\xd6\xa7\x7b\x0d\xc6\x7c\x20\x55\x41\xb4\x0e\xde\x16\x41\x75\xd7\xfb\x99\xef\xdb\x11\xde\x60\x6e\xdb\xca\xa9\x96\x28\x6e\x65\x63\xa8\x53\xda\xa7\xb6\x18\xb6\xa3\xb3\x3f\x49\x1a\xdb\x81\xbe\xb6\xa7\xad\x1d\x8c\x4b\x5d\xe9\x69\x5b\x6b\x52\xa1\xd8\x84\x7f\xee\x80\x8f\xe7\xa2\x52\x51\x78\xca\x84\xb1\x8a\x00\x64\xa6\x2e\x14\x2b\x98\x48\x43\xb8\x1f\x38\x78\x89\xfa\x3a\x1e\xf5\xc6\x08\xa5\x8c\xee\xc7\xeb\x76\x95\x14\xd3\x9f\xad\x9f\xf8\xd9\x72\xbb\x7e\xf8\x83\x25\x64\xba\xd5\xf9\xbb\xb1\x8f\x51\x8f\x86\xa7\xab\x4b\xff\xed\x26\x69\xb5\xb7\x70\xe5\x54\xc8\x14\x73\x5c\x9b\xca\x09\x61\x44\x6e\x57\xf4\x04\x5f\x03\xd7\xe2\xf8\x58\xa3\x5b\x82\x6e\x0e\xd4\x88\x6e\x46\xcf\x04\x1c\xb4\x23\x4a\x21\xab\x2b\x15\x58\x7e\xcf\xa8\xd6\x7c\x2a\x86\x85\x4c\x21\x2f\xf7\xd9\x3a\x84\x68\x71\xa8\xba\x79\x36\x6d\xc5\xab\x60\x9c\x68\xb7\x4d\x1f\x83\xfd\x2d\x92\x2d\x7c\x46\x78\x15\xfd\xe8\xec\x3a\xde\x8f\x3e\x92\x21\x2b\x89\x68\x3f\x98\xe6\x54\xd0\x29\x1b\xba\x8f\x0f\xc3\xc7\x87\xe1\x5b\xfb\x80\xb9\x0d\xd5\x42\x93\x62\xeb\xb2\x10\xc7\xef\xd0\x64\x99\x86\xf2\x10\xe8\xbf\xf7\x99\xe7\x65\x4e\x68\x2e\x4b\x74\xd1\x5b\x06\xa7\x77\x64\x39\x08\xc0\x56\x00\x4a\xaf\x85\x54\x4b\x68\x91\x9d\x5c\xee\x5e\xa8\x65\xab\x95\x45\xab\x9b\x25\xab\x83\x05\x6b\x67\xcb\x95\x37\x52\xb7\xc7\xc7\x8f\xde\x6e\xde\xc0\x48\x2e\xb6\x62\xa4\x0a\xf9\xee\xaf\x27\x24\x8c\xc3\x35\x91\x39\x37\xc6\x19\x74\x69\x75\xec\x07\x84\x9b\x9a\xf5\xd3\x9d\x05\xa8\xf7\x80\x25\x32\xd8\x67\xab\x4d\x71\xb0\xa2\xfb\x5b\x8b\x01\x72\xd9\x07\x8e\xd9\x21\xa8\x20\x3c\x2f\xd0\x99\x15\x70\x7a\xe8\x75\x33\xe7\x64\xd0\x9f\x8f\xfe\x7c\xac\xea\xa4\xbb\xc8\x22\xb1\x18\x52\x79\x30\x06\x71\xc4\x62\xb6\x2f\x3c\x03\x1e\x9a\x88\x43\xf6\x2c\x80\x13\x3d\x17\x53\xf2\x91\x81\x65\xe0\x96\x19\xed\x7c\x22\xa1\x07\x55\x6c\x39\xc4\xcc\x5b\x42\x82\xab\x2d\x9d\x4c\xea\x2d\x52\x56\x64\x72\x91\x83\x64\x7b\x6d\x62\x79\x26\x88\x2e\x2c\x2f\x32\x6a\x58\x10\x6c\x36\x5b\x1b\xf6\xe6\x7c\x5d\xe2\xbb\x9e\x37\xa2\xab\x9d\x77\x70\x0b\x9f\xe0\x97\x1f\xa7\xd5\x5a\x23\x6b\x6b\x77\x6f\x63\x73\x6f\x19\x6f\xd5\x5e\x09\x6c\x65\x94\x7f\xec\x28\xaa\x4e\xea\x58\xdb\x48\xa9\x97\x1f\x1b\xd5\x61\xd9\x6d\xe3\x9f\xfa\x88\xa7\x4d\xa0\x6e\x17\xb5\xd0\x3a\x62\xa1\xd5\xfe\xb5\x8c\x5c\xea\x63\x95\x3a\xf0\x97\x47\x10\xfe\xb6\xee\xa5\x91\x19\x43\xc9\xb5\x9d\xee\x7e\x57\xb5\x0f\xf5\xcf\xf0\x7a\x37\x1a\xe9\x69\x6e\x29\xee\xbc\xd8\x62\xcf\x56\x35\x2f\x40\x2d\x63\x28\x14\x3b\x33\xd2\xcf\xcb\x6e\x9c\x58\x10\xbb\x67\xc6\x55\xbe\x8b\x4a\xc1\x19\x05\x97\x3e\x7f\x08\xd8\x36\x60\x20\x3f\xfd\x31\xf2\x6f\x0f\xf1\x2f\x01\x43\xfe\xe0\xff\xf5\xc7\x3d\xe3\x16\xda\x31\x36\x9c\x52\x07\x01\xe3\x0a\x3a\x10\x2e\x52\xb8\x60\x72\x4b\x05\x08\xe0\x58\x16\x3e\xb0\x2c\x1f\xff\x82\x81\x54\xce\xcc\x05\x37\x51\x55\x63\xed\xae\xcc\x22\xbd\xca\x99\x14\xaa\x93\xc1\xc8\x07\xe9\x92\x12\xb2\x01\xb9\x01\x5b\x6a\xf5\x06\x4e\xd2\x07\x89\xe9\x09\xd7\xde\x65\xc5\x70\xdb\xca\x45\xb6\x32\xfa\x1a\x40\xbe\xad\x98\x3c\xae\xac\xc6\xe4\x2b\x0c\xae\x45\xc2\x6d\x82\xcc\x3d\x5b\x54\xcc\xc6\x89\x10\x40\xf2\x07\x15\x96\x78\x56\x80\xbc\xe3\x3f\xbc\x29\x2b\x1f\x73\x81\x1f\xc3\xa1\xfd\x56\xc0\xe8\x1e\xa0\x56\xb2\xcb\x32\xfc\xcc\x21\xc0\xd5\x4e\xce\xa8\xc1\xec\xbb\x0e\x32\x46\xa0\x92\xab\xa5\x8b\x48\xa4\xb8\xfa\xb1\xa4\x59\x3d\x08\xc1\xbd\x72\x8d\x96\xa8\xfa\x03\xcf\xd2\x84\x2a\xe7\xe5\x05\x67\x94\x68\x89\xbb\x87\x59\xf1\x12\x2a\xc2\x69\xaf\xf6\x08\xeb\x20\x92\x82\x2a\xc3\x93\x32\xa3\x8a\xd8\xb3\x30\x95\xaa\x55\xa0\xc0\x56\x88\x56\x48\x73\xcb\x12\x29\xd2\x2e\x0a\xc0\x5d\xb3\x6f\xf3\xae\xb5\x60\x8a\xbb\x74\x7f\x3c\x67\x4d\x24\x3d\xa9\xdb\xb4\xe5\xc4\x9f\xea\x70\xc4\x6a\x96\x8f\x2a\x26\x93\x6b\xc2\x31\x5f\xe8\x69\x44\x1e\xc3\xa9\x18\x91\xaf\x17\xde\xcc\x02\x26\x17\x17\x5d\xa1\x99\xf1\x81\x30\x1e\x65\x1d\xb0\xab\x03\x35\x91\x0a\x82\x53\x4e\x52\x89\x11\x19\x73\x9e\x98\xd3\x11\xf9\x7f\x99\x92\x18\xc1\xc9\xa6\x98\xbd\xd1\xa1\x78\x50\x5c\xa1\x70\x29\xdc\xe0\xbf\x22\x27\x98\x49\x93\xe7\x39\x4b\x39\x35\x2c\x5b\x9c\xa2\x1e\xeb\x73\x71\xb6\xd9\xba\x36\x46\x83\x28\xf1\xea\x6f\x7f\xb3\xa1\x65\xd7\x18\xaa\xef\x7d\x54\x4a\x05\x19\xf4\x21\x68\x6c\x61\xe0\x41\x72\x83\xb8\x19\xfb\x20\x54\x41\x9d\x9e\xcc\x84\x0d\xfe\x9b\xc5\x03\x4a\x14\x9b\x02\x96\x23\xe6\xee\x89\xe3\xe8\x4d\xf9\x5e\x96\x62\xbd\x49\xb0\xb6\xf0\x77\x4e\x09\xff\x3e\xea\xb8\x36\x4a\xf1\x49\xc4\x84\x68\x26\x91\x89\x92\x12\xb0\x4b\x02\x3b\xb7\xe4\x01\x5b\x55\x9e\x28\x5b\x27\x79\xd0\x88\x44\x98\xcb\x16\xaf\xf7\x83\xc4\x2d\x86\x0f\x75\xc0\x65\x70\x10\x77\x80\x69\xc4\xed\x19\x47\x0e\x00\x3f\x11\x82\x15\x82\xc2\xb7\x58\xea\xbd\xd8\x30\xd6\x18\xba\x92\xe3\x37\xc7\x07\x21\xbe\xb8\x1c\x25\x0b\x3a\xa5\xdb\xf3\x1d\xd7\x95\x91\x46\x57\x92\x32\xc3\x54\x0e\x89\x69\x67\xf2\x01\x7f\x47\xb6\x55\xb8\x56\xcc\xe5\xf4\xb5\xab\x9d\x49\x0d\x5c\xa9\x1e\xc4\x08\xe7\x17\x2e\x46\x1f\xe8\x82\x50\x25\x4b\x91\x3a\xa9\x29\x10\xd0\xf7\x8d\x0f\x7f\x90\x02\x28\x45\xa9\x2d\xac\xee\x6a\x54\x7a\xcc\x0c\xb5\xc7\xe6\xf5\xe8\xf5\x96\xdc\xd3\x2d\x01\xd6\x31\x6e\x15\x66\xd3\xb0\x14\xfa\xbb\x72\x7f\x66\x0e\x32\x2f\xc5\x68\xfa\x9d\xc8\xba\xc8\x72\xef\x11\xbd\xa0\xeb\x10\x94\x30\x3e\x01\xdb\xed\x00\x5f\x3d\x28\x6e\x58\x44\x1e\x4f\x26\x34\xd3\x50\x70\xbb\x14\x41\x84\x3d\xad\x8b\x20\xd0\xa4\xcd\x82\xb6\xfb\x83\xe8\x72\xbc\xe7\x39\x73\x07\x0a\x50\xae\x3a\x66\x01\xe1\x8e\xf5\x86\x23\x57\x0f\xee\x24\x27\xd8\xd2\x4a\x6c\x52\x9a\x8d\xe5\xdd\xdb\x3b\x89\xe0\x02\xad\x66\xdd\x45\x25\xf1\x71\xc3\xc5\x01\x57\xfb\x35\x9b\xd1\x39\xd3\x44\xf3\x9c\x67\x54\x65\x10\x2b\x78\x8b\xf3\x83\x62\xec\x2b\x23\xd0\xbb\x45\x37\xc7\x33\x89\x86\xdb\x0a\x6a\x3f\x0f\x0b\x27\xa0\x11\x7e\x5e\x98\x04\xdc\x67\x0e\xff\x9c\x64\xa5\xe6\xf3\x7d\x4f\x93\x8b\x7e\xd8\x81\x55\x37\xb9\x74\x21\xd3\xdb\x82\x25\x4f\xc9\xa3\xeb\x1a\x86\x25\x55\xa9\xdf\x74\xe0\xc9\xa8\xec\x53\x2c\xac\x3f\x66\x84\x26\x09\xd3\xda\xfb\x54\x2e\x62\x3f\xcf\xb0\x86\x2f\x25\xa1\x00\x7d\xd0\x57\x19\xd5\x86\x27\x5f\x67\x32\xb9\xbf\x35\x52\x75\x8a\xd9\x5f\xd5\xbf\x91\x86\xe1\xfc\x87\x5b\x72\xc9\xf5\x7d\x14\x4d\xe0\x2e\x4d\x63\x73\x09\x25\xf7\xe5\x98\x65\xcc\x1c\x1f\x6b\xe4\x72\x39\x4d\x66\x5c\x30\xcf\xe0\x44\x08\x49\x71\x0a\x9f\x85\x72\xd7\x3b\x53\x17\xf8\x74\xe6\xf0\xf5\x17\xf4\x41\x33\x9c\xfe\xd8\x4e\xdf\xfe\xcc\xda\x44\xa4\x1f\xf4\x9e\x02\x27\x73\x7d\x79\xa0\x3b\x88\x89\xbe\xb3\x73\xec\x66\xdc\x3e\xc6\x5e\x5e\x75\x98\xf0\x8c\xb9\xea\x03\x76\xc1\xde\x47\xcd\x9d\x0a\xd8\xbf\x85\x2c\xc9\x03\x45\x1d\x19\x28\xe2\x88\xdc\xf1\xe2\x0d\xb9\x12\xba\x54\xac\xb2\x6e\x34\x87\xe2\xba\x8a\x33\xf3\xca\x15\xec\x37\x2a\x20\x96\xee\x39\x5d\x8b\x5c\x7d\xa6\x79\x91\x31\xfd\x86\x1c\xb1\xcf\xe6\x37\x47\x03\x72\xf4\x79\xa2\xed\xff\x84\x99\xe8\xa3\x11\xb9\xce\xc3\xad\x3b\x17\x13\xa6\x14\xf3\x8e\x50\xd8\xc1\xb2\xe6\x88\xeb\x3e\x0a\xba\x38\xa7\x3a\x2b\xbb\xa5\x92\x3c\x60\x3e\x0a\x4b\xf0\x99\x52\x52\x05\x3f\xf4\x08\x0c\xc0\x6b\x12\x99\x17\x4a\xe6\x3c\x32\xf3\x01\xba\x1f\xd4\xdb\x0e\x8c\x0f\x6d\x0a\x72\x34\xb1\x21\x74\xf4\x08\x11\xbd\x10\x6d\x50\xe1\x7a\xe2\x9d\x29\x50\x8b\x74\x6a\x3d\x0c\xe7\x1a\xd9\xcd\x77\xa3\x58\x42\x16\x6f\xf7\xdb\x10\x50\x47\xce\x52\x36\x3f\xd3\x29\x7d\x3d\x80\xcf\x68\xe7\x08\x58\x9f\x13\xd5\xe4\xe8\xf5\xd1\x88\xdc\x7a\x46\x3c\x88\xe7\x58\xb5\x9b\x48\x15\x06\x04\x3b\xfb\xab\x23\x72\x22\x15\x8c\x9c\x50\x41\x32\x46\xe7\xce\xb6\x8c\xc7\x6d\x81\xea\xee\x69\xeb\x80\xc8\xb6\xb1\x61\xed\x2b\xaf\xb4\x15\x52\x97\x37\xd1\xf7\xf3\x26\x00\x55\xba\x58\x81\x89\x54\x2e\x0f\x48\x68\xa2\x99\x81\xa3\xc7\x45\x4d\x85\x7e\x06\x02\x4b\x3a\x86\xd2\x7b\xea\xd9\x15\x3a\xbe\x1f\xe8\x40\x82\xff\x58\x32\x72\x7d\x19\x02\xea\x99\xd2\x5c\x1b\x7b\x8c\xd3\x1a\xeb\xe2\xc8\xcf\x4e\xce\x73\xfa\x77\x29\xc8\xd5\xd7\xb7\x6e\x02\xa7\xcf\x0a\xaa\xad\xd4\x80\xfe\xbd\x54\xcc\x72\xe1\x0e\xcc\x3d\xf4\x69\x32\x74\xfb\x9e\x5c\x52\x43\x91\xaf\x3b\x4f\x2b\x51\x91\x72\xcb\xb2\xc7\x5c\xa4\xee\xa7\x88\x61\x3f\x35\x6f\xb5\xbb\xf7\x61\x93\x98\x14\x37\xfc\xf4\xf1\xfa\x40\x3c\x38\x01\x62\x3e\x7d\x2f\xd3\xce\x8c\x38\xea\xea\x89\xef\x9f\x2c\x4c\x2f\xf0\x3d\xc9\xed\x98\xc4\x6a\xef\x03\xf2\x91\xd1\x94\xd8\xf3\xeb\xfe\xf9\x83\xd5\x3d\x5b\xd3\xaa\x56\x2c\xc4\x03\xb0\xe3\x32\x7c\x37\xbf\x84\xd8\xd3\x3d\xb5\x98\x03\xc7\xca\xf1\x92\x71\x26\xc7\xc4\x1d\x87\x43\xcf\xfd\xd3\xc7\xeb\x1d\xa6\xfe\xe9\xe3\xb5\x9f\xb9\xfd\xa7\x9c\x3c\xdd\xa4\x77\x12\xdf\x2a\xe9\xed\x6d\x43\xdc\xaa\x58\x72\x15\xb8\xd1\x14\xc9\xda\xcb\x63\xa3\x43\x49\x62\x87\x84\xd8\x3d\x17\x2d\xa2\x70\xeb\xa7\xcc\xf6\xb1\x0a\x05\xfa\xaa\x45\xf7\x88\xb7\x33\x0a\xa1\xcf\x21\x20\x0f\xf6\xd9\x6e\xbc\xb6\x5c\xc1\xef\xb8\x55\x02\x81\xb6\x91\x4b\x86\xb7\x9c\xe9\x1b\xef\x3b\x10\x7a\xac\xee\xf0\x1e\x3c\x35\x53\x47\x5f\x09\x3a\x6e\xa6\x11\x82\x9d\xa0\x55\x49\x84\x9f\xe8\x9c\xf2\x8c\x8e\x79\xc6\x21\x95\xba\xd5\xee\x63\x6f\x54\x0d\x53\x3e\xe8\xa9\xdf\x51\xe4\x08\xe2\xc4\x92\x71\x8b\x9c\xd8\xdf\xce\xc0\x38\x76\x3a\x02\x6a\x05\x0d\x21\x47\x63\x43\x28\xf9\xb8\x4d\x28\x39\x98\xfc\x00\x3b\x60\x4f\x4c\x57\xae\x68\xfb\xac\xe4\x8a\xf0\xc3\xad\xcb\x27\xf7\x92\x19\x23\xc6\x5a\xb5\x62\x8d\x80\x5f\x5b\x5b\xb6\x67\x8e\xfb\x22\x57\xfa\x65\x20\x17\x09\x11\x6d\x3b\xf0\xcf\xaa\xa3\xe7\x43\xa0\x24\x81\xc7\x99\x8b\x76\xab\xb9\x66\x22\xf6\xdd\x3a\x5a\xe3\x52\x30\x21\xd7\xb5\x38\xd7\xa6\x2e\x5a\x97\xa4\x0d\x1e\x23\xba\xae\xca\xf7\xf3\x8b\x42\x12\x08\xaf\x49\x0b\x5c\x6c\x3d\xc9\x84\x15\xb3\x49\x97\x2b\x71\xdb\xe1\xed\x6d\xdd\x12\x78\xc1\x8a\x19\x79\x7b\xbb\xe2\x18\x03\xec\x61\xd6\x1a\xed\x83\xc7\x9a\x64\x7c\xc2\x0c\xdf\xb2\x84\x47\x38\xc8\xb9\x14\xdc\x48\xb5\x3e\x04\x9a\x74\x3a\x9c\x7e\xb8\xae\x0c\xd5\xf7\xb3\x3b\x5b\x25\x10\x79\x1f\xbd\xa5\x24\x91\x59\xc6\x12\xe3\x52\x5a\x01\x78\x43\xb7\x15\xca\x13\x73\xf6\x80\xd1\xfd\xef\x41\x7d\x72\x8a\xd2\x19\x6e\xee\xd9\xc7\xab\xf3\xcb\xf7\x57\xa3\x3c\xfd\xc5\x4c\x3e\x0c\x8d\x1c\x96\x9a\x0d\x79\x8b\x0c\x25\xcf\xe7\xbd\x88\x4f\xd1\x2a\x61\x56\xd3\x20\x83\xb9\xbe\xbe\xf3\xf1\x93\xe4\x93\x46\xaf\x05\xb0\x1d\xf9\x3b\x29\x29\xcd\x80\x28\xea\x62\x24\xa9\x33\x3d\x95\x59\x86\xd0\x36\x8a\xb1\x41\x6c\x8b\xd9\x18\x1a\xd2\x79\x61\x7b\x1b\x2a\x6a\x0b\x7c\x5c\x19\xe2\xe9\x11\xae\x0b\xc7\xd8\x2e\x93\x2c\x43\xb1\xea\x59\x87\xe3\x6d\xed\x3d\x1a\xce\xcc\xcc\x42\xf5\x9e\x2d\x08\x38\x02\x4f\xa4\xb2\xf8\xa4\xea\xb8\xc1\x4c\x02\x4b\x3f\x2b\x35\x53\x23\xc7\x76\x9e\x1c\x6c\x1d\xb2\x08\xed\x90\xbc\x2d\x74\x5c\x05\x33\xf7\xba\xca\xec\xeb\xe4\x35\x5a\x9a\x19\x13\xc6\x8a\xfd\x96\x96\x39\xc8\xac\x04\xa2\xf3\xc3\x7e\x72\xa8\xb5\x4c\x62\xd4\x2d\xe5\x50\x9f\xa6\xa7\x0b\x4e\xda\x53\xd3\x15\x1d\x6d\x1f\x08\x44\x8c\xc9\x7c\x88\xe5\x52\x34\x95\xe0\xb0\x81\x19\xe8\x6a\x88\x46\xd3\x9c\x8b\x17\x78\x3a\x13\x2e\xd2\x6d\x70\x68\x18\xc0\xa0\x47\x5d\x14\x73\xef\x9c\x41\x3f\xdc\x1b\x52\xaf\x49\x61\xc0\xbb\xbb\x41\xac\xdf\x1f\xb6\x3a\x7c\xf9\x42\xff\x98\x0d\xf1\x2b\xc3\x22\xad\xa0\xd2\x5f\x06\x2e\xdf\xe0\x1d\xd6\xa4\xf4\x04\x57\x7c\x07\xda\x6d\xf2\xc4\xd2\xd0\xe3\xea\xb9\x4f\x02\xa8\x2e\x32\xcf\xbe\xdc\xbb\xa2\x99\x50\x78\x5f\xfb\xe0\x33\xcc\x6c\x06\x67\xd4\xeb\xcb\x50\x90\x9f\x2a\x9a\x33\xc3\x14\xba\xc0\x39\xa7\x3a\xe1\xa2\x13\xbe\x2b\x98\xb8\x35\x34\xb9\x3f\x74\x2a\xd4\x9e\xe3\x3e\x1e\xc7\xdd\xfb\x2a\xd0\x23\x82\xcb\x8b\xb4\x88\x6f\x91\xb9\x70\x5c\xe8\x85\x90\x98\x90\x8e\xac\x8b\x95\x23\xa4\xa3\xaa\x73\xd7\x2a\x3d\x19\x1a\x36\xc0\xd3\x2d\xe4\xd7\x03\x0f\x7e\x84\xc2\x61\xb8\x61\xfb\x33\xe0\x48\xe0\x2e\xf7\x68\x51\xd7\x3a\x75\xc8\xed\x9b\x31\x37\xd5\xb9\xd7\xcc\x90\x82\xa9\x9c\xbb\xb0\x6e\x29\x48\xe2\xc2\x02\x80\xaf\x59\x1e\xe6\x86\x8b\x78\x9e\x20\x32\x31\xd4\xc5\xcc\x90\x31\x33\x0f\x8c\x09\xf2\xea\xd5\xab\x57\x20\x97\xbc\xfa\xdd\xef\x7e\x47\x20\x8f\x44\xca\x12\x9e\x2f\x37\x84\x56\xff\xe7\xf5\xeb\x11\xf9\xef\xf3\xf7\xef\xc0\xab\xac\x30\x9a\x8c\xa5\x99\xb9\x91\x6d\x83\x5a\x67\x3d\x20\xff\xf7\xf6\xbb\x0f\x5e\x9c\xd0\x8d\x5f\x41\x05\x09\xcb\xab\xbb\x08\xbe\xfa\xed\x6f\x7e\x33\x22\x97\x5c\x41\x3c\x31\x87\x08\x88\xe0\x04\x59\x78\xc7\x40\x28\x3c\xd4\x8c\xe0\x77\x1c\xc4\x39\x09\xe7\x7c\x3a\x03\x00\xd8\x03\x21\xc5\x24\xe3\x89\xc1\x9c\x82\x78\xf4\x11\xd0\xae\x2e\x12\x75\xe1\x5e\x4e\x8a\x80\xc9\x0d\x48\xc6\xef\x19\x99\xe8\x6f\x94\x2c\x8b\x2a\xcc\x51\x31\x6d\x65\xd9\x84\x0a\x88\x2a\x81\xc1\xaa\xbd\xd2\xcc\x3c\xab\x13\x46\x4b\x43\x50\x0d\x07\xa1\x4f\x43\x40\x19\x84\xdc\x6a\x43\xc4\x87\x82\xf2\xe0\x38\x08\x77\xea\xb5\xcc\xfe\x41\xf7\x4c\xa3\x5c\x72\x3e\x76\xa5\x50\xf2\x6f\xb8\x55\x5c\xf8\x28\x28\x27\x21\x6b\x27\x93\xb9\xa0\x53\x11\xd9\x5c\x7d\x54\xbe\xe5\x85\x2e\xe2\x3f\x8a\x9f\xba\x9e\xc4\x81\x76\x10\x96\x8e\xe5\xd5\x6a\x89\x2f\x57\x7c\xb9\x4a\xd6\x6e\xb1\x49\xe3\xbe\x96\x62\xa9\xb7\xab\xa3\xe2\xc8\x8f\xab\xae\xe3\x42\xd8\xaa\x31\xd0\x15\xd7\x05\x00\x45\x35\x9b\x6a\xc9\xe8\x6a\x5e\x3e\x9a\x99\xd2\x81\x06\x3c\xaf\xec\xb7\x99\xd6\x2e\x8e\x28\xa7\xea\xde\x2a\x09\x8e\x0a\x8c\xc0\xeb\x59\x87\x18\x26\x0c\x28\x9b\xa3\xb1\x3c\xa7\x8b\x5a\xd4\x80\xfd\xc8\xf1\x68\x74\x8c\xc7\x44\x2a\xcc\xe5\x89\x38\x6f\xdf\x3f\x53\xbc\x74\xdd\x2b\x9d\x16\x58\x76\x0f\xec\x39\xae\x6c\x09\xad\x79\x3b\x53\x07\xa9\x36\x19\x7c\x3b\x96\x2d\xec\x56\x1f\xb7\x7d\x5d\xdc\x21\x2c\xa0\x45\xd3\xae\x35\x70\x3b\xd4\xbe\x5d\x97\xad\xc1\xc1\xd8\x9d\x84\xb6\x15\x21\x3b\xe7\x02\xcf\x5b\xb1\xbe\x15\x53\x3d\xce\x1d\xe7\xfb\xae\x1b\xe7\x73\xf1\x7a\xb5\xe2\x60\x2f\x9f\xd5\x5d\x4f\x30\xd2\xa5\x4e\xba\x1c\x69\x88\x45\x81\x50\x88\xab\x0a\x7b\x79\xd1\x1c\x2d\x46\x9b\x6e\x89\xe7\xbb\x70\x37\x7c\xda\x5d\x4c\xe0\x53\xc3\x35\x7f\x3b\x81\x8b\x76\xa4\xb4\xa8\x15\xf8\xc8\xd0\x6e\x00\x32\xa6\x3f\x3c\x23\xf2\xde\x91\x5a\x44\x32\x3a\xd6\x32\x2b\x0d\x76\xad\x7e\x8c\xe9\x30\x0c\xea\xb3\x2c\x00\xf1\x0d\xcd\x22\xaa\x6c\xaa\x12\x67\xed\x08\x34\x3e\x1d\x0e\x67\x9f\xed\xf3\x11\xb3\x7d\x86\xfc\xb4\xba\x65\xbd\x26\xfd\x68\xe9\x75\x13\xcd\xbb\xe8\x57\x9a\x93\x93\xaa\x4c\x88\xbf\x8e\xbf\x16\x86\xa9\x09\x4d\xd8\x69\xac\x77\x85\x72\x2c\xc1\x45\xc8\xc7\x45\xcc\xa8\x48\x33\x14\xc0\x13\xa6\x00\xf7\xd9\x67\xc3\x94\x05\xc9\xc5\xed\x35\x49\x15\x9f\x33\xa5\xc9\xc9\xd7\xcc\xca\x8b\x8c\x9a\x52\xb1\x56\xd1\x55\x87\xf5\xad\x84\x69\x1c\x4a\xd3\x83\xc1\xba\xba\xea\x41\x27\x4f\x79\x44\x74\xbe\x2a\x30\x21\x54\x11\xa4\x3a\xd6\x65\x47\x16\x95\x80\x40\x03\xcd\x58\xc8\x52\x39\x2b\xba\xcf\xab\x9a\x48\x65\xd5\x25\x1c\x98\x6a\xa2\xd8\xd4\x4a\xb3\xca\x17\x1b\x66\x24\xc9\x4a\xfb\xe2\xa0\xee\x6c\xfb\x38\x00\x56\xa6\xd9\x4d\xbe\x7a\x13\x27\x55\xcb\x39\x4f\x3d\xab\xc4\xda\xc7\xa1\xaa\x61\x41\x75\x14\x6a\x13\x65\xa0\x8f\x00\x8b\x32\x3a\x30\xd4\x10\xc4\x5a\x73\xf6\x8f\x8d\xc2\x12\x72\x5b\xb4\x28\x1f\xd1\x85\x08\xcb\x94\xdd\x94\xe3\x8c\xeb\xd9\xed\x8e\x26\xc4\x55\x43\xa0\xb3\xc2\xd2\xad\xdf\x5a\x4b\xa2\x66\x42\x73\x60\x79\x96\x8c\x5b\xa6\xcb\xad\x1c\x25\x01\x88\xbe\x77\x8c\x90\x12\xa2\x3f\x32\xe6\x32\x18\xd8\x9f\x3e\x54\xf3\x70\x41\x69\x98\xb3\x24\x65\x9f\x44\x51\x7b\x9f\xd0\x2c\xd3\xcd\x80\x5d\x4f\x31\x51\xf6\xf0\x81\x6a\xb8\xa7\xdc\x6e\x77\xa8\x8c\xd2\xc8\x7e\xb9\x76\x61\x9a\xe4\x12\xc3\x78\x04\x91\xc2\x37\x82\xd4\x2b\xbe\x43\x14\xc8\x08\xe1\xca\x80\x32\x07\x2e\x1d\xd9\x9b\x4b\x1f\xcf\x5c\xba\xaf\x1f\x5e\x5c\xef\xbd\x8a\x86\xae\xa5\x25\x0d\xa4\xd4\x93\xdc\x2d\x4e\x1d\x07\xbd\x56\xc0\x6f\x9e\x1b\xa3\xf8\xb8\x34\xdd\xf3\xbd\x35\xba\x03\x9b\xb6\x8a\x08\x9c\xe2\xa1\x5b\x7d\x12\xa1\xa8\xd3\x10\xc2\x59\x58\x3e\xfb\x15\xcf\x01\x76\x83\x2f\x8f\x35\x49\x65\x52\x86\xbc\xb0\x00\xb4\xea\x02\xad\x4d\xf6\x44\xd2\xf5\x5c\x75\x4f\xe9\x15\x7f\x64\x2b\x7a\xa5\xf2\x41\x3c\x50\x95\x9e\xdf\x6c\xf1\xbe\xaf\xb3\xf3\xaa\x57\x2c\x28\xf9\xd7\x50\x05\x90\x8e\x65\x69\xaa\xd4\xa1\x3f\x1d\x7b\xf5\x2a\x35\xdd\x48\x4b\x1a\x5a\xda\xa3\xbb\x2a\xfa\xbd\x89\xbb\x37\x71\xd7\x9e\x5d\x4c\xdc\xd7\x68\xe2\x8e\xf3\xe0\xd6\x8e\xab\x4f\xaf\xc0\xb3\xb6\xbe\xbd\x8f\x69\x25\xbd\xac\x08\x0c\x4a\x53\x4d\x3f\xfe\x86\x00\x87\x47\xa4\xda\xdb\x48\xe8\xf3\x14\x08\x78\xf6\xf3\x5b\x54\x1f\xc9\x4e\xda\xbe\x4e\x31\x3e\xeb\x0a\x09\x6e\xaa\x5b\x0c\x52\x43\x54\x68\x78\xe0\xb2\x40\x0f\x9c\xde\x25\xd2\xaa\x84\x1f\x26\xa1\xee\x50\xa6\x14\x9f\x8e\xc0\x27\x9d\x37\x80\x74\x2c\x22\x8c\x4f\xd7\xdd\x20\x3b\x14\x14\xc6\xe7\x99\xcb\x0a\xe3\xd3\xd9\xf6\x4d\xba\x97\x18\x5e\xb1\xdc\xc7\x2d\x34\xbc\xe3\xd2\x76\x37\xeb\xef\x6a\xce\x1f\x54\xe5\xed\x5e\x3e\x5b\xef\xcd\xf9\x4b\xcf\x13\x9a\xf3\x23\xc2\xed\x89\xc1\x0a\xd3\x7e\x6c\x6e\xf3\xf6\xfd\x31\xf3\x62\xe5\xa8\xca\xbe\x66\x51\xce\x5b\xf6\xa5\xaa\x5f\xab\x1e\x8f\x46\xc7\xc7\xde\xde\xef\xf0\xb3\x34\x93\xe1\xef\x09\x13\x89\x4c\x71\x53\xed\xf8\x4a\x1b\x60\xfa\x95\x9a\x1e\xcf\x25\xf7\xdf\x8a\xaf\x66\x61\xec\x6e\x5b\xd2\xe1\x04\x77\x2f\x1b\xbe\x0a\xd2\x4f\x51\x3c\x3c\x2e\x11\x5e\xaf\x08\x8e\x2d\xf6\x29\x03\x1e\x03\xef\xd1\xf9\x6b\xeb\xc2\xe0\xf8\xec\xc2\x5e\x77\x28\x12\x8e\xcf\x13\x97\x0a\xc7\x67\x27\x8e\xda\xa9\x6c\xf8\x8a\xc5\x3d\x5d\xf1\x70\x7c\x5e\x68\x21\x99\xfa\xd3\xa9\x90\x38\x3e\xbb\x95\x13\xaf\xf7\xed\xb8\xf5\x07\x29\x2d\x8e\x4f\xb7\x02\xe3\xf8\x1c\xba\xcc\x38\x3e\x2d\x21\x01\xc6\xf0\x4b\xde\x29\x14\xc1\xf7\xa9\xbb\x4b\x1a\x96\x17\x52\x51\xb5\x20\xa9\xb3\x35\x2c\x56\x44\x84\x46\x21\xa1\x7b\xa7\x86\x81\x79\xa4\x5c\x1d\x28\x1a\xa1\x43\x34\x28\x4b\x79\xb9\xb6\x5c\xf3\x3a\xb0\x61\xaf\x18\x68\x0f\x90\x0d\xcc\x65\x12\xf3\xd7\x9d\xae\x99\x4f\xac\x48\x93\x7b\x57\x31\xc8\x43\x15\x79\x7f\x14\xe4\x72\x74\xd4\xc8\x03\x0d\xe6\x31\xb8\xfb\x73\x95\x11\x7d\x63\x1c\xbb\x66\xca\xc2\xdb\x10\xe7\x16\x70\xe2\x1a\x9e\x5a\x89\xe4\x3d\xb0\xc1\x27\xda\x25\xd2\x31\xb2\x8d\xff\x9d\x41\xb9\xb1\xce\xbe\xf1\xbe\x63\x48\x07\x2d\x41\x32\x0f\x75\xd1\x32\x99\x44\x77\xcf\x35\x0e\x05\xdb\x70\xe5\x91\xdf\xdb\xee\xed\x66\xd8\x51\x51\xbe\x00\xa3\x4f\xa6\xf1\x5e\x8f\x27\x90\xda\x12\xa4\x78\x00\x66\xd8\x80\xbb\xa8\x4a\x60\xa9\xed\x97\x20\xf3\x7c\xd4\xa6\xfa\xd0\x83\xcf\xb0\x69\xa2\x42\x6e\x75\xdd\xc3\xfe\x72\x1b\x56\x56\xe9\x6d\x10\x02\xe1\x05\x75\x5d\x82\x98\xe8\xbe\xe2\xc4\x25\x39\x81\xbb\xab\xaa\x2c\x5a\x48\xee\xb8\x84\x66\x82\x67\x75\x3c\xf3\xb9\xec\xc2\xc2\x4b\xe1\x1c\x0d\x96\x90\x66\x35\xce\x94\x9a\xa9\xe1\xb4\xe4\xe9\x2e\xd8\xf2\x82\x19\x60\x6b\xb6\xd7\x9d\xd9\x75\x64\x71\x7b\x30\xb6\xe0\x88\xd1\x81\x35\x1c\x55\xde\x1b\x35\xde\x10\xa7\xc5\xab\x7b\x72\x50\xef\x2c\x10\x8e\x9c\xbf\x12\xba\x0b\xaa\xad\xe3\x19\xc9\x22\x71\xc1\xba\xbc\x96\xee\x12\x87\x45\xcc\x03\xc7\xd6\xa1\xfd\x8f\x57\x81\xbd\x3d\x7f\xcc\x26\xb2\xaa\x90\x82\x1a\x91\x73\xc7\x4d\x59\xc6\xa0\x8c\xbc\x2f\x51\x6f\x1b\xc0\x95\x70\x2e\xe7\x16\x99\xff\x47\x90\x4f\x3e\x67\x3f\x9f\xbc\x21\xf4\xb4\x16\x02\xe1\xaa\xce\x08\xc6\x52\xf4\xd1\xcd\xaa\xef\xa8\x52\xe8\x01\x19\x9f\x7a\x7f\x14\x38\x71\xc2\x8a\x85\x99\x97\x78\x51\xaf\x56\xcc\x02\x00\xc2\x8e\x95\xcc\x89\x16\xb4\xd0\x33\x69\x40\x35\xa4\x05\x4d\xb8\x59\x10\xa3\x68\x72\x0f\x25\x8a\x14\x73\x9f\x1b\x90\xe4\xd4\x39\x76\xc5\xe0\xab\xbb\x0d\x9b\x99\x92\xe5\x74\x06\x9e\xb0\xd8\x2a\xc9\xa8\xf6\xab\x5f\xd9\xdf\x69\x3b\x9a\xa4\x0b\x41\x73\x9e\x84\xac\x81\x4a\xce\xb9\xe6\xd2\x59\x7b\xfd\xb8\x37\x21\x33\x1c\x5a\x90\x2f\x32\xca\x73\x72\xa2\x19\x23\x57\x1e\x25\xf0\x17\x57\xc6\x1e\x2d\x1b\xaa\xee\x1c\x20\x43\x4a\x73\xe1\x12\x22\x54\x04\x2e\x5c\x5e\x21\xc3\xb4\x33\x5f\xf9\xd1\xd3\xb0\x5d\xab\xe7\x24\x15\x5c\xdc\xfb\xd4\x9d\x4c\xa4\x32\xba\xb5\x3c\xbf\xb9\xd6\xb1\x36\x82\xb8\xe5\xf2\xde\xc1\x0f\x99\x14\xd3\x38\x8d\x40\x85\x99\x96\x94\x0a\x28\xef\x32\xe7\x69\x49\x33\x24\xa2\x6e\x32\x17\xb7\xd7\xd8\x9d\x4f\x67\x66\xf8\xc0\xc0\x1a\x83\xbc\xa6\x3a\x33\xfe\xa3\x7c\xc9\x5b\x87\x6b\x20\xba\xc6\x59\x13\xd0\xb2\x65\xa7\xf6\x40\x17\x90\xb6\xc6\xb9\x98\xd4\x2e\x4c\x7d\x62\x31\x1c\x62\x15\xc4\x61\x7a\xe7\xa1\x5c\x87\x15\x1b\xc0\x5c\x65\x41\x0c\x98\xba\x3c\x37\x0b\xf8\x28\x0f\x60\x78\xed\x2a\xb3\x51\xbb\x41\x56\xb8\xdb\xac\xcb\x3c\x82\x50\x36\xaf\x36\xf9\xce\x95\x4e\xec\x28\x1c\x1c\xfd\x10\x99\xcd\xa2\x8b\x0e\x7b\x6c\xa8\x48\x87\x34\xb3\x98\x73\xf3\xfd\x85\xf3\x70\xc6\x83\x50\xbb\xc8\xf7\x55\x90\xb8\x08\x69\xb3\xad\xcc\xb0\xf2\x08\x40\x1c\xfc\x98\xa5\x40\x34\xe2\x82\x91\x0f\x56\x43\x76\x9b\x77\xf3\xfd\xc5\x80\xf0\x11\x1b\xf9\xbf\x42\x53\x4f\xb5\x8c\x9c\xa2\x1b\x60\xf0\xf1\x04\xbc\x83\xa9\xc4\xc6\xa8\xb8\xef\x5f\xff\x60\x27\x69\x7f\xfd\xe3\xf0\x0f\x51\xb6\xd1\x3f\xfe\xd5\x12\x41\x65\x1b\xd4\xdf\xc6\xbe\x64\x21\xeb\xfe\x5f\x6f\x5c\x56\x6a\x97\xb3\xfa\xaf\xae\x18\x17\x13\xc6\xca\x8d\x37\x12\x6e\xe9\x79\x8a\xd8\x08\xdf\x56\xec\x6f\xde\xb0\x08\x60\x0a\x46\x9d\x84\x1a\x26\x80\x50\xfb\xa0\x0c\x21\x0d\x76\x77\x75\x67\xed\xfc\x4f\xc0\x24\x80\x41\x65\x03\x62\xa4\x84\xe3\x88\x47\xfe\x5c\x10\xe6\x6b\x75\xe2\x5a\x01\x1c\xd4\x39\xaa\x79\xde\x63\x87\xb5\x10\x0e\x21\xb8\x76\x1e\x30\xb7\x5f\x09\x69\x7e\x15\xb6\xbf\x51\x45\x9c\xce\x25\xf7\x09\xc8\xed\x49\x11\x58\xd1\x31\xa4\xc4\x1e\x2f\x48\xce\xb5\xa1\xf7\x6c\x44\x6e\x2d\x6f\x89\x6f\xc3\x10\x7a\x82\x40\x06\x4b\x96\x92\x52\x18\x9e\xc1\xaf\xd5\x38\x76\xca\x31\xcf\xb9\x9e\x10\x5d\x42\x79\xf3\x42\xb1\xa1\xe7\x62\xae\xd5\x12\x2d\xa8\xd6\x32\x08\x9b\x3d\xa3\xa8\x0b\x14\x29\x74\x05\x78\x50\xe1\xd0\x6b\xc9\x8f\xcb\xce\x53\x8a\xa4\xe2\x5c\x00\x4c\x3d\x22\x1f\x80\x59\x65\xfe\x4a\x18\xd5\x12\x67\xc0\x14\x2c\x61\x5a\x53\xb5\x18\x40\x62\x77\x1e\x92\x81\x3b\xd7\x1d\xe0\xa8\x39\x15\x98\x56\x5d\xb1\x44\x0a\x6d\x54\x99\x18\xac\xb3\x37\x56\xf2\x9e\x89\xe0\x2e\x68\x77\xb1\xee\xc0\x55\xf9\xcf\xc0\x7d\x97\x24\xc9\x8c\x8a\x69\x54\xa7\x26\xa7\x29\xc0\xfe\xdb\x20\xe5\xf8\xf5\x58\x08\xd0\x89\x15\x2c\xb8\x01\x50\x8c\x2d\x1f\x09\x66\xd8\xff\x11\x21\x1f\xcf\xa0\xb2\x93\xda\x25\xf1\x6c\x0b\xed\xea\x44\xbf\x48\x47\xa3\xde\x10\xd8\xf6\x81\x1d\xc0\x72\x66\x68\x4a\x0d\xdd\xc1\x09\xec\x7d\x55\x5c\xcf\xd7\xd7\xc7\x02\xa7\xe1\x62\xd2\xf1\x21\x2f\x6e\xc9\x82\xc7\xf1\x4f\x70\x12\x67\x1e\xf2\x10\x71\x6d\x2c\x4e\xb9\x8b\x02\xf4\xed\x02\x79\xc6\x57\x2f\xb3\xc3\xfb\xd1\x90\x5c\x54\xa5\x19\x2b\x72\xd2\xee\x1a\xaa\xa3\x05\xd6\x82\x7e\x07\x18\xdd\x55\x77\x65\x49\xdd\xbf\x6b\xa5\x08\x82\x5c\x82\x09\xc3\x15\x8b\xc3\xcd\x1c\xe8\x4a\x81\x48\xde\x00\x22\x40\x79\xca\x8c\xae\x3c\x54\x90\x0e\x5b\xe2\xe2\xf8\x9d\x53\x46\x81\x48\x3b\xc0\x3a\x7d\x6e\xb5\x2c\x84\x60\xd7\xd2\xd1\x59\x4b\xf9\x1f\x05\xae\xbb\x18\x9d\xb1\x9c\xc0\x7b\x99\x76\xb1\x53\x37\xb2\xf0\x57\x43\x54\xfe\x9b\xe8\x89\xab\x41\xa9\xc7\x06\x70\x5b\xa5\x6b\x41\x73\x48\xe4\x66\x74\xbe\xbb\x91\xaa\x92\x91\x86\x21\x95\x31\x7c\x6e\x08\x9f\x1b\xbe\x6e\x6f\xcc\xeb\xe2\x01\xe2\x9f\xd6\x9e\x20\xf5\x8f\x74\xb2\x9c\x5a\x92\x72\xdb\xd1\xdc\xd9\x88\x46\x0e\x23\x38\x9a\xef\x6e\x11\xc3\xcd\xad\x8b\x74\x60\xdc\x52\x8b\x37\xe4\x57\x35\x2e\xef\xa4\xa9\xa0\x29\xa1\xa7\xee\x89\x57\x9d\x46\x6e\x2b\x7c\xf0\x79\xbd\xf9\x69\x63\x30\x10\x2f\x56\x6b\x14\xde\x23\x38\x88\x7c\x56\x3c\x53\x60\x3c\xf3\xf1\x07\x16\xbd\x94\xcc\x32\xa6\x60\x09\x4e\x7b\x6a\xdc\xa2\x43\x2e\x53\xb4\xe9\x0e\x82\x8a\x1a\x64\x4c\xc1\x1e\x82\x30\x41\x35\xa6\x6e\xf1\x37\x5e\xcc\x15\xce\x5b\x3b\x5e\xf0\x5a\x3e\x17\x0b\x9c\xfa\x65\x04\x5a\x54\x3d\xc9\xd4\x7e\xc8\x4a\x9d\x82\x8e\x33\xbc\x3d\x0e\xcc\x16\xe6\x42\xb3\x07\xba\xd0\x80\xf7\x95\x34\x1f\xbe\xef\xb2\xaa\x55\x03\x7f\x64\x13\xec\xdd\xfa\x46\x6c\xa7\x3b\xb1\x5d\x6e\xc5\x20\x9c\x92\x8b\x36\x2e\x48\x55\x87\x8d\x85\x43\x9a\xcf\x2e\xd7\x68\xe0\xa7\x02\xd7\xe7\xdd\xee\x44\xea\x75\xca\x6f\xae\x61\x08\x2f\x93\x4f\xe1\x0f\xcf\x71\xc2\xa5\xc1\x98\x59\xac\xae\x02\xa5\x01\x43\xe2\xbe\x2b\x3c\x09\x2a\xd4\xfa\x16\xb2\xb1\x3a\x2b\x71\xa8\x34\xa6\x18\x78\x82\xc0\x17\x47\x50\x8e\x80\x8a\x85\xe3\xe4\x66\xc6\x55\x3a\x2c\xa8\x32\x0b\x54\x1f\x07\xb5\xaf\x05\xf7\xfa\x4e\x0b\xdf\xf1\x3a\xa7\x5d\xea\xe3\xb5\x10\x86\xc5\x7b\xf3\xb0\xb3\xce\xaf\x85\xeb\x53\xac\xa7\xbd\x03\xff\xca\xf5\xc4\xa9\x45\xbd\x46\xf8\x6c\xeb\x49\x63\xf2\xb1\x3f\xdf\xb0\x34\x48\xd7\xaf\x5e\x91\x0d\xc4\xa5\xab\x64\xec\x05\x1d\xb8\x3c\x28\x44\x76\xa4\x81\xd5\x43\x69\x55\x6b\x3c\x32\xec\x39\x49\xc1\xfb\xd0\xb8\x4a\x47\x62\xe1\x4c\x37\xf1\xb7\xe2\x01\xc2\x29\x21\x27\x42\x0a\x3c\x39\xd8\xf6\x14\x5d\x88\xd6\xd8\xa6\xa0\x89\x2b\x51\x57\xaf\x10\x1a\x9d\x54\xcf\x24\xb8\x48\xed\xd6\x01\xe5\x06\x1d\x49\x97\x49\xc2\x58\xd0\xaa\xe3\x12\x35\xd5\xc9\x76\x53\xf6\xa5\x2e\xb5\x84\x24\x2e\xda\xd0\x2c\xab\xb4\x59\x07\x2e\x09\x7c\xce\x5b\x00\x23\xf6\x57\x0b\xb4\x71\x8a\x3d\x14\x51\x47\xb7\x97\x52\x24\x78\x85\xcf\xcd\xc2\xcf\xe0\xb2\xc9\xea\x41\x8d\xd0\xa8\xe4\xf2\x09\xda\x9d\x22\x75\x20\x00\x13\x48\x93\x2b\xe1\x5e\xe7\x4c\x2e\x37\x83\xa5\x43\x63\x9a\xdc\x3f\x50\x95\x42\x29\xdf\x82\x1a\x8e\x69\xc1\x07\xb5\x61\x4f\xa2\x39\x40\x21\xfd\x18\x8b\x4e\x83\xd2\xa1\x59\x48\x41\x5d\x7d\x86\xd0\xd2\xc8\x9c\x1a\x9e\x80\x2a\xcb\x27\x91\x15\x31\x0f\x29\x0d\x1b\x65\x07\x81\xca\x86\x02\xf6\x77\x78\x1b\xa3\x18\x31\x0f\x92\xf0\xdc\x4a\x08\x14\x4a\x69\x4c\x42\xc4\x90\xb7\x77\x6e\x9a\xa9\x15\x83\x7e\x00\x23\x73\xd4\x0a\x95\x64\xab\x42\x69\x18\x3e\x58\x34\x83\x29\xcf\x85\xdc\x0c\x1a\x0c\xdc\xf5\xb1\x38\x6d\xe7\x1a\xa1\xea\xc0\x6e\xcf\x03\xb3\x72\x81\xde\x88\xb0\x7a\xb4\x6a\x46\x58\xd3\x56\x93\x94\xeb\x46\x61\xea\x93\x54\xc9\xa2\x70\x06\x92\xfc\xb4\x39\x23\xb8\x37\x50\x73\xa6\xa3\xda\xcb\x68\xaa\x9e\x32\x11\x8a\x87\xbb\x74\x16\x70\x72\x9b\x9f\xa8\x1d\x98\x11\x06\x84\x9e\x92\x4f\xae\xa8\x50\x40\xdc\xe0\x75\xd7\x4a\x70\x42\x6b\x8b\x93\x9d\x7a\x89\xa7\xed\xd3\x4b\x3c\xbd\xc4\xf3\xf3\x96\x78\x82\xbb\xd7\xae\xd2\x4e\xe5\xe3\xd8\x28\x48\xee\x9d\x01\xaa\x06\xeb\x8c\x18\xd7\x13\xf2\x91\x25\x72\xce\x14\x12\x39\x28\xfc\x69\x79\xf9\x5b\xca\x33\x4b\xe2\x3c\xa9\xab\xd4\x43\xc8\xa8\x5a\x37\xcd\x45\x1a\x79\x80\xa6\x43\xf3\xdc\x4d\xca\x45\xfa\xd9\xf6\xee\x92\xac\x50\x6c\xce\x65\xa9\xbd\xcb\x42\x69\xf0\x98\x69\xe3\xf8\xed\x8c\x4f\x43\x62\xee\x70\xd5\xa9\x58\x22\x55\x5a\x85\x94\x6b\x43\x4d\xa9\xeb\x71\x12\x09\x5a\xd3\x0e\x67\xa0\x09\x70\x7c\x64\xea\xbe\x1b\x25\x45\x8f\x8d\x3d\x4e\xc5\xf1\x3b\xf4\xf9\xa8\xea\x6e\x9b\xc8\x0d\xa5\x72\x81\xb1\x22\x54\x69\x58\x84\x56\x0e\x01\x3a\xc3\xba\x16\xf5\x7a\x86\x85\x5b\x86\x61\xd8\x61\xe5\x75\xd2\x22\xe3\x7a\xfc\xec\x04\x75\xb2\x47\x80\x67\xfc\xbc\x60\xc7\x93\xc6\x62\xbb\x7b\x5f\x92\x3d\x3d\x30\xc9\x3e\x5e\x98\xe4\x90\x9e\x98\x24\xf8\x73\xef\x73\x62\x3e\x7a\x4f\xf2\xc6\x99\x71\x84\x77\xd3\x99\xa9\x25\x14\x08\xe3\x70\xed\x2b\x40\xba\x6b\xcd\x70\x06\xc0\x24\x18\xfb\x03\xbb\xd3\x0a\xda\x1c\xde\x5d\xb2\xcf\x21\xeb\x6f\x24\xc7\x54\x45\xb5\x8d\x04\x0f\x84\xbc\xc0\x4c\x40\x70\xea\x86\xce\x25\xcb\x6b\x4b\xfd\x09\xee\x4f\x70\xdb\xfe\xcf\x79\x82\xd1\xe3\xb9\x8b\x43\x7e\xa3\x52\x10\x76\x77\x41\xb8\x74\xcc\x32\xf2\x63\xc9\xd4\x82\x58\x21\xa8\x72\xef\x81\xf4\xc6\x9a\xa7\xce\x41\xc6\x19\x55\xda\xcb\xec\x4f\xc8\xff\xc1\x64\x73\xf5\xd9\x4a\x80\x10\xc7\xb6\x07\x5d\x6b\x0e\x55\x0f\x55\x46\x68\x05\x08\xc6\x12\x1e\xde\x30\xd6\x64\x3e\x2b\xee\x9d\x7f\xb8\xdc\x4d\xd1\xe9\x76\xa9\x45\x76\xb9\xd8\x5a\x5a\xfc\xf9\x86\x05\x22\x20\xc2\x2f\xf5\x6a\x52\xc1\x14\x41\xee\xd9\x62\xe0\xee\xc1\x5d\xf6\x76\xdf\x18\xdd\x39\xea\x29\x45\xdb\xa6\xaa\x58\x05\xa0\x1d\x28\xe4\x6e\xd6\x03\x7c\xda\x27\xa1\xac\xf7\xf2\x40\xe8\x4a\x88\x77\x26\xe1\x9d\x92\x55\xc6\xcf\xba\xc4\x95\x88\x13\x90\x81\xcf\xfb\x35\x07\x34\x00\x5f\x6e\xa0\x16\x5d\x37\x91\xec\xae\x02\xe3\xe3\x01\xbb\xf7\x52\x03\x9a\xd6\x1c\x73\xef\xd9\xe2\x58\xbb\xa8\x41\x29\xf4\x8c\x17\x3e\x3f\x3c\x50\x02\x87\xb9\xe4\x7b\xf0\x0f\xf0\x43\xe0\x99\xbf\x16\x03\xf2\x41\x1a\xfb\xbf\x2b\x70\x15\x42\x4b\xa5\x64\xfa\x83\x34\xf0\xe6\xc9\x81\x85\xd3\xdd\x1b\x54\xce\x4c\xc9\xc1\xcc\x88\x2e\x6d\x10\x9f\xe1\x5d\x50\x00\x24\xee\xbe\x35\x80\x95\x6b\x72\x2d\x88\x54\x1e\x26\xc6\x27\x0f\xd6\x6e\x08\x6f\x5b\x8a\x2c\xc2\x2b\xc6\x70\xa0\x94\xaa\x06\xc9\x0d\xc3\x05\xe3\x32\xf7\xbf\x80\xed\x09\xac\xf1\xc1\x6f\x06\x52\xe0\x52\xc3\xa6\x3c\x21\x39\x53\x53\x88\x0f\x4d\x66\xbb\x6f\x50\x77\xba\x8d\xcf\x4e\xd4\x3b\xfe\x70\x67\xcc\x00\x56\xf7\x0e\x3c\x97\xf6\x65\x98\x38\x0a\xb2\x88\x9c\x16\x16\x29\xfe\x61\x39\x01\xec\xcb\xbf\x20\x65\xb5\x1e\x91\x73\x5f\xf0\x34\xfe\xcd\x59\x31\xe2\x61\xec\x08\x56\xa6\xff\xb1\xe4\x73\x9a\x31\xf4\xe7\xa3\x22\xa4\xf1\x94\x93\x25\x36\x3d\x70\x79\xab\x2d\x95\x0a\x37\x43\x47\xf7\x6c\x71\x34\x58\x42\xa4\xa3\x6b\x71\x54\x05\x69\xd7\x50\x27\x30\x34\xb8\x34\x38\x82\xdf\x8e\x0e\xcd\xd9\x9f\x49\xb4\xdf\x01\x4b\x9c\x41\xe8\x22\xa3\x5a\x77\x8b\x6f\x6d\x84\x16\x35\xc6\x59\x95\x80\xf1\x36\x6a\x53\x05\x17\x39\xef\xcd\x83\xdb\xb3\xc0\xcb\xbf\xbb\xa7\x51\x27\xe8\xcd\x5d\xf5\x94\xf6\x89\x1b\x56\x26\x14\x83\xb4\x05\x3e\x86\xa3\x16\x17\x57\x5d\xc6\xae\x81\xd7\xf7\x60\x57\x94\x93\xb8\xc8\x33\xd7\xa0\x06\x73\x1f\xd5\x21\xa4\x21\x5c\x24\x59\xe9\x4c\x8a\xd0\x15\x94\xe8\xae\xa2\xfe\x0e\xc0\xd9\x03\xa9\xaa\x01\x3c\x36\xf9\x6b\xdf\x25\x07\xde\xe6\x0d\x1d\xdc\x89\x86\x1b\x2f\x84\xd5\xa1\xd7\x3a\xd9\xe2\x2e\x59\x4f\xc6\x99\xd4\x65\x8f\xb7\x7c\xac\x18\xb9\x98\x51\x21\x58\x16\x45\xbb\x3a\x63\x47\x28\x67\x05\x02\x89\x2b\x62\x75\x5c\xaf\x62\xe5\xe9\x9b\x08\xb1\xd5\x07\xaf\x1d\xfc\x53\x2a\x2a\x75\xb0\x3a\xe5\x2e\x55\xe3\x4c\x3e\x90\x54\x92\x07\xa8\x5b\x30\xb7\x4c\x0b\x2e\x65\xb5\x67\x77\xd1\x4c\xc1\x45\x22\x91\x79\xa1\x64\xce\xb5\x77\x8e\x77\xdb\x78\xd0\xd0\xd0\xac\x6c\x91\x03\xa8\xbe\x07\x59\x29\xea\x29\xe1\xdf\x5e\x10\x43\xd5\x94\x19\x3b\x1a\x11\x65\x3e\x66\xad\xe3\x57\x1f\x23\x07\xd9\x97\x54\x42\xf4\xb0\x45\xb0\x70\x1b\x7e\xf8\xe1\x43\xe7\xd2\xbb\x55\xcf\x75\x7b\xfb\x20\x55\x96\x3e\xf0\x14\x59\xb4\x26\x27\xb6\xf1\xe9\xcb\xaf\x94\xfb\xf0\xc0\xd3\xce\xe0\x80\x4e\x75\x30\x78\x3f\x28\x0b\x06\x02\x70\x70\x15\x9e\x38\xa4\xd1\x86\x1e\xa7\xe4\x8a\x63\x74\x11\xf4\x87\x44\x35\xf9\x98\x8b\x2a\xc2\xac\x02\xb3\x25\xc6\xf6\xbc\x78\xd5\x44\x33\x83\x71\x21\x10\x5a\x21\xcd\x8c\x68\x9e\x97\x99\xa1\x82\xc9\x52\x67\x8b\xd6\xa8\xf2\x3c\xa0\x9e\x64\xec\x33\x62\x76\x17\x26\x17\x3a\xd5\x99\x1d\xb8\xae\x54\x61\x94\x4b\xdc\xae\x72\xae\x4a\xcf\x02\xe7\x0b\xe1\x46\xec\x33\x4b\x9c\x57\x70\x91\x95\x53\xbe\x25\xfc\xe1\x67\x96\xd5\xbc\x4a\x20\x5d\x6a\x56\x45\xea\xb7\xad\xeb\xf2\x44\x49\xc8\x9f\x97\xc3\xdf\xad\x4e\x40\x9e\xb2\x82\x89\x14\x52\xa2\xbd\xad\x30\x17\x27\x7f\x50\xc8\xb9\xf4\x62\x5d\xa9\x96\xcf\x4a\x56\xa3\xe0\x91\x0b\xd7\x4c\x66\xa9\x26\xec\xb3\x51\xd4\x12\xa6\xdc\x92\xa0\xd0\x67\x42\xa8\x68\x4f\x64\x5e\x46\x8a\x60\x72\x70\x6e\xff\xb8\xf5\x32\x5f\x62\xc9\xcb\x6a\xed\x7a\x63\xc1\xea\xfd\x52\xd7\x23\x21\x76\x67\x45\xd7\x3d\x84\x57\xa4\x98\x77\x5f\xa9\x7b\x26\xee\x97\x6a\x5e\xaf\x48\xaa\xdd\x98\x55\x5f\xa6\xf3\x8b\xc8\x3b\x3f\x81\xc0\xe0\x2e\x49\x98\x5c\x8f\x86\x46\xed\x5e\x36\x0b\x42\x6f\xd0\xa0\x1d\xde\x46\x7c\x00\x32\x9e\xba\x81\x5c\x58\x13\xd1\x16\x96\x95\xeb\x5c\x29\xc4\x36\x2a\xf6\x18\x59\xc4\xa9\xa1\x9a\x99\x76\xd6\x94\xba\xe8\x50\xf5\xb4\x07\x30\xc6\x2f\xf7\x13\x66\xb1\x07\x87\x74\x1f\x2c\x4b\x86\x7f\x74\x52\x86\xa8\xb5\xb4\xf2\x85\x87\x8f\x4f\xd2\xc4\xc2\x2d\x32\x8e\x91\xda\x5d\x49\xa8\x69\x5d\x72\xa7\x15\x5f\x70\x33\xf8\xf4\xa9\x73\x2d\xd7\xa8\xa7\x97\x43\xe0\xdf\x75\x20\x38\x5c\x80\x44\x3e\xfc\xc7\x32\x56\x07\x20\xb9\x45\x58\xb6\x6b\x7f\xa8\xb5\x4d\x13\x56\x19\xaf\x2e\xb9\xbe\xef\x92\x8c\x6c\xa9\x73\xfd\x48\x7c\x73\x71\x45\xdc\xdb\x56\xf6\xa5\x2e\x06\xa6\x7d\x33\x63\x4d\x13\x56\x19\x6d\x53\xae\xef\x9f\xbc\xac\x7a\x91\x7e\xd8\xe6\x01\xfe\x74\xf6\xaf\xa6\xd4\xeb\x53\xb4\x44\xb9\x83\x16\xb2\x24\x0f\x2e\xf5\x81\x93\x9a\xef\x78\xf1\x86\x5c\x09\x5d\x2a\x56\xdd\xdc\x36\x87\xb2\x5c\xf7\x25\x95\x5e\xdf\x0b\x4b\x5e\xb2\xf1\xad\xa0\xca\x80\x78\xdc\x15\x0d\x42\x47\x4f\x9f\xa2\x17\xa2\x0d\x1e\x5c\x4f\xbc\x63\xdd\xc0\xc5\x78\x87\xc4\x65\xbe\x91\xdd\xf9\x28\xad\x49\xbc\xd7\x6f\x43\xca\x1f\x72\x96\xb2\xf9\x99\x4e\xe9\xeb\x01\x7c\xc6\x3b\x3c\xd7\xe7\x44\x35\x39\x7a\x7d\x34\x22\xb7\x3c\xe7\x19\x55\xd9\xa2\x96\x8a\xb9\x6a\x67\x99\x85\x1f\x10\x6e\xe5\x5e\x1d\x91\x13\xa9\x60\xe4\x84\x0a\x92\x31\x1f\xd1\xe4\xce\xd9\x02\x65\xc7\xd3\xa7\x26\x2e\xe4\x51\xed\x97\x48\x67\x3a\xe3\x44\xea\x39\xb6\xe3\x47\xb5\x74\x36\x97\x15\x49\xe7\xc2\xd2\xf9\x11\xf9\xb4\xaa\x50\x39\x1c\x19\xdf\xe2\xb9\x80\xfa\x34\x7a\xdf\x4e\x1a\xdc\xb2\x39\xf8\xf9\xc0\xb4\x5d\x4b\x9c\x72\xf3\x91\x15\xb2\x93\x84\x80\x5d\x1a\xf6\x38\x6e\xec\x0b\xa9\x39\x24\x2a\xa5\x06\xca\x02\x2b\xc3\x93\x32\xa3\x56\xac\x46\x6b\xdc\x88\x5c\x5e\xdd\x7c\xbc\xba\x38\xbf\xbb\xba\x7c\x43\xbe\x71\x23\xf1\x58\xc2\x1b\x91\xbb\x38\x1b\x54\xe4\xd1\xeb\x52\xee\x84\x6f\x0d\x1c\x19\xa2\xa2\x4a\xee\x08\x39\x3e\xa8\x20\xd7\x82\x9b\x2a\x3d\x32\xfa\x9d\x65\x52\x30\x5f\x3d\xb4\x90\xce\x1a\x38\xe5\xe8\x0d\x22\xdc\x60\xf6\xe7\xfa\x68\x70\x3a\x30\xd5\x6a\x98\xca\x16\x45\xf0\x11\x44\x8b\x0a\xb8\x87\x12\xff\x7d\xfe\xd3\xae\xb2\x6f\xc8\x46\xeb\x03\x9c\xd0\xfa\x5f\xbd\x47\x66\x10\x12\xb3\xfb\x74\x37\x2b\x4a\x5a\x13\xcb\x66\x8e\x47\xc7\x5e\xa0\xc8\x96\x92\xf0\x87\x41\xe3\x8c\x5e\x75\x64\x1b\x11\xf2\x9d\x77\xd9\x86\xd0\xe3\xd5\xf9\xfc\x31\x3b\x44\x94\x15\xbe\x81\xb2\x3e\x30\xa6\x1c\xc7\x1f\x75\x29\xc0\xa6\x7c\xce\x04\x2e\xec\xb0\x14\xca\x7f\xbe\x73\x75\xb4\x6a\xde\x4e\xff\xf8\xf8\xee\xb0\x33\xc3\xf3\xd7\x79\x5e\xee\xd8\xba\x59\x25\x32\xcf\x31\x5f\xd4\x2c\x04\x18\x56\x31\x82\x81\x2a\x1c\x4c\xf3\xc1\xcc\x57\x93\x2d\xc8\xdf\xa0\x67\xbe\x53\x43\xd3\x09\xaf\x5d\x50\x82\xa8\xc4\xdc\xee\x79\x98\x5d\x92\x35\xed\x93\xa7\x38\xd2\x7e\x16\x3e\x7e\xf6\xf1\xea\xfc\xf2\xfd\xd5\x28\x4f\x9f\x9c\xb4\x30\x91\x16\x92\x0b\xa3\xb7\xeb\x37\xdb\xaa\xce\xb4\x27\x3f\xe1\xa3\x5d\xb9\x73\xe8\xe8\x71\xcc\xbf\x88\xf2\xd2\xa5\xcc\x50\x9e\xe9\x68\x0f\x8d\x2c\x64\x26\xa7\xab\xd3\x2f\x77\xd8\x9c\x5f\x60\x7e\x99\x21\x1d\xda\x5d\x3f\xac\xa8\xdf\xa6\x8e\x46\x53\xca\xaf\x2a\x62\x57\x6b\x0d\x52\x33\x94\xbb\x78\xa1\xcb\x7d\x14\xe1\x6c\x09\x06\xa8\x48\xc2\x01\xf6\x29\xfb\xaa\x1c\x78\x51\x0d\x9b\xb6\x52\xdb\x63\x83\x6e\xbb\xc0\x66\xe9\xcf\xf6\x42\x45\x75\x98\xf9\x3e\x75\x02\x57\x28\x36\x0c\xe9\x9a\xa0\xb4\x8a\x54\x11\xc3\x8d\xe9\x9d\xb7\xde\x78\x5b\x0f\xb6\xca\x16\x4d\x2b\x4e\x25\x1f\x05\xd3\x17\xe6\x18\xc8\xb2\x45\x95\x06\xd2\x69\xd1\x74\x8a\x69\x98\x94\x33\x13\x17\x8a\xcf\x79\xc6\xa6\x90\x8a\x95\x8b\x69\x14\xfe\x1a\x07\xcc\xba\xd4\xac\x75\xa3\xeb\x7b\xfb\x57\x94\x74\x1b\xf0\xe2\xc3\x77\x77\x90\xd5\x17\x2e\xb8\xf6\x16\xc2\xed\x07\xe1\xbc\x0d\x87\x43\x30\x19\x9c\xfc\xcd\xca\x93\x69\x76\x4a\x7e\x60\xee\x3b\x12\xd2\x0e\x2b\x28\x05\x34\x93\x21\x07\x2c\xcc\xb5\x82\x2c\xa0\x23\x5e\xef\xbb\x56\x67\xb6\xa5\x95\x95\x90\xd5\xd4\xda\x43\xe5\x53\x4c\xdd\x88\x77\x4c\x4f\x2f\x7b\x1e\x90\xec\xef\x4c\xe5\xbc\x69\x75\x15\x7e\x86\x8b\x1f\x4f\x0f\x29\xd1\x8b\x3c\xe3\xe2\xbe\xca\x0b\x36\x91\x16\x87\x30\x34\x81\x8b\x7b\x8f\xb1\x8a\xd1\x6c\x3d\xa5\xdc\x05\x3f\x0e\x4a\x25\xcd\x0e\x16\x40\xb0\xd0\xd9\x73\xf6\x27\x7f\xec\xdd\x35\x74\x4c\xe2\x8e\x8e\x5e\xdc\x7a\xb9\xee\x56\x06\xff\x18\x3a\xd4\x68\x9a\x20\xd7\xb7\x17\xb7\xd7\x4f\x6a\xa1\x5e\xc7\x12\x60\x76\xcf\x28\xd5\xf1\x1f\xb7\xdd\x0e\x0f\x49\x56\x6e\x6f\x83\xea\xdd\x8d\x54\x86\x66\x07\x22\x02\xc9\x8c\x16\xe7\xa5\x99\x5d\x72\x0d\x39\x14\xba\x0a\x01\x4b\xfd\x23\x4f\x67\xcc\xdd\xec\x13\x06\x72\x8f\x0e\xae\xdd\xc5\x9f\xce\x6f\x08\x2d\xed\xfe\x1a\x97\x5c\xf4\xa0\x17\xee\x7e\x66\xb7\x18\x61\xb0\xe3\xba\x5c\xef\x2d\xab\xf2\xad\x1e\x7b\x4d\x8f\xe1\x87\xdb\xdf\x45\x00\x0d\x45\x0a\xf6\x82\xef\x1f\xb8\xe0\x86\x53\x23\x5b\x16\x2a\xab\xa1\x40\xad\x6f\x30\x08\x94\xda\xc8\xdc\x61\xf0\xb5\x6f\x01\x57\xc8\xc0\xc5\x97\x3a\x55\xd6\x02\x90\xde\x01\x62\xd7\xc2\xca\xda\x34\x61\x0d\x07\xc8\x01\x24\xfd\xc4\xb1\x79\x68\xf3\x07\x67\xa0\x82\xfc\x60\xd9\x1f\xdf\xd4\x52\xb1\x2f\xd5\xb5\xf0\x56\x8a\xaa\x68\xc2\x41\x2d\x3e\xfc\xc7\xae\x44\x81\xff\x28\x1a\x96\x36\x5c\xe0\x7f\x95\x34\x43\xc0\x7c\x38\xb4\x59\xaa\x0e\xe4\xae\xf3\xad\xef\x90\x9b\x7a\xb5\x1d\x1f\x82\x96\x5e\x6a\xcc\x3c\x86\xeb\x31\x8a\x0a\x6d\xf7\xa8\xae\x8b\x1d\xbb\x8b\xa7\x63\x72\x62\x92\xa2\x75\xed\xfe\x47\x72\x6d\xcf\x4a\x51\x2b\xe4\x0c\x33\xbf\xc3\x6d\x79\x17\x5c\xdb\xdb\x4e\xf2\x51\xae\x86\x00\xcb\xbb\x5a\x55\x5c\xaf\xb0\x5b\xf1\xba\x90\xf5\x93\x77\x5c\x1b\x5f\x90\x01\x5e\x70\xed\xf2\x08\x83\xdc\x75\x63\x15\x39\x5e\xfc\x2f\x4d\x53\xf5\x06\xb9\x94\xaf\xbe\xac\x40\xfa\xf2\x49\xbe\xa8\x08\x77\x89\x27\x66\x51\xb8\x04\x80\x77\x17\x37\x04\x0b\xa4\xfc\xfe\xb7\x58\xf9\xf5\xdf\x7f\xfd\xdb\x57\xad\xb7\xfb\xf9\x9c\xc7\x77\xb4\x63\x1c\xfc\x8e\xe9\x45\xf8\x0d\xd6\xfc\x03\xed\x4a\x40\x36\xb9\x45\x77\x3c\x4b\x59\xdd\x51\x47\xc4\xb2\xbb\x1c\xe8\xfd\x6e\x12\x4c\xef\x67\xf7\xac\x7e\x76\x24\x44\x94\x20\x91\xe8\x88\x2e\x71\x57\x08\x31\x5c\x26\x3b\x48\x71\x6e\x5e\x1e\xc5\xd9\x0a\x9b\xed\x58\x54\xc7\x9e\xf8\x32\xde\x97\xbf\xa9\x5c\xd8\x2f\x3f\xdc\xfe\xef\xbb\xf3\xaf\xaf\xde\xc1\x4c\xdd\xfd\xbd\x45\x0d\x2e\x76\xf6\x9f\x6a\x8f\x6a\x6d\x94\xd7\xed\x00\xe9\x76\x2d\x23\x1a\x17\x32\x82\x7c\x78\x7b\xdb\xf5\x2e\x66\x5f\x01\x5d\x4c\x5a\xad\xfd\x69\xad\x6d\x50\xd5\x84\xa9\xc3\xc5\x8f\xec\x6c\x94\x8b\x12\x69\xd5\xf4\x2f\xbb\x53\x38\xc3\xbd\x55\xa4\xad\x3b\x40\x5e\xc0\xbd\x83\x5d\x2f\xc2\xe0\xe0\x37\x0e\x8f\x04\xab\xb6\x72\x80\xea\x1e\x58\x74\x8c\xbd\xbc\x08\x60\x0f\x29\xd2\x36\x65\x69\xb6\xa5\xd6\x4c\x87\xea\x0b\x2f\x14\x53\x8a\x55\xe9\x99\xbb\x50\xaf\x95\x03\xd4\xca\x95\xd5\xee\x62\x6a\xb1\x14\xeb\xd2\x99\x7b\x0f\x05\xea\x94\x57\x5d\xd0\xe4\xa0\x05\x55\xaa\x57\xf8\x06\x82\xdc\x9f\x9e\x00\xc2\x67\x0f\xe8\x48\x1b\xc6\xeb\x8a\xc8\xa1\x63\x33\x4a\xae\xd3\x0e\xf9\x42\x1f\x85\xf4\x11\x88\x71\x38\xdd\x33\x6f\x1f\x79\x5a\x6d\xe7\x87\x1d\x15\x9d\x43\x2b\x39\xc5\x4c\x1a\x29\x76\xf6\x92\x5f\xd5\xbd\x7e\xa0\x6f\xa0\xc5\x45\x55\xc6\x26\xaa\xf1\x08\x1e\x94\xe1\x32\xc2\xca\x73\x9e\x5d\x48\xe1\xaf\x25\xea\x97\x12\x4f\x2e\x82\xa4\xd7\x97\x07\x3a\x7c\x5f\x6e\x88\x67\x57\x63\xf0\x41\x9d\x41\xd2\xce\x31\x29\xb6\x8b\x87\xd8\xf5\xa5\x13\xcd\x7c\xc0\x89\x76\x08\x49\xd6\x63\xe4\xc1\x58\xa7\x54\xe6\x41\xaa\xee\xa1\xde\xf5\x8e\x0d\x5f\x05\xf7\xdb\x52\x28\xd6\x4b\x3c\x3d\x38\xc7\x67\x3e\x41\xb7\x70\x82\x1a\x09\xce\xd7\x9d\xa4\xc7\x38\x48\xcf\x7b\x80\xf6\x65\x54\x8f\x1b\xe5\x7b\x50\x21\xdd\xa3\x5b\xc7\xa5\xfa\x6e\xce\x98\x60\x37\xa9\xa2\x16\x14\x4c\x2e\xd1\x89\x3b\x18\x75\x50\x12\x4b\x50\x76\x21\x0c\xbe\x0f\x1a\x70\x31\xd1\x73\x96\x59\xa8\x4a\x11\xa7\x88\x76\x61\xbc\x03\x82\x59\x96\x73\x5a\xf8\x9a\xdc\xf2\x41\x3c\x50\x95\x92\xf3\x9b\xeb\xc3\x50\x83\x0e\x7e\xd6\x88\x49\xed\x32\x7a\xd5\x3d\xad\xab\x9e\x58\xe6\x66\xc6\xa0\xb6\x22\x19\x73\xa3\xab\x9a\x7e\xcc\xc4\x7a\xa5\xa5\x82\xe1\x2e\xcb\x9e\x65\x7b\x6e\xdd\x48\x11\xc3\x14\x44\x26\x86\x66\xbe\x88\x80\x2b\x93\xf3\xea\xd5\x2b\x34\x85\xbd\xfa\xdd\xef\x7e\x87\x95\x95\x52\x96\xf0\x7c\xb9\x21\xb4\xfa\x3f\xaf\x5f\x8f\xc8\x7f\x9f\xbf\x7f\x07\x95\x1f\x0b\xa3\x31\x2b\x09\x8e\x8c\x95\xe0\xa3\xce\x7a\x40\xfe\xef\xed\x77\x1f\xaa\x32\x31\xf5\x5f\x5d\x41\x6d\xb7\xbc\x11\xb9\x8c\xfc\x9f\x62\x43\x17\x35\x33\x57\xd0\xc8\x10\x3a\x99\x20\x62\x8c\x7d\x39\x5d\x3c\x70\x3e\x7a\x1c\xaa\x82\x63\xfd\x11\x8b\x12\x19\x38\x66\x59\x95\x1c\x4d\x83\x3e\xb3\x01\xfa\x99\xc1\x58\x81\x4c\xc2\x54\x06\x58\x4b\x7e\xa2\xa1\x0a\x49\x95\xfe\x4f\x31\x6d\x85\x52\x57\x5d\x11\x07\xab\x76\x46\xb3\xd6\xb9\x1e\x1e\xe3\x06\xa8\x75\x75\x8c\xba\xe9\xde\x9d\x21\x9f\xbe\xd5\xe5\x2e\xae\xca\xd4\xff\x0d\x6f\x43\xb7\x39\x09\x3f\xd2\x8d\x4c\x6d\xae\x37\x61\x36\xb8\x75\x2e\x4b\x40\x45\x27\x68\x26\xa1\x92\x57\xd8\xe9\x8a\x8b\x45\x45\xef\xb7\x2f\xa5\x73\xf2\xc5\xae\x09\x78\x91\x50\xbd\xa7\xad\xcb\xf9\xd4\xfd\x45\x7c\xef\x5a\x5e\x05\x3a\x96\xa5\xf1\x77\xd8\xee\x77\x08\xc0\xc6\x2a\xeb\x1d\xd2\x48\xee\x90\x79\x72\x97\x0c\xc4\x9d\x93\x98\xd6\xef\x9b\x81\x27\xd4\x45\x89\x01\x61\x34\x99\x91\x7b\xb6\x18\x22\xdd\x2a\x28\x44\xf3\x00\x54\x2e\x2d\x2c\x6a\x85\x4f\xaa\xda\x35\x56\x3e\x76\x20\xf3\x8e\x01\x11\xf7\xf1\xd1\x40\x5e\x08\xd5\x4e\x5e\x72\x69\x44\x45\x64\x29\xf0\xb9\xaa\xa3\x7a\xc4\x21\x6f\x28\x16\x23\xaf\x07\xa9\xd8\xf3\xc6\x52\xdb\x4d\x6f\xfa\x72\xe5\x0d\x61\xe9\xa0\xe3\x6e\xa5\x58\xea\xed\x8a\x6f\x3b\xe1\x0f\x3e\x48\x7d\x76\xe6\xc8\xa3\x02\xca\xf9\xb9\x4a\x4e\xae\xad\x87\x52\x00\x44\x2d\x88\x46\x33\x53\x3a\xd0\x60\xbd\xb0\x52\x64\x4c\x6b\xc2\x61\x85\x39\x55\xf7\xcc\x27\x8c\xa1\xd9\x88\xdc\xd8\x49\x86\xfc\x55\x98\x16\x79\x8e\x2e\x76\xf6\xcc\xc6\xd1\x41\xf6\x23\xc7\xa3\xd1\x31\x12\xf8\x15\xb1\x42\x1d\xf0\x63\xb7\x9c\xba\x3b\xe4\xd2\x6d\x94\xf6\x2e\x34\x66\x06\xb6\x22\x1f\x64\xbe\x96\x10\x05\x67\x66\x9e\x81\xd1\xd6\x49\x94\x96\x97\xb3\x43\x02\xd8\x5d\xf3\x96\xef\x92\xb5\xbc\xd5\xbd\x45\xfd\xd9\x3d\x5b\xf9\x4e\xb9\xca\xd7\x65\x2a\x77\x3b\xe5\x4e\x5b\xf7\x1c\xce\x7b\xa4\xd8\xce\x3b\xa5\x79\xf5\x4f\xdd\x48\x09\x72\x47\x2d\x4b\x4f\x2b\x19\xd1\x25\x7d\xca\xd8\x17\x25\x14\x5e\x4f\x56\x55\x9d\xf3\xc1\x82\x91\xbc\xec\x69\xa8\x85\xc0\xf3\x4b\x83\xdd\x6a\xb9\x90\xce\xe2\x61\xf3\xe9\x22\x2e\x36\x9f\x76\x97\x81\xcd\xa7\xae\xb0\x45\x61\x49\x81\xe8\xc7\x5e\xfc\x00\x52\x23\x21\x67\x77\x75\x04\x47\xe4\xbd\x63\x0a\x88\x8c\x74\xac\x65\x56\x9a\x10\xc9\xb4\x82\x63\xc0\xa0\x3e\xc3\x37\x86\x94\xfa\x66\x11\xff\x00\xce\x89\x64\xb9\x2b\x2b\xc1\x67\xa7\x23\xde\xb5\xe6\xde\x4f\xd6\x99\x64\x0f\x18\x7a\x51\x62\x67\x38\xfa\x01\x42\xde\x09\xef\x4b\x5d\x93\x71\xc0\x93\xc4\x68\x14\xa0\xbc\xb8\xe2\x0a\x3d\x75\x5e\x62\x3b\xab\x8d\x9b\xab\x33\x4c\x9c\xdf\x5c\xef\xa4\x01\x44\xfd\xd7\xe8\x00\x71\x8b\x9f\xb0\x16\x70\x8d\x5a\x40\x5c\x76\xe7\xb2\x5a\xb9\x33\x29\x5b\xb2\xf3\xe2\xc5\xc8\xa5\x69\xbf\xb5\xc4\x32\x76\x3a\xad\xe7\xd0\x43\x63\x4f\x45\x56\xa3\xbc\x7b\xfe\xd6\x11\x0e\xf1\x4b\x17\x39\x9f\x50\x7c\x04\x78\x74\x2a\x97\xee\x9f\xe5\x6a\x76\xb0\x58\x72\x0b\xa5\x6d\x50\x1f\x8c\x14\xcb\x42\xa6\x6f\x5c\x29\x69\x21\x24\x16\x90\xd3\x03\xac\x8d\xa3\x07\xa8\x30\x5a\x29\x22\xba\x2b\x56\x91\xc9\x7d\x67\xb9\x61\xa7\x2a\x47\xfb\xd4\x39\xb2\x1b\x08\x2b\xbf\xe9\xba\x8b\x64\xcf\xb2\x45\x24\x62\x4d\xbb\x15\x42\xa9\xed\xa9\x1b\x29\xd4\x79\x4f\x66\x2c\xa7\x98\xc3\xcf\x2f\xcf\x52\x99\x07\xc5\x8d\x61\x98\x4b\x89\xa9\x5c\x13\x39\x19\xd4\xee\x0c\x8e\xe6\xaf\x8f\x76\x29\x07\xb3\x67\xc5\x1e\x52\xed\xc2\x01\x80\x71\x53\x13\xd9\x2c\x5e\x83\x2e\x91\x41\xe2\x4d\xd1\x30\x48\x58\x06\x33\x47\xe8\x3d\xf9\xc2\x0f\xa1\x47\xed\xaa\x3f\x0d\x82\xc0\xd0\xeb\x4f\xbd\xfe\x74\x10\xfd\x29\x62\x2c\x9e\xe0\xac\xd0\xa5\x62\x87\x61\xaf\x50\x55\x81\x4c\x51\x02\x1e\x8b\x9a\x5e\x95\x92\xaa\x6e\x71\xb3\xfa\xd0\xb1\x57\xb0\x1c\x1e\x97\x66\x32\xfc\x3d\x61\x22\x91\x29\x6e\xbe\x1d\x5f\x69\x03\xa2\x4d\xa5\x93\xc4\x73\xc9\xfd\xb7\x62\xab\x1d\x8c\xbd\xeb\xd6\xed\x44\x07\xfc\x55\xe0\xdb\x03\x31\xf8\x8a\xad\x87\x60\x62\x5f\x2b\xdb\xe7\x1a\x70\xfc\xbd\xba\x84\xc4\xb2\xd2\x80\xdc\xbe\x62\x2e\x39\xc1\x97\xa3\xa4\x28\x07\xae\xc1\x28\x67\xb9\x54\x8b\x41\x68\x64\x7f\xac\xf5\x72\x2d\x4e\x41\x26\x48\x4a\x65\x35\xc0\x6c\xf1\xa5\x4a\x07\x1e\x40\x4f\x2c\x1c\x84\x7d\xea\x56\x34\x28\x7e\xea\x28\x51\x25\x15\x03\xfd\xbe\x2a\xa2\x34\x09\x29\x0f\xf5\xa0\x52\x3b\xed\x5b\x26\xe6\x64\x4e\x55\x87\x2a\xe8\xf1\xb3\xa7\x3c\x90\xf2\x39\xd7\xbb\xd5\x3b\x6c\x2c\xfd\xd6\x31\x0d\xb4\xeb\xc8\xd2\x14\xa5\x71\x94\xd2\x9f\x0a\x1f\x32\x1f\x4e\x43\x43\x28\x7a\x7d\xb4\xd3\x34\xbe\x98\xfa\xc2\xf8\xec\x58\x65\x18\x9f\x7d\x6b\x0d\xd7\x47\xd9\x19\x6d\x0e\x5a\x39\xdc\x3f\x1e\x2d\x0e\x71\x0e\x2b\x16\x59\xe5\x79\xf0\xc2\xe9\x13\x1d\x34\x74\x37\xd9\xc9\x6e\xe3\x32\xd4\xaf\x36\xd9\xb8\x1f\x7f\xc2\xd6\x9a\xc3\xde\xd9\xba\xf8\xc2\x9f\xf9\x85\xed\xad\xab\x67\xd0\xdf\xd6\xb6\x42\xc1\xfe\xb6\xb6\xbf\xad\xed\x6f\x6b\x7b\x6b\x43\x6f\x6d\xe8\x6f\x6b\x49\x7f\x5b\x7b\x10\x18\x1e\xee\xb6\x16\x45\xbd\x55\x77\xb6\x4e\xd8\xab\x2e\x6c\x9f\xf4\xbe\xd6\x15\xee\x39\x4f\x12\x59\x0a\x73\x27\xef\x59\xeb\x4b\x87\x86\xfc\xbf\x34\x0e\x24\x40\x58\xa3\x0f\x2c\x37\x7e\x32\xe5\xa0\xbb\x54\xd2\x49\xb6\xd8\x45\xaa\xa0\x65\xca\xad\xe4\xbf\x33\x9a\xf9\x01\xe2\xe4\x44\x22\x65\x69\xf5\x83\x3b\xca\xc6\xc2\x7a\x44\xce\x89\x62\x09\x2f\xb8\x2b\x23\x4f\xf1\x3d\x22\x5e\xa8\x8d\xc0\x8d\x66\xd9\xc4\xe5\xa8\x17\x71\xad\x9f\x4a\x7e\x77\x74\x70\xe5\x67\x90\x43\x49\x9f\xc9\xdc\xd7\x42\x52\xec\x6f\x9e\xb5\xb9\xd9\xdc\xc5\x23\xc4\xe6\x15\x58\x4a\xad\xc4\x10\x7c\xac\xe0\x2e\xc0\xfa\xb1\x8f\x3f\xfb\x5c\x70\x05\xc8\x7b\xcb\x12\x29\xda\xd4\x54\x5d\xb3\x41\x4b\x23\x55\xfc\x09\x6c\xa3\x2c\x25\x69\xa9\x42\xcd\xd4\x39\xcd\x78\xca\xcd\x22\xdc\xda\xb9\xf2\x5a\x14\x4f\x4c\xd8\x46\x5d\x81\x91\xd0\xa2\x50\x92\x26\x33\xa6\xa3\xaf\xa1\x80\xe2\x82\xc8\x82\xef\x3b\x96\x80\x03\x19\x05\xfa\x58\x06\x99\x2d\x88\x92\xc6\x5f\xbc\xaf\xf9\xe0\x5d\x34\x18\x74\x47\x2e\x67\xd4\x02\x6e\xe7\x65\x3c\x04\xce\x8a\x4f\xe2\x3f\x34\x91\x59\xea\x53\x98\xfc\xfe\x95\x15\x0a\x13\x87\x83\x96\xf8\x41\x82\x0b\x23\x49\x66\x19\xb6\x25\x88\xeb\x3b\xff\xfa\x37\x64\x26\x4b\xa5\x47\x71\xd2\x81\xd7\xf0\x0e\xf5\x3b\x2f\x54\x1a\x92\x31\xaa\x0d\x79\xfd\x8a\xe4\x5c\x94\x96\x4f\x75\x46\x9b\xee\x72\x50\x24\x01\xfd\xf6\x37\xad\xfb\x75\x95\x7d\xd6\x4a\x3d\x05\xe6\x46\x76\xa2\x8f\x3b\x49\x18\x18\x87\x99\xc5\x1b\x82\x90\x23\xba\x31\xb4\x85\x91\x8f\x70\xbe\x7e\x2c\xe5\x78\x61\xba\x04\x51\xba\x1e\xf5\xe8\xc9\xff\x72\x2f\xdb\x24\x4f\xa9\x72\xa7\x6c\xfc\xe8\xa3\x54\xb8\x98\x72\x6d\xb6\xd4\xb7\xa8\xe2\x2b\x37\x36\x6b\xcf\x56\xa6\x56\x3b\xe8\x18\x2b\x03\x7d\xbc\x44\xec\x6d\x4b\x49\xc2\xb0\x98\xe5\x65\x55\x29\x49\x48\x6c\xbb\x75\xf8\x67\x4e\x38\xe6\x11\xe4\x00\x59\xd3\x5b\x2e\xb5\x9d\xd0\xe5\x51\xa2\xf3\x5a\xb1\x5b\xfd\x14\x68\x2e\xa6\x98\xe4\x3c\x2f\x33\xc3\x8b\xac\x5a\xf7\x47\xdf\xc1\x11\xf2\xd8\xe6\x46\x23\x33\x11\xc5\xc0\x62\xcc\x36\x05\xf6\xc9\x93\x30\x16\x13\x06\x73\x75\x2b\xcb\x0f\x0a\xaa\x68\x00\x1e\x54\xd2\xd5\xa7\xce\x7c\x47\xe1\x46\xd1\xa5\xc3\xb4\xbd\x68\x56\xcd\x38\xba\x45\x3a\x24\xd2\x18\x26\xa8\x68\x61\xaa\xae\xa7\xe7\x82\x4e\x44\x3e\x04\x67\x32\x2c\x83\xd2\xc0\x16\x27\xd4\x7c\x4d\x93\x7b\x26\x52\x2c\x1a\x05\xcb\x4e\x17\x82\xe6\x2e\xdb\x56\x54\x8f\xbb\xd1\x5f\x0f\x9c\x61\x02\xc3\xf7\x7c\x98\x31\x72\xdd\x43\xc2\xa0\xd4\x9d\x53\xd9\xd8\x2e\xdb\xce\xb9\x46\x93\x8d\xe2\xf3\x84\x79\xfe\x6f\xfb\x1d\x72\xea\xf3\x16\xb1\xf4\x4b\x93\xf7\xdb\x13\xe1\x2f\x90\xfb\x60\x39\x87\xa4\x5a\x34\xb3\x47\x7b\x11\x62\x46\x1b\x9b\x3b\x5e\x1c\xb6\xea\x8d\x1a\x77\x89\xfc\x3d\x56\xe3\xb4\x7e\x88\x3f\xd2\x54\x6a\xf2\x75\x26\x93\x7b\x72\xc9\x40\xe8\x7a\xcc\xf2\x2c\x6a\x9c\x3e\x67\x0a\xef\x9c\x4e\xb7\xdd\xb3\x0d\x49\x2e\x05\x37\x52\x6d\xa6\x17\x4f\x57\x76\xb2\x4f\xf7\xbc\x36\x43\x95\xc5\xe6\x97\x9c\xec\xd9\xa2\x5b\xd7\x8d\x87\x4e\x41\x3d\x83\xd3\x89\xaf\x5c\x15\xb0\x1d\xcf\xda\x2f\x66\xf2\x61\x68\xe4\xb0\xd4\x6c\xc8\x5b\x5c\xe8\x76\x58\xe6\x3d\x5b\xc0\x2d\x76\xc7\x85\xba\x6e\x35\x9d\xc1\x48\xb0\x40\xc1\x7b\xcb\xb9\x3f\x7e\x7d\xf9\x49\x33\x35\x8a\x65\xc0\x33\x66\x92\xb3\x84\x15\xb3\x33\x37\xc2\x8b\x04\x8a\x27\x22\x5d\xa1\xe2\xfb\x21\x9b\x49\x64\x96\xb9\xc0\x6c\x39\x21\x17\xac\x98\x85\x81\x9f\x7a\xd5\xcf\x97\x11\xb8\x90\xb2\x6b\x22\xd4\x63\xdb\xa7\x7e\x88\xe0\x0d\x9e\xa1\x08\x99\xd4\xb8\x5b\x11\x8a\xa7\x42\x9f\x17\x5d\x6a\xf3\x11\x81\xf3\xb8\xe9\x94\x8f\x6b\xf9\x94\x63\x7f\xcf\x7a\xb2\x64\xef\x31\x52\x23\x41\xd7\x13\x14\xba\x53\x96\x12\x39\x67\x4a\xf1\x94\x69\x12\x68\x50\xac\xa5\xf2\xec\xa9\xe1\xd6\xe7\x6d\x7e\xf6\xbc\xcd\x3b\xa8\x43\xc7\xa0\x0f\xd5\xc8\x14\xbc\x59\x22\x53\x34\xcd\xb9\x78\x71\x84\x4a\x27\x34\x63\xd7\xdf\x75\xd0\x3f\x5c\x8f\xba\x0a\x72\xeb\x5e\x46\xf9\xd3\xb6\x64\x25\xfb\x36\xe0\x0d\x11\x32\xdd\x66\x52\x7d\x04\x45\x62\x4a\x0d\x7b\xd8\xca\x0e\x87\x15\xa1\xda\xde\x12\x84\xd3\xe7\x54\x39\x5e\x44\x8e\xc0\x08\xe7\x31\xe9\xd9\x21\x99\xaa\xdb\xb5\xae\xc6\x49\xec\x15\xa7\xdf\x6d\x26\xdd\xf5\x18\x7c\x7e\x73\x4d\xbe\xc1\xe6\x87\xcd\x5e\xa8\xa4\x41\x31\xf0\x52\xe6\x94\x77\x2d\xb2\xd1\xec\xde\xcc\xbe\x1a\x2f\xe1\x26\xb4\x25\xae\x71\x54\xc0\x65\xc2\xa7\xa5\xd5\xe9\x9c\x1e\xf6\xa2\x12\xcc\x2d\x89\x2e\x2f\x37\xc1\xdc\xfe\xd5\x20\x22\x93\x93\xf7\x8b\xac\x24\x16\xbf\x95\xc0\x4a\xc2\x1d\x28\xd1\x4c\x68\x0e\x17\x32\xd1\xad\xb8\xab\xf4\x87\xa5\x25\xd1\x09\x12\x45\x9c\x01\x79\x27\xa7\x5c\xf8\xd3\x2b\xdd\x7d\xdd\x84\xf2\xac\x2d\x30\x7a\x99\xe4\xd9\x65\x12\xad\xb3\x2b\x41\xc7\x59\x1b\x77\x83\x3a\xaa\x85\x8e\xe4\x6d\x46\xa7\x84\xc1\x1f\x67\x29\xd7\xf6\xff\xe4\xf6\xf6\x1d\x18\xe1\x4b\xe1\x25\x66\x30\x50\x3b\xda\x17\x82\x14\xf0\x20\x1e\xf6\xec\x20\xe9\xd9\x21\xfb\x5f\xd4\x93\x70\x91\xda\x89\x47\xa5\xe0\xd0\x49\x0a\x5a\x60\x3e\xc4\xe0\xf3\x8b\x6e\x03\x63\x46\xee\x66\x3c\xb9\xbf\x89\xec\xee\x52\xd9\x77\x22\x7a\x55\x63\x60\xcd\xdf\x0e\x49\x2d\xdd\x54\x6f\xba\xab\xc6\x51\x4f\xcf\x07\x3c\xc1\xb8\x75\xeb\x87\xdf\xa8\xd6\x32\xe1\xd5\x9d\x0b\xd8\x68\x2a\xe6\x90\x02\x73\x38\xec\x9a\x40\x3c\xe8\xba\x1c\x94\x3f\x56\x70\x34\xbf\x9b\xbe\x3a\xae\x8e\x39\x18\x17\x7e\xd5\x07\x5d\x02\xe2\xcc\x0e\xa9\xd1\xab\x8e\xcb\xa9\xd1\xbd\x30\xdc\xb8\x58\xf0\x6e\xea\x6e\xf3\xbc\x20\xe6\x6b\x73\x2e\x6d\x5f\x48\x91\xee\x52\x13\x1e\x6c\xe1\x6d\xc2\x36\x56\xa9\xe1\x8d\xdb\x44\x7c\xe7\xae\x1a\xe0\xcc\x15\xb2\x28\x33\xf4\xe7\xd8\x3f\xbf\xbb\xb7\x19\xe3\x77\x0e\x74\xf5\xf0\x14\x59\x4b\x8f\x63\xc7\xde\xee\x9e\xce\x3f\x8d\xdc\xa5\x91\x70\xf7\xea\xb7\xbf\xf9\xcd\x97\x9e\xcd\xb4\xad\x0a\xfe\x18\xe9\x4c\x5b\x9a\x68\x57\xc4\x17\x5d\xf7\xf1\x45\x3f\xdf\xf8\xa2\xc7\xcf\x42\x7b\xe0\x08\xa2\x8e\xbe\xb9\xdd\xfc\x72\xdb\xc7\x08\xb5\xf6\xde\xed\xea\xb9\xdb\x21\x0a\xe8\xb0\xb1\x3f\x9d\x7d\x59\xbb\xc4\xf9\xf4\xd1\x3d\x3f\xd5\xe8\x9e\x5d\x7c\x59\xbb\x47\xf2\x74\xf1\x61\xfd\x29\x46\xed\x74\x38\x9c\xed\xa3\x4b\xf6\x8e\x29\xe9\x9e\x04\xb0\xbb\x3d\x6d\x97\x82\x54\x55\xcf\x95\x1a\xa4\x0f\x2a\xf7\xb9\xc7\x8e\x8f\x75\x94\x5a\xcc\x48\x7b\x02\x9f\x44\x21\x21\x1d\xb4\x31\x1c\x5e\x76\xa9\x0d\xe9\xfa\x7c\x77\xdb\xb8\x98\x09\xaf\x9f\xe7\x3e\xe6\xe7\x70\xe1\xd1\xd7\x74\xf9\x42\x4c\xee\xba\x96\xad\xc5\x5b\x2b\x80\x04\x00\x23\x97\xe3\x38\x4b\x64\x75\x74\xce\x6f\xae\xad\x0e\x0e\x61\x44\x34\xd3\x23\xb2\x82\xcf\x7b\x73\xa9\x93\x0b\x3c\x7f\xa7\xc6\xb0\xbc\x30\xed\x77\xbd\xb7\xb8\x3f\xbb\xc5\xfd\x80\x16\xc0\x59\x99\x53\x31\xb4\x27\x0a\x6c\xee\xb5\xdb\xba\x06\x65\x1e\x11\x77\x76\x90\x3d\x81\x05\x04\x82\x0b\xea\x85\x8d\x69\x54\xe6\xf2\x71\xcc\x9e\x30\xf6\xce\x2b\x47\xbe\xda\x38\x69\x89\x5c\x72\x78\x75\xcb\x09\x50\xf0\x87\x2a\x62\xce\x35\x35\xdc\xcc\x18\xf2\xf0\x1b\x08\xc8\xa9\x5a\xd5\x25\x69\x14\xa5\x69\x96\xc9\x07\xfc\x76\xcc\xd7\x2c\xf4\xed\x5c\x5c\xa4\xd9\x98\x91\x9c\x5b\x1d\xdd\x19\x58\xe3\xe9\xe0\x95\xa9\x95\xc8\x99\x42\x81\x57\xb9\xcb\xb6\x5b\x66\xdc\x46\xc1\x46\x5b\xfd\x56\xa0\x43\xb8\xfd\xb7\xf7\x2a\x82\x6f\x7b\x9a\x30\x66\x33\x3a\xe7\xb2\x54\xd8\xdb\x48\x72\xe4\x7e\x02\xde\xb0\x90\x65\xb0\x77\x61\x31\xcc\xb0\x3a\xbd\x02\x4e\x1f\xaa\x1f\x41\x15\x48\xa5\x37\x4d\x0c\xd9\x67\xae\xcd\xf2\x5a\x3c\x88\x7c\x1a\xbc\x43\xe1\xcd\x5c\x17\x96\x2d\x74\xae\x6a\x57\xeb\x57\x97\x57\xe6\xb7\xf0\xd3\x17\x54\xd3\x6e\x6b\x76\xd7\x27\x13\x81\x7e\x86\xe2\x4f\xb8\x09\xcb\x78\xb2\xe8\x5c\xee\xad\xd1\xdb\x13\x6d\x1d\xee\xd0\xec\x7b\xf2\x35\xd5\x2c\x25\xef\xa9\xa0\x53\xd4\xf7\x4e\x6e\x6f\xbe\x7e\x7f\x6a\xf7\x15\xf4\xc9\xeb\xcb\x95\x17\x6d\xb7\xf1\xe0\x1f\x0e\x19\x2f\xb2\xb4\xf0\x1d\x58\xd5\x52\xff\x1d\x17\x7f\xd0\x40\x18\x12\xf8\x50\xbb\x64\xbd\x2b\x58\xd0\x4d\x33\x84\xb5\x59\xf3\xb3\x41\x60\xe6\x79\xba\x67\x95\x4f\x2e\xb4\xa1\x59\x76\x93\x51\x71\x5e\x14\x4a\xce\x57\x6b\xe3\xb5\xb9\xfa\x86\x7e\xa6\xe8\xe6\xe1\x5f\x16\x08\x7a\xb8\xc2\x16\xe4\xba\x1a\x7f\x44\xae\x4d\xd0\xc2\xa5\x00\x96\x7a\x74\x5e\x1a\x99\x53\xc3\x93\x23\xab\xac\x1f\xbd\xa7\xa2\xa4\xd9\x4a\xa7\xab\x8d\xcb\x58\x27\x22\x6e\xec\xb4\x3e\x75\x5d\x8b\x6e\x1b\x65\x8d\xcd\xfd\x0d\x55\x96\x3a\x5d\xdc\x7e\xdf\xa9\xaf\x36\xd4\x94\x4b\x54\x78\x03\x67\x58\xcf\x0b\x86\x24\xa3\xda\x7c\x2a\x52\x7b\xe8\x1b\xbf\x6e\x22\xf8\x09\x35\x34\x93\xd3\x3f\x31\x9a\xad\xc6\xf0\x1a\x9e\x5c\xc4\xad\xbd\x01\xca\x5d\xf8\x97\xe3\xd0\xf0\x58\x13\x2b\x60\xfb\x18\x78\xc5\x32\x36\xa7\xc2\xf8\xee\x58\x5c\x5d\x1f\xbb\xf5\x03\x16\xf1\xca\xf8\x9a\x32\xc3\x54\xce\x45\x7d\xcc\x5b\x68\x7b\x21\x45\xca\xd1\xec\x08\x06\x35\xec\x51\x1f\x77\x3d\xaa\xad\xbb\x69\xd8\x70\xb7\x50\xcf\xae\x19\xcd\xa7\x0e\x0a\x6c\x36\x76\xf2\xe5\x0c\x5f\xc2\x4d\x7b\x6d\x6e\x4b\x90\x22\xf7\xc2\x0a\x86\x90\x47\x64\x35\xd9\xda\x2a\x27\x6c\x93\x0f\x86\x7e\x8f\x71\x0a\xeb\x1d\x47\x87\x6e\xde\xeb\xee\x20\x36\xa1\x18\x3e\xdb\x25\x8b\xe6\x54\xd6\xd3\xd4\x55\x78\x17\xba\x61\x24\x4b\xa3\x20\x7f\xad\xd1\x7a\x1e\xd0\x4a\xf0\x6a\x27\x23\xb5\xcd\x6a\x5f\xa7\xb5\x55\x0e\xf6\x25\x55\xb6\x85\xc4\xb8\x95\x69\xb5\x4c\x2e\x5f\x57\xac\xaf\x9d\xff\x9f\x72\xaa\x08\x25\x05\x67\x98\xfc\x84\x0a\x07\x2c\xe0\x2c\x8c\xa6\xee\xa5\xe5\x60\x56\x25\x84\xdf\x06\xee\x32\x1c\x8d\xcb\xce\xd7\xc2\x1b\xa8\x29\x26\xff\x80\x8b\x8b\xb3\x6f\xa4\x33\xf2\xba\x20\x5d\x4b\x03\x80\x93\x0f\x88\x2e\x93\x19\xa1\xda\x4e\xcd\x22\xb4\x3d\xf1\x6c\x94\x53\xc1\x27\x4c\x9b\x51\xc8\x12\xac\xff\xfc\xeb\xbf\x8c\xc8\x5b\xa9\x88\x73\x54\x1f\xf8\xac\x1a\x6e\x9e\x15\x5e\x70\x8d\x8b\x09\x7d\x2b\xad\xb5\x90\xa9\x9b\xf4\x03\x4c\xd6\xd0\x7b\xcb\xc3\x70\xb2\x25\x83\xab\x8b\x37\xe4\xc8\x8a\x89\xd1\xa7\xff\x61\xd9\xd2\xbf\x8e\xc8\xc9\x03\x30\xed\x23\xfb\xe7\x11\x7e\x30\xb8\x4d\xc6\x4a\x75\xf5\x61\x0c\x96\x54\x7c\x3a\x65\x0a\xd5\x47\x02\x41\x85\xa7\x2e\x2b\x88\x90\x51\x63\x7f\x29\x5d\xa9\x9b\xcd\x89\xfc\xf9\xd7\x7f\x39\x22\x27\xf5\x75\x11\x2e\x52\xf6\x99\xfc\x1a\xad\xcb\x5c\xdb\x35\x9e\xba\xcb\x1c\xbd\x10\x86\x7e\xb6\x63\x26\x33\xa9\x99\x40\x55\xde\x48\x32\xa3\x73\x46\xb4\xb4\x1a\x30\xcb\xb2\xa1\xb3\xa5\x93\x07\x0a\x99\x5a\x3c\x28\x21\xb0\x9e\x14\x54\x99\x1a\x4a\x8c\x9c\x85\x04\xbe\x66\xb7\x6d\x2a\xfc\xcd\xf4\x84\x0b\x77\x7f\xe5\x6e\xce\xec\x9e\x43\x60\x28\x6e\x92\x91\x24\x99\x51\x31\x0d\xb1\xe9\x93\xd2\x94\x8a\x6d\xb9\xfa\x69\x79\x06\xee\xb9\xe8\x14\xc2\xfc\x2d\x17\x4d\xa7\x82\xd5\x76\xa5\x29\x37\x3e\x2a\xc2\xf9\x2a\x9a\xc5\x99\xdd\x05\xc5\xc7\xa5\x91\x4a\x9f\xa5\x6c\xce\xb2\x33\xcd\xa7\x43\xaa\x92\x19\x37\x2c\xb1\xcb\x3a\xa3\x05\x1f\x26\x52\xd8\x1d\x87\xac\x0c\x79\xfa\x0b\x28\x6f\x3a\xb4\x53\xdd\x92\x75\xba\xe5\xa2\xb7\x1b\xd5\x9e\xd5\x98\x76\xb0\x35\xb6\xb0\x07\x2d\x2f\x14\x6d\x33\x4f\xb0\x5a\x30\x84\x9c\x1d\x64\xb1\x3e\x69\x72\x77\x1e\x73\xec\xf2\x80\x27\xcd\x31\xec\xb1\x43\x07\x12\x38\x95\x35\x4a\x99\xd3\x14\x49\x29\x15\x8b\x47\x47\x7e\x0b\x52\x48\x97\x9f\x2c\x86\x30\x84\xcc\x86\x54\xa4\xf6\xdf\x18\xb0\x93\x2c\x0e\x02\xc3\x92\x77\x22\x04\x9f\xae\x2f\x9f\xe6\x48\x94\xfc\x00\xa7\xde\xc9\x6b\x2d\x85\x28\x14\x55\xd1\x51\x43\x95\xcc\x33\xcd\xba\x80\xca\xb5\x1f\xf5\x3f\xdc\xfd\x4b\xc8\x76\xb6\x4d\xa4\xda\x7c\x6b\x12\xc9\x8e\x2d\xe7\xfb\xae\xea\x11\xdb\xe4\xc0\xf1\x8a\x6a\xe3\x52\x6b\xf9\x1c\x04\xb5\x65\x78\x05\x05\x18\xcc\xfa\x8b\xe1\x56\x38\xe4\xfd\x05\xec\x44\x86\x2b\x73\x2e\x25\x41\x29\xd9\xae\x40\x55\xfa\x4b\xad\x0e\x1a\x2e\xca\x30\x6d\x08\x9d\x53\x9e\x81\x75\x5e\x8e\x35\x53\x73\x2c\x48\xe5\x52\x0d\xd2\xa6\x9e\xe5\x6a\x4e\xa0\x18\xf5\x44\x9a\x8f\x5f\xc3\xf2\xae\x6c\x5a\x00\x68\x43\x8d\xd9\xaf\x9d\xf5\x41\xf4\x1e\x54\x2f\xd7\xfe\x6c\xbf\xb0\xa3\x1a\x63\xf1\xef\x4f\x8c\x2a\x33\x66\xd4\xdc\xf1\x4d\x7c\x77\x09\xa5\x6b\xfd\x42\x29\xf7\x80\xd0\x0f\x8c\x4c\xa5\xb1\x22\x56\x09\xb8\x8f\x32\x29\x26\xf5\x09\x88\xf6\xd8\x18\x5d\xad\xf2\x4e\x51\x08\xf1\x91\xa2\xe3\x32\xeb\x1d\x97\xd7\xe9\xa4\x63\x87\x49\x06\x5b\x63\x22\x0d\x29\x98\xdb\x3b\xbc\xcd\x00\x0a\xf4\x34\x4b\xce\x99\xd6\x1b\x13\x6c\xd4\xbd\x0b\xb1\x35\x1e\xe5\xc6\xd5\x5a\xee\x7f\xc3\xb0\x10\x2b\x40\xa7\xcc\x50\x9e\xf9\xa3\x8c\xa0\x08\x50\xda\x46\x5d\x37\x2e\x50\x31\xaa\x37\x09\x08\xb5\x59\x7f\x84\xc6\x38\x69\x29\xd8\xf0\x41\xaa\x94\x5c\xd0\x9c\x65\x17\x54\x33\x37\x56\x1c\xa2\x87\x7b\x74\xac\x0f\x3a\xe5\xd5\xb6\xaf\x35\x53\x46\xe3\x4f\x65\x12\x86\xbf\x2a\x15\x0b\x27\x38\xf0\x26\xc8\x3b\x55\xb2\x01\x79\x6b\xb9\xd7\x80\x7c\x12\xf7\x42\x3e\xec\x37\x57\xb3\xf1\x16\xa4\x36\xd3\xd8\xfd\xc3\xa7\xd5\xa9\x19\x7c\xc2\x74\x77\x9c\x91\x23\xf8\x6b\x4c\x8d\x75\x66\x13\x9a\xfa\x19\xd9\x7f\x2e\x99\xa0\xac\xa2\xa8\xe4\x54\x31\x8d\x99\x6b\x56\x26\x49\x6c\x6b\x72\xfe\x86\x09\x17\xdc\xb7\x75\x7a\xd7\xab\x7a\xf9\x99\x7a\xbe\x36\xad\x7e\x71\xfb\xed\x3e\x56\x64\x2b\x45\x8d\xcd\x1e\x81\xd1\x44\xd7\x18\x9f\xd6\xcd\x70\xb5\xd1\x29\xe2\x7a\x51\x5b\x14\x4a\x36\x59\x47\xfd\xea\x2e\x6e\xbf\x5f\x0f\xec\xb5\xbc\x6f\x1b\x7f\xda\x6e\x96\xda\xd7\x20\xb5\xf5\xcc\x6c\x35\x42\xf5\xe6\xa7\xde\xfc\xf4\x25\x99\x9f\xb6\x62\xfc\x26\x93\xd3\x97\x61\x6c\xda\xba\xc4\x4d\x06\xa6\x17\x69\x5a\x6a\xb5\xa2\x8d\xe6\xa4\x17\x6b\x48\xda\xba\xb4\x96\xc6\xa3\x9f\x8f\xd9\x68\x2b\xc4\x36\x98\x8a\x5e\xa0\x91\xa8\x8d\x40\xc6\xd2\x36\x62\xe2\x75\xd4\x38\x16\x14\xab\x72\x96\x61\x38\xef\x94\x13\x8b\x33\xbb\x4a\x8b\x56\x80\xdb\x3a\xb7\x63\x37\xb9\xf6\xb2\x97\x13\x18\x5d\xb1\xc7\xa5\xc9\x92\xcb\xab\x9b\x8f\x57\x17\xe7\x77\x57\x97\x4d\xf9\x6e\x15\xa4\xb7\x48\x62\x9b\x6d\x10\xc3\x48\x12\x5b\xd3\xc0\x12\xe4\x35\x3f\x59\x1c\x58\xf3\x53\x59\xf2\x55\xbd\xf6\x97\x0b\xf7\xe2\x72\x7b\xf1\x8f\xed\xa7\xb3\xed\xf1\xfc\x84\x8e\x53\xd4\xf9\x9c\x59\xb9\x67\x26\xb3\x54\x7b\xbf\xd5\xeb\xcb\x10\x49\xc5\x45\x92\x95\xa9\x15\x2e\x3e\x7d\xba\xbe\xd4\x23\x42\xbe\x66\x09\x2d\x35\x58\x61\x52\x29\x8e\x0d\xf9\xee\xc3\xbb\xff\x06\x7f\x6c\x68\x31\x08\x79\x4d\x20\x2b\x2f\xa7\x98\x58\xd8\x60\xba\x36\xf2\x35\x43\x41\x05\xbe\x9c\xd0\xc2\x52\x31\x8d\x95\x2b\x0c\xc8\x22\x33\x96\x15\x96\x62\xde\x33\x52\x65\x50\xb5\x03\x57\x15\xe6\xbd\xfb\xe4\x94\x19\x8c\xba\xda\xe4\x21\xb9\x11\x6a\x5b\x2c\xae\x7b\xd8\x5a\x6b\xea\xa3\xd3\xc6\x1f\xa8\x76\x16\xab\x95\xb3\xdd\xb2\xbf\xdb\xed\x33\xeb\x4d\x1c\x6b\x8c\x1b\x48\x9e\xe1\xaf\xa5\x39\xdb\xc9\x56\x76\x0c\x74\x22\xe1\xa6\xb5\x35\x75\xbd\x1b\xd0\xea\x3a\x00\x4b\xb6\x0c\xd6\x04\x72\xed\xc3\xc1\x23\x3b\x9a\x72\xbb\xb9\x40\x11\x91\xb4\x56\xfb\xd3\xf9\xcf\xd5\xdf\x95\xe3\x50\xfd\xb5\x9a\xaf\xb3\xc8\x90\x7f\xfc\xeb\xab\xff\x3f\x00\x00\xff\xff\x01\xa8\x18\xd1\x2e\x5c\x02\x00") +var _operatorsCoreosCom_subscriptionsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\x7b\x73\xe3\xb8\x95\x28\xfe\xff\x7c\x0a\x94\x93\x2a\xdb\x59\x49\xee\xce\xe6\x26\xb9\xbd\xa9\x6c\x79\x6c\xf7\xc4\x77\xba\x7b\x7c\xdb\xee\x99\xda\x5f\x36\xbf\x0d\x44\x42\x12\x62\x12\xe0\x00\xa0\xdc\xca\xe3\xbb\xdf\xc2\x39\x00\x08\x52\x2f\x52\x92\x1f\x3d\x43\xfe\x31\xd3\xa6\x00\x10\x38\x38\x38\x2f\x9c\x07\x2d\xf8\xf7\x4c\x69\x2e\xc5\x1b\x42\x0b\xce\x3e\x1b\x26\xec\x5f\x7a\x74\xff\x7b\x3d\xe2\xf2\x6c\xfe\xfa\xab\x7b\x2e\xd2\x37\xe4\xa2\xd4\x46\xe6\x1f\x99\x96\xa5\x4a\xd8\x25\x9b\x70\xc1\x0d\x97\xe2\xab\x9c\x19\x9a\x52\x43\xdf\x7c\x45\x08\x15\x42\x1a\x6a\x5f\x6b\xfb\x27\x21\x89\x14\x46\xc9\x2c\x63\x6a\x38\x65\x62\x74\x5f\x8e\xd9\xb8\xe4\x59\xca\x14\x0c\xee\x3f\x3d\x7f\x35\xfa\xdf\xa3\x57\x5f\x11\x92\x28\x06\xdd\xef\x78\xce\xb4\xa1\x79\xf1\x86\x88\x32\xcb\xbe\x22\x44\xd0\x9c\xbd\x21\xba\x1c\xeb\x44\xf1\x02\x3e\x31\x92\x05\x53\xd4\x48\xa5\x47\x89\x54\x4c\xda\xff\xe5\x5f\xe9\x82\x25\xf6\xe3\x53\x25\xcb\xe2\x0d\x59\xd9\x06\x87\xf3\x73\xa4\x86\x4d\xa5\xe2\xfe\x6f\x42\x86\x44\x66\x39\xfc\x1b\xd7\x7e\x1b\x7d\x15\x5e\x67\x5c\x9b\x6f\x97\x7e\x7a\xc7\xb5\x81\x9f\x8b\xac\x54\x34\x6b\xcc\x16\x7e\xd1\x33\xa9\xcc\x87\xea\xdb\xf6\x5b\xba\x1c\xc7\xff\x76\x0d\xb9\x98\x96\x19\x55\xf5\x41\xbe\x22\x44\x27\xb2\x60\x6f\x08\x8c\x51\xd0\x84\xa5\x5f\x11\xe2\xe0\xe8\xc6\x1c\x12\x9a\xa6\xb0\x37\x34\xbb\x51\x5c\x18\xa6\x2e\x64\x56\xe6\x22\x7c\xd3\xb6\x49\x59\x18\xf5\x0d\xb9\x9b\x31\x52\xd0\xe4\x9e\x4e\x99\xff\xde\x98\xa5\xc4\xc8\xd0\x81\x90\xbf\x69\x29\x6e\xa8\x99\xbd\x21\x23\x0b\xe2\x91\x85\x60\xf4\x33\xee\xcf\x0d\x0e\x12\xbd\x37\x0b\x3b\x5d\x6d\x14\x17\xd3\x4d\x9f\x4f\xa8\xa1\x99\x9c\x12\xc4\x2f\x32\x91\x8a\x98\x19\x23\xf6\x53\x7c\xc2\x59\xea\xe7\xb7\x61\x46\xd8\x75\x69\x4e\xb7\xcd\xd7\xad\xa7\x34\xa3\x42\xb0\x8c\xc8\x09\x29\x8b\x94\x1a\xa6\x89\x91\x15\x7c\x36\x83\xc7\x75\x5e\x9a\xcd\xc5\xd2\xfb\x15\xd3\xc1\xa6\xf3\xd7\x34\x2b\x66\xf4\xb5\x7b\xa9\x93\x19\xcb\x69\xb5\x87\xb2\x60\xe2\xfc\xe6\xfa\xfb\x7f\xbf\x6d\xfc\x40\xea\x4b\x89\x51\x94\xdc\x33\x56\xe8\xea\x50\x90\xb2\xb0\x6b\xb2\x8b\x23\xe3\x05\x31\x8a\x26\xf7\x5c\x4c\x61\xe9\x53\x5c\xef\x05\x6e\x8c\x1e\x2d\x4d\x59\x8e\xff\xc6\x12\x13\xbd\x56\xec\xc7\x92\x2b\x96\xc6\x53\xb1\x90\xf5\x24\xa2\xf1\xda\xc2\x29\x7a\x55\x28\x3b\x2d\x13\x9d\x43\x7c\x22\x1a\x55\x7b\xdf\x58\xe6\xb1\x85\x05\xb6\x23\xa9\x25\x4f\x76\xfa\x33\xe6\x0f\x07\x4b\x1d\x00\xed\x76\x9a\x19\xd7\x44\xb1\x42\x31\xcd\x04\x12\x2c\xfb\x9a\x0a\xb7\xa6\x11\xb9\x65\xca\x76\xb4\x07\xb6\xcc\x52\x4b\xc7\xe6\x4c\x19\xa2\x58\x22\xa7\x82\xff\x3d\x8c\x06\x20\xb2\x9f\xc9\x2c\x7e\x18\x02\xc7\x4d\xd0\x8c\xcc\x69\x56\xb2\x01\xa1\x22\x25\x39\x5d\x10\xc5\xec\xb8\xa4\x14\xd1\x08\xd0\x44\x8f\xc8\x7b\xa9\x18\xe1\x62\x22\xdf\x90\x99\x31\x85\x7e\x73\x76\x36\xe5\xc6\x53\xe0\x44\xe6\x79\x29\xb8\x59\x9c\x01\x31\xe5\xe3\xd2\x6e\xdc\x59\xca\xe6\x2c\x3b\xd3\x7c\x3a\xa4\x2a\x99\x71\xc3\x12\x53\x2a\x76\x46\x0b\x3e\x84\xc9\x0a\x24\x91\x79\xfa\x0b\xe5\x68\xb6\x3e\x6e\x80\x6f\xe5\x39\x20\x9e\xea\x6d\x84\xb5\x25\x7e\x84\x6b\x42\x5d\x77\x5c\x4b\x05\x52\xfb\xca\x42\xe5\xe3\xd5\xed\x1d\xf1\x13\x40\xb0\x23\x84\xab\xa6\xba\x02\xb6\x05\x14\x17\x13\xa6\xb0\xe5\x44\xc9\x1c\x46\x61\x22\x2d\x24\x17\x06\xfe\x48\x32\xce\x84\xb1\xc7\x30\xe7\x46\x03\xce\x31\x6d\xec\x3e\x8c\xc8\x05\x30\x20\x32\x66\xee\xc0\xa6\x23\x72\x2d\xc8\x05\xcd\x59\x76\x41\x35\x7b\x74\x50\x5b\x88\xea\xa1\x05\x5f\x7b\x60\xc7\xfc\x73\xb9\xc3\xd2\x19\x23\xc4\x33\xb8\xb5\xbb\x13\x1f\xf8\xdb\x82\x25\xe1\x38\x50\x41\xce\x8b\x22\xe3\x09\x62\xbc\x99\x51\x43\x12\x2a\x2c\xbc\xb8\xd0\x86\x66\x19\xb0\x93\x56\xb3\x58\x77\xda\x09\x1c\xed\x06\x73\xf0\xaf\x97\x28\x74\xfd\x87\xc0\xd4\x1a\x2d\xd6\x51\x06\xfb\x38\x3a\xbb\xfc\xc3\x06\x90\x13\x94\x4c\x26\x7c\xba\xaa\xdb\x5a\x58\x5e\x40\x17\x90\x69\x28\x17\xda\x0d\x51\x2a\x84\x66\xc5\xa9\x2c\xef\xa2\x35\xbe\x3d\x5a\x3b\xbb\x95\x90\xdd\xb6\x66\xfb\xd0\x09\x48\x60\x8b\xd5\xbf\x36\x56\x71\x3d\xa9\xa6\x37\x20\x72\xce\x94\xe2\xa9\xa3\x8f\x85\x4c\x8f\x35\x50\xb3\xb4\xcc\x80\xf6\x4b\xa1\x8d\xa2\x1c\x8e\xa6\xe0\x99\x5d\xc9\x90\x1a\x3c\x0f\x4c\x93\x07\x9e\x65\xe4\x57\x42\x9a\x5f\x85\x91\x60\x20\xa9\xf8\x94\x07\xd2\xa7\x09\x17\x7e\x7c\xe0\x88\x8e\xa5\x4b\xcd\x1a\x03\x8e\xc8\x27\xcd\x08\xcb\x0b\xb3\xf0\xc4\xe1\xe4\x1f\xff\x3a\xb5\x84\x95\x29\xaa\xa3\x81\x6b\xfd\x3c\xf9\x5c\xb3\xfe\x2d\xe0\x6d\x03\x62\xfb\x08\x99\xb2\xf3\x2d\xa0\x5e\x02\xf7\x25\x43\x09\x41\x43\xf7\xb0\x55\x31\x90\x55\x99\x31\x1d\xa4\x1c\x0b\xa3\x0d\x83\xb7\x58\x4b\xdb\xf5\x60\x3b\x36\x61\x4a\xb1\xf4\xb2\xb4\x47\xe3\x36\xcc\xea\x7a\x2a\x64\x78\x7d\xf5\x99\x25\xa5\x59\xc1\x75\x37\x2e\xdd\xca\x4d\x6e\x99\x4c\x21\xaa\xe0\xe7\x40\x74\x72\x3f\xd8\xf5\x02\xe3\xb4\xe0\xd1\x48\x87\x34\x35\x5c\x4f\x16\x00\x8e\x00\x30\xf6\xd9\x32\x09\x90\x6d\xa3\xf3\x65\x05\x15\xe0\x0f\x9c\x65\xe9\x80\x8c\x4b\x43\xb8\x01\xe6\x91\xcc\xa4\xc5\x2f\x8a\x70\x87\x71\xe7\x5c\x02\x6b\x26\x52\x58\x4c\x22\xb9\xe5\x00\x20\x02\xb0\x78\xf8\x11\xcc\xbc\xea\xc6\x35\xc9\xa5\x36\x15\xac\xec\x1b\xc0\x72\xc1\xc8\x03\x37\x33\xf8\x63\x6a\xd5\x15\xcb\xf6\x75\x99\xdb\x41\x1f\x18\x9f\xce\x8c\x1e\x10\x3e\x62\x23\xd8\x5d\x46\x93\x59\x34\x6c\xce\x98\xd1\x84\x66\x99\x9f\x42\x8c\x12\x48\x4f\x73\xcb\x13\xc9\x49\x60\x9a\x8e\xc1\x0d\x02\xbd\x6d\xee\xda\x4a\x70\x0d\x08\x33\xc9\xe8\x74\x40\x12\x99\x17\xf6\xb4\x50\x98\xe3\x78\x41\xb8\xb1\xb2\x1f\x32\x68\x25\xcb\x29\xae\x84\x65\xee\xc3\x5e\x3a\x02\xe0\x82\xf8\x62\xb5\x09\x31\x25\x47\xb8\xb8\x23\x2f\xf0\xd8\xe1\x38\x2e\x02\xd6\x97\x53\x93\xcc\x1c\x4d\x49\xa4\x52\x4c\x17\x52\x40\x4f\xf8\xe5\xaa\x9a\xdb\x7f\x84\x4e\x27\xfa\xb4\x02\xe6\x8c\x4f\x67\x1e\x96\x54\x21\x4d\xa9\xef\xc1\xa6\x33\x52\x9d\x13\xaa\x14\x5d\x6c\x69\xc9\x0d\xcb\xb7\x9c\x92\x25\xd4\x3e\x17\x8e\x48\x55\x38\x11\xed\x9e\x61\x2a\x0f\x30\x80\x0d\x86\xe3\xaa\x71\x7d\x3c\xb7\x6c\x97\x1b\x87\x21\xe4\x15\x39\x01\x14\xe1\xe6\x58\x03\xba\x0e\x65\x71\x3a\x22\xe7\xa0\xed\xb6\xf8\x80\x90\x61\x7c\x37\x90\xfd\xa8\x96\xd5\x58\x5b\xd7\xd6\x92\xa8\xe0\xb3\x9e\xd7\x2f\x3f\x43\x37\x7f\x26\x56\xb0\xfa\x55\xcd\x11\x26\x5b\x9b\xb6\x25\x6f\xbe\xb5\x9f\x43\x9b\xd6\xcd\xad\x46\x94\xd6\x2c\x63\x89\xb1\x34\x9a\xa9\x7c\x40\xa8\xd6\x32\xe1\x56\xac\xac\x90\xb6\x8e\xe9\xb8\x92\xed\xb0\x27\x5d\xe1\x4f\x3a\xaf\xdf\x3e\xcd\x83\xd7\xb6\xdf\x12\x34\x32\xae\x8d\xa5\x0c\x75\xa8\xd4\x08\xd6\x78\x01\xbf\x1e\x6b\x92\xd1\x31\xcb\xd6\xf2\xe5\xe5\xa7\xfd\xa9\xad\x9e\x96\xe7\x77\xed\x82\xd6\x2e\xc4\x29\x35\x61\xe3\x41\x44\xf6\x02\x1f\x4a\x1c\x03\x42\xc9\x3d\x5b\xa0\x6e\x67\x55\x46\xa7\x4c\x63\x63\xc5\x90\xdd\x58\xe4\xb8\x67\x0b\x68\xb4\x59\x52\x59\x0f\x93\x0e\xc8\x81\x4f\x97\x63\x5a\x3d\x43\x3b\xd1\x8e\x3d\xfc\xa2\x3b\x74\xeb\x8e\xbf\xf8\xdc\xb3\x8d\x92\xd7\xaa\x67\x49\x24\x01\x9c\x84\xfd\x80\x4d\x02\xfe\xe5\xf7\x98\x5a\x95\x08\x6c\x1d\x5d\x76\x88\x6c\x53\x30\x36\x3d\x1e\x7a\x7b\xad\xeb\x63\xd0\xa0\x11\x21\x8f\x35\x22\x9f\x3d\xe9\x33\x0e\x76\x1d\x8b\xc9\x70\x70\xbd\xa9\xe1\x7b\x9a\xf1\x34\x32\xff\x58\x3e\x7b\x2d\x06\xe4\x83\x34\xf6\x7f\x57\x9f\xb9\xb6\xe2\xcb\xa5\x64\xfa\x83\x34\xf0\xe7\x88\x7c\x63\x10\xd7\xdf\xb5\xa4\x6c\x07\x00\x10\xce\x77\x2f\xf0\x9c\x0b\xa4\x29\x76\xf9\xb1\x91\x42\x8f\xac\x3a\x04\xa2\x9c\x3f\xb8\x5c\x93\x6b\x61\x85\x43\x07\x06\x30\x1b\xa1\x12\x83\x43\xe4\xa5\x06\xab\x82\x90\x62\x08\x32\xc0\xca\x31\x10\x7a\x76\x9c\x18\x7e\x1b\x86\x5b\x3f\xd4\x37\xc6\x0e\xf3\x6e\x6d\xe7\x19\x9d\x83\x48\xc7\xc5\x34\x0b\xc2\xdb\x80\x3c\xcc\x78\x32\x43\xa9\x1b\x74\x7a\xc3\x54\xa1\x98\x65\x58\x14\xb4\x7f\xfb\x66\xca\x94\x15\x76\xb9\x1f\x0f\x2d\x61\x19\x4d\x58\x4a\x52\x10\x2d\xd1\xaa\x43\x0d\x9b\xf2\x84\xe4\x4c\x4d\x19\x29\x2c\x27\xd9\x6d\xf7\xbb\x11\x76\x7c\x3a\x93\xf7\xf8\x83\x9d\xd0\x0d\x58\xe4\x5b\x2b\xeb\x3e\x11\x77\x04\xb9\xba\xe7\x8e\x3d\x77\x6c\x3c\x3d\x77\x0c\x4f\xcf\x1d\xb7\x3c\x3d\x77\xec\xb9\xe3\xa3\x73\x47\xd4\x65\x77\x50\x9e\x7f\x40\x13\x47\x53\x5b\x06\x4e\xeb\xef\x85\xea\x6a\xb3\xe5\x37\xb7\x8e\xe0\xdc\x81\xaa\xed\x6c\xc7\x8a\x8a\x29\x23\xaf\x87\xaf\x5f\xbd\xea\xa2\x54\xbb\x8d\x6c\xd5\x63\x22\x55\x4e\x0d\xf4\xf9\xf7\x5f\x6f\xec\xb1\xce\xfe\x76\x00\xab\xa9\xc3\xf1\x60\xc8\xab\xc9\x0e\x6b\x0c\x9f\x40\x9d\x84\x34\x24\x67\x86\x50\x53\x33\x15\xf1\x9c\x0d\xbc\x61\x19\x11\xde\x5d\x8b\x79\x0b\x6c\x4a\xa4\x70\x76\x3c\x0b\xfc\xd1\x6e\x33\x48\x18\xd5\xcc\x52\xd2\x31\x0b\xb3\x90\xb9\xfd\x2a\x17\xc6\x1f\x17\x3b\x05\xe6\xa1\x42\x4e\xd8\x68\x3a\x22\x69\x09\xdd\xa8\x70\xf7\x74\xa7\x38\x5b\xbd\xd0\x86\xe5\x60\xc9\x95\x0a\xfe\x67\xa7\x6d\xd4\x02\xee\x02\xe6\x4c\x98\x92\x66\xd9\x82\xb0\x39\x4f\x4c\x58\x1f\x5c\x13\x72\x83\xc6\xf6\x76\x26\xc2\x56\xa2\x43\x7b\x71\x61\xb8\x84\xc1\x7a\x4b\x9f\x2e\xdc\x7e\x69\xec\x36\x67\xb2\xc1\x0b\x71\x25\xa3\xb5\xc2\xaa\xb1\xe3\xa2\x0d\x1c\xfe\x09\xc8\xf5\xdd\xc7\xed\x26\x57\xd2\x99\x92\x75\xa0\x5e\x4d\xb1\xb4\xcc\x32\x8b\x18\x68\x85\x5d\x5e\xc0\x0a\xeb\x28\x2e\xa9\x86\xcc\x68\x78\x47\x13\xf3\xf9\x87\x4b\x0b\x15\xdb\xe6\x4e\x16\x32\x93\xd3\x45\x0c\x69\x58\x19\xd8\x6e\x5d\x5f\xbc\xd5\x43\xa1\xc1\xa2\xdf\x87\xc6\xd6\xf4\x96\xbf\xde\xf2\xd7\xeb\x36\x4b\x4f\xaf\xdb\x84\xa7\xd7\x6d\xb6\x3c\xbd\x6e\xd3\xeb\x36\xbd\xe5\x8f\xf4\xdc\x71\x03\x4c\x7a\xee\x48\x7a\xee\xb8\x76\x5d\x3d\x77\xdc\x08\x9e\x9e\x3b\xf6\xdc\x71\xd5\x53\xc8\x74\x0f\x47\xc7\x42\xa6\x1b\xfc\x1c\xd1\xea\x93\xc8\x61\x26\x13\x6a\x9c\x23\xb8\xed\xe2\xec\x7c\x9a\xe6\x68\x88\x1a\x90\xbf\x4b\xc1\xd0\x79\xcd\xee\x0d\x98\x93\xa4\x99\x31\x65\x9b\x9f\xe8\xd3\x8d\x8e\x4d\xbd\x9f\x64\xef\x27\xf9\xe2\xfd\x24\x67\x54\xe3\xbe\x22\x51\x5a\xef\x36\x19\x1d\xc8\x3b\xa6\xf2\x2f\xd4\x6b\xd2\xa2\x8b\xdb\x6e\x08\xb1\xa9\xb6\x14\x57\x9e\xba\xfb\x02\x96\xde\xd4\xd7\xeb\xe4\x65\x58\x14\x4d\x53\x96\x92\x82\xa9\x21\xa2\x88\x24\x13\x2e\xd2\x15\x6b\xf5\xf0\x79\x56\xef\xc7\xfa\x3a\x9e\xd1\x05\xb2\x3e\x91\x1d\x6c\xae\xb1\xe1\xb8\x46\xe1\x5f\x84\x43\x64\x57\xa9\x7e\x48\x8c\x33\xf2\x7e\xdb\x52\xae\xef\x2e\x9a\x83\x40\xed\x4d\xc2\xbb\xeb\x95\x20\x96\xff\x58\x32\xb5\x80\x18\x8b\x4a\x60\x0d\xc1\x5c\xee\x8e\x8c\x6b\x92\x50\x8d\x9c\xa2\xab\x6a\xd9\x51\x8d\xda\x4d\x4f\xd9\xdd\x12\x4d\x9a\x70\x69\x0e\x85\x3a\xa9\xd7\xc1\x11\x66\x2b\x95\xf0\x15\xb7\x00\x95\xf5\xbf\xd3\x7c\x76\x15\xdd\x76\x12\xdc\x56\x22\xc5\x0b\x56\xce\xc9\xee\x0a\x3a\xd9\x59\x49\x27\x3b\x29\xea\x64\x57\x65\x9d\xec\xa1\xb0\x93\xdd\x94\x76\xd2\x44\x05\xbb\x43\x4e\xca\x7a\x1c\xfd\x9d\xec\xa3\xa2\x92\x3d\xf4\x78\xd2\x5c\x6a\x40\x53\xf5\x58\x4a\x3d\xe0\x7a\x4d\xaf\x7f\x6a\x60\xed\xa6\xd3\x93\x26\xa8\x7c\xd4\x1d\x28\xb4\x5f\x88\x86\xff\x24\xea\x36\xd9\x4b\xe5\x26\xbb\xab\xdd\x64\x77\xcc\x00\x56\xf7\x0e\xae\x53\xf7\x65\x98\x38\x0a\xb2\x88\x9c\x16\x16\x29\xfe\x61\x39\x01\xec\xcb\xbf\x48\x41\xb9\xd2\x56\xbe\x73\x36\x93\xf8\x37\xa7\x9d\xc7\xc3\xd8\x11\xb8\x26\x96\x54\xcf\x69\x66\x79\x0f\xfa\x71\x38\xbd\xc8\x8e\xde\x64\xd3\x03\xf2\x00\x51\x9f\x96\x4a\xa1\xb6\xc4\x35\x39\xba\x67\x8b\xa3\xc1\x12\x22\x1d\x5d\x8b\x23\xe4\x51\x4b\xa8\x13\x18\x9a\x14\xd9\x82\x1c\xc1\x6f\x47\x87\xe6\xec\x3b\x30\xae\x38\xd9\xc6\xae\x7c\x61\x07\x2c\x11\x3e\x56\xfa\xf0\xc2\x26\x72\x11\xbc\xd8\xf0\x5f\xd1\x15\x83\x01\x57\x8b\x88\xb9\x04\xaf\x11\xc0\x31\x78\x9f\x7a\xe5\xb7\x14\x2e\xb5\x02\xe8\xae\xd5\x60\xc8\xa4\x96\x5d\x9a\xdc\xc6\x4b\xc1\x34\x08\x76\x2c\x98\x88\xa2\xce\xd0\x76\x84\xee\x20\x15\xb7\x13\x69\xd3\x41\xa4\xea\x01\x32\x62\xce\xa8\xd0\xe4\xc8\xdb\x9e\x8e\x75\xd5\xe2\x68\x54\x45\xf7\x85\x11\x21\x08\x39\x8e\xe8\xab\x06\xec\x25\xed\x5e\xd2\xee\x25\xed\x0e\xbd\x7a\x49\x7b\xfd\xd3\x4b\xda\x1d\x9e\x5e\xd2\xee\x25\xed\x4d\x1f\xee\x25\xed\x5e\xd2\xde\xfe\xf1\xdd\x24\xed\x5d\xfd\x84\x62\xb9\xd7\x5d\xce\x61\xe6\x2c\x6a\x78\x52\xf9\x10\xf9\x56\xf8\xaf\xc3\xca\xdb\xb1\x2c\xbd\x5a\xda\x8e\x25\xf2\x25\xdd\x62\xb4\x45\xb4\x0e\xc2\xf7\x52\xcf\xcd\x52\xf7\xcb\xf2\x85\xda\x01\x37\xa2\x0b\x85\x1d\x91\xe3\xce\x5f\x85\xbb\x4c\x73\x63\x56\xdd\x93\xa7\xe4\xc4\xdf\xb8\x9c\x5a\xe0\x0b\x69\xea\x3f\x0a\xc3\x87\x55\x8b\x70\x07\x03\xd7\x8b\xb5\x78\x9b\xda\xb5\x44\xb8\x75\x0f\x37\xc5\xd5\x7e\x5a\x12\xc2\x54\x6d\x0e\x5c\xbb\x04\x62\xe0\x2d\xa1\x4a\x21\xec\xa8\x52\xf8\xeb\x63\xa4\x39\x98\x00\xce\x61\x1e\x0a\x4b\x30\x1f\x90\x98\x2a\x28\x45\xf7\x9d\xd4\x60\xce\x3d\xe7\xca\x2f\x85\xbb\x11\xb5\x6f\xfc\xad\xaf\x47\x4a\x58\x11\x0f\x5f\x1f\x91\x2b\xc0\xc3\x78\x60\xae\x01\x3e\x34\xcb\xe4\x43\x17\x92\xf4\x54\x61\x51\x0f\x9d\xc3\xa2\x1a\xf7\x77\x7d\x54\xd4\xcf\x24\x2a\x0a\x7e\xc4\x23\x74\xf0\xf0\x28\xf2\xc3\x8c\x01\x16\x29\x06\xa0\xca\xcb\xcc\xf0\xa2\xf2\x95\xd2\xf8\xa9\x0c\xa5\xcc\x89\xf3\x3c\xa9\xe3\xa5\xfd\x1a\x4d\x66\x4d\xfc\x84\xf1\xc0\xb7\x4a\xc3\xa1\x75\xde\x1d\x34\xcb\x5c\x4c\x91\x17\x49\xd1\x85\x85\x3f\xb7\x67\xc2\xa5\xcf\x8a\xe8\xb5\x19\x20\x32\x27\x96\x16\x66\x0b\x97\xa9\x6e\x03\x11\x45\xa5\x68\xce\x3c\xeb\x9d\xf2\x39\x13\x15\x25\x3d\xd1\xa7\xa7\x9e\x87\x1f\x94\xc2\x3f\x0a\x85\xfe\x43\x44\x49\xff\xd8\x86\x46\xc3\x82\x02\x95\xae\xc0\x57\xd1\xe8\xe7\x74\xc1\xe8\x72\xcf\xdf\xcd\xc6\xb0\xc3\xfd\xfe\x13\xde\xed\x7f\x39\x91\x65\xcf\x6c\x61\x7c\x0e\xdf\xfa\x17\x6f\x55\xec\x9d\xeb\xab\x67\x5f\xe7\xfa\x47\xb7\x1c\x3e\xaf\x8f\xfd\x17\x60\x2d\x7c\x4e\x1f\xfb\xde\x42\xb8\x71\x53\x5e\x9a\xeb\x7b\xfd\xd9\xc9\x22\xd8\x5b\x03\x77\xe6\xc2\x1d\x19\xce\xbe\x56\xc0\x8e\x18\xb1\xe3\x3d\x7b\x7f\xc7\xfe\x34\x77\xec\xbd\xc4\xdb\xf2\xe9\x25\xde\xb5\x40\xe9\x25\x5e\xd2\x4b\xbc\xdb\x96\xd7\x4b\xbc\x1b\xc1\xd3\x4b\xbc\x1b\x37\xa5\x97\x78\x7b\x89\x97\x7c\x69\x12\xef\x2e\x59\xba\xfa\xbb\xee\xbd\xee\xba\xbb\x52\x8b\x4e\x34\xa2\x23\x1e\x74\xbe\xdb\xee\xef\xb5\x5f\xca\xbd\x76\xeb\x80\x7f\x61\xf8\xbe\x41\xff\xf1\x5e\xad\x8b\xfc\xa7\x73\xc9\x53\x52\x94\xc6\xc5\x53\xf7\xd1\xff\x87\x88\xfe\xaf\x41\xbe\x4f\x01\xd0\x2a\x05\xc0\x3a\x98\xf5\x79\x00\xfa\x3c\x00\x07\xbe\x84\xee\xf3\x00\xf4\x79\x00\xfa\x3c\x00\xfe\xe9\xa3\x93\x48\x1f\x9d\xd4\xea\xe9\xa3\x93\xd6\x3f\x7d\x74\xd2\x8b\xb5\xbe\x92\x3e\x3a\xe9\x65\x5b\x62\x49\x1f\x9d\xd4\x5b\x67\x5b\x6e\xd4\x17\x18\x9d\xd4\xe7\x01\x78\xa9\x3e\x0a\xa4\x97\xb4\x7b\x49\xbb\x97\xb4\x7b\x49\x7b\xf3\xd3\x4b\xda\x1d\x9e\x5e\xd2\xee\x25\xed\x4d\x1f\xee\x25\xed\x5e\xd2\xde\xfe\xf1\x3e\x0f\xc0\x17\xe4\x1b\x41\xfa\x3c\x00\xbd\xbf\x44\x9f\x07\xe0\xe7\x9b\x07\xa0\x76\x77\xff\x7c\xc9\x00\xba\x4f\xa3\xcf\x08\xd0\x67\x04\xe8\x33\x02\xf4\x19\x01\xfc\xd3\x67\x04\xc0\xe7\x25\xd9\x1a\xfb\xf8\xa8\xb5\x40\xe9\xe3\xa3\x48\x1f\x1f\xb5\x6d\x79\x5f\x80\xdd\xb0\x8f\x8f\x7a\x81\xb6\xc2\x3e\x3e\xaa\xb7\x0b\x36\x37\xe7\x0b\x89\x8f\xea\x33\x02\xbc\xc4\xdb\xf6\x5e\xe2\x6d\xf9\xf4\x12\xef\x5a\xa0\xf4\x12\x2f\xe9\x25\xde\x6d\xcb\xeb\x25\xde\x8d\xe0\xe9\x25\xde\x8d\x9b\xd2\x4b\xbc\xbd\xc4\x4b\xbe\x34\x89\xb7\xcf\x08\xd0\x67\x04\xe8\x33\x02\x7c\x89\x37\xdc\x5b\x77\x9a\x89\xf9\xba\x3d\xad\xed\xe2\x95\x98\xd7\xf5\x14\x26\xe6\x5c\x49\x01\x14\x78\x4e\x15\xa7\xe3\x0c\x4e\x2a\x48\x3c\x0e\xfe\x8e\x7e\x32\x35\x22\x17\x54\xb8\x8b\x56\xbc\xc9\x5c\x3b\xff\xed\x88\xbf\x05\xd5\x9b\xd3\xfe\x9e\xd6\x45\x35\xb1\x72\xea\xc4\x35\xb0\x53\xa7\xe4\x22\x4c\x7c\xed\x67\x5a\x11\xf0\x36\xfa\xc1\x10\x90\x73\x6d\x83\x76\x52\xbc\x1d\x62\xf3\xd9\xac\x81\xe5\x03\xcd\xab\x10\xff\x15\xd0\x18\x91\xf7\x4e\x42\xa2\xe4\xe2\x7f\xae\x2f\xaf\x3e\xdc\x5d\xbf\xbd\xbe\xfa\xb8\x19\xe9\x5a\x92\x15\x38\x48\x1d\x26\x7b\xfc\xbd\xdf\x23\x08\xf3\x66\xc2\x52\xe0\x5f\x9e\x7c\x7f\xfe\xf1\x7f\x3e\x9c\xbf\xbf\x3a\x05\xf6\xcb\x3e\x17\x54\xa4\x2c\x25\xa5\xf6\x24\xa1\x50\x6c\xce\x65\xa9\xb3\x45\x38\xde\xab\x91\xb6\x89\xad\x4e\xd1\x5c\x10\xcd\xd4\x9c\x27\xab\x41\x84\x52\x2c\xad\x10\x28\x09\x18\xae\x98\x96\xd9\x9c\xa5\x28\x6b\x84\x49\xfb\xef\x70\x51\x94\xc6\x4b\xc4\xe0\x82\x60\x4f\x85\x48\x66\x54\x4c\x59\x3a\x22\x97\xb2\xb4\xe3\xfd\xf2\x97\xb0\x30\xc5\xd2\x32\x41\x5e\x47\xbd\xc0\xf4\xcb\x81\xa7\x24\x96\x16\x68\x4c\xa3\xa0\x13\x5a\xf8\xa5\xc7\xd0\xd1\x0b\x61\xe8\xe7\x37\x78\x07\x7f\xf4\xcb\xe8\xa7\x23\x9f\x82\x42\xda\x4f\x20\x3d\xc2\x59\x65\x90\xfd\x20\x23\x47\x71\xeb\x11\xb9\xb2\xdf\x60\x69\xbc\x0f\xe8\x42\xc1\xe6\x4c\x81\x3c\xed\x76\x61\x40\x14\x9b\x52\x95\x66\x4c\x83\xf3\xc0\xc3\x8c\x41\x3a\x0f\x94\xb0\x1c\xc0\x58\x90\xd6\x85\x34\x23\x72\xc9\x26\xb4\xcc\x0c\xd0\x90\xa3\xa3\xd1\xf1\xc1\x50\xed\xad\x92\x5b\x82\xdf\x6b\xe8\x76\x8b\x49\x25\x26\x52\xad\x3d\x1e\xc7\xce\x34\x51\x23\x6b\xda\x72\x12\xa7\xe9\x79\x5a\x8d\xfa\x45\x8b\x95\xb4\x10\x04\xdb\xab\xf3\x89\x14\x13\x3e\x7d\x4f\x8b\x6f\xd9\xe2\x23\x9b\x74\xf4\x86\x40\x26\xea\x74\x5a\x60\x60\x96\x1c\xe2\x80\xdb\x99\xce\x23\xde\xe5\xb7\x31\x9a\x74\xb3\x79\xb4\xb6\x74\x2c\xa5\xb4\x40\xa6\xef\xd8\xf7\x01\x93\xf3\x54\xcf\x76\x8a\xbe\x72\x72\xc7\x31\x69\x77\xe7\xd4\x8c\xc8\x7b\x09\x2e\x39\x13\xf9\x86\xcc\x8c\x29\xf4\x9b\xb3\xb3\xfb\x72\xcc\x94\x60\x86\xe9\x11\x97\x67\xa9\x4c\xf4\x59\x22\x45\xc2\x0a\xa3\xcf\xe4\xdc\x52\x3e\xf6\x70\xf6\x20\xd5\x3d\x17\xd3\xa1\x95\x74\x86\xb8\xab\xfa\x0c\x84\xa9\xb3\x5f\xa0\xc4\x7e\xf7\xdd\xe5\x77\x6f\xc8\x79\x9a\xba\x8c\x3d\xa5\x66\x93\x32\x73\xd9\x3b\x46\x84\x16\xfc\x7b\xa6\xac\x52\x36\x20\xf7\x5c\xa4\x03\x52\xf2\xf4\x3f\x37\x1f\xee\x1d\x21\x26\x0b\xd4\x8d\x76\x80\xda\x2d\x08\x8a\x8b\x1a\x9d\x0a\x48\x6f\x29\x14\x37\x1a\xf6\xdc\x1b\x0e\x1c\x43\xe9\xb0\x8c\xb1\x94\x19\xa3\x62\x4b\x0f\x00\x5b\xf7\x33\x7b\x5c\x1d\x5a\xd4\x72\x1c\x02\x14\x32\x7d\x43\x74\x59\x14\x52\x19\x4d\x72\x66\x68\x4a\x0d\x1d\xd9\x9d\x1b\xd4\xff\x04\xe1\x78\x40\xfe\x1a\x5e\x82\x84\xab\xff\x7c\x7c\xfc\x87\x6f\xaf\xfe\xeb\x8f\xc7\xc7\x7f\xf9\x6b\xfc\x2b\x90\x3d\x34\x75\xd5\x9b\x58\x91\x7b\x64\xc5\xdd\x0f\xf0\x0d\xf8\xd3\xb1\xd1\xf3\x24\x91\xa5\x30\xee\x07\x43\x4d\xa9\x47\x33\xa9\xcd\xf5\x4d\xf8\xb3\x90\x69\xf3\x2f\xbd\x85\x13\x90\xc7\x25\x3a\x00\xce\x1b\x6a\x66\x07\x26\x3d\xd5\xb9\xd8\x01\x5d\x5d\xcf\x38\x43\x52\x4e\xe1\x9f\x6f\xfd\x74\x2d\x07\x7a\x50\xdc\x18\x26\x40\xee\x00\xbf\x3b\x39\x19\x58\xcc\xad\xd8\xec\xfc\x75\x27\x75\xb4\xf5\x51\x0c\x50\xdb\x61\x71\x30\x7b\xb7\x32\x44\xe6\x40\x68\x97\xf5\xba\xf3\x9b\x6b\x32\x47\x68\x1c\x7c\x21\xde\x0b\xeb\xed\xde\x67\x32\x64\xaa\x72\xcb\x0a\x92\xe6\x1b\xb4\x2c\x05\x7f\x2f\x92\xf1\x9c\x3b\x03\xb0\xcb\x6a\xa5\xc9\x09\xbe\x1c\x25\x45\x39\x70\x0d\x46\x39\xcb\xa5\x5a\x84\x3f\x59\x31\x63\xb9\x95\xd8\x86\xda\x48\x45\xa7\x6c\x10\xba\x63\xb7\xf0\x17\x76\xac\x7d\x60\xb9\x37\x8a\xd4\x49\xa9\x2c\xf3\xc8\x16\x9e\x82\xb0\xf4\x79\xcf\xa2\x07\xd3\x81\x8f\x62\xd8\x8d\x0f\x3b\xb2\xdc\xa0\x2d\x22\xd3\x0e\xab\x02\x19\x72\x2e\xb3\x32\x67\x7a\x10\xd8\x13\x4a\xeb\x62\x6e\xa5\x49\xfd\x28\x8c\x30\xe5\x73\xae\x77\xba\x9f\xbe\x0d\x96\x3a\x30\x91\x95\xc6\x6a\x2a\xe8\x0c\x1e\x65\x84\x93\x1a\x74\x80\xe0\xa3\x58\x23\x29\xaf\x8f\xda\xdd\xbe\x52\x63\x98\x12\x6f\xc8\xff\x7f\xf2\xdf\xff\xf6\xcf\xe1\xe9\x7f\x9e\x9c\xfc\xf9\xd5\xf0\x7f\xff\xe5\xdf\x4e\xfe\x7b\x04\xff\xf8\xd5\xe9\x7f\x9e\xfe\xd3\xff\xf1\x6f\xa7\xa7\x27\x27\x7f\xfe\xf6\xfd\x37\x77\x37\x57\x7f\xe1\xa7\xff\xfc\xb3\x28\xf3\x7b\xfc\xeb\x9f\x27\x7f\x66\x57\x7f\x69\x39\xc8\xe9\xe9\x7f\xfe\xb2\xd5\xf4\xa8\x58\x7c\xd7\xe2\xc0\xe3\x33\xdc\xc1\xc3\xbe\xea\xd5\xc1\x40\xff\x79\x58\x09\x6d\x43\x2e\xcc\x50\xaa\x21\x76\x7f\x43\x8c\x2a\xb7\x1f\x8c\x8a\xa8\xed\x82\xe7\x3e\x1d\xd8\x9b\x8a\xa0\x05\xd2\x7c\x70\x44\xd6\x2c\x51\xcc\x1c\x4a\x83\xc1\xd1\x3c\xff\x68\x98\x64\x7b\xa5\xa6\x52\x6a\x82\x5d\x12\xe0\x55\x71\xde\x89\x92\xf9\x88\x44\x66\xa1\x39\xdc\x64\xba\x76\xf7\x6c\x8b\x96\xeb\x9f\x5e\x09\xfa\xb2\x94\xa0\x5b\xdc\xdf\x47\xd7\x80\x98\x98\x6f\x32\xd3\x34\x6d\xba\x6f\x21\x94\x25\x36\x47\x7b\x01\xca\x48\x52\xc8\xa2\xcc\xa8\x59\x63\xb6\x5b\x61\x9b\x76\xb8\x5f\xdd\x02\xd8\x8d\x06\x3b\xb0\xa3\x72\xf9\x6a\x63\x28\x39\xcf\x32\xc2\x05\x9e\x04\x18\xc0\x5b\xf3\x14\x43\x79\x89\x50\x34\x38\xcf\xed\x14\x1e\x5c\xc0\x4d\x64\x68\xe4\xda\xea\x3a\xca\x80\xc5\x1f\x02\x72\x90\x66\x39\xd3\x18\x17\x55\x58\x4e\xe0\xb6\xe1\x96\x72\x65\xfe\xc5\x8c\x6a\xe3\xa7\x0d\xb3\x31\xf4\x1e\x4c\xa1\x09\x4b\x99\x48\x18\xb8\x20\x94\xac\x5a\xeb\xd8\x0a\x83\x60\xde\x87\x31\x28\x49\xcb\x22\xe3\x89\x85\x9f\x9d\xc9\xea\x31\xae\xf3\xbc\x34\x60\x28\x7e\x2a\x2b\xbe\xdd\xf1\x5b\x9f\xee\x35\x18\xf3\x81\x54\x05\xd1\x3a\x78\x5b\x04\xd5\x5d\xef\x67\xbe\x6f\x47\x78\x83\xb9\x6d\x2b\xa7\x5a\xa2\xb8\x95\x8d\xa1\x4e\x69\x9f\xda\x62\xd8\x8e\xce\xfe\x24\x69\x6c\x07\xfa\xda\x9e\xb6\x76\x30\x2e\x75\xa5\xa7\x6d\xad\x49\x85\x62\x13\xfe\xb9\x03\x3e\x9e\x8b\x4a\x45\xe1\x29\x13\xc6\x2a\x02\x90\x99\xba\x50\xac\x60\x22\x0d\xe1\x7e\xe0\xe0\x25\xea\xeb\x78\xd4\x1b\x23\x94\x32\xba\x1f\xaf\xdb\x55\x52\x4c\x7f\xb6\x7e\xe2\x67\xcb\xed\xfa\xe1\x0f\x96\x90\xe9\x56\xe7\xef\xc6\x3e\x46\x3d\x1a\x9e\xae\x2e\xfd\xb7\x9b\xa4\xd5\xde\xc2\x95\x53\x21\x53\xcc\x71\x6d\x2a\x27\x84\x11\xb9\x5d\xd1\x13\x7c\x0d\x5c\x8b\xe3\x63\x8d\x6e\x09\xba\x39\x50\x23\xba\x19\x3d\x13\x70\xd0\x8e\x28\x85\xac\xae\x54\x60\xf9\x3d\xa3\x5a\xf3\xa9\x18\x16\x32\x85\xbc\xdc\x67\xeb\x10\xa2\xc5\xa1\xea\xe6\xd9\xb4\x15\xaf\x82\x71\xa2\xdd\x36\x7d\x0c\xf6\xb7\x48\xb6\xf0\x19\xe1\x55\xf4\xa3\xb3\xeb\x78\x3f\xfa\x48\x86\xac\x24\xa2\xfd\x60\x9a\x53\x41\xa7\x6c\xe8\x3e\x3e\x0c\x1f\x1f\x86\x6f\xed\x03\xe6\x36\x54\x0b\x4d\x8a\xad\xcb\x42\x1c\xbf\x43\x93\x65\x1a\xca\x43\xa0\xff\xde\x67\x9e\x97\x39\xa1\xb9\x2c\xd1\x45\x6f\x19\x9c\xde\x91\xe5\x20\x00\x5b\x01\x28\xbd\x16\x52\x2d\xa1\x45\x76\x72\xb9\x7b\xa1\x96\xad\x56\x16\xad\x6e\x96\xac\x0e\x16\xac\x9d\x2d\x57\xde\x48\xdd\x1e\x1f\x3f\x7a\xbb\x79\x03\x23\xb9\xd8\x8a\x91\x2a\xe4\xbb\xbf\x9e\x90\x30\x0e\xd7\x44\xe6\xdc\x18\x67\xd0\xa5\xd5\xb1\x1f\x10\x6e\x6a\xd6\x4f\x77\x16\xa0\xde\x03\x96\xc8\x60\x9f\xad\x36\xc5\xc1\x8a\xee\x6f\x2d\x06\xc8\x65\x1f\x38\x66\x87\xa0\x82\xf0\xbc\x40\x67\x56\xc0\xe9\xa1\xd7\xcd\x9c\x93\x41\x7f\x3e\xfa\xf3\xb1\xaa\x93\xee\x22\x8b\xc4\x62\x48\xe5\xc1\x18\xc4\x11\x8b\xd9\xbe\xf0\x0c\x78\x68\x22\x0e\xd9\xb3\x00\x4e\xf4\x5c\x4c\xc9\x47\x06\x96\x81\x5b\x66\xb4\xf3\x89\x84\x1e\x54\xb1\xe5\x10\x33\x6f\x09\x09\xae\xb6\x74\x32\xa9\xb7\x48\x59\x91\xc9\x45\x0e\x92\xed\xb5\x89\xe5\x99\x20\xba\xb0\xbc\xc8\xa8\x61\x41\xb0\xd9\x6c\x6d\xd8\x9b\xf3\x75\x89\xef\x7a\xde\x88\xae\x76\xde\xc1\x2d\x7c\x82\x5f\x7e\x9c\x56\x6b\x8d\xac\xad\xdd\xbd\x8d\xcd\xbd\x65\xbc\x55\x7b\x25\xb0\x95\x51\xfe\xb1\xa3\xa8\x3a\xa9\x63\x6d\x23\xa5\x5e\x7e\x6c\x54\x87\x65\xb7\x8d\x7f\xea\x23\x9e\x36\x81\xba\x5d\xd4\x42\xeb\x88\x85\x56\xfb\xd7\x32\x72\xa9\x8f\x55\xea\xc0\x5f\x1e\x41\xf8\xdb\xba\x97\x46\x66\x0c\x25\xd7\x76\xba\xfb\x5d\xd5\x3e\xd4\x3f\xc3\xeb\xdd\x68\xa4\xa7\xb9\xa5\xb8\xf3\x62\x8b\x3d\x5b\xd5\xbc\x00\xb5\x8c\xa1\x50\xec\xcc\x48\x3f\x2f\xbb\x71\x62\x41\xec\x9e\x19\x57\xf9\x2e\x2a\x05\x67\x14\x5c\xfa\xfc\x21\x60\xdb\x80\x81\xfc\xf4\xc7\xc8\xbf\x3d\xc4\xbf\x04\x0c\xf9\x83\xff\xd7\x1f\xf7\x8c\x5b\x68\xc7\xd8\x70\x4a\x1d\x04\x8c\x2b\xe8\x40\xb8\x48\xe1\x82\xc9\x2d\x15\x20\x80\x63\x59\xf8\xc0\xb2\x7c\xfc\x0b\x06\x52\x39\x33\x17\xdc\x44\x55\x8d\xb5\xbb\x32\x8b\xf4\x2a\x67\x52\xa8\x4e\x06\x23\x1f\xa4\x4b\x4a\xc8\x06\xe4\x06\x6c\xa9\xd5\x1b\x38\x49\x1f\x24\xa6\x27\x5c\x7b\x97\x15\xc3\x6d\x2b\x17\xd9\xca\xe8\x6b\x00\xf9\xb6\x62\xf2\xb8\xb2\x1a\x93\xaf\x30\xb8\x16\x09\xb7\x09\x32\xf7\x6c\x51\x31\x1b\x27\x42\x00\xc9\x1f\x54\x58\xe2\x59\x01\xf2\x8e\xff\xf0\xa6\xac\x7c\xcc\x05\x7e\x0c\x87\xf6\x5b\x01\xa3\x7b\x80\x5a\xc9\x2e\xcb\xf0\x33\x87\x00\x57\x3b\x39\xa3\x06\xb3\xef\x3a\xc8\x18\x81\x4a\xae\x96\x2e\x22\x91\xe2\xea\xc7\x92\x66\xf5\x20\x04\xf7\xca\x35\x5a\xa2\xea\x0f\x3c\x4b\x13\xaa\x9c\x97\x17\x9c\x51\xa2\x25\xee\x1e\x66\xc5\x4b\xa8\x08\xa7\xbd\xda\x23\xac\x83\x48\x0a\xaa\x0c\x4f\xca\x8c\x2a\x62\xcf\xc2\x54\xaa\x56\x81\x02\x5b\x21\x5a\x21\xcd\x2d\x4b\xa4\x48\xbb\x28\x00\x77\xcd\xbe\xcd\xbb\xd6\x82\x29\xee\xd2\xfd\xf1\x9c\x35\x91\xf4\xa4\x6e\xd3\x96\x13\x7f\xaa\xc3\x11\xab\x59\x3e\xaa\x98\x4c\xae\x09\xc7\x7c\xa1\xa7\x11\x79\x0c\xa7\x62\x44\xbe\x5e\x78\x33\x0b\x98\x5c\x5c\x74\x85\x66\xc6\x07\xc2\x78\x94\x75\xc0\xae\x0e\xd4\x44\x2a\x08\x4e\x39\x49\x25\x46\x64\xcc\x79\x62\x4e\x47\xe4\xff\x63\x4a\x62\x04\x27\x9b\x62\xf6\x46\x87\xe2\x41\x71\x85\xc2\xa5\x70\x83\xff\x8a\x9c\x60\x26\x4d\x9e\xe7\x2c\xe5\xd4\xb0\x6c\x71\x8a\x7a\xac\xcf\xc5\xd9\x66\xeb\xda\x18\x0d\xa2\xc4\xab\xbf\xfd\xcd\x86\x96\x5d\x63\xa8\xbe\xf7\x51\x29\x15\x64\xd0\x87\xa0\xb1\x85\x81\x07\xc9\x0d\xe2\x66\xec\x83\x50\x05\x75\x7a\x32\x13\x36\xf8\x6f\x16\x0f\x28\x51\x6c\x0a\x58\x8e\x98\xbb\x27\x8e\xa3\x37\xe5\x7b\x59\x8a\xf5\x26\xc1\xda\xc2\xdf\x39\x25\xfc\xfb\xa8\xe3\xda\x28\xc5\x27\x11\x13\xa2\x99\x44\x26\x4a\x4a\xc0\x2e\x09\xec\xdc\x92\x07\x6c\x55\x79\xa2\x6c\x9d\xe4\x41\x23\x12\x61\x2e\x5b\xbc\xde\x0f\x12\xb7\x18\x3e\xd4\x01\x97\xc1\x41\xdc\x01\xa6\x11\xb7\x67\x1c\x39\x00\xfc\x44\x08\x56\x08\x0a\xdf\x62\xa9\xf7\x62\xc3\x58\x63\xe8\x4a\x8e\xdf\x1c\x1f\x84\xf8\xe2\x72\x94\x2c\xe8\x94\x6e\xcf\x77\x5c\x57\x46\x1a\x5d\x49\xca\x0c\x53\x39\x24\xa6\x9d\xc9\x07\xfc\x1d\xd9\x56\xe1\x5a\x31\x97\xd3\xd7\xae\x76\x26\x35\x70\xa5\x7a\x10\x23\x9c\x5f\xb8\x18\x7d\xa0\x0b\x42\x95\x2c\x45\xea\xa4\xa6\x40\x40\xdf\x37\x3e\xfc\x41\x0a\xa0\x14\xa5\xb6\xb0\xba\xab\x51\xe9\x31\x33\xd4\x1e\x9b\xd7\xa3\xd7\x5b\x72\x4f\xb7\x04\x58\xc7\xb8\x55\x98\x4d\xc3\x52\xe8\xef\xca\xfd\x99\x39\xc8\xbc\x14\xa3\xe9\x77\x22\xeb\x22\xcb\xbd\x47\xf4\x82\xae\x43\x50\xc2\xf8\x04\x6c\xb7\x03\x7c\xf5\xa0\xb8\x61\x11\x79\x3c\x99\xd0\x4c\x43\xc1\xed\x52\x04\x11\xf6\xb4\x2e\x82\x40\x93\x36\x0b\xda\xee\x0f\xa2\xcb\xf1\x9e\xe7\xcc\x1d\x28\x40\xb9\xea\x98\x05\x84\x3b\xd6\x1b\x8e\x5c\x3d\xb8\x93\x9c\x60\x4b\x2b\xb1\x49\x69\x36\x96\x77\x6f\xef\x24\x82\x0b\xb4\x9a\x75\x17\x95\xc4\xc7\x0d\x17\x07\x5c\xed\xd7\x6c\x46\xe7\x4c\x13\xcd\x73\x9e\x51\x95\x41\xac\xe0\x2d\xce\x0f\x8a\xb1\xaf\x8c\x40\xef\x16\xdd\x1c\xcf\x24\x1a\x6e\x2b\xa8\xfd\x3c\x2c\x9c\x80\x46\xf8\x79\x61\x12\x70\x9f\x39\xfc\x73\x92\x95\x9a\xcf\xf7\x3d\x4d\x2e\xfa\x61\x07\x56\xdd\xe4\xd2\x85\x4c\x6f\x0b\x96\x3c\x25\x8f\xae\x6b\x18\x96\x54\xa5\x7e\xd3\x81\x27\xa3\xb2\x4f\xb1\xb0\xfe\x98\x11\x9a\x24\x4c\x6b\xef\x53\xb9\x88\xfd\x3c\xc3\x1a\xbe\x94\x84\x02\xf4\x41\x5f\x65\x54\x1b\x9e\x7c\x9d\xc9\xe4\xfe\xd6\x48\xd5\x29\x66\x7f\x55\xff\x46\x1a\x86\xf3\x1f\x6e\xc9\x25\xd7\xf7\x51\x34\x81\xbb\x34\x8d\xcd\x25\x94\xdc\x97\x63\x96\x31\x73\x7c\xac\x91\xcb\xe5\x34\x99\x71\xc1\x3c\x83\x13\x21\x24\xc5\x29\x7c\x16\xca\x5d\xef\x4c\x5d\xe0\xd3\x99\xc3\xd7\x5f\xd0\x07\xcd\x70\xfa\x63\x3b\x7d\xfb\x33\x6b\x13\x91\x7e\xd0\x7b\x0a\x9c\xcc\xf5\xe5\x81\xee\x20\x26\xfa\xce\xce\xb1\x9b\x71\xfb\x18\x7b\x79\xd5\x61\xc2\x33\xe6\xaa\x0f\xd8\x05\x7b\x1f\x35\x77\x2a\x60\xff\x16\xb2\x24\x0f\x14\x75\x64\xa0\x88\x23\x72\xc7\x8b\x37\xe4\x4a\xe8\x52\xb1\xca\xba\xd1\x1c\x8a\xeb\x2a\xce\xcc\x2b\x57\xb0\xdf\xa8\x80\x58\xba\xe7\x74\x2d\x72\xf5\x99\xe6\x45\xc6\xf4\x1b\x72\xc4\x3e\x9b\xdf\x1c\x0d\xc8\xd1\xe7\x89\xb6\xff\x13\x66\xa2\x8f\x46\xe4\x3a\x0f\xb7\xee\x5c\x4c\x98\x52\xcc\x3b\x42\x61\x07\xcb\x9a\x23\xae\xfb\x28\xe8\xe2\x9c\xea\xac\xec\x96\x4a\xf2\x80\xf9\x28\x2c\xc1\x67\x4a\x49\x15\xfc\xd0\x23\x30\x00\xaf\x49\x64\x5e\x28\x99\xf3\xc8\xcc\x07\xe8\x7e\x50\x6f\x3b\x30\x3e\xb4\x29\xc8\xd1\xc4\x86\xd0\xd1\x23\x44\xf4\x42\xb4\x41\x85\xeb\x89\x77\xa6\x40\x2d\xd2\xa9\xf5\x30\x9c\x6b\x64\x37\xdf\x8d\x62\x09\x59\xbc\xdd\x6f\x43\x40\x1d\x39\x4b\xd9\xfc\x4c\xa7\xf4\xf5\x00\x3e\xa3\x9d\x23\x60\x7d\x4e\x54\x93\xa3\xd7\x47\x23\x72\xeb\x19\xf1\x20\x9e\x63\xd5\x6e\x22\x55\x18\x10\xec\xec\xaf\x8e\xc8\x89\x54\x30\x72\x42\x05\xc9\x18\x9d\x3b\xdb\x32\x1e\xb7\x05\xaa\xbb\xa7\xad\x03\x22\xdb\xc6\x86\xb5\xaf\xbc\xd2\x56\x48\x5d\xde\x44\xdf\xcf\x9b\x00\x54\xe9\x62\x05\x26\x52\xb9\x3c\x20\xa1\x89\x66\x06\x8e\x1e\x17\x35\x15\xfa\x19\x08\x2c\xe9\x18\x4a\xef\xa9\x67\x57\xe8\xf8\x7e\xa0\x03\x09\xfe\x63\xc9\xc8\xf5\x65\x08\xa8\x67\x4a\x73\x6d\xec\x31\x4e\x6b\xac\x8b\x23\x3f\x3b\x39\xcf\xe9\xdf\xa5\x20\x57\x5f\xdf\xba\x09\x9c\x3e\x2b\xa8\xb6\x52\x03\xfa\xf7\x52\x31\xcb\x85\x3b\x30\xf7\xd0\xa7\xc9\xd0\xed\x7b\x72\x49\x0d\x45\xbe\xee\x3c\xad\x44\x45\xca\x2d\xcb\x1e\x73\x91\xba\x9f\x22\x86\xfd\xd4\xbc\xd5\xee\xde\x87\x4d\x62\x52\xdc\xf0\xd3\xc7\xeb\x03\xf1\xe0\x04\x88\xf9\xf4\xbd\x4c\x3b\x33\xe2\xa8\xab\x27\xbe\x7f\xb2\x30\xbd\xc0\xf7\x24\xb7\x63\x12\xab\xbd\x0f\xc8\x47\x46\x53\x62\xcf\xaf\xfb\xe7\x0f\x56\xf7\x6c\x4d\xab\x5a\xb1\x10\x0f\xc0\x8e\xcb\xf0\xdd\xfc\x12\x62\x4f\xf7\xd4\x62\x0e\x1c\x2b\xc7\x4b\xc6\x99\x1c\x13\x77\x1c\x0e\x3d\xf7\x4f\x1f\xaf\x77\x98\xfa\xa7\x8f\xd7\x7e\xe6\xf6\x9f\x72\xf2\x74\x93\xde\x49\x7c\xab\xa4\xb7\xb7\x0d\x71\xab\x62\xc9\x55\xe0\x46\x53\x24\x6b\x2f\x8f\x8d\x0e\x25\x89\x1d\x12\x62\xf7\x5c\xb4\x88\xc2\xad\x9f\x32\xdb\xc7\x2a\x14\xe8\xab\x16\xdd\x23\xde\xce\x28\x84\x3e\x87\x80\x3c\xd8\x67\xbb\xf1\xda\x72\x05\xbf\xe3\x56\x09\x04\xda\x46\x2e\x19\xde\x72\xa6\x6f\xbc\xef\x40\xe8\xb1\xba\xc3\x7b\xf0\xd4\x4c\x1d\x7d\x25\xe8\xb8\x99\x46\x08\x76\x82\x56\x25\x11\x7e\xa2\x73\xca\x33\x3a\xe6\x19\x87\x54\xea\x56\xbb\x8f\xbd\x51\x35\x4c\xf9\xa0\xa7\x7e\x47\x91\x23\x88\x13\x4b\xc6\x2d\x72\x62\x7f\x3b\x03\xe3\xd8\xe9\x08\xa8\x15\x34\x84\x1c\x8d\x0d\xa1\xe4\xe3\x36\xa1\xe4\x60\xf2\x03\xec\x80\x3d\x31\x5d\xb9\xa2\xed\xb3\x92\x2b\xc2\x0f\xb7\x2e\x9f\xdc\x4b\x66\x8c\x18\x6b\xd5\x8a\x35\x02\x7e\x6d\x6d\xd9\x9e\x39\xee\x8b\x5c\xe9\x97\x81\x5c\x24\x44\xb4\xed\xc0\x3f\xab\x8e\x9e\x0f\x81\x92\x04\x1e\x67\x2e\xda\xad\xe6\x9a\x89\xd8\x77\xeb\x68\x8d\x4b\xc1\x84\x5c\xd7\xe2\x5c\x9b\xba\x68\x5d\x92\x36\x78\x8c\xe8\xba\x2a\xdf\xcf\x2f\x0a\x49\x20\xbc\x26\x2d\x70\xb1\xf5\x24\x13\x56\xcc\x26\x5d\xae\xc4\x6d\x87\xb7\xb7\x75\x4b\xe0\x05\x2b\x66\xe4\xed\xed\x8a\x63\x0c\xb0\x87\x59\x6b\xb4\x0f\x1e\x6b\x92\xf1\x09\x33\x7c\xcb\x12\x1e\xe1\x20\xe7\x52\x70\x23\xd5\xfa\x10\x68\xd2\xe9\x70\xfa\xe1\xba\x32\x54\xdf\xcf\xee\x6c\x95\x40\xe4\x7d\xf4\x96\x92\x44\x66\x19\x4b\x8c\x4b\x69\x05\xe0\x0d\xdd\x56\x28\x4f\xcc\xd9\x03\x46\xf7\xbf\x07\xf5\xc9\x29\x4a\x67\xb8\xb9\x67\x1f\xaf\xce\x2f\xdf\x5f\x8d\xf2\xf4\x17\x33\xf9\x30\x34\x72\x58\x6a\x36\xe4\x2d\x32\x94\x3c\x9f\xf7\x22\x3e\x45\xab\x84\x59\x4d\x83\x0c\xe6\xfa\xfa\xce\xc7\x4f\x92\x4f\x1a\xbd\x16\xc0\x76\xe4\xef\xa4\xa4\x34\x03\xa2\xa8\x8b\x91\xa4\xce\xf4\x54\x66\x19\x42\xdb\x28\xc6\x06\xb1\x2d\x66\x63\x68\x48\xe7\x85\xed\x6d\xa8\xa8\x2d\xf0\x71\x65\x88\xa7\x47\xb8\x2e\x1c\x63\xbb\x4c\xb2\x0c\xc5\xaa\x67\x1d\x8e\xb7\xb5\xf7\x68\x38\x33\x33\x0b\xd5\x7b\xb6\x20\xe0\x08\x3c\x91\xca\xe2\x93\xaa\xe3\x06\x33\x09\x2c\xfd\xac\xd4\x4c\x8d\x1c\xdb\x79\x72\xb0\x75\xc8\x22\xb4\x43\xf2\xb6\xd0\x71\x15\xcc\xdc\xeb\x2a\xb3\xaf\x93\xd7\x68\x69\x66\x4c\x18\x2b\xf6\x5b\x5a\xe6\x20\xb3\x12\x88\xce\x0f\xfb\xc9\xa1\xd6\x32\x89\x51\xb7\x94\x43\x7d\x9a\x9e\x2e\x38\x69\x4f\x4d\x57\x74\xb4\x7d\x20\x10\x31\x26\xf3\x21\x96\x4b\xd1\x54\x82\xc3\x06\x66\xa0\xab\x21\x1a\x4d\x73\x2e\x5e\xe0\xe9\x4c\xb8\x48\xb7\xc1\xa1\x61\x00\x83\x1e\x75\x51\xcc\xbd\x73\x06\xfd\x70\x6f\x48\xbd\x26\x85\x01\xef\xee\x06\xb1\x7e\x7f\xd8\xea\xf0\xe5\x0b\xfd\x63\x36\xc4\xaf\x0c\x8b\xb4\x82\x4a\x7f\x19\xb8\x7c\x83\x77\x58\x93\xd2\x13\x5c\xf1\x1d\x68\xb7\xc9\x13\x4b\x43\x8f\xab\xe7\x3e\x09\xa0\xba\xc8\x3c\xfb\x72\xef\x8a\x66\x42\xe1\x7d\xed\x83\xcf\x30\xb3\x19\x9c\x51\xaf\x2f\x43\x41\x7e\xaa\x68\xce\x0c\x53\xe8\x02\xe7\x9c\xea\x84\x8b\x4e\xf8\xae\x60\xe2\xd6\xd0\xe4\xfe\xd0\xa9\x50\x7b\x8e\xfb\x78\x1c\x77\xef\xab\x40\x8f\x08\x2e\x2f\xd2\x22\xbe\x45\xe6\xc2\x71\xa1\x17\x42\x62\x42\x3a\xb2\x2e\x56\x8e\x90\x8e\xaa\xce\x5d\xab\xf4\x64\x68\xd8\x00\x4f\xb7\x90\x5f\x0f\x3c\xf8\x11\x0a\x87\xe1\x86\xed\xcf\x80\x23\x81\xbb\xdc\xa3\x45\x5d\xeb\xd4\x21\xb7\x6f\xc6\xdc\x54\xe7\x5e\x33\x43\x0a\xa6\x72\xee\xc2\xba\xa5\x20\x89\x0b\x0b\x00\xbe\x66\x79\x98\x1b\x2e\xe2\x79\x82\xc8\xc4\x50\x17\x33\x43\xc6\xcc\x3c\x30\x26\xc8\xab\x57\xaf\x5e\x81\x5c\xf2\xea\x77\xbf\xfb\x1d\x81\x3c\x12\x29\x4b\x78\xbe\xdc\x10\x5a\xfd\xaf\xd7\xaf\x47\xe4\xbf\xce\xdf\xbf\x03\xaf\xb2\xc2\x68\x32\x96\x66\xe6\x46\xb6\x0d\x6a\x9d\xf5\x80\xfc\x9f\xdb\xef\x3e\x78\x71\x42\x37\x7e\x05\x15\x24\x2c\xaf\xee\x22\xf8\xea\xb7\xbf\xf9\xcd\x88\x5c\x72\x05\xf1\xc4\x1c\x22\x20\x82\x13\x64\xe1\x1d\x03\xa1\xf0\x50\x33\x82\xdf\x71\x10\xe7\x24\x9c\xf3\xe9\x0c\x00\x60\x0f\x84\x14\x93\x8c\x27\x06\x73\x0a\xe2\xd1\x47\x40\xbb\xba\x48\xd4\x85\x7b\x39\x29\x02\x26\x37\x20\x19\xbf\x67\x64\xa2\xbf\x51\xb2\x2c\xaa\x30\x47\xc5\xb4\x95\x65\x13\x2a\x20\xaa\x04\x06\xab\xf6\x4a\x33\xf3\xac\x4e\x18\x2d\x0d\x41\x35\x1c\x84\x3e\x0d\x01\x65\x10\x72\xab\x0d\x11\x1f\x0a\xca\x83\xe3\x20\xdc\xa9\xd7\x32\xfb\x07\xdd\x33\x8d\x72\xc9\xf9\xd8\x95\x42\xc9\xbf\xe1\x56\x71\xe1\xa3\xa0\x9c\x84\xac\x9d\x4c\xe6\x82\x4e\x45\x64\x73\xf5\x51\xf9\x96\x17\xba\x88\xff\x28\x7e\xea\x7a\x12\x07\xda\x41\x58\x3a\x96\x57\xab\x25\xbe\x5c\xf1\xe5\x2a\x59\xbb\xc5\x26\x8d\xfb\x5a\x8a\xa5\xde\xae\x8e\x8a\x23\x3f\xae\xba\x8e\x0b\x61\xab\xc6\x40\x57\x5c\x17\x00\x14\xd5\x6c\xaa\x25\xa3\xab\x79\xf9\x68\x66\x4a\x07\x1a\xf0\xbc\xb2\xdf\x66\x5a\xbb\x38\xa2\x9c\xaa\x7b\xab\x24\x38\x2a\x30\x02\xaf\x67\x1d\x62\x98\x30\xa0\x6c\x8e\xc6\xf2\x9c\x2e\x6a\x51\x03\xf6\x23\xc7\xa3\xd1\x31\x1e\x13\xa9\x30\x97\x27\xe2\xbc\x7d\xff\x4c\xf1\xd2\x75\xaf\x74\x5a\x60\xd9\x3d\xb0\xe7\xb8\xb2\x25\xb4\xe6\xed\x4c\x1d\xa4\xda\x64\xf0\xed\x58\xb6\xb0\x5b\x7d\xdc\xf6\x75\x71\x87\xb0\x80\x16\x4d\xbb\xd6\xc0\xed\x50\xfb\x76\x5d\xb6\x06\x07\x63\x77\x12\xda\x56\x84\xec\x9c\x0b\x3c\x6f\xc5\xfa\x56\x4c\xf5\x38\x77\x9c\xef\xbb\x6e\x9c\xcf\xc5\xeb\xd5\x8a\x83\xbd\x7c\x56\x77\x3d\xc1\x48\x97\x3a\xe9\x72\xa4\x21\x16\x05\x42\x21\xae\x2a\xec\xe5\x45\x73\xb4\x18\x6d\xba\x25\x9e\xef\xc2\xdd\xf0\x69\x77\x31\x81\x4f\x0d\xd7\xfc\xed\x04\x2e\xda\x91\xd2\xa2\x56\xe0\x23\x43\xbb\x01\xc8\x98\xfe\xf0\x8c\xc8\x7b\x47\x6a\x11\xc9\xe8\x58\xcb\xac\x34\xd8\xb5\xfa\x31\xa6\xc3\x30\xa8\xcf\xb2\x00\xc4\x37\x34\x8b\xa8\xb2\xa9\x4a\x9c\xb5\x23\xd0\xf8\x74\x38\x9c\x7d\xb6\xcf\x47\xcc\xf6\x19\xf2\xd3\xea\x96\xf5\x9a\xf4\xa3\xa5\xd7\x4d\x34\xef\xa2\x5f\x69\x4e\x4e\xaa\x32\x21\xfe\x3a\xfe\x5a\x18\xa6\x26\x34\x61\xa7\xb1\xde\x15\xca\xb1\x04\x17\x21\x1f\x17\x31\xa3\x22\xcd\x50\x00\x4f\x98\x02\xdc\x67\x9f\x0d\x53\x16\x24\x17\xb7\xd7\x24\x55\x7c\xce\x94\x26\x27\x5f\x33\x2b\x2f\x32\x6a\x4a\xc5\x5a\x45\x57\x1d\xd6\xb7\x12\xa6\x71\x28\x4d\x0f\x06\xeb\xea\xaa\x07\x9d\x3c\xe5\x11\xd1\xf9\xaa\xc0\x84\x50\x45\x90\xea\x58\x97\x1d\x59\x54\x02\x02\x0d\x34\x63\x21\x4b\xe5\xac\xe8\x3e\xaf\x6a\x22\x95\x55\x97\x70\x60\xaa\x89\x62\x53\x2b\xcd\x2a\x5f\x6c\x98\x91\x24\x2b\xed\x8b\x83\xba\xb3\xed\xe3\x00\x58\x99\x66\x37\xf9\xea\x4d\x9c\x54\x2d\xe7\x3c\xf5\xac\x12\x6b\x1f\x87\xaa\x86\x05\xd5\x51\xa8\x4d\x94\x81\x3e\x02\x2c\xca\xe8\xc0\x50\x43\x10\x6b\xcd\xd9\x3f\x36\x0a\x4b\xc8\x6d\xd1\xa2\x7c\x44\x17\x22\x2c\x53\x76\x53\x8e\x33\xae\x67\xb7\x3b\x9a\x10\x57\x0d\x81\xce\x0a\x4b\xb7\x7e\x6b\x2d\x89\x9a\x09\xcd\x81\xe5\x59\x32\x6e\x99\x2e\xb7\x72\x94\x04\x20\xfa\xde\x31\x42\x4a\x88\xfe\xc8\x98\xcb\x60\x60\x7f\xfa\x50\xcd\xc3\x05\xa5\x61\xce\x92\x94\x7d\x12\x45\xed\x7d\x42\xb3\x4c\x37\x03\x76\x3d\xc5\x44\xd9\xc3\x07\xaa\xe1\x9e\x72\xbb\xdd\xa1\x32\x4a\x23\xfb\xe5\xda\x85\x69\x92\x4b\x0c\xe3\x11\x44\x0a\xdf\x08\x52\xaf\xf8\x0e\x51\x20\x23\x84\x2b\x03\xca\x1c\xb8\x74\x64\x6f\x2e\x7d\x3c\x73\xe9\xbe\x7e\x78\x71\xbd\xf7\x2a\x1a\xba\x96\x96\x34\x90\x52\x4f\x72\xb7\x38\x75\x1c\xf4\x5a\x01\xbf\x79\x6e\x8c\xe2\xe3\xd2\x74\xcf\xf7\xd6\xe8\x0e\x6c\xda\x2a\x22\x70\x8a\x87\x6e\xf5\x49\x84\xa2\x4e\x43\x08\x67\x61\xf9\xec\x57\x3c\x07\xd8\x0d\xbe\x3c\xd6\x24\x95\x49\x19\xf2\xc2\x02\xd0\xaa\x0b\xb4\x36\xd9\x13\x49\xd7\x73\xd5\x3d\xa5\x57\xfc\x91\xad\xe8\x95\xca\x07\xf1\x40\x55\x7a\x7e\xb3\xc5\xfb\xbe\xce\xce\xab\x5e\xb1\xa0\xe4\x5f\x43\x15\x40\x3a\x96\xa5\xa9\x52\x87\xfe\x74\xec\xd5\xab\xd4\x74\x23\x2d\x69\x68\x69\x8f\xee\xaa\xe8\xf7\x26\xee\xde\xc4\x5d\x7b\x76\x31\x71\x5f\xa3\x89\x3b\xce\x83\x5b\x3b\xae\x3e\xbd\x02\xcf\xda\xfa\xf6\x3e\xa6\x95\xf4\xb2\x22\x30\x28\x4d\x35\xfd\xf8\x1b\x02\x1c\x1e\x91\x6a\x6f\x23\xa1\xcf\x53\x20\xe0\xd9\xcf\x6f\x51\x7d\x24\x3b\x69\xfb\x3a\xc5\xf8\xac\x2b\x24\xb8\xa9\x6e\x31\x48\x0d\x51\xa1\xe1\x81\xcb\x02\x3d\x70\x7a\x97\x48\xab\x12\x7e\x98\x84\xba\x43\x99\x52\x7c\x3a\x02\x9f\x74\xde\x00\xd2\xb1\x88\x30\x3e\x5d\x77\x83\xec\x50\x50\x18\x9f\x67\x2e\x2b\x8c\x4f\x67\xdb\x37\xe9\x5e\x62\x78\xc5\x72\x1f\xb7\xd0\xf0\x8e\x4b\xdb\xdd\xac\xbf\xab\x39\x7f\x50\x95\xb7\x7b\xf9\x6c\xbd\x37\xe7\x2f\x3d\x4f\x68\xce\x8f\x08\xb7\x27\x06\x2b\x4c\xfb\xb1\xb9\xcd\xdb\xf7\xc7\xcc\x8b\x95\xa3\x2a\xfb\x9a\x45\x39\x6f\xd9\x97\xaa\x7e\xad\x7a\x3c\x1a\x1d\x1f\x7b\x7b\xbf\xc3\xcf\xd2\x4c\x86\xbf\x27\x4c\x24\x32\xc5\x4d\xb5\xe3\x2b\x6d\x80\xe9\x57\x6a\x7a\x3c\x97\xdc\x7f\x2b\xbe\x9a\x85\xb1\xbb\x6d\x49\x87\x13\xdc\xbd\x6c\xf8\x2a\x48\x3f\x45\xf1\xf0\xb8\x44\x78\xbd\x22\x38\xb6\xd8\xa7\x0c\x78\x0c\xbc\x47\xe7\xaf\xad\x0b\x83\xe3\xb3\x0b\x7b\xdd\xa1\x48\x38\x3e\x4f\x5c\x2a\x1c\x9f\x9d\x38\x6a\xa7\xb2\xe1\x2b\x16\xf7\x74\xc5\xc3\xf1\x79\xa1\x85\x64\xea\x4f\xa7\x42\xe2\xf8\xec\x56\x4e\xbc\xde\xb7\xe3\xd6\x1f\xa4\xb4\x38\x3e\xdd\x0a\x8c\xe3\x73\xe8\x32\xe3\xf8\xb4\x84\x04\x18\xc3\x2f\x79\xa7\x50\x04\xdf\xa7\xee\x2e\x69\x58\x5e\x48\x45\xd5\x82\xa4\xce\xd6\xb0\x58\x11\x11\x1a\x85\x84\xee\x9d\x1a\x06\xe6\x91\x72\x75\xa0\x68\x84\x0e\xd1\xa0\x2c\xe5\xe5\xda\x72\xcd\xeb\xc0\x86\xbd\x62\xa0\x3d\x40\x36\x30\x97\x49\xcc\x5f\x77\xba\x66\x3e\xb1\x22\x4d\xee\x5d\xc5\x20\x0f\x55\xe4\xfd\x51\x90\xcb\xd1\x51\x23\x0f\x34\x98\xc7\xe0\xee\xcf\x55\x46\xf4\x8d\x71\xec\x9a\x29\x0b\x6f\x43\x9c\x5b\xc0\x89\x6b\x78\x6a\x25\x92\xf7\xc0\x06\x9f\x68\x97\x48\xc7\xc8\x36\xfe\x77\x06\xe5\xc6\x3a\xfb\xc6\xfb\x8e\x21\x1d\xb4\x04\xc9\x3c\xd4\x45\xcb\x64\x12\xdd\x3d\xd7\x38\x14\x6c\xc3\x95\x47\x7e\x6f\xbb\xb7\x9b\x61\x47\x45\xf9\x02\x8c\x3e\x99\xc6\x7b\x3d\x9e\x40\x6a\x4b\x90\xe2\x01\x98\x61\x03\xee\xa2\x2a\x81\xa5\xb6\x5f\x82\xcc\xf3\x51\x9b\xea\x43\x0f\x3e\xc3\xa6\x89\x0a\xb9\xd5\x75\x0f\xfb\xcb\x6d\x58\x59\xa5\xb7\x41\x08\x84\x17\xd4\x75\x09\x62\xa2\xfb\x8a\x13\x97\xe4\x04\xee\xae\xaa\xb2\x68\x21\xb9\xe3\x12\x9a\x09\x9e\xd5\xf1\xcc\xe7\xb2\x0b\x0b\x2f\x85\x73\x34\x58\x42\x9a\xd5\x38\x53\x6a\xa6\x86\xd3\x92\xa7\xbb\x60\xcb\x0b\x66\x80\xad\xd9\x5e\x77\x66\xd7\x91\xc5\xed\xc1\xd8\x82\x23\x46\x07\xd6\x70\x54\x79\x6f\xd4\x78\x43\x9c\x16\xaf\xee\xc9\x41\xbd\xb3\x40\x38\x72\xfe\x4a\xe8\x2e\xa8\xb6\x8e\x67\x24\x8b\xc4\x05\xeb\xf2\x5a\xba\x4b\x1c\x16\x31\x0f\x1c\x5b\x87\xf6\x3f\x5e\x05\xf6\xf6\xfc\x31\x9b\xc8\xaa\x42\x0a\x6a\x44\xce\x1d\x37\x65\x19\x83\x32\xf2\xbe\x44\xbd\x6d\x00\x57\xc2\xb9\x9c\x5b\x64\xfe\x6f\x41\x3e\xf9\x9c\xfd\x7c\xf2\x86\xd0\xd3\x5a\x08\x84\xab\x3a\x23\x18\x4b\xd1\x47\x37\xab\xbe\xa3\x4a\xa1\x07\x64\x7c\xea\xfd\x51\xe0\xc4\x09\x2b\x16\x66\x5e\xe2\x45\xbd\x5a\x31\x0b\x00\x08\x3b\x56\x32\x27\x5a\xd0\x42\xcf\xa4\x01\xd5\x90\x16\x34\xe1\x66\x41\x8c\xa2\xc9\x3d\x94\x28\x52\xcc\x7d\x6e\x40\x92\x53\xe7\xd8\x15\x83\xaf\xee\x36\x6c\x66\x4a\x96\xd3\x19\x78\xc2\x62\xab\x24\xa3\xda\xaf\x7e\x65\x7f\xa7\xed\x68\x92\x2e\x04\xcd\x79\x12\xb2\x06\x2a\x39\xe7\x9a\x4b\x67\xed\xf5\xe3\xde\x84\xcc\x70\x68\x41\xbe\xc8\x28\xcf\xc9\x89\x66\x8c\x5c\x79\x94\xc0\x5f\x5c\x19\x7b\xb4\x6c\xa8\xba\x73\x80\x0c\x29\xcd\x85\x4b\x88\x50\x11\xb8\x70\x79\x85\x0c\xd3\xce\x7c\xe5\x47\x4f\xc3\x76\xad\x9e\x93\x54\x70\x71\xef\x53\x77\x32\x91\xca\xe8\xd6\xf2\xfc\xe6\x5a\xc7\xda\x08\xe2\x96\xcb\x7b\x07\x3f\x64\x52\x4c\xe3\x34\x02\x15\x66\x5a\x52\x2a\xa0\xbc\xcb\x9c\xa7\x25\xcd\x90\x88\xba\xc9\x5c\xdc\x5e\x63\x77\x3e\x9d\x99\xe1\x03\x03\x6b\x0c\xf2\x9a\xea\xcc\xf8\x8f\xf2\x25\x6f\x1d\xae\x81\xe8\x1a\x67\x4d\x40\xcb\x96\x9d\xda\x03\x5d\x40\xda\x1a\xe7\x62\x52\xbb\x30\xf5\x89\xc5\x70\x88\x55\x10\x87\xe9\x9d\x87\x72\x1d\x56\x6c\x00\x73\x95\x05\x31\x60\xea\xf2\xdc\x2c\xe0\xa3\x3c\x80\xe1\xb5\xab\xcc\x46\xed\x06\x59\xe1\x6e\xb3\x2e\xf3\x08\x42\xd9\xbc\xda\xe4\x3b\x57\x3a\xb1\xa3\x70\x70\xf4\x43\x64\x36\x8b\x2e\x3a\xec\xb1\xa1\x22\x1d\xd2\xcc\x62\xce\xcd\xf7\x17\xce\xc3\x19\x0f\x42\xed\x22\xdf\x57\x41\xe2\x22\xa4\xcd\xb6\x32\xc3\xca\x23\x00\x71\xf0\x63\x96\x02\xd1\x88\x0b\x46\x3e\x58\x0d\xd9\x6d\xde\xcd\xf7\x17\x03\xc2\x47\x6c\xe4\xff\x0a\x4d\x3d\xd5\x32\x72\x8a\x6e\x80\xc1\xc7\x13\xf0\x0e\xa6\x12\x1b\xa3\xe2\xbe\x7f\xfd\x83\x9d\xa4\xfd\xf5\x8f\xc3\x3f\x44\xd9\x46\xff\xf8\x57\x4b\x04\x95\x6d\x50\x7f\x1b\xfb\x92\x85\xac\xfb\x7f\xbd\x71\x59\xa9\x5d\xce\xea\xbf\xba\x62\x5c\x4c\x18\x2b\x37\xde\x48\xb8\xa5\xe7\x29\x62\x23\x7c\x5b\xb1\xbf\x79\xc3\x22\x80\x29\x18\x75\x12\x6a\x98\x00\x42\xed\x83\x32\x84\x34\xd8\xdd\xd5\x9d\xb5\xf3\x3f\x01\x93\x00\x06\x95\x0d\x88\x91\x12\x8e\x23\x1e\xf9\x73\x41\x98\xaf\xd5\x89\x6b\x05\x70\x50\xe7\xa8\xe6\x79\x8f\x1d\xd6\x42\x38\x84\xe0\xda\x79\xc0\xdc\x7e\x25\xa4\xf9\x55\xd8\xfe\x46\x15\x71\x3a\x97\xdc\x27\x20\xb7\x27\x45\x60\x45\xc7\x90\x12\x7b\xbc\x20\x39\xd7\x86\xde\xb3\x11\xb9\xb5\xbc\x25\xbe\x0d\x43\xe8\x09\x02\x19\x2c\x59\x4a\x4a\x61\x78\x06\xbf\x56\xe3\xd8\x29\xc7\x3c\xe7\x7a\x42\x74\x09\xe5\xcd\x0b\xc5\x86\x9e\x8b\xb9\x56\x4b\xb4\xa0\x5a\xcb\x20\x6c\xf6\x8c\xa2\x2e\x50\xa4\xd0\x15\xe0\x41\x85\x43\xaf\x25\x3f\x2e\x3b\x4f\x29\x92\x8a\x73\x01\x30\xf5\x88\x7c\x00\x66\x95\xf9\x2b\x61\x54\x4b\x9c\x01\x53\xb0\x84\x69\x4d\xd5\x62\x00\x89\xdd\x79\x48\x06\xee\x5c\x77\x80\xa3\xe6\x54\x60\x5a\x75\xc5\x12\x29\xb4\x51\x65\x62\xb0\xce\xde\x58\xc9\x7b\x26\x82\xbb\xa0\xdd\xc5\xba\x03\x57\xe5\x3f\x03\xf7\x5d\x92\x24\x33\x2a\xa6\x51\x9d\x9a\x9c\xa6\x00\xfb\x6f\x83\x94\xe3\xd7\x63\x21\x40\x27\x56\xb0\xe0\x06\x40\x31\xb6\x7c\x24\x98\x61\xff\x5b\x84\x7c\x3c\x83\xca\x4e\x6a\x97\xc4\xb3\x2d\xb4\xab\x13\xfd\x22\x1d\x8d\x7a\x43\x60\xdb\x07\x76\x00\xcb\x99\xa1\x29\x35\x74\x07\x27\xb0\xf7\x55\x71\x3d\x5f\x5f\x1f\x0b\x9c\x86\x8b\x49\xc7\x87\xbc\xb8\x25\x0b\x1e\xc7\x3f\xc1\x49\x9c\x79\xc8\x43\xc4\xb5\xb1\x38\xe5\x2e\x0a\xd0\xb7\x0b\xe4\x19\x5f\xbd\xcc\x0e\xef\x47\x43\x72\x51\x95\x66\xac\xc8\x49\xbb\x6b\xa8\x8e\x16\x58\x0b\xfa\x1d\x60\x74\x57\xdd\x95\x25\x75\xff\xae\x95\x22\x08\x72\x09\x26\x0c\x57\x2c\x0e\x37\x73\xa0\x2b\x05\x22\x79\x03\x88\x00\xe5\x29\x33\xba\xf2\x50\x41\x3a\x6c\x89\x8b\xe3\x77\x4e\x19\x05\x22\xed\x00\xeb\xf4\xb9\xd5\xb2\x10\x82\x5d\x4b\x47\x67\x2d\xe5\x7f\x14\xb8\xee\x62\x74\xc6\x72\x02\xef\x65\xda\xc5\x4e\xdd\xc8\xc2\x5f\x0d\x51\xf9\x6f\xa2\x27\xae\x06\xa5\x1e\x1b\xc0\x6d\x95\xae\x05\xcd\x21\x91\x9b\xd1\xf9\xee\x46\xaa\x4a\x46\x1a\x86\x54\xc6\xf0\xb9\x21\x7c\x6e\xf8\xba\xbd\x31\xaf\x8b\x07\x88\x7f\x5a\x7b\x82\xd4\x3f\xd2\xc9\x72\x6a\x49\xca\x6d\x47\x73\x67\x23\x1a\x39\x8c\xe0\x68\xbe\xbb\x45\x0c\x37\xb7\x2e\xd2\x81\x71\x4b\x2d\xde\x90\x5f\xd5\xb8\xbc\x93\xa6\x82\xa6\x84\x9e\xba\x27\x5e\x75\x1a\xb9\xad\xf0\xc1\xe7\xf5\xe6\xa7\x8d\xc1\x40\xbc\x58\xad\x51\x78\x8f\xe0\x20\xf2\x59\xf1\x4c\x81\xf1\xcc\xc7\x1f\x58\xf4\x52\x32\xcb\x98\x82\x25\x38\xed\xa9\x71\x8b\x0e\xb9\x4c\xd1\xa6\x3b\x08\x2a\x6a\x90\x31\x05\x7b\x08\xc2\x04\xd5\x98\xba\xc5\xdf\x78\x31\x57\x38\x6f\xed\x78\xc1\x6b\xf9\x5c\x2c\x70\xea\x97\x11\x68\x51\xf5\x24\x53\xfb\x21\x2b\x75\x0a\x3a\xce\xf0\xf6\x38\x30\x5b\x98\x0b\xcd\x1e\xe8\x42\x03\xde\x57\xd2\x7c\xf8\xbe\xcb\xaa\x56\x0d\xfc\x91\x4d\xb0\x77\xeb\x1b\xb1\x9d\xee\xc4\x76\xb9\x15\x83\x70\x4a\x2e\xda\xb8\x20\x55\x1d\x36\x16\x0e\x69\x3e\xbb\x5c\xa3\x81\x9f\x0a\x5c\x9f\x77\xbb\x13\xa9\xd7\x29\xbf\xb9\x86\x21\xbc\x4c\x3e\x85\x3f\x3c\xc7\x09\x97\x06\x63\x66\xb1\xba\x0a\x94\x06\x0c\x89\xfb\xae\xf0\x24\xa8\x50\xeb\x5b\xc8\xc6\xea\xac\xc4\xa1\xd2\x98\x62\xe0\x09\x02\x5f\x1c\x41\x39\x02\x2a\x16\x8e\x93\x9b\x19\x57\xe9\xb0\xa0\xca\x2c\x50\x7d\x1c\xd4\xbe\x16\xdc\xeb\x3b\x2d\x7c\xc7\xeb\x9c\x76\xa9\x8f\xd7\x42\x18\x16\xef\xcd\xc3\xce\x3a\xbf\x16\xae\x4f\xb1\x9e\xf6\x0e\xfc\x2b\xd7\x13\xa7\x16\xf5\x1a\xe1\xb3\xad\x27\x8d\xc9\xc7\xfe\x7c\xc3\xd2\x20\x5d\xbf\x7a\x45\x36\x10\x97\xae\x92\xb1\x17\x74\xe0\xf2\xa0\x10\xd9\x91\x06\x56\x0f\xa5\x55\xad\xf1\xc8\xb0\xe7\x24\x05\xef\x43\xe3\x2a\x1d\x89\x85\x33\xdd\xc4\xdf\x8a\x07\x08\xa7\x84\x9c\x08\x29\xf0\xe4\x60\xdb\x53\x74\x21\x5a\x63\x9b\x82\x26\xae\x44\x5d\xbd\x42\x68\x74\x52\x3d\x93\xe0\x22\xb5\x5b\x07\x94\x1b\x74\x24\x5d\x26\x09\x63\x41\xab\x8e\x4b\xd4\x54\x27\xdb\x4d\xd9\x97\xba\xd4\x12\x92\xb8\x68\x43\xb3\xac\xd2\x66\x1d\xb8\x24\xf0\x39\x6f\x01\x8c\xd8\x5f\x2d\xd0\xc6\x29\xf6\x50\x44\x1d\xdd\x5e\x4a\x91\xe0\x15\x3e\x37\x0b\x3f\x83\xcb\x26\xab\x07\x35\x42\xa3\x92\xcb\x27\x68\x77\x8a\xd4\x81\x00\x4c\x20\x4d\xae\x84\x7b\x9d\x33\xb9\xdc\x0c\x96\x0e\x8d\x69\x72\xff\x40\x55\x0a\xa5\x7c\x0b\x6a\x38\xa6\x05\x1f\xd4\x86\x3d\x89\xe6\x00\x85\xf4\x63\x2c\x3a\x0d\x4a\x87\x66\x21\x05\x75\xf5\x19\x42\x4b\x23\x73\x6a\x78\x02\xaa\x2c\x9f\x44\x56\xc4\x3c\xa4\x34\x6c\x94\x1d\x04\x2a\x1b\x0a\xd8\xdf\xe1\x6d\x8c\x62\xc4\x3c\x48\xc2\x73\x2b\x21\x50\x28\xa5\x31\x09\x11\x43\xde\xde\xb9\x69\xa6\x56\x0c\xfa\x01\x8c\xcc\x51\x2b\x54\x92\xad\x0a\xa5\x61\xf8\x60\xd1\x0c\xa6\x3c\x17\x72\x33\x68\x30\x70\xd7\xc7\xe2\xb4\x9d\x6b\x84\xaa\x03\xbb\x3d\x0f\xcc\xca\x05\x7a\x23\xc2\xea\xd1\xaa\x19\x61\x4d\x5b\x4d\x52\xae\x1b\x85\xa9\x4f\x52\x25\x8b\xc2\x19\x48\xf2\xd3\xe6\x8c\xe0\xde\x40\xcd\x99\x8e\x6a\x2f\xa3\xa9\x7a\xca\x44\x28\x1e\xee\xd2\x59\xc0\xc9\x6d\x7e\xa2\x76\x60\x46\x18\x10\x7a\x4a\x3e\xb9\xa2\x42\x01\x71\x83\xd7\x5d\x2b\xc1\x09\xad\x2d\x4e\x76\xea\x25\x9e\xb6\x4f\x2f\xf1\xf4\x12\xcf\xcf\x5b\xe2\x09\xee\x5e\xbb\x4a\x3b\x95\x8f\x63\xa3\x20\xb9\x77\x06\xa8\x1a\xac\x33\x62\x5c\x4f\xc8\x47\x96\xc8\x39\x53\x48\xe4\xa0\xf0\xa7\xe5\xe5\x6f\x29\xcf\x2c\x89\xf3\xa4\xae\x52\x0f\x21\xa3\x6a\xdd\x34\x17\x69\xe4\x01\x9a\x0e\xcd\x73\x37\x29\x17\xe9\x67\xdb\xbb\x4b\xb2\x42\xb1\x39\x97\xa5\xf6\x2e\x0b\xa5\xc1\x63\xa6\x8d\xe3\xb7\x33\x3e\x0d\x89\xb9\xc3\x55\xa7\x62\x89\x54\x69\x15\x52\xae\x0d\x35\xa5\xae\xc7\x49\x24\x68\x4d\x3b\x9c\x81\x26\xc0\xf1\x91\xa9\xfb\x6e\x94\x14\x3d\x36\xf6\x38\x15\xc7\xef\xd0\xe7\xa3\xaa\xbb\x6d\x22\x37\x94\xca\x05\xc6\x8a\x50\xa5\x61\x11\x5a\x39\x04\xe8\x0c\xeb\x5a\xd4\xeb\x19\x16\x6e\x19\x86\x61\x87\x95\xd7\x49\x8b\x8c\xeb\xf1\xb3\x13\xd4\xc9\x1e\x01\x9e\xf1\xf3\x82\x1d\x4f\x1a\x8b\xed\xee\x7d\x49\xf6\xf4\xc0\x24\xfb\x78\x61\x92\x43\x7a\x62\x92\xe0\xcf\xbd\xcf\x89\xf9\xe8\x3d\xc9\x1b\x67\xc6\x11\xde\x4d\x67\xa6\x96\x50\x20\x8c\xc3\xb5\xaf\x00\xe9\xae\x35\xc3\x19\x00\x93\x60\xec\x0f\xec\x4e\x2b\x68\x73\x78\x77\xc9\x3e\x87\xac\xbf\x91\x1c\x53\x15\xd5\x36\x12\x3c\x10\xf2\x02\x33\x01\xc1\xa9\x1b\x3a\x97\x2c\xaf\x2d\xf5\x27\xb8\x3f\xc1\x6d\xfb\x3f\xe7\x09\x46\x8f\xe7\x2e\x0e\xf9\x8d\x4a\x41\xd8\xdd\x05\xe1\xd2\x31\xcb\xc8\x8f\x25\x53\x0b\x62\x85\xa0\xca\xbd\x07\xd2\x1b\x6b\x9e\x3a\x07\x19\x67\x54\x69\x2f\xb3\x3f\x21\xff\x07\x93\xcd\xd5\x67\x2b\x01\x42\x1c\xdb\x1e\x74\xad\x39\x54\x3d\x54\x19\xa1\x15\x20\x18\x4b\x78\x78\xc3\x58\x93\xf9\xac\xb8\x77\xfe\xe1\x72\x37\x45\xa7\xdb\xa5\x16\xd9\xe5\x62\x6b\x69\xf1\xe7\x1b\x16\x88\x80\x08\xbf\xd4\xab\x49\x05\x53\x04\xb9\x67\x8b\x81\xbb\x07\x77\xd9\xdb\x7d\x63\x74\xe7\xa8\xa7\x14\x6d\x9b\xaa\x62\x15\x80\x76\xa0\x90\xbb\x59\x0f\xf0\x69\x9f\x84\xb2\xde\xcb\x03\xa1\x2b\x21\xde\x99\x84\x77\x4a\x56\x19\x3f\xeb\x12\x57\x22\x4e\x40\x06\x3e\xef\xd7\x1c\xd0\x00\x7c\xb9\x81\x5a\x74\xdd\x44\xb2\xbb\x0a\x8c\x8f\x07\xec\xde\x4b\x0d\x68\x5a\x73\xcc\xbd\x67\x8b\x63\xed\xa2\x06\xa5\xd0\x33\x5e\xf8\xfc\xf0\x40\x09\x1c\xe6\x92\xef\xc1\x3f\xc0\x0f\x81\x67\xfe\x5a\x0c\xc8\x07\x69\xec\xff\xae\xc0\x55\x08\x2d\x95\x92\xe9\x0f\xd2\xc0\x9b\x27\x07\x16\x4e\x77\x6f\x50\x39\x33\x25\x07\x33\x23\xba\xb4\x41\x7c\x86\x77\x41\x01\x90\xb8\xfb\xd6\x00\x56\xae\xc9\xb5\x20\x52\x79\x98\x18\x9f\x3c\x58\xbb\x21\xbc\x6d\x29\xb2\x08\xaf\x18\xc3\x81\x52\xaa\x1a\x24\x37\x0c\x17\x8c\xcb\xdc\xff\x02\xb6\x27\xb0\xc6\x07\xbf\x19\x48\x81\x4b\x0d\x9b\xf2\x84\xe4\x4c\x4d\x21\x3e\x34\x99\xed\xbe\x41\xdd\xe9\x36\x3e\x3b\x51\xef\xf8\xc3\x9d\x31\x03\x58\xdd\x3b\xf0\x5c\xda\x97\x61\xe2\x28\xc8\x22\x72\x5a\x58\xa4\xf8\x87\xe5\x04\xb0\x2f\xff\x82\x94\xd5\x7a\x44\xce\x7d\xc1\xd3\xf8\x37\x67\xc5\x88\x87\xb1\x23\x58\x99\xfe\xc7\x92\xcf\x69\xc6\xd0\x9f\x8f\x8a\x90\xc6\x53\x4e\x96\xd8\xf4\xc0\xe5\xad\xb6\x54\x2a\xdc\x0c\x1d\xdd\xb3\xc5\xd1\x60\x09\x91\x8e\xae\xc5\x51\x15\xa4\x5d\x43\x9d\xc0\xd0\xe0\xd2\xe0\x08\x7e\x3b\x3a\x34\x67\x7f\x26\xd1\x7e\x07\x2c\x71\x06\xa1\x8b\x8c\x6a\xdd\x2d\xbe\xb5\x11\x5a\xd4\x18\x67\x55\x02\xc6\xdb\xa8\x4d\x15\x5c\xe4\xbc\x37\x0f\x6e\xcf\x02\x2f\xff\xee\x9e\x46\x9d\xa0\x37\x77\xd5\x53\xda\x27\x6e\x58\x99\x50\x0c\xd2\x16\xf8\x18\x8e\x5a\x5c\x5c\x75\x19\xbb\x06\x5e\xdf\x83\x5d\x51\x4e\xe2\x22\xcf\x5c\x83\x1a\xcc\x7d\x54\x87\x90\x86\x70\x91\x64\xa5\x33\x29\x42\x57\x50\xa2\xbb\x8a\xfa\x3b\x00\x67\x0f\xa4\xaa\x06\xf0\xd8\xe4\xaf\x7d\x97\x1c\x78\x9b\x37\x74\x70\x27\x1a\x6e\xbc\x10\x56\x87\x5e\xeb\x64\x8b\xbb\x64\x3d\x19\x67\x52\x97\x3d\xde\xf2\xb1\x62\xe4\x62\x46\x85\x60\x59\x14\xed\xea\x8c\x1d\xa1\x9c\x15\x08\x24\xae\x88\xd5\x71\xbd\x8a\x95\xa7\x6f\x22\xc4\x56\x1f\xbc\x76\xf0\x4f\xa9\xa8\xd4\xc1\xea\x94\xbb\x54\x8d\x33\xf9\x40\x52\x49\x1e\xa0\x6e\xc1\xdc\x32\x2d\xb8\x94\xd5\x9e\xdd\x45\x33\x05\x17\x89\x44\xe6\x85\x92\x39\xd7\xde\x39\xde\x6d\xe3\x41\x43\x43\xb3\xb2\x45\x0e\xa0\xfa\x1e\x64\xa5\xa8\xa7\x84\x7f\x7b\x41\x0c\x55\x53\x66\xec\x68\x44\x94\xf9\x98\xb5\x8e\x5f\x7d\x8c\x1c\x64\x5f\x52\x09\xd1\xc3\x16\xc1\xc2\x6d\xf8\xe1\x87\x0f\x9d\x4b\xef\x56\x3d\xd7\xed\xed\x83\x54\x59\xfa\xc0\x53\x64\xd1\x9a\x9c\xd8\xc6\xa7\x2f\xbf\x52\xee\xc3\x03\x4f\x3b\x83\x03\x3a\xd5\xc1\xe0\xfd\xa0\x2c\x18\x08\xc0\xc1\x55\x78\xe2\x90\x46\x1b\x7a\x9c\x92\x2b\x8e\xd1\x45\xd0\x1f\x12\xd5\xe4\x63\x2e\xaa\x08\xb3\x0a\xcc\x96\x18\xdb\xf3\xe2\x55\x13\xcd\x0c\xc6\x85\x40\x68\x85\x34\x33\xa2\x79\x5e\x66\x86\x0a\x26\x4b\x9d\x2d\x5a\xa3\xca\xf3\x80\x7a\x92\xb1\xcf\x88\xd9\x5d\x98\x5c\xe8\x54\x67\x76\xe0\xba\x52\x85\x51\x2e\x71\xbb\xca\xb9\x2a\x3d\x0b\x9c\x2f\x84\x1b\xb1\xcf\x2c\x71\x5e\xc1\x45\x56\x4e\xf9\x96\xf0\x87\x9f\x59\x56\xf3\x2a\x81\x74\xa9\x59\x15\xa9\xdf\xb6\xae\xcb\x13\x25\x21\x7f\x5e\x0e\x7f\xb7\x3a\x01\x79\xca\x0a\x26\x52\x48\x89\xf6\xb6\xc2\x5c\x9c\xfc\x41\x21\xe7\xd2\x8b\x75\xa5\x5a\x3e\x2b\x59\x8d\x82\x47\x2e\x5c\x33\x99\xa5\x9a\xb0\xcf\x46\x51\x4b\x98\x72\x4b\x82\x42\x9f\x09\xa1\xa2\x3d\x91\x79\x19\x29\x82\xc9\xc1\xb9\xfd\xe3\xd6\xcb\x7c\x89\x25\x2f\xab\xb5\xeb\x8d\x05\xab\xf7\x4b\x5d\x8f\x84\xd8\x9d\x15\x5d\xf7\x10\x5e\x91\x62\xde\x7d\xa5\xee\x99\xb8\x5f\xaa\x79\xbd\x22\xa9\x76\x63\x56\x7d\x99\xce\x2f\x22\xef\xfc\x04\x02\x83\xbb\x24\x61\x72\x3d\x1a\x1a\xb5\x7b\xd9\x2c\x08\xbd\x41\x83\x76\x78\x1b\xf1\x01\xc8\x78\xea\x06\x72\x61\x4d\x44\x5b\x58\x56\xae\x73\xa5\x10\xdb\xa8\xd8\x63\x64\x11\xa7\x86\x6a\x66\xda\x59\x53\xea\xa2\x43\xd5\xd3\x1e\xc0\x18\xbf\xdc\x4f\x98\xc5\x1e\x1c\xd2\x7d\xb0\x2c\x19\xfe\xd1\x49\x19\xa2\xd6\xd2\xca\x17\x1e\x3e\x3e\x49\x13\x0b\xb7\xc8\x38\x46\x6a\x77\x25\xa1\xa6\x75\xc9\x9d\x56\x7c\xc1\xcd\xe0\xd3\xa7\xce\xb5\x5c\xa3\x9e\x5e\x0e\x81\x7f\xd7\x81\xe0\x70\x01\x12\xf9\xf0\x1f\xcb\x58\x1d\x80\xe4\x16\x61\xd9\xae\xfd\xa1\xd6\x36\x4d\x58\x65\xbc\xba\xe4\xfa\xbe\x4b\x32\xb2\xa5\xce\xf5\x23\xf1\xcd\xc5\x15\x71\x6f\x5b\xd9\x97\xba\x18\x98\xf6\xcd\x8c\x35\x4d\x58\x65\xb4\x4d\xb9\xbe\x7f\xf2\xb2\xea\x45\xfa\x61\x9b\x07\xf8\xd3\xd9\xbf\x9a\x52\xaf\x4f\xd1\x12\xe5\x0e\x5a\xc8\x92\x3c\xb8\xd4\x07\x4e\x6a\xbe\xe3\xc5\x1b\x72\x25\x74\xa9\x58\x75\x73\xdb\x1c\xca\x72\xdd\x97\x54\x7a\x7d\x2f\x2c\x79\xc9\xc6\xb7\x82\x2a\x03\xe2\x71\x57\x34\x08\x1d\x3d\x7d\x8a\x5e\x88\x36\x78\x70\x3d\xf1\x8e\x75\x03\x17\xe3\x1d\x12\x97\xf9\x46\x76\xe7\xa3\xb4\x26\xf1\x5e\xbf\x0d\x29\x7f\xc8\x59\xca\xe6\x67\x3a\xa5\xaf\x07\xf0\x19\xef\xf0\x5c\x9f\x13\xd5\xe4\xe8\xf5\xd1\x88\xdc\xf2\x9c\x67\x54\x65\x8b\x5a\x2a\xe6\xaa\x9d\x65\x16\x7e\x40\xb8\x95\x7b\x75\x44\x4e\xa4\x82\x91\x13\x2a\x48\xc6\x7c\x44\x93\x3b\x67\x0b\x94\x1d\x4f\x9f\x9a\xb8\x90\x47\xb5\x5f\x22\x9d\xe9\x8c\x13\xa9\xe7\xd8\x8e\x1f\xd5\xd2\xd9\x5c\x56\x24\x9d\x0b\x4b\xe7\x47\xe4\xd3\xaa\x42\xe5\x70\x64\x7c\x8b\xe7\x02\xea\xd3\xe8\x7d\x3b\x69\x70\xcb\xe6\xe0\xe7\x03\xd3\x76\x2d\x71\xca\xcd\x47\x56\xc8\x4e\x12\x02\x76\x69\xd8\xe3\xb8\xb1\x2f\xa4\xe6\x90\xa8\x94\x1a\x28\x0b\xac\x0c\x4f\xca\x8c\x5a\xb1\x1a\xad\x71\x23\x72\x79\x75\xf3\xf1\xea\xe2\xfc\xee\xea\xf2\x0d\xf9\xc6\x8d\xc4\x63\x09\x6f\x44\xee\xe2\x6c\x50\x91\x47\xaf\x4b\xb9\x13\xbe\x35\x70\x64\x88\x8a\x2a\xb9\x23\xe4\xf8\xa0\x82\x5c\x0b\x6e\xaa\xf4\xc8\xe8\x77\x96\x49\xc1\x7c\xf5\xd0\x42\x3a\x6b\xe0\x94\xa3\x37\x88\x70\x83\xd9\x9f\xeb\xa3\xc1\xe9\xc0\x54\xab\x61\x2a\x5b\x14\xc1\x47\x10\x2d\x2a\xe0\x1e\x4a\xfc\xf7\xf9\x4f\xbb\xca\xbe\x21\x1b\xad\x0f\x70\x42\xeb\x7f\xf5\x1e\x99\x41\x48\xcc\xee\xd3\xdd\xac\x28\x69\x4d\x2c\x9b\x39\x1e\x1d\x7b\x81\x22\x5b\x4a\xc2\x1f\x06\x8d\x33\x7a\xd5\x91\x6d\x44\xc8\x77\xde\x65\x1b\x42\x8f\x57\xe7\xf3\xc7\xec\x10\x51\x56\xf8\x06\xca\xfa\xc0\x98\x72\x1c\x7f\xd4\xa5\x00\x9b\xf2\x39\x13\xb8\xb0\xc3\x52\x28\xff\xf9\xce\xd5\xd1\xaa\x79\x3b\xfd\xe3\xe3\xbb\xc3\xce\x0c\xcf\x5f\xe7\x79\xb9\x63\xeb\x66\x95\xc8\x3c\xc7\x7c\x51\xb3\x10\x60\x58\xc5\x08\x06\xaa\x70\x30\xcd\x07\x33\x5f\x4d\xb6\x20\x7f\x83\x9e\xf9\x4e\x0d\x4d\x27\xbc\x76\x41\x09\xa2\x12\x73\xbb\xe7\x61\x76\x49\xd6\xb4\x4f\x9e\xe2\x48\xfb\x59\xf8\xf8\xd9\xc7\xab\xf3\xcb\xf7\x57\xa3\x3c\x7d\x72\xd2\xc2\x44\x5a\x48\x2e\x8c\xde\xae\xdf\x6c\xab\x3a\xd3\x9e\xfc\x84\x8f\x76\xe5\xce\xa1\xa3\xc7\x31\xff\x22\xca\x4b\x97\x32\x43\x79\xa6\xa3\x3d\x34\xb2\x90\x99\x9c\xae\x4e\xbf\xdc\x61\x73\x7e\x81\xf9\x65\x86\x74\x68\x77\xfd\xb0\xa2\x7e\x9b\x3a\x1a\x4d\x29\xbf\xaa\x88\x5d\xad\x35\x48\xcd\x50\xee\xe2\x85\x2e\xf7\x51\x84\xb3\x25\x18\xa0\x22\x09\x07\xd8\xa7\xec\xab\x72\xe0\x45\x35\x6c\xda\x4a\x6d\x8f\x0d\xba\xed\x02\x9b\xa5\x3f\xdb\x0b\x15\xd5\x61\xe6\xfb\xd4\x09\x5c\xa1\xd8\x30\xa4\x6b\x82\xd2\x2a\x52\x45\x0c\x37\xa6\x77\xde\x7a\xe3\x6d\x3d\xd8\x2a\x5b\x34\xad\x38\x95\x7c\x14\x4c\x5f\x98\x63\x20\xcb\x16\x55\x1a\x48\xa7\x45\xd3\x29\xa6\x61\x52\xce\x4c\x5c\x28\x3e\xe7\x19\x9b\x42\x2a\x56\x2e\xa6\x51\xf8\x6b\x1c\x30\xeb\x52\xb3\xd6\x8d\xae\xef\xed\x5f\x51\xd2\x6d\xc0\x8b\x0f\xdf\xdd\x41\x56\x5f\xb8\xe0\xda\x5b\x08\xb7\x1f\x84\xf3\x36\x1c\x0e\xc1\x64\x70\xf2\x37\x2b\x4f\xa6\xd9\x29\xf9\x81\xb9\xef\x48\x48\x3b\xac\xa0\x14\xd0\x4c\x86\x1c\xb0\x30\xd7\x0a\xb2\x80\x8e\x78\xbd\xef\x5a\x9d\xd9\x96\x56\x56\x42\x56\x53\x6b\x0f\x95\x4f\x31\x75\x23\xde\x31\x3d\xbd\xec\x79\x40\xb2\xbf\x33\x95\xf3\xa6\xd5\x55\xf8\x19\x2e\x7e\x3c\x3d\xa4\x44\x2f\xf2\x8c\x8b\xfb\x2a\x2f\xd8\x44\x5a\x1c\xc2\xd0\x04\x2e\xee\x3d\xc6\x2a\x46\xb3\xf5\x94\x72\x17\xfc\x38\x28\x95\x34\x3b\x58\x00\xc1\x42\x67\xcf\xd9\x9f\xfc\xb1\x77\xd7\xd0\x31\x89\x3b\x3a\x7a\x71\xeb\xe5\xba\x5b\x19\xfc\x63\xe8\x50\xa3\x69\x82\x5c\xdf\x5e\xdc\x5e\x3f\xa9\x85\x7a\x1d\x4b\x80\xd9\x3d\xa3\x54\xc7\x7f\xdc\x76\x3b\x3c\x24\x59\xb9\xbd\x0d\xaa\x77\x37\x52\x19\x9a\x1d\x88\x08\x24\x33\x5a\x9c\x97\x66\x76\xc9\x35\xe4\x50\xe8\x2a\x04\x2c\xf5\x8f\x3c\x9d\x31\x77\xb3\x4f\x18\xc8\x3d\x3a\xb8\x76\x17\x7f\x3a\xbf\x21\xb4\xb4\xfb\x6b\x5c\x72\xd1\x83\x5e\xb8\xfb\x99\xdd\x62\x84\xc1\x8e\xeb\x72\xbd\xb7\xac\xca\xb7\x7a\xec\x35\x3d\x86\x1f\x6e\x7f\x17\x01\x34\x14\x29\xd8\x0b\xbe\x7f\xe0\x82\x1b\x4e\x8d\x6c\x59\xa8\xac\x86\x02\xb5\xbe\xc1\x20\x50\x6a\x23\x73\x87\xc1\xd7\xbe\x05\x5c\x21\x03\x17\x5f\xea\x54\x59\x0b\x40\x7a\x07\x88\x5d\x0b\x2b\x6b\xd3\x84\x35\x1c\x20\x07\x90\xf4\x13\xc7\xe6\xa1\xcd\x1f\x9c\x81\x0a\xf2\x83\x65\x7f\x7c\x53\x4b\xc5\xbe\x54\xd7\xc2\x5b\x29\xaa\xa2\x09\x07\xb5\xf8\xf0\x1f\xbb\x12\x05\xfe\xa3\x68\x58\xda\x70\x81\xff\xb7\xa4\x19\x02\xe6\xc3\xa1\xcd\x52\x75\x20\x77\x9d\x6f\x7d\x87\xdc\xd4\xab\xed\xf8\x10\xb4\xf4\x52\x63\xe6\x31\x5c\x8f\x51\x54\x68\xbb\x47\x75\x5d\xec\xd8\x5d\x3c\x1d\x93\x13\x93\x14\xad\x6b\xf7\x3f\x92\x6b\x7b\x56\x8a\x5a\x21\x67\x98\xf9\x1d\x6e\xcb\xbb\xe0\xda\xde\x76\x92\x8f\x72\x35\x04\x58\xde\xd5\xaa\xe2\x7a\x85\xdd\x8a\xd7\x85\xac\x9f\xbc\xe3\xda\xf8\x82\x0c\xf0\x82\x6b\x97\x47\x18\xe4\xae\x1b\xab\xc8\xf1\xe2\x7f\x68\x9a\xaa\x37\xc8\xa5\x7c\xf5\x65\x05\xd2\x97\x4f\xf2\x45\x45\xb8\x4b\x3c\x31\x8b\xc2\x25\x00\xbc\xbb\xb8\x21\x58\x20\xe5\xf7\xbf\xc5\xca\xaf\xff\xfe\xeb\xdf\xbe\x6a\xbd\xdd\xcf\xe7\x3c\xbe\xa3\x1d\xe3\xe0\x77\x4c\x2f\xc2\x6f\xb0\xe6\x1f\x68\x57\x02\xb2\xc9\x2d\xba\xe3\x59\xca\xea\x8e\x3a\x22\x96\xdd\xe5\x40\xef\x77\x93\x60\x7a\x3f\xbb\x67\xf5\xb3\x23\x21\xa2\x04\x89\x44\x47\x74\x89\xbb\x42\x88\xe1\x32\xd9\x41\x8a\x73\xf3\xf2\x28\xce\x56\xd8\x6c\xc7\xa2\x3a\xf6\xc4\x97\xf1\xbe\xfc\x4d\xe5\xc2\x7e\xf9\xe1\xf6\x7f\xde\x9d\x7f\x7d\xf5\x0e\x66\xea\xee\xef\x2d\x6a\x70\xb1\xb3\xff\x54\x7b\x54\x6b\xa3\xbc\x6e\x07\x48\xb7\x6b\x19\xd1\xb8\x90\x11\xe4\xc3\xdb\xdb\xae\x77\x31\xfb\x0a\xe8\x62\xd2\x6a\xed\x4f\x6b\x6d\x83\xaa\x26\x4c\x1d\x2e\x7e\x64\x67\xa3\x5c\x94\x48\xab\xa6\x7f\xd9\x9d\xc2\x19\xee\xad\x22\x6d\xdd\x01\xf2\x02\xee\x1d\xec\x7a\x11\x06\x07\xbf\x71\x78\x24\x58\xb5\x95\x03\x54\xf7\xc0\xa2\x63\xec\xe5\x45\x00\x7b\x48\x91\xb6\x29\x4b\xb3\x2d\xb5\x66\x3a\x54\x5f\x78\xa1\x98\x52\xac\x4a\xcf\xdc\x85\x7a\xad\x1c\xa0\x56\xae\xac\x76\x17\x53\x8b\xa5\x58\x97\xce\xdc\x7b\x28\x50\xa7\xbc\xea\x82\x26\x07\x2d\xa8\x52\xbd\xc2\x37\x10\xe4\xfe\xf4\x04\x10\x3e\x7b\x40\x47\xda\x30\x5e\x57\x44\x0e\x1d\x9b\x51\x72\x9d\x76\xc8\x17\xfa\x28\xa4\x8f\x40\x8c\xc3\xe9\x9e\x79\xfb\xc8\xd3\x6a\x3b\x3f\xec\xa8\xe8\x1c\x5a\xc9\x29\x66\xd2\x48\xb1\xb3\x97\xfc\xaa\xee\xf5\x03\x7d\x03\x2d\x2e\xaa\x32\x36\x51\x8d\x47\xf0\xa0\x0c\x97\x11\x56\x9e\xf3\xec\x42\x0a\x7f\x2d\x51\xbf\x94\x78\x72\x11\x24\xbd\xbe\x3c\xd0\xe1\xfb\x72\x43\x3c\xbb\x1a\x83\x0f\xea\x0c\x92\x76\x8e\x49\xb1\x5d\x3c\xc4\xae\x2f\x9d\x68\xe6\x03\x4e\xb4\x43\x48\xb2\x1e\x23\x0f\xc6\x3a\xa5\x32\x0f\x52\x75\x0f\xf5\xae\x77\x6c\xf8\x2a\xb8\xdf\x96\x42\xb1\x5e\xe2\xe9\xc1\x39\x3e\xf3\x09\xba\x85\x13\xd4\x48\x70\xbe\xee\x24\x3d\xc6\x41\x7a\xde\x03\xb4\x2f\xa3\x7a\xdc\x28\xdf\x83\x0a\xe9\x1e\xdd\x3a\x2e\xd5\x77\x73\xc6\x04\xbb\x49\x15\xb5\xa0\x60\x72\x89\x4e\xdc\xc1\xa8\x83\x92\x58\x82\xb2\x0b\x61\xf0\x7d\xd0\x80\x8b\x89\x9e\xb3\xcc\x42\x55\x8a\x38\x45\xb4\x0b\xe3\x1d\x10\xcc\xb2\x9c\xd3\xc2\xd7\xe4\x96\x0f\xe2\x81\xaa\x94\x9c\xdf\x5c\x1f\x86\x1a\x74\xf0\xb3\x46\x4c\x6a\x97\xd1\xab\xee\x69\x5d\xf5\xc4\x32\x37\x33\x06\xb5\x15\xc9\x98\x1b\x5d\xd5\xf4\x63\x26\xd6\x2b\x2d\x15\x0c\x77\x59\xf6\x2c\xdb\x73\xeb\x46\x8a\x18\xa6\x20\x32\x31\x34\xf3\x45\x04\x5c\x99\x9c\x57\xaf\x5e\xa1\x29\xec\xd5\xef\x7e\xf7\x3b\xac\xac\x94\xb2\x84\xe7\xcb\x0d\xa1\xd5\xff\x7a\xfd\x7a\x44\xfe\xeb\xfc\xfd\x3b\xa8\xfc\x58\x18\x8d\x59\x49\x70\x64\xac\x04\x1f\x75\xd6\x03\xf2\x7f\x6e\xbf\xfb\x50\x95\x89\xa9\xff\xea\x0a\x6a\xbb\xe5\x8d\xc8\x65\xe4\xff\x14\x1b\xba\xa8\x99\xb9\x82\x46\x86\xd0\xc9\x04\x11\x63\xec\xcb\xe9\xe2\x81\xf3\xd1\xe3\x50\x15\x1c\xeb\x8f\x58\x94\xc8\xc0\x31\xcb\xaa\xe4\x68\x1a\xf4\x99\x0d\xd0\xcf\x0c\xc6\x0a\x64\x12\xa6\x32\xc0\x5a\xf2\x13\x0d\x55\x48\xaa\xf4\x7f\x8a\x69\x2b\x94\xba\xea\x8a\x38\x58\xb5\x33\x9a\xb5\xce\xf5\xf0\x18\x37\x40\xad\xab\x63\xd4\x4d\xf7\xee\x0c\xf9\xf4\xad\x2e\x77\x71\x55\xa6\xfe\x6f\x78\x1b\xba\xcd\x49\xf8\x91\x6e\x64\x6a\x73\xbd\x09\xb3\xc1\xad\x73\x59\x02\x2a\x3a\x41\x33\x09\x95\xbc\xc2\x4e\x57\x5c\x2c\x2a\x7a\xbf\x7d\x29\x9d\x93\x2f\x76\x4d\xc0\x8b\x84\xea\x3d\x6d\x5d\xce\xa7\xee\x2f\xe2\x7b\xd7\xf2\x2a\xd0\xb1\x2c\x8d\xbf\xc3\x76\xbf\x43\x00\x36\x56\x59\xef\x90\x46\x72\x87\xcc\x93\xbb\x64\x20\xee\x9c\xc4\xb4\x7e\xdf\x0c\x3c\xa1\x2e\x4a\x0c\x08\xa3\xc9\x8c\xdc\xb3\xc5\x10\xe9\x56\x41\x21\x9a\x07\xa0\x72\x69\x61\x51\x2b\x7c\x52\xd5\xae\xb1\xf2\xb1\x03\x99\x77\x0c\x88\xb8\x8f\x8f\x06\xf2\x42\xa8\x76\xf2\x92\x4b\x23\x2a\x22\x4b\x81\xcf\x55\x1d\xd5\x23\x0e\x79\x43\xb1\x18\x79\x3d\x48\xc5\x9e\x37\x96\xda\x6e\x7a\xd3\x97\x2b\x6f\x08\x4b\x07\x1d\x77\x2b\xc5\x52\x6f\x57\x7c\xdb\x09\x7f\xf0\x41\xea\xb3\x33\x47\x1e\x15\x50\xce\xcf\x55\x72\x72\x6d\x3d\x94\x02\x20\x6a\x41\x34\x9a\x99\xd2\x81\x06\xeb\x85\x95\x22\x63\x5a\x13\x0e\x2b\xcc\xa9\xba\x67\x3e\x61\x0c\xcd\x46\xe4\xc6\x4e\x32\xe4\xaf\xc2\xb4\xc8\x73\x74\xb1\xb3\x67\x36\x8e\x0e\xb2\x1f\x39\x1e\x8d\x8e\x91\xc0\xaf\x88\x15\xea\x80\x1f\xbb\xe5\xd4\xdd\x21\x97\x6e\xa3\xb4\x77\xa1\x31\x33\xb0\x15\xf9\x20\xf3\xb5\x84\x28\x38\x33\xf3\x0c\x8c\xb6\x4e\xa2\xb4\xbc\x9c\x1d\x12\xc0\xee\x9a\xb7\x7c\x97\xac\xe5\xad\xee\x2d\xea\xcf\xee\xd9\xca\x77\xca\x55\xbe\x2e\x53\xb9\xdb\x29\x77\xda\xba\xe7\x70\xde\x23\xc5\x76\xde\x29\xcd\xab\x7f\xea\x46\x4a\x90\x3b\x6a\x59\x7a\x5a\xc9\x88\x2e\xe9\x53\xc6\xbe\x28\xa1\xf0\x7a\xb2\xaa\xea\x9c\x0f\x16\x8c\xe4\x65\x4f\x43\x2d\x04\x9e\x5f\x1a\xec\x56\xcb\x85\x74\x16\x0f\x9b\x4f\x17\x71\xb1\xf9\xb4\xbb\x0c\x6c\x3e\x75\x85\x2d\x0a\x4b\x0a\x44\x3f\xf6\xe2\x07\x90\x1a\x09\x39\xbb\xab\x23\x38\x22\xef\x1d\x53\x40\x64\xa4\x63\x2d\xb3\xd2\x84\x48\xa6\x15\x1c\x03\x06\xf5\x19\xbe\x31\xa4\xd4\x37\x8b\xf8\x07\x70\x4e\x24\xcb\x5d\x59\x09\x3e\x3b\x1d\xf1\xae\x35\xf7\x7e\xb2\xce\x24\x7b\xc0\xd0\x8b\x12\x3b\xc3\xd1\x0f\x10\xf2\x4e\x78\x5f\xea\x9a\x8c\x03\x9e\x24\x46\xa3\x00\xe5\xc5\x15\x57\xe8\xa9\xf3\x12\xdb\x59\x6d\xdc\x5c\x9d\x61\xe2\xfc\xe6\x7a\x27\x0d\x20\xea\xbf\x46\x07\x88\x5b\xfc\x84\xb5\x80\x6b\xd4\x02\xe2\xb2\x3b\x97\xd5\xca\x9d\x49\xd9\x92\x9d\x17\x2f\x46\x2e\x4d\xfb\xad\x25\x96\xb1\xd3\x69\x3d\x87\x1e\x1a\x7b\x2a\xb2\x1a\xe5\xdd\xf3\xb7\x8e\x70\x88\x5f\xba\xc8\xf9\x84\xe2\x23\xc0\xa3\x53\xb9\x74\xff\x2c\x57\xb3\x83\xc5\x92\x5b\x28\x6d\x83\xfa\x60\xa4\x58\x16\x32\x7d\xe3\x4a\x49\x0b\x21\xb1\x80\x9c\x1e\x60\x6d\x1c\x3d\x40\x85\xd1\x4a\x11\xd1\x5d\xb1\x8a\x4c\xee\x3b\xcb\x0d\x3b\x55\x39\xda\xa7\xce\x91\xdd\x40\x58\xf9\x4d\xd7\x5d\x24\x7b\x96\x2d\x22\x11\x6b\xda\xad\x10\x4a\x6d\x4f\xdd\x48\xa1\xce\x7b\x32\x63\x39\xc5\x1c\x7e\x7e\x79\x96\xca\x3c\x28\x6e\x0c\xc3\x5c\x4a\x4c\xe5\x9a\xc8\xc9\xa0\x76\x67\x70\x34\x7f\x7d\xb4\x4b\x39\x98\x3d\x2b\xf6\x90\x6a\x17\x0e\x00\x8c\x9b\x9a\xc8\x66\xf1\x1a\x74\x89\x0c\x12\x6f\x8a\x86\x41\xc2\x32\x98\x39\x42\xef\xc9\x17\x7e\x08\x3d\x6a\x57\xfd\x69\x10\x04\x86\x5e\x7f\xea\xf5\xa7\x83\xe8\x4f\x11\x63\xf1\x04\x67\x85\x2e\x15\x3b\x0c\x7b\x85\xaa\x0a\x64\x8a\x12\xf0\x58\xd4\xf4\xaa\x94\x54\x75\x8b\x9b\xd5\x87\x8e\xbd\x82\xe5\xf0\xb8\x34\x93\xe1\xef\x09\x13\x89\x4c\x71\xf3\xed\xf8\x4a\x1b\x10\x6d\x2a\x9d\x24\x9e\x4b\xee\xbf\x15\x5b\xed\x60\xec\x5d\xb7\x6e\x27\x3a\xe0\xaf\x02\xdf\x1e\x88\xc1\x57\x6c\x3d\x04\x13\xfb\x5a\xd9\x3e\xd7\x80\xe3\xef\xd5\x25\x24\x96\x95\x06\xe4\xf6\x15\x73\xc9\x09\xbe\x1c\x25\x45\x39\x70\x0d\x46\x39\xcb\xa5\x5a\x0c\x42\x23\xfb\x63\xad\x97\x6b\x71\x0a\x32\x41\x52\x2a\xab\x01\x66\x8b\x2f\x55\x3a\xf0\x00\x7a\x62\xe1\x20\xec\x53\xb7\xa2\x41\xf1\x53\x47\x89\x2a\xa9\x18\xe8\xf7\x55\x11\xa5\x49\x48\x79\xa8\x07\x95\xda\x69\xdf\x32\x31\x27\x73\xaa\x3a\x54\x41\x8f\x9f\x3d\xe5\x81\x94\xcf\xb9\xde\xad\xde\x61\x63\xe9\xb7\x8e\x69\xa0\x5d\x47\x96\xa6\x28\x8d\xa3\x94\xfe\x54\xf8\x90\xf9\x70\x1a\x1a\x42\xd1\xeb\xa3\x9d\xa6\xf1\xc5\xd4\x17\xc6\x67\xc7\x2a\xc3\xf8\xec\x5b\x6b\xb8\x3e\xca\xce\x68\x73\xd0\xca\xe1\xfe\xf1\x68\x71\x88\x73\x58\xb1\xc8\x2a\xcf\x83\x17\x4e\x9f\xe8\xa0\xa1\xbb\xc9\x4e\x76\x1b\x97\xa1\x7e\xb5\xc9\xc6\xfd\xf8\x13\xb6\xd6\x1c\xf6\xce\xd6\xc5\x17\xfe\xcc\x2f\x6c\x6f\x5d\x3d\x83\xfe\xb6\xb6\x15\x0a\xf6\xb7\xb5\xfd\x6d\x6d\x7f\x5b\xdb\x5b\x1b\x7a\x6b\x43\x7f\x5b\x4b\xfa\xdb\xda\x83\xc0\xf0\x70\xb7\xb5\x28\xea\xad\xba\xb3\x75\xc2\x5e\x75\x61\xfb\xa4\xf7\xb5\xae\x70\xcf\x79\x92\xc8\x52\x98\x3b\x79\xcf\x5a\x5f\x3a\x34\xe4\xff\xa5\x71\x20\x01\xc2\x1a\x7d\x60\xb9\xf1\x93\x29\x07\xdd\xa5\x92\x4e\xb2\xc5\x2e\x52\x05\x2d\x53\x6e\x25\xff\x9d\xd1\xcc\x0f\x10\x27\x27\x12\x29\x4b\xab\x1f\xdc\x51\x36\x16\xd6\x23\x72\x4e\x14\x4b\x78\xc1\x5d\x19\x79\x8a\xef\x11\xf1\x42\x6d\x04\x6e\x34\xcb\x26\x2e\x47\xbd\x88\x6b\xfd\x54\xf2\xbb\xa3\x83\x2b\x3f\x83\x1c\x4a\xfa\x4c\xe6\xbe\x16\x92\x62\x7f\xf3\xac\xcd\xcd\xe6\x2e\x1e\x21\x36\xaf\xc0\x52\x6a\x25\x86\xe0\x63\x05\x77\x01\xd6\x8f\x7d\xfc\xd9\xe7\x82\x2b\x40\xde\x5b\x96\x48\xd1\xa6\xa6\xea\x9a\x0d\x5a\x1a\xa9\xe2\x4f\x60\x1b\x65\x29\x49\x4b\x15\x6a\xa6\xce\x69\xc6\x53\x6e\x16\xe1\xd6\xce\x95\xd7\xa2\x78\x62\xc2\x36\xea\x0a\x8c\x84\x16\x85\x92\x34\x99\x31\x1d\x7d\x0d\x05\x14\x17\x44\x16\x7c\xdf\xb1\x04\x1c\xc8\x28\xd0\xc7\x32\xc8\x6c\x41\x94\x34\xfe\xe2\x7d\xcd\x07\xef\xa2\xc1\xa0\x3b\x72\x39\xa3\x16\x70\x3b\x2f\xe3\x21\x70\x56\x7c\x12\xff\xa1\x89\xcc\x52\x9f\xc2\xe4\xf7\xaf\xac\x50\x98\x38\x1c\xb4\xc4\x0f\x12\x5c\x18\x49\x32\xcb\xb0\x2d\x41\x5c\xdf\xf9\xd7\xbf\x21\x33\x59\x2a\x3d\x8a\x93\x0e\xbc\x86\x77\xa8\xdf\x79\xa1\xd2\x90\x8c\x51\x6d\xc8\xeb\x57\x24\xe7\xa2\xb4\x7c\xaa\x33\xda\x74\x97\x83\x22\x09\xe8\xb7\xbf\x69\xdd\xaf\xab\xec\xb3\x56\xea\x29\x30\x37\xb2\x13\x7d\xdc\x49\xc2\xc0\x38\xcc\x2c\xde\x10\x84\x1c\xd1\x8d\xa1\x2d\x8c\x7c\x84\xf3\xf5\x63\x29\xc7\x0b\xd3\x25\x88\xd2\xf5\xa8\x47\x4f\xfe\x5f\xf7\xb2\x4d\xf2\x94\x2a\x77\xca\xc6\x8f\x3e\x4a\x85\x8b\x29\xd7\x66\x4b\x7d\x8b\x2a\xbe\x72\x63\xb3\xf6\x6c\x65\x6a\xb5\x83\x8e\xb1\x32\xd0\xc7\x4b\xc4\xde\xb6\x94\x24\x0c\x8b\x59\x5e\x56\x95\x92\x84\xc4\xb6\x5b\x87\x7f\xe6\x84\x63\x1e\x41\x0e\x90\x35\xbd\xe5\x52\xdb\x09\x5d\x1e\x25\x3a\xaf\x15\xbb\xd5\x4f\x81\xe6\x62\x8a\x49\xce\xf3\x32\x33\xbc\xc8\xaa\x75\x7f\xf4\x1d\x1c\x21\x8f\x6d\x6e\x34\x32\x13\x51\x0c\x2c\xc6\x6c\x53\x60\x9f\x3c\x09\x63\x31\x61\x30\x57\xb7\xb2\xfc\xa0\xa0\x8a\x06\xe0\x41\x25\x5d\x7d\xea\xcc\x77\x14\x6e\x14\x5d\x3a\x4c\xdb\x8b\x66\xd5\x8c\xa3\x5b\xa4\x43\x22\x8d\x61\x82\x8a\x16\xa6\xea\x7a\x7a\x2e\xe8\x44\xe4\x43\x70\x26\xc3\x32\x28\x0d\x6c\x71\x42\xcd\xd7\x34\xb9\x67\x22\xc5\xa2\x51\xb0\xec\x74\x21\x68\xee\xb2\x6d\x45\xf5\xb8\x1b\xfd\xf5\xc0\x19\x26\x30\x7c\xcf\x87\x19\x23\xd7\x3d\x24\x0c\x4a\xdd\x39\x95\x8d\xed\xb2\xed\x9c\x6b\x34\xd9\x28\x3e\x4f\x98\xe7\xff\xb6\xdf\x21\xa7\x3e\x6f\x11\x4b\xbf\x34\x79\xbf\x3d\x11\xfe\x02\xb9\x0f\x96\x73\x48\xaa\x45\x33\x7b\xb4\x17\x21\x66\xb4\xb1\xb9\xe3\xc5\x61\xab\xde\xa8\x71\x97\xc8\xdf\x63\x35\x4e\xeb\x87\xf8\x23\x4d\xa5\x26\x5f\x67\x32\xb9\x27\x97\x0c\x84\xae\xc7\x2c\xcf\xa2\xc6\xe9\x73\xa6\xf0\xce\xe9\x74\xdb\x3d\xdb\x90\xe4\x52\x70\x23\xd5\x66\x7a\xf1\x74\x65\x27\xfb\x74\xcf\x6b\x33\x54\x59\x6c\x7e\xc9\xc9\x9e\x2d\xba\x75\xdd\x78\xe8\x14\xd4\x33\x38\x9d\xf8\xca\x55\x01\xdb\xf1\xac\xfd\x62\x26\x1f\x86\x46\x0e\x4b\xcd\x86\xbc\xc5\x85\x6e\x87\x65\xde\xb3\x05\xdc\x62\x77\x5c\xa8\xeb\x56\xd3\x19\x8c\x04\x0b\x14\xbc\xb7\x9c\xfb\xe3\xd7\x97\x9f\x34\x53\xa3\x58\x06\x3c\x63\x26\x39\x4b\x58\x31\x3b\x73\x23\xbc\x48\xa0\x78\x22\xd2\x15\x2a\xbe\x1f\xb2\x99\x44\x66\x99\x0b\xcc\x96\x13\x72\xc1\x8a\x59\x18\xf8\xa9\x57\xfd\x7c\x19\x81\x0b\x29\xbb\x26\x42\x3d\xb6\x7d\xea\x87\x08\xde\xe0\x19\x8a\x90\x49\x8d\xbb\x15\xa1\x78\x2a\xf4\x79\xd1\xa5\x36\x1f\x11\x38\x8f\x9b\x4e\xf9\xb8\x96\x4f\x39\xf6\xf7\xac\x27\x4b\xf6\x1e\x23\x35\x12\x74\x3d\x41\xa1\x3b\x65\x29\x91\x73\xa6\x14\x4f\x99\x26\x81\x06\xc5\x5a\x2a\xcf\x9e\x1a\x6e\x7d\xde\xe6\x67\xcf\xdb\xbc\x83\x3a\x74\x0c\xfa\x50\x8d\x4c\xc1\x9b\x25\x32\x45\xd3\x9c\x8b\x17\x47\xa8\x74\x42\x33\x76\xfd\x5d\x07\xfd\xc3\xf5\xa8\xab\x20\xb7\xee\x65\x94\x3f\x6d\x4b\x56\xb2\x6f\x03\xde\x10\x21\xd3\x6d\x26\xd5\x47\x50\x24\xa6\xd4\xb0\x87\xad\xec\x70\x58\x11\xaa\xed\x2d\x41\x38\x7d\x4e\x95\xe3\x45\xe4\x08\x8c\x70\x1e\x93\x9e\x1d\x92\xa9\xba\x5d\xeb\x6a\x9c\xc4\x5e\x71\xfa\xdd\x66\xd2\x5d\x8f\xc1\xe7\x37\xd7\xe4\x1b\x6c\x7e\xd8\xec\x85\x4a\x1a\x14\x03\x2f\x65\x4e\x79\xd7\x22\x1b\xcd\xee\xcd\xec\xab\xf1\x12\x6e\x42\x5b\xe2\x1a\x47\x05\x5c\x26\x7c\x5a\x5a\x9d\xce\xe9\x61\x2f\x2a\xc1\xdc\x92\xe8\xf2\x72\x13\xcc\xed\x5f\x0d\x22\x32\x39\x79\xbf\xc8\x4a\x62\xf1\x5b\x09\xac\x24\xdc\x81\x12\xcd\x84\xe6\x70\x21\x13\xdd\x8a\xbb\x4a\x7f\x58\x5a\x12\x9d\x20\x51\xc4\x19\x90\x77\x72\xca\x85\x3f\xbd\xd2\xdd\xd7\x4d\x28\xcf\xda\x02\xa3\x97\x49\x9e\x5d\x26\xd1\x3a\xbb\x12\x74\x9c\xb5\x71\x37\xa8\xa3\x5a\xe8\x48\xde\x66\x74\x4a\x18\xfc\x71\x96\x72\x6d\xff\x4f\x6e\x6f\xdf\x81\x11\xbe\x14\x5e\x62\x06\x03\xb5\xa3\x7d\x21\x48\x01\x0f\xe2\x61\xcf\x0e\x92\x9e\x1d\xb2\xff\x45\x3d\x09\x17\xa9\x9d\x78\x54\x0a\x0e\x9d\xa4\xa0\x05\xe6\x43\x0c\x3e\xbf\xe8\x36\x30\x66\xe4\x6e\xc6\x93\xfb\x9b\xc8\xee\x2e\x95\x7d\x27\xa2\x57\x35\x06\xd6\xfc\xed\x90\xd4\xd2\x4d\xf5\xa6\xbb\x6a\x1c\xf5\xf4\x7c\xc0\x13\x8c\x5b\xb7\x7e\xf8\x8d\x6a\x2d\x13\x5e\xdd\xb9\x80\x8d\xa6\x62\x0e\x29\x30\x87\xc3\xae\x09\xc4\x83\xae\xcb\x41\xf9\x63\x05\x47\xf3\xbb\xe9\xab\xe3\xea\x98\x83\x71\xe1\x57\x7d\xd0\x25\x20\xce\xec\x90\x1a\xbd\xea\xb8\x9c\x1a\xdd\x0b\xc3\x8d\x8b\x05\xef\xa6\xee\x36\xcf\x0b\x62\xbe\x36\xe7\xd2\xf6\x85\x14\xe9\x2e\x35\xe1\xc1\x16\xde\x26\x6c\x63\x95\x1a\xde\xb8\x4d\xc4\x77\xee\xaa\x01\xce\x5c\x21\x8b\x32\x43\x7f\x8e\xfd\xf3\xbb\x7b\x9b\x31\x7e\xe7\x40\x57\x0f\x4f\x91\xb5\xf4\x38\x76\xec\xed\xee\xe9\xfc\xd3\xc8\x5d\x1a\x09\x77\xaf\x7e\xfb\x9b\xdf\x7c\xe9\xd9\x4c\xdb\xaa\xe0\x8f\x91\xce\xb4\xa5\x89\x76\x45\x7c\xd1\x75\x1f\x5f\xf4\xf3\x8d\x2f\x7a\xfc\x2c\xb4\x07\x8e\x20\xea\xe8\x9b\xdb\xcd\x2f\xb7\x7d\x8c\x50\x6b\xef\xdd\xae\x9e\xbb\x1d\xa2\x80\x0e\x1b\xfb\xd3\xd9\x97\xb5\x4b\x9c\x4f\x1f\xdd\xf3\x53\x8d\xee\xd9\xc5\x97\xb5\x7b\x24\x4f\x17\x1f\xd6\x9f\x62\xd4\x4e\x87\xc3\xd9\x3e\xba\x64\xef\x98\x92\xee\x49\x00\xbb\xdb\xd3\x76\x29\x48\x55\xf5\x5c\xa9\x41\xfa\xa0\x72\x9f\x7b\xec\xf8\x58\x47\xa9\xc5\x8c\xb4\x27\xf0\x49\x14\x12\xd2\x41\x1b\xc3\xe1\x65\x97\xda\x90\xae\xcf\x77\xb7\x8d\x8b\x99\xf0\xfa\x79\xee\x63\x7e\x0e\x17\x1e\x7d\x4d\x97\x2f\xc4\xe4\xae\x6b\xd9\x5a\xbc\xb5\x02\x48\x00\x30\x72\x39\x8e\xb3\x44\x56\x47\xe7\xfc\xe6\xda\xea\xe0\x10\x46\x44\x33\x3d\x22\x2b\xf8\xbc\x37\x97\x3a\xb9\xc0\xf3\x77\x6a\x0c\xcb\x0b\xd3\x7e\xd7\x7b\x8b\xfb\xb3\x5b\xdc\x0f\x68\x01\x9c\x95\x39\x15\x43\x7b\xa2\xc0\xe6\x5e\xbb\xad\x6b\x50\xe6\x11\x71\x67\x07\xd9\x13\x58\x40\x20\xb8\xa0\x5e\xd8\x98\x46\x65\x2e\x1f\xc7\xec\x09\x63\xef\xbc\x72\xe4\xab\x8d\x93\x96\xc8\x25\x87\x57\xb7\x9c\x00\x05\x7f\xa8\x22\xe6\x5c\x53\xc3\xcd\x8c\x21\x0f\xbf\x81\x80\x9c\xaa\x55\x5d\x92\x46\x51\x9a\x66\x99\x7c\xc0\x6f\xc7\x7c\xcd\x42\xdf\xce\xc5\x45\x9a\x8d\x19\xc9\xb9\xd5\xd1\x9d\x81\x35\x9e\x0e\x5e\x99\x5a\x89\x9c\x29\x14\x78\x95\xbb\x6c\xbb\x65\xc6\x6d\x14\x6c\xb4\xd5\x6f\x05\x3a\x84\xdb\x7f\x7b\xaf\x22\xf8\xb6\xa7\x09\x63\x36\xa3\x73\x2e\x4b\x85\xbd\x8d\x24\x47\xee\x27\xe0\x0d\x0b\x59\x06\x7b\x17\x16\xc3\x0c\xab\xd3\x2b\xe0\xf4\xa1\xfa\x11\x54\x81\x54\x7a\xd3\xc4\x90\x7d\xe6\xda\x2c\xaf\xc5\x83\xc8\xa7\xc1\x3b\x14\xde\xcc\x75\x61\xd9\x42\xe7\xaa\x76\xb5\x7e\x75\x79\x65\x7e\x0b\x3f\x7d\x41\x35\xed\xb6\x66\x77\x7d\x32\x11\xe8\x67\x28\xfe\x84\x9b\xb0\x8c\x27\x8b\xce\xe5\xde\x1a\xbd\x3d\xd1\xd6\xe1\x0e\xcd\xbe\x27\x5f\x53\xcd\x52\xf2\x9e\x0a\x3a\x45\x7d\xef\xe4\xf6\xe6\xeb\xf7\xa7\x76\x5f\x41\x9f\xbc\xbe\x5c\x79\xd1\x76\x1b\x0f\xfe\xe1\x90\xf1\x22\x4b\x0b\xdf\x81\x55\x2d\xf5\xdf\x71\xf1\x07\x0d\x84\x21\x81\x0f\xb5\x4b\xd6\xbb\x82\x05\xdd\x34\x43\x58\x9b\x35\x3f\x1b\x04\x66\x9e\xa7\x7b\x56\xf9\xe4\x42\x1b\x9a\x65\x37\x19\x15\xe7\x45\xa1\xe4\x7c\xb5\x36\x5e\x9b\xab\x6f\xe8\x67\x8a\x6e\x1e\xfe\x65\x81\xa0\x87\x2b\x6c\x41\xae\xab\xf1\x47\xe4\xda\x04\x2d\x5c\x0a\x60\xa9\x47\xe7\xa5\x91\x39\x35\x3c\x39\xb2\xca\xfa\xd1\x7b\x2a\x4a\x9a\xad\x74\xba\xda\xb8\x8c\x75\x22\xe2\xc6\x4e\xeb\x53\xd7\xb5\xe8\xb6\x51\xd6\xd8\xdc\xdf\x50\x65\xa9\xd3\xc5\xed\xf7\x9d\xfa\x6a\x43\x4d\xb9\x44\x85\x37\x70\x86\xf5\xbc\x60\x48\x32\xaa\xcd\xa7\x22\xb5\x87\xbe\xf1\xeb\x26\x82\x9f\x50\x43\x33\x39\xfd\x13\xa3\xd9\x6a\x0c\xaf\xe1\xc9\x45\xdc\xda\x1b\xa0\xdc\x85\x7f\x39\x0e\x0d\x8f\x35\xb1\x02\xb6\x8f\x81\x57\x2c\x63\x73\x2a\x8c\xef\x8e\xc5\xd5\xf5\xb1\x5b\x3f\x60\x11\xaf\x8c\xaf\x29\x33\x4c\xe5\x5c\xd4\xc7\xbc\x85\xb6\x17\x52\xa4\x1c\xcd\x8e\x60\x50\xc3\x1e\xf5\x71\xd7\xa3\xda\xba\x9b\x86\x0d\x77\x0b\xf5\xec\x9a\xd1\x7c\xea\xa0\xc0\x66\x63\x27\x5f\xce\xf0\x25\xdc\xb4\xd7\xe6\xb6\x04\x29\x72\x2f\xac\x60\x08\x79\x44\x56\x93\xad\xad\x72\xc2\x36\xf9\x60\xe8\xf7\x18\xa7\xb0\xde\x71\x74\xe8\xe6\xbd\xee\x0e\x62\x13\x8a\xe1\xb3\x5d\xb2\x68\x4e\x65\x3d\x4d\x5d\x85\x77\xa1\x1b\x46\xb2\x34\x0a\xf2\xd7\x1a\xad\xe7\x01\xad\x04\xaf\x76\x32\x52\xdb\xac\xf6\x75\x5a\x5b\xe5\x60\x5f\x52\x65\x5b\x48\x8c\x5b\x99\x56\xcb\xe4\xf2\x75\xc5\xfa\xda\xf9\xff\x29\xa7\x8a\x50\x52\x70\x86\xc9\x4f\xa8\x70\xc0\x02\xce\xc2\x68\xea\x5e\x5a\x0e\x66\x55\x42\xf8\x6d\xe0\x2e\xc3\xd1\xb8\xec\x7c\x2d\xbc\x81\x9a\x62\xf2\x0f\xb8\xb8\x38\xfb\x46\x3a\x23\xaf\x0b\xd2\xb5\x34\x00\x38\xf9\x80\xe8\x32\x99\x11\xaa\xed\xd4\x2c\x42\xdb\x13\xcf\x46\x39\x15\x7c\xc2\xb4\x19\x85\x2c\xc1\xfa\xcf\xbf\xfe\xcb\x88\xbc\x95\x8a\x38\x47\xf5\x81\xcf\xaa\xe1\xe6\x59\xe1\x05\xd7\xb8\x98\xd0\xb7\xd2\x5a\x0b\x99\xba\x49\x3f\xc0\x64\x0d\xbd\xb7\x3c\x0c\x27\x5b\x32\xb8\xba\x78\x43\x8e\xac\x98\x18\x7d\xfa\x1f\x96\x2d\xfd\xeb\x88\x9c\x3c\x00\xd3\x3e\xb2\x7f\x1e\xe1\x07\x83\xdb\x64\xac\x54\x57\x1f\xc6\x60\x49\xc5\xa7\x53\xa6\x50\x7d\x24\x10\x54\x78\xea\xb2\x82\x08\x19\x35\xf6\x97\xd2\x95\xba\xd9\x9c\xc8\x9f\x7f\xfd\x97\x23\x72\x52\x5f\x17\xe1\x22\x65\x9f\xc9\xaf\xd1\xba\xcc\xb5\x5d\xe3\xa9\xbb\xcc\xd1\x0b\x61\xe8\x67\x3b\x66\x32\x93\x9a\x09\x54\xe5\x8d\x24\x33\x3a\x67\x44\x4b\xab\x01\xb3\x2c\x1b\x3a\x5b\x3a\x79\xa0\x90\xa9\xc5\x83\x12\x02\xeb\x49\x41\x95\xa9\xa1\xc4\xc8\x59\x48\xe0\x6b\x76\xdb\xa6\xc2\xdf\x4c\x4f\xb8\x70\xf7\x57\xee\xe6\xcc\xee\x39\x04\x86\xe2\x26\x19\x49\x92\x19\x15\xd3\x10\x9b\x3e\x29\x4d\xa9\xd8\x96\xab\x9f\x96\x67\xe0\x9e\x8b\x4e\x21\xcc\xdf\x72\xd1\x74\x2a\x58\x6d\x57\x9a\x72\xe3\xa3\x22\x9c\xaf\xa2\x59\x9c\xd9\x5d\x50\x7c\x5c\x1a\xa9\xf4\x59\xca\xe6\x2c\x3b\xd3\x7c\x3a\xa4\x2a\x99\x71\xc3\x12\xbb\xac\x33\x5a\xf0\x61\x22\x85\xdd\x71\xc8\xca\x90\xa7\xbf\x80\xf2\xa6\x43\x3b\xd5\x2d\x59\xa7\x5b\x2e\x7a\xbb\x51\xed\x59\x8d\x69\x07\x5b\x63\x0b\x7b\xd0\xf2\x42\xd1\x36\xf3\x04\xab\x05\x43\xc8\xd9\x41\x16\xeb\x93\x26\x77\xe7\x31\xc7\x2e\x0f\x78\xd2\x1c\xc3\x1e\x3b\x74\x20\x81\x53\x59\xa3\x94\x39\x4d\x91\x94\x52\xb1\x78\x74\xe4\xb7\x20\x85\x74\xf9\xc9\x62\x08\x43\xc8\x6c\x48\x45\x6a\xff\x8d\x01\x3b\xc9\xe2\x20\x30\x2c\x79\x27\x42\xf0\xe9\xfa\xf2\x69\x8e\x44\xc9\x0f\x70\xea\x9d\xbc\xd6\x52\x88\x42\x51\x15\x1d\x35\x54\xc9\x3c\xd3\xac\x0b\xa8\x5c\xfb\x51\xff\xc3\xdd\xbf\x84\x6c\x67\xdb\x44\xaa\xcd\xb7\x26\x91\xec\xd8\x72\xbe\xef\xaa\x1e\xb1\x4d\x0e\x1c\xaf\xa8\x36\x2e\xb5\x96\xcf\x41\x50\x5b\x86\x57\x50\x80\xc1\xac\xbf\x18\x6e\x85\x43\xde\x5f\xc0\x4e\x64\xb8\x32\xe7\x52\x12\x94\x92\xed\x0a\x54\xa5\xbf\xd4\xea\xa0\xe1\xa2\x0c\xd3\x86\xd0\x39\xe5\x19\x58\xe7\xe5\x58\x33\x35\xc7\x82\x54\x2e\xd5\x20\x6d\xea\x59\xae\xe6\x04\x8a\x51\x4f\xa4\xf9\xf8\x35\x2c\xef\xca\xa6\x05\x80\x36\xd4\x98\xfd\xda\x59\x1f\x44\xef\x41\xf5\x72\xed\xcf\xf6\x0b\x3b\xaa\x31\x16\xff\xfe\xc4\xa8\x32\x63\x46\xcd\x1d\xdf\xc4\x77\x97\x50\xba\xd6\x2f\x94\x72\x0f\x08\xfd\xc0\xc8\x54\x1a\x2b\x62\x95\x80\xfb\x28\x93\x62\x52\x9f\x80\x68\x8f\x8d\xd1\xd5\x2a\xef\x14\x85\x10\x1f\x29\x3a\x2e\xb3\xde\x71\x79\x9d\x4e\x3a\x76\x98\x64\xb0\x35\x26\xd2\x90\x82\xb9\xbd\xc3\xdb\x0c\xa0\x40\x4f\xb3\xe4\x9c\x69\xbd\x31\xc1\x46\xdd\xbb\x10\x5b\xe3\x51\x6e\x5c\xad\xe5\xfe\x37\x0c\x0b\xb1\x02\x74\xca\x0c\xe5\x99\x3f\xca\x08\x8a\x00\xa5\x6d\xd4\x75\xe3\x02\x15\xa3\x7a\x93\x80\x50\x9b\xf5\x47\x68\x8c\x93\x96\x82\x0d\x1f\xa4\x4a\xc9\x05\xcd\x59\x76\x41\x35\x73\x63\xc5\x21\x7a\xb8\x47\xc7\xfa\xa0\x53\x5e\x6d\xfb\x5a\x33\x65\x34\xfe\x54\x26\x61\xf8\xab\x52\xb1\x70\x82\x03\x6f\x82\xbc\x53\x25\x1b\x90\xb7\x96\x7b\x0d\xc8\x27\x71\x2f\xe4\xc3\x7e\x73\x35\x1b\x6f\x41\x6a\x33\x8d\xdd\x3f\x7c\x5a\x9d\x9a\xc1\x27\x4c\x77\xc7\x19\x39\x82\xbf\xc6\xd4\x58\x67\x36\xa1\xa9\x9f\x91\xfd\xe7\x92\x09\xca\x2a\x8a\x4a\x4e\x15\xd3\x98\xb9\x66\x65\x92\xc4\xb6\x26\xe7\x6f\x98\x70\xc1\x7d\x5b\xa7\x77\xbd\xaa\x97\x9f\xa9\xe7\x6b\xd3\xea\x17\xb7\xdf\xee\x63\x45\xb6\x52\xd4\xd8\xec\x11\x18\x4d\x74\x8d\xf1\x69\xdd\x0c\x57\x1b\x9d\x22\xae\x17\xb5\x45\xa1\x64\x93\x75\xd4\xaf\xee\xe2\xf6\xfb\xf5\xc0\x5e\xcb\xfb\xb6\xf1\xa7\xed\x66\xa9\x7d\x0d\x52\x5b\xcf\xcc\x56\x23\x54\x6f\x7e\xea\xcd\x4f\x5f\x92\xf9\x69\x2b\xc6\x6f\x32\x39\x7d\x19\xc6\xa6\xad\x4b\xdc\x64\x60\x7a\x91\xa6\xa5\x56\x2b\xda\x68\x4e\x7a\xb1\x86\xa4\xad\x4b\x6b\x69\x3c\xfa\xf9\x98\x8d\xb6\x42\x6c\x83\xa9\xe8\x05\x1a\x89\xda\x08\x64\x2c\x6d\x23\x26\x5e\x47\x8d\x63\x41\xb1\x2a\x67\x19\x86\xf3\x4e\x39\xb1\x38\xb3\xab\xb4\x68\x05\xb8\xad\x73\x3b\x76\x93\x6b\x2f\x7b\x39\x81\xd1\x15\x7b\x5c\x9a\x2c\xb9\xbc\xba\xf9\x78\x75\x71\x7e\x77\x75\xd9\x94\xef\x56\x41\x7a\x8b\x24\xb6\xd9\x06\x31\x8c\x24\xb1\x35\x0d\x2c\x41\x5e\xf3\x93\xc5\x81\x35\x3f\x95\x25\x5f\xd5\x6b\x7f\xb9\x70\x2f\x2e\xb7\x17\xff\xd8\x7e\x3a\xdb\x1e\xcf\x4f\xe8\x38\x45\x9d\xcf\x99\x95\x7b\x66\x32\x4b\xb5\xf7\x5b\xbd\xbe\x0c\x91\x54\x5c\x24\x59\x99\x5a\xe1\xe2\xd3\xa7\xeb\x4b\x3d\x22\xe4\x6b\x96\xd0\x52\x83\x15\x26\x95\xe2\xd8\x90\xef\x3e\xbc\xfb\x2f\xf0\xc7\x86\x16\x83\x90\xd7\x04\xb2\xf2\x72\x8a\x89\x85\x0d\xa6\x6b\x23\x5f\x33\x14\x54\xe0\xcb\x09\x2d\x2c\x15\xd3\x58\xb9\xc2\x80\x2c\x32\x63\x59\x61\x29\xe6\x3d\x23\x55\x06\x55\x3b\x70\x55\x61\xde\xbb\x4f\x4e\x99\xc1\xa8\xab\x4d\x1e\x92\x1b\xa1\xb6\xc5\xe2\xba\x87\xad\xb5\xa6\x3e\x3a\x6d\xfc\x81\x6a\x67\xb1\x5a\x39\xdb\x2d\xfb\xbb\xdd\x3e\xb3\xde\xc4\xb1\xc6\xb8\x81\xe4\x19\xfe\x5a\x9a\xb3\x9d\x6c\x65\xc7\x40\x27\x12\x6e\x5a\x5b\x53\xd7\xbb\x01\xad\xae\x03\xb0\x64\xcb\x60\x4d\x20\xd7\x3e\x1c\x3c\xb2\xa3\x29\xb7\x9b\x0b\x14\x11\x49\x6b\xb5\x3f\x9d\xff\x5c\xfd\x5d\x39\x0e\xd5\x5f\xab\xf9\x3a\x8b\x0c\xf9\xc7\xbf\xbe\xfa\x7f\x01\x00\x00\xff\xff\x49\x53\xc6\xeb\x2e\x5c\x02\x00") func operatorsCoreosCom_subscriptionsYamlBytes() ([]byte, error) { return bindataRead( @@ -311,11 +311,13 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error diff --git a/vendor/github.com/operator-framework/api/pkg/manifests/bundleloader.go b/vendor/github.com/operator-framework/api/pkg/manifests/bundleloader.go index 5d5bf2dc1a..94f14a22ac 100644 --- a/vendor/github.com/operator-framework/api/pkg/manifests/bundleloader.go +++ b/vendor/github.com/operator-framework/api/pkg/manifests/bundleloader.go @@ -51,6 +51,10 @@ func (b *bundleLoader) LoadBundle() error { // Add values from the annotations when the values are not loaded func (b *bundleLoader) addChannelsFromAnnotationsFile() { + if b.bundle == nil { + // None of this is relevant if the bundle was not found + return + } // Note that they will not get load for Bundle Format directories // and PackageManifest should not have the annotationsFile. However, // the following check to ensure that channels and default channels diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go index 020fecc0ec..6641a614a6 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go @@ -89,6 +89,11 @@ type CatalogSourceSpec struct { // +optional Secrets []string `json:"secrets,omitempty"` + // RunAsRoot allows admins to indicate that they wish to run the CatalogSource pod in a privileged + // pod as root. This should only be enabled when running older catalog images which could not be run as non-root. + // +optional + RunAsRoot bool `json:"runAsRoot,omitempty"` + // Metadata DisplayName string `json:"displayName,omitempty"` Description string `json:"description,omitempty"` diff --git a/vendor/github.com/operator-framework/api/pkg/validation/internal/annotations.go b/vendor/github.com/operator-framework/api/pkg/validation/internal/annotations.go index 2ab63aa9fb..715b04171f 100644 --- a/vendor/github.com/operator-framework/api/pkg/validation/internal/annotations.go +++ b/vendor/github.com/operator-framework/api/pkg/validation/internal/annotations.go @@ -30,13 +30,13 @@ which are known to be case sensitive. It also checks to see if the olm.propertie annotation is defined in order to add a warning if present. This function can be used anywhere annotations need to be checked for case sensitivity. -Arguments +# Arguments • annotations: annotations map usually obtained from ObjectMeta.GetAnnotations() • value: is the field or file that caused an error or warning -Returns +# Returns • errs: Any errors that may have been detected with the annotation keys provided */ diff --git a/vendor/github.com/operator-framework/api/pkg/validation/internal/community.go b/vendor/github.com/operator-framework/api/pkg/validation/internal/community.go index dfc7c4aabe..debaae2bab 100644 --- a/vendor/github.com/operator-framework/api/pkg/validation/internal/community.go +++ b/vendor/github.com/operator-framework/api/pkg/validation/internal/community.go @@ -7,7 +7,7 @@ import ( "os" "strings" - "github.com/blang/semver" + "github.com/blang/semver/v4" "github.com/operator-framework/api/pkg/manifests" "github.com/operator-framework/api/pkg/validation/errors" diff --git a/vendor/github.com/operator-framework/api/pkg/validation/internal/operatorhub.go b/vendor/github.com/operator-framework/api/pkg/validation/internal/operatorhub.go index ac9fd0cf53..f5da37a274 100644 --- a/vendor/github.com/operator-framework/api/pkg/validation/internal/operatorhub.go +++ b/vendor/github.com/operator-framework/api/pkg/validation/internal/operatorhub.go @@ -71,15 +71,15 @@ import ( // containing a list of categories will enable those categories to be used when comparing CSV categories for // OperatorHub validation. The json file should be in the following format: // -// ```json -// { -// "categories":[ -// "Cloud Pak", -// "Registry", -// "MyCoolThing", -// ] -// } -// ``` +// ```json +// { +// "categories":[ +// "Cloud Pak", +// "Registry", +// "MyCoolThing", +// ] +// } +// ``` // // - The `csv.Spec.Provider.Name` was provided // diff --git a/vendor/github.com/operator-framework/api/pkg/validation/internal/removed_apis.go b/vendor/github.com/operator-framework/api/pkg/validation/internal/removed_apis.go index 44dee85d06..13feafb5d2 100644 --- a/vendor/github.com/operator-framework/api/pkg/validation/internal/removed_apis.go +++ b/vendor/github.com/operator-framework/api/pkg/validation/internal/removed_apis.go @@ -2,12 +2,17 @@ package internal import ( "fmt" - "github.com/blang/semver" + "sort" + "strings" + + "github.com/blang/semver/v4" "github.com/operator-framework/api/pkg/manifests" + "github.com/operator-framework/api/pkg/operators/v1alpha1" "github.com/operator-framework/api/pkg/validation/errors" interfaces "github.com/operator-framework/api/pkg/validation/interfaces" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sort" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) // k8sVersionKey defines the key which can be used by its consumers @@ -147,11 +152,12 @@ func checkRemovedAPIsForVersion( errs []error, warns []error) ([]error, []error) { found := map[string][]string{} + warnsFound := map[string][]string{} switch k8sVersionToCheck.String() { case "1.22.0": found = getRemovedAPIsOn1_22From(bundle) case "1.25.0": - found = getRemovedAPIsOn1_25From(bundle) + found, warnsFound = getRemovedAPIsOn1_25From(bundle) case "1.26.0": found = getRemovedAPIsOn1_26From(bundle) default: @@ -172,6 +178,16 @@ func checkRemovedAPIsForVersion( warns = append(warns, msg) } } + + if len(warnsFound) > 0 { + deprecatedAPIsMessage := generateMessageWithDeprecatedAPIs(warnsFound) + msg := fmt.Errorf(DeprecateMessage, + k8sVersionToCheck.Major, k8sVersionToCheck.Minor, + k8sVersionToCheck.Major, k8sVersionToCheck.Minor, + deprecatedAPIsMessage) + warns = append(warns, msg) + } + return errs, warns } @@ -287,40 +303,115 @@ func getRemovedAPIsOn1_22From(bundle *manifests.Bundle) map[string][]string { // add manifests on the bundle using these APIs. On top of that some Kinds such as the CronJob // are not currently a valid/supported by OLM and never would to be added to bundle. // See: https://github.com/operator-framework/operator-registry/blob/v1.19.5/pkg/lib/bundle/supported_resources.go#L3-L23 -func getRemovedAPIsOn1_25From(bundle *manifests.Bundle) map[string][]string { +func getRemovedAPIsOn1_25From(bundle *manifests.Bundle) (map[string][]string, map[string][]string) { deprecatedAPIs := make(map[string][]string) + warnDeprecatedAPIs := make(map[string][]string) + + deprecatedGvk := map[schema.GroupVersionKind]struct{}{ + {Group: "batch", Version: "v1beta1", Kind: "CronJob"}: {}, + {Group: "discovery.k8s.io", Version: "v1beta1", Kind: "EndpointSlice"}: {}, + {Group: "events.k8s.io", Version: "v1beta1", Kind: "Event"}: {}, + {Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"}: {}, + {Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"}: {}, + {Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {}, + {Group: "node.k8s.io", Version: "v1beta1", Kind: "RuntimeClass"}: {}, + } + + addIfDeprecated := func(u *unstructured.Unstructured) { + if _, ok := deprecatedGvk[u.GetObjectKind().GroupVersionKind()]; ok { + deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], u.GetName()) + } + } + + deprecatedGroupResource := map[schema.GroupResource]struct{}{ + {Group: "batch", Resource: "cronjobs"}: {}, + {Group: "discovery.k8s.io", Resource: "endpointslices"}: {}, + {Group: "events.k8s.io", Resource: "events"}: {}, + {Group: "autoscaling", Resource: "horizontalpodautoscalers"}: {}, + {Group: "policy", Resource: "poddisruptionbudgets"}: {}, + {Group: "policy", Resource: "podsecuritypolicies"}: {}, + {Group: "node.k8s.io", Resource: "runtimeclasses"}: {}, + } + + warnIfDeprecated := func(gr schema.GroupResource, msg string) { + if _, ok := deprecatedGroupResource[gr]; ok { + warnDeprecatedAPIs[gr.Resource] = append(warnDeprecatedAPIs[gr.Resource], msg) + } + } + for _, obj := range bundle.Objects { switch u := obj.GetObjectKind().(type) { case *unstructured.Unstructured: switch u.GetAPIVersion() { - case "batch/v1beta1": - if u.GetKind() == "CronJob" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "discovery.k8s.io/v1beta1": - if u.GetKind() == "EndpointSlice" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "events.k8s.io/v1beta1": - if u.GetKind() == "Event" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "autoscaling/v2beta1": - if u.GetKind() == "HorizontalPodAutoscaler" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "policy/v1beta1": - if u.GetKind() == "PodDisruptionBudget" || u.GetKind() == "PodSecurityPolicy" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) - } - case "node.k8s.io/v1beta1": - if u.GetKind() == "RuntimeClass" { - deprecatedAPIs[u.GetKind()] = append(deprecatedAPIs[u.GetKind()], obj.GetName()) + case "operators.coreos.com/v1alpha1": + // Check a couple CSV fields for references to deprecated APIs + if u.GetKind() == "ClusterServiceVersion" { + resInCsvCrds := make(map[string]struct{}) + csv := &v1alpha1.ClusterServiceVersion{} + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, csv) + if err != nil { + fmt.Println("failed to convert unstructured.Unstructed to v1alpha1.ClusterServiceVersion:", err) + } + + // Loop through all the CRDDescriptions to see + // if there is any with an API Version & Kind that is deprecated + crdCheck := func(crdsField string, crdDescriptions []v1alpha1.CRDDescription) { + for i, desc := range crdDescriptions { + for j, res := range desc.Resources { + resFromKind := fmt.Sprintf("%ss", strings.ToLower(res.Kind)) + resInCsvCrds[resFromKind] = struct{}{} + unstruct := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": res.Version, + "kind": res.Kind, + "metadata": map[string]interface{}{ + "name": fmt.Sprintf("ClusterServiceVersion.Spec.CustomResourceDefinitions.%s[%d].Resource[%d]", crdsField, i, j), + }, + }, + } + addIfDeprecated(unstruct) + } + } + } + + // Check the Owned Resources + crdCheck("Owned", csv.Spec.CustomResourceDefinitions.Owned) + + // Check the Required Resources + crdCheck("Required", csv.Spec.CustomResourceDefinitions.Required) + + // Loop through all the StrategyDeploymentPermissions to see + // if the rbacv1.PolicyRule that is defined specifies a resource that + // *may* have a deprecated API then add it to the warnings. + // Only present a warning if the resource was NOT found as a resource + // in the ClusterServiceVersion.Spec.CustomResourceDefinitions fields + permCheck := func(permField string, perms []v1alpha1.StrategyDeploymentPermissions) { + for i, perm := range perms { + for j, rule := range perm.Rules { + for _, apiGroup := range rule.APIGroups { + for _, res := range rule.Resources { + if _, ok := resInCsvCrds[res]; ok { + continue + } + warnIfDeprecated(schema.GroupResource{Group: apiGroup, Resource: res}, fmt.Sprintf("ClusterServiceVersion.Spec.InstallStrategy.StrategySpec.%s[%d].Rules[%d]", permField, i, j)) + } + } + } + } + } + + // Check the ClusterPermissions + permCheck("ClusterPermissions", csv.Spec.InstallStrategy.StrategySpec.ClusterPermissions) + + // Check the Permissions + permCheck("Permissions", csv.Spec.InstallStrategy.StrategySpec.Permissions) } + default: + addIfDeprecated(u) } } } - return deprecatedAPIs + return deprecatedAPIs, warnDeprecatedAPIs } // getRemovedAPIsOn1_26From return the list of resources which were deprecated diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go index aa24543eef..6d1cbfb097 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go @@ -39,8 +39,7 @@ type Interface interface { OperatorsV2() operatorsv2.OperatorsV2Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient operatorsV1alpha1 *operatorsv1alpha1.OperatorsV1alpha1Client diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go index f037340b49..3a265e8e4c 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go @@ -47,6 +47,11 @@ type sharedInformerFactory struct { // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -107,20 +112,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -167,11 +191,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Operators() operators.Interface } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go index 559520aad7..43aab8e1ce 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go @@ -175,7 +175,7 @@ func (i *StrategyDeploymentInstaller) deploymentForSpec(name string, spec appsv1 // By default, each deployment created by OLM could spawn up to 10 replicaSets. // By setting the deployments revisionHistoryLimit to 1, OLM will only create up // to 2 ReplicaSets per deployment it manages, saving memory. - dep.Spec.RevisionHistoryLimit = pointer.Int32Ptr(1) + dep.Spec.RevisionHistoryLimit = pointer.Int32(1) hash = HashDeploymentSpec(dep.Spec) dep.Labels[DeploymentSpecHashLabelKey] = hash diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go index dfc9f855dd..0c3531e780 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go @@ -749,16 +749,19 @@ func (o *Operator) syncRegistryServer(logger *logrus.Entry, in *v1alpha1.Catalog logger.Debug("ensured registry server") // requeue the catalog sync based on the polling interval, for accurate syncs of catalogs with polling enabled - if out.Spec.UpdateStrategy != nil { - if out.Spec.UpdateStrategy.RegistryPoll != nil { - if out.Spec.UpdateStrategy.RegistryPoll.ParsingError != "" && out.Status.Reason != v1alpha1.CatalogSourceIntervalInvalidError { - out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, fmt.Errorf(out.Spec.UpdateStrategy.RegistryPoll.ParsingError)) - } - logger.Debugf("requeuing registry server sync based on polling interval %s", out.Spec.UpdateStrategy.Interval.Duration.String()) - resyncPeriod := reconciler.SyncRegistryUpdateInterval(out, time.Now()) - o.catsrcQueueSet.RequeueAfter(out.GetNamespace(), out.GetName(), queueinformer.ResyncWithJitter(resyncPeriod, 0.1)()) + if out.Spec.UpdateStrategy != nil && out.Spec.UpdateStrategy.RegistryPoll != nil { + if out.Spec.UpdateStrategy.Interval == nil { + syncError = fmt.Errorf("empty polling interval; cannot requeue registry server sync without a provided polling interval") + out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, syncError) return } + if out.Spec.UpdateStrategy.RegistryPoll.ParsingError != "" && out.Status.Reason != v1alpha1.CatalogSourceIntervalInvalidError { + out.SetError(v1alpha1.CatalogSourceIntervalInvalidError, fmt.Errorf(out.Spec.UpdateStrategy.RegistryPoll.ParsingError)) + } + logger.Debugf("requeuing registry server sync based on polling interval %s", out.Spec.UpdateStrategy.Interval.Duration.String()) + resyncPeriod := reconciler.SyncRegistryUpdateInterval(out, time.Now()) + o.catsrcQueueSet.RequeueAfter(out.GetNamespace(), out.GetName(), queueinformer.ResyncWithJitter(resyncPeriod, 0.1)()) + return } if err := o.sources.Remove(sourceKey); err != nil { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go index 08f6b95a8f..78b5cb7e6b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go @@ -1246,7 +1246,7 @@ func (a *Operator) removeDanglingChildCSVs(csv *v1alpha1.ClusterServiceVersion) func (a *Operator) deleteChild(csv *v1alpha1.ClusterServiceVersion, logger *logrus.Entry) error { logger.Debug("gcing csv") - return a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Delete(context.TODO(), csv.GetName(), *metav1.NewDeleteOptions(0)) + return a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Delete(context.TODO(), csv.GetName(), metav1.DeleteOptions{}) } // syncClusterServiceVersion is the method that gets called when we see a CSV event in the cluster @@ -2287,7 +2287,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v syncError = fmt.Errorf("marked as replacement, but no replacement CSV found in cluster") } case v1alpha1.CSVPhaseDeleting: - syncError = a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Delete(context.TODO(), out.GetName(), *metav1.NewDeleteOptions(0)) + syncError = a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Delete(context.TODO(), out.GetName(), metav1.DeleteOptions{}) if syncError != nil { logger.Debugf("unable to get delete csv marked for deletion: %s", syncError.Error()) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go index 50432767c9..8d105fbfa5 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/overrides/inject/inject.go @@ -235,10 +235,12 @@ func InjectNodeSelectorIntoDeployment(podSpec *corev1.PodSpec, nodeSelector map[ // with the given corev1.Affinity. Any nil top-level sub-attributes (e.g. NodeAffinity, PodAffinity, and PodAntiAffinity) // will be ignored. Hint: to overwrite those top-level attributes, empty them out. I.e. use the empty/default object ({}) // e.g. NodeAffinity{}. In yaml: -// affinity: -// nodeAffinity: {} -// podAffinity: {} -// podAntiAffinity: {} +// +// affinity: +// nodeAffinity: {} +// podAffinity: {} +// podAntiAffinity: {} +// // will completely remove the deployment podSpec.affinity and is equivalent to // affinity: {} func OverrideDeploymentAffinity(podSpec *corev1.PodSpec, affinity *corev1.Affinity) error { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go index c8a58caaea..821ed00b96 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/catalogsource/catalogsource_update.go @@ -12,7 +12,8 @@ import ( "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" ) -/* UpdateStatus can be used to update the status of the provided catalog source. Note that +/* +UpdateStatus can be used to update the status of the provided catalog source. Note that the caller is responsible for ensuring accurate status values in the catsrc argument (i.e. the status is used as-is). @@ -34,7 +35,8 @@ func UpdateStatus(logger *logrus.Entry, client versioned.Interface, catsrc *v1al return nil } -/* UpdateStatusWithConditions can be used to update the status conditions for the provided catalog source. +/* +UpdateStatusWithConditions can be used to update the status conditions for the provided catalog source. This function will make no changes to the other status fields (those fields will be used as-is). If the provided conditions do not result in any status condition changes, then the API server will not be updated. Note that the caller is responsible for ensuring accurate status values for all other fields. @@ -71,7 +73,8 @@ func UpdateStatusWithConditions(logger *logrus.Entry, client versioned.Interface return nil } -/* UpdateSpecAndStatusConditions can be used to update the catalog source with the provided status conditions. +/* +UpdateSpecAndStatusConditions can be used to update the catalog source with the provided status conditions. This will update the spec and status portions of the catalog source. Calls to the API server will occur even if the provided conditions result in no changes. @@ -98,7 +101,8 @@ func UpdateSpecAndStatusConditions(logger *logrus.Entry, client versioned.Interf return nil } -/* RemoveStatusConditions can be used to remove the status conditions for the provided catalog source. +/* +RemoveStatusConditions can be used to remove the status conditions for the provided catalog source. This function will make no changes to the other status fields (those fields will be used as-is). If the provided conditions do not result in any status condition changes, then the API server will not be updated. Note that the caller is responsible for ensuring accurate status values for all other fields. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go index a7e04cb873..3044cd6d9b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/fake_ssa.go @@ -35,8 +35,7 @@ type fakeStatusWriter struct { k8scontrollerclient.StatusWriter } -func (c fakeStatusWriter) Patch(ctx context.Context, obj k8scontrollerclient.Object, patch k8scontrollerclient.Patch, opts ...k8scontrollerclient.PatchOption) error { - patch, opts = convertApplyToMergePatch(patch, opts...) +func (c fakeStatusWriter) Patch(ctx context.Context, obj k8scontrollerclient.Object, patch k8scontrollerclient.Patch, opts ...k8scontrollerclient.SubResourcePatchOption) error { return c.StatusWriter.Patch(ctx, obj, patch, opts...) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go index b13f923b3d..ebedcee31b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client/ssa.go @@ -90,10 +90,11 @@ type ServerSideApplier struct { // plan := &InstallPlan{} // plan.SetNamespace("ns") // plan.SetName("install-123def") -// Eventually(c.Apply(plan, func(p *v1alpha1.InstallPlan) error { -// p.Spec.Approved = true -// return nil -// })).Should(Succeed()) +// +// Eventually(c.Apply(plan, func(p *v1alpha1.InstallPlan) error { +// p.Spec.Approved = true +// return nil +// })).Should(Succeed()) func (c *ServerSideApplier) Apply(ctx context.Context, obj Object, changeFunc interface{}) func() error { // Ensure given object is a pointer objType := reflect.TypeOf(obj) @@ -182,7 +183,10 @@ func (c *ServerSideApplier) Apply(ctx context.Context, obj Object, changeFunc in return err } - if err := c.client.Status().Patch(ctx, cp, k8scontrollerclient.Apply, k8scontrollerclient.ForceOwnership, c.Owner); err != nil { + pos := &k8scontrollerclient.SubResourcePatchOptions{} + k8scontrollerclient.ForceOwnership.ApplyToPatch(&pos.PatchOptions) + + if err := c.client.Status().Patch(ctx, cp, k8scontrollerclient.Apply, pos, c.Owner); err != nil { fmt.Printf("second patch error: %s\n", err) return err } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go index 4fcee4e457..58f577ef45 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/filemonitor/cabundle_updater.go @@ -2,7 +2,7 @@ package filemonitor import ( "crypto/x509" - "io/ioutil" + "os" "sync" "github.com/fsnotify/fsnotify" @@ -16,7 +16,7 @@ type certPoolStore struct { } func NewCertPoolStore(clientCAPath string) (*certPoolStore, error) { - pem, err := ioutil.ReadFile(clientCAPath) + pem, err := os.ReadFile(clientCAPath) if err != nil { return nil, err } @@ -31,7 +31,7 @@ func NewCertPoolStore(clientCAPath string) (*certPoolStore, error) { } func (c *certPoolStore) storeCABundle(clientCAPath string) error { - pem, err := ioutil.ReadFile(clientCAPath) + pem, err := os.ReadFile(clientCAPath) if err == nil { c.mutex.Lock() defer c.mutex.Unlock() diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go index b3d5891bb7..04e9556e17 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.conversion.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go index 7bf8d13745..a4ff45d659 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go index f0d53c1721..ba7fdabd85 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/v1/zz_generated.defaults.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go index 33518a9868..0f7023a2db 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/apis/rbac/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go index add7c3896e..f96239dc0d 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/printers/tablegenerator.go @@ -150,7 +150,9 @@ func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1beta1.Ta // ValidateRowPrintHandlerFunc validates print handler signature. // printFunc is the function that will be called to print an object. // It must be of the following type: -// func printFunc(object ObjectType, options GenerateOptions) ([]metav1beta1.TableRow, error) +// +// func printFunc(object ObjectType, options GenerateOptions) ([]metav1beta1.TableRow, error) +// // where ObjectType is the type of the object that will be printed, and the first // return value is an array of rows, with each row containing a number of cells that // match the number of columns defined for that printer function. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go index 99e41817da..0bf77a89e4 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go @@ -28,6 +28,7 @@ import ( //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -o ./operatorlisterfakes/fake_clusterserviceversion_v1alpha1_namespace_lister.go ../../api/client/listers/operators/v1alpha1.ClusterServiceVersionNamespaceLister // OperatorLister is a union of versioned informer listers +// //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . OperatorLister type OperatorLister interface { AppsV1() AppsV1Lister diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go index eb8c57ab20..bf2b9b51b7 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/csv_handler.go @@ -86,8 +86,8 @@ type handler struct { // OnAddOrUpdate is invoked when a CSV has been added or edited. We tap into // this notification and do the following: // -// a. Make sure this is the CSV related to the cluster operator resource we are -// tracking. Otherwise, do nothing. +// a. Make sure this is the CSV related to the cluster operator resource we are tracking. Otherwise, do nothing. +// // b. If this is the right CSV then send it to the monitor. func (h *handler) OnAddOrUpdate(in *v1alpha1.ClusterServiceVersion) { h.onNotification(in, false) @@ -96,8 +96,8 @@ func (h *handler) OnAddOrUpdate(in *v1alpha1.ClusterServiceVersion) { // OnDelete is invoked when a CSV has been deleted. We tap into // this notification and do the following: // -// a. Make sure this is the CSV related to the cluster operator resource we are -// tracking. Otherwise, do nothing. +// a. Make sure this is the CSV related to the cluster operator resource we are tracking. Otherwise, do nothing. +// // b. If this is the right CSV then send it to the monitor. func (h *handler) OnDelete(in *v1alpha1.ClusterServiceVersion) { h.onNotification(in, true) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy/overridden.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy/overridden.go index 8ad45f1a78..42eec7acd6 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy/overridden.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/proxy/overridden.go @@ -6,8 +6,9 @@ import ( // IsOverridden returns true if the given container overrides proxy env variable(s). // We apply the following rule: -// If a container already defines any of the proxy env variable then it -// overrides all of these. +// +// If a container already defines any of the proxy env variable then it +// overrides all of these. func IsOverridden(envVar []corev1.EnvVar) (overrides bool) { for _, envVarName := range allProxyEnvVarNames { _, found := find(envVar, envVarName) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go index c048e4e8d6..cb48c6efa6 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go @@ -512,6 +512,9 @@ func (p *RegistryProvider) List(namespace string, selector labels.Selector) (*op func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Package, client *registryClient, entriesByChannel map[string][]operators.ChannelEntry) (*operators.PackageManifest, error) { pkgChannels := pkg.GetChannels() + sort.Slice(pkgChannels, func(i, j int) bool { + return pkgChannels[i].Name < pkgChannels[j].Name + }) catsrc := client.catsrc manifest := &operators.PackageManifest{ ObjectMeta: metav1.ObjectMeta{ diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/subresources.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/subresources.go index a851ee215a..24bc799e69 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/subresources.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/subresources.go @@ -3,7 +3,7 @@ package storage import ( "context" "encoding/base64" - "io/ioutil" + "io" "net/http" "strconv" "strings" @@ -72,7 +72,7 @@ func (s *LogoStorage) Connect(ctx context.Context, name string, options runtime. etag := `"` + strings.Join([]string{name, pkgChannel.Name, pkgChannel.CurrentCSV}, ".") + `"` reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data)) - imgBytes, _ := ioutil.ReadAll(reader) + imgBytes, _ := io.ReadAll(reader) return imgBytes, mimeType, etag } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/util/cpb/main.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/util/cpb/main.go index ae9912bf97..5b1769bb37 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/util/cpb/main.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/util/cpb/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -118,7 +117,7 @@ func getMetadata() (m *metadata, err error) { m.annotationsFile = path // Unmarshal metadata - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { return fmt.Errorf("couldn't get content of annotations.yaml file: %s", path) } diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/declcfg.go b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/declcfg.go index a4169c28c5..d575987b10 100644 --- a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/declcfg.go +++ b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/declcfg.go @@ -52,11 +52,11 @@ type ChannelEntry struct { // Top-level fields are the source of truth, i.e. not CSV values. // // Notes: -// - Any field slice type field or type containing a slice somewhere -// where two types/fields are equal if their contents are equal regardless -// of order must have a `hash:"set"` field tag for bundle comparison. -// - Any fields that have a `json:"-"` tag must be included in the equality -// evaluation in bundlesEqual(). +// - Any field slice type field or type containing a slice somewhere +// where two types/fields are equal if their contents are equal regardless +// of order must have a `hash:"set"` field tag for bundle comparison. +// - Any fields that have a `json:"-"` tag must be included in the equality +// evaluation in bundlesEqual(). type Bundle struct { Schema string `json:"schema"` Name string `json:"name"` diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/load.go b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/load.go index 65c289780e..98b25da02a 100644 --- a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/load.go +++ b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/load.go @@ -1,6 +1,7 @@ package declcfg import ( + "bytes" "encoding/json" "errors" "fmt" @@ -135,7 +136,7 @@ func LoadReader(r io.Reader) (*DeclarativeConfig, error) { var in Meta if err := json.Unmarshal(doc, &in); err != nil { - return nil, err + return nil, fmt.Errorf("unmarshal error: %s", resolveUnmarshalErr(doc, err)) } switch in.Schema { @@ -186,3 +187,47 @@ func LoadFile(root fs.FS, path string) (*DeclarativeConfig, error) { return cfg, nil } + +func resolveUnmarshalErr(data []byte, err error) string { + var te *json.UnmarshalTypeError + if errors.As(err, &te) { + return formatUnmarshallErrorString(data, te.Error(), te.Offset) + } + var se *json.SyntaxError + if errors.As(err, &se) { + return formatUnmarshallErrorString(data, se.Error(), se.Offset) + } + return err.Error() +} + +func formatUnmarshallErrorString(data []byte, errmsg string, offset int64) string { + sb := new(strings.Builder) + _, _ = sb.WriteString(fmt.Sprintf("%s at offset %d (indicated by <==)\n ", errmsg, offset)) + // attempt to present the erroneous JSON in indented, human-readable format + // errors result in presenting the original, unformatted output + var pretty bytes.Buffer + err := json.Indent(&pretty, data, "", " ") + if err == nil { + pString := pretty.String() + // calc the prettified string offset which correlates to the original string offset + var pOffset, origOffset int64 + origOffset = 0 + for origOffset = 0; origOffset < offset; { + pOffset++ + if pString[pOffset] != '\n' && pString[pOffset] != ' ' { + origOffset++ + } + } + _, _ = sb.WriteString(pString[:pOffset]) + _, _ = sb.WriteString(" <== ") + _, _ = sb.WriteString(pString[pOffset:]) + } else { + for i := int64(0); i < offset; i++ { + _ = sb.WriteByte(data[i]) + } + _, _ = sb.WriteString(" <== ") + _, _ = sb.Write(data[offset:]) + } + + return sb.String() +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/write.go b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/write.go index 6eb616bf41..3a66829ef0 100644 --- a/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/write.go +++ b/vendor/github.com/operator-framework/operator-registry/alpha/declcfg/write.go @@ -124,12 +124,12 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer) if len(ce.Replaces) > 0 { replacesId := fmt.Sprintf("%s-%s", channelID, ce.Replaces) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", entryId, ce.Name, "replaces", replacesId, ce.Replaces)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", replacesId, ce.Replaces, "replace", entryId, ce.Name)) } if len(ce.Skips) > 0 { for _, s := range ce.Skips { skipsId := fmt.Sprintf("%s-%s", channelID, s) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", entryId, ce.Name, "skips", skipsId, s)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- %s --> %s[%q]\n", skipsId, s, "skip", entryId, ce.Name)) } } if len(ce.SkipRange) > 0 { @@ -138,7 +138,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer) for _, edgeName := range filteredChannel.Entries { if skipRange(versionMap[edgeName.Name]) { skipRangeId := fmt.Sprintf("%s-%s", channelID, edgeName.Name) - pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- \"%s(%s)\" --> %s[%q]\n", entryId, ce.Name, "skipRange", ce.SkipRange, skipRangeId, edgeName.Name)) + pkgBuilder.WriteString(fmt.Sprintf(" %s[%q]-- \"%s(%s)\" --> %s[%q]\n", skipRangeId, edgeName.Name, "skipRange", ce.SkipRange, entryId, ce.Name)) } } } else { diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/model/model.go b/vendor/github.com/operator-framework/operator-registry/alpha/model/model.go index a6ca060420..48861e49cd 100644 --- a/vendor/github.com/operator-framework/operator-registry/alpha/model/model.go +++ b/vendor/github.com/operator-framework/operator-registry/alpha/model/model.go @@ -141,8 +141,9 @@ type Channel struct { } // TODO(joelanford): This function determines the channel head by finding the bundle that has 0 -// incoming edges, based on replaces and skips. It also expects to find exactly one such bundle. -// Is this the correct algorithm? +// +// incoming edges, based on replaces and skips. It also expects to find exactly one such bundle. +// Is this the correct algorithm? func (c Channel) Head() (*Bundle, error) { incoming := map[string]int{} for _, b := range c.Bundles { @@ -210,11 +211,11 @@ func (c *Channel) Validate() error { // validateReplacesChain checks the replaces chain of a channel. // Specifically the following rules must be followed: -// 1. There must be exactly 1 channel head. -// 2. Beginning at the head, the replaces chain must reach all non-skipped entries. -// Non-skipped entries are defined as entries that are not skipped by any other entry in the channel. -// 3. There must be no cycles in the replaces chain. -// 4. The tail entry in the replaces chain is permitted to replace a non-existent entry. +// 1. There must be exactly 1 channel head. +// 2. Beginning at the head, the replaces chain must reach all non-skipped entries. +// Non-skipped entries are defined as entries that are not skipped by any other entry in the channel. +// 3. There must be no cycles in the replaces chain. +// 4. The tail entry in the replaces chain is permitted to replace a non-existent entry. func (c *Channel) validateReplacesChain() error { head, err := c.Head() if err != nil { diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/property/property.go b/vendor/github.com/operator-framework/operator-registry/alpha/property/property.go index 695bfd6da8..9ccd0f14bc 100644 --- a/vendor/github.com/operator-framework/operator-registry/alpha/property/property.go +++ b/vendor/github.com/operator-framework/operator-registry/alpha/property/property.go @@ -40,8 +40,9 @@ type Package struct { } // NOTICE: The Channel properties are for internal use only. -// DO NOT use it for any public-facing functionalities. -// This API is in alpha stage and it is subject to change. +// +// DO NOT use it for any public-facing functionalities. +// This API is in alpha stage and it is subject to change. type Channel struct { ChannelName string `json:"channelName"` //Priority string `json:"priority"` @@ -287,8 +288,9 @@ func MustBuildBundleObjectData(data []byte) Property { } // NOTICE: The Channel properties are for internal use only. -// DO NOT use it for any public-facing functionalities. -// This API is in alpha stage and it is subject to change. +// +// DO NOT use it for any public-facing functionalities. +// This API is in alpha stage and it is subject to change. func MustBuildChannelPriority(name string, priority int) Property { return MustBuild(&Channel{ChannelName: name, Priority: priority}) } diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/basic/basic.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/basic/basic.go new file mode 100644 index 0000000000..18566fbcf2 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/basic/basic.go @@ -0,0 +1,50 @@ +package basic + +import ( + "context" + "fmt" + "io" + + "github.com/operator-framework/operator-registry/alpha/action" + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/pkg/image" +) + +type Template struct { + Registry image.Registry +} + +func (t Template) Render(ctx context.Context, reader io.Reader) (*declcfg.DeclarativeConfig, error) { + cfg, err := declcfg.LoadReader(reader) + if err != nil { + return cfg, err + } + + outb := cfg.Bundles[:0] // allocate based on max size of input, but empty slice + // populate registry, incl any flags from CLI, and enforce only rendering bundle images + r := action.Render{ + Registry: t.Registry, + AllowedRefMask: action.RefBundleImage, + } + + for _, b := range cfg.Bundles { + if !isBundleTemplate(&b) { + return nil, fmt.Errorf("unexpected fields present in basic template bundle") + } + r.Refs = []string{b.Image} + contributor, err := r.Run(ctx) + if err != nil { + return nil, err + } + outb = append(outb, contributor.Bundles...) + } + + cfg.Bundles = outb + return cfg, nil +} + +// isBundleTemplate identifies a Bundle template source as having a Schema and Image defined +// but no Properties, RelatedImages or Package defined +func isBundleTemplate(b *declcfg.Bundle) bool { + return b.Schema != "" && b.Image != "" && b.Package == "" && len(b.Properties) == 0 && len(b.RelatedImages) == 0 +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/builder.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/builder.go new file mode 100644 index 0000000000..615cd09256 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/builder.go @@ -0,0 +1,322 @@ +package composite + +import ( + "bytes" + "fmt" + "io" + "os" + "os/exec" + "path" + "strings" + + "sigs.k8s.io/yaml" + + "github.com/operator-framework/operator-registry/alpha/declcfg" +) + +const ( + BasicBuilderSchema = "olm.builder.basic" + SemverBuilderSchema = "olm.builder.semver" + RawBuilderSchema = "olm.builder.raw" + CustomBuilderSchema = "olm.builder.custom" +) + +type ContainerConfig struct { + ContainerTool string + BaseImage string + WorkingDir string +} + +type BuilderConfig struct { + ContainerCfg ContainerConfig + OutputType string + CurrentDirectory string +} + +type Builder interface { + Build(dir string, td TemplateDefinition) error + Validate(dir string) error +} + +type BasicBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &BasicBuilder{} + +func NewBasicBuilder(builderCfg BuilderConfig) *BasicBuilder { + return &BasicBuilder{ + builderCfg: builderCfg, + } +} + +func (bb *BasicBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != BasicBuilderSchema { + return fmt.Errorf("schema %q does not match the basic template builder schema %q", td.Schema, BasicBuilderSchema) + } + // Parse out the basic template configuration + basicConfig := &BasicConfig{} + err := yaml.UnmarshalStrict(td.Config, basicConfig) + if err != nil { + return fmt.Errorf("unmarshalling basic template config: %w", err) + } + + // validate the basic config fields + valid := true + validationErrs := []string{} + if basicConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "basic template config must have a non-empty input (templateDefinition.config.input)") + } + + if basicConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "basic template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("basic template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(bb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", bb.builderCfg.CurrentDirectory, bb.builderCfg.ContainerCfg.WorkingDir), + bb.builderCfg.ContainerCfg.BaseImage, + "alpha", + "render-template", + "basic", + path.Join(bb.builderCfg.ContainerCfg.WorkingDir, basicConfig.Input)) + + return build(containerCmd, path.Join(dir, basicConfig.Output), bb.builderCfg.OutputType) +} + +func (bb *BasicBuilder) Validate(dir string) error { + return validate(bb.builderCfg.ContainerCfg, path.Join(bb.builderCfg.CurrentDirectory, dir)) +} + +type SemverBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &SemverBuilder{} + +func NewSemverBuilder(builderCfg BuilderConfig) *SemverBuilder { + return &SemverBuilder{ + builderCfg: builderCfg, + } +} + +func (sb *SemverBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != SemverBuilderSchema { + return fmt.Errorf("schema %q does not match the semver template builder schema %q", td.Schema, SemverBuilderSchema) + } + // Parse out the semver template configuration + semverConfig := &SemverConfig{} + err := yaml.UnmarshalStrict(td.Config, semverConfig) + if err != nil { + return fmt.Errorf("unmarshalling semver template config: %w", err) + } + + // validate the semver config fields + valid := true + validationErrs := []string{} + if semverConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "semver template config must have a non-empty input (templateDefinition.config.input)") + } + + if semverConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "semver template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("semver template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(sb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", sb.builderCfg.CurrentDirectory, sb.builderCfg.ContainerCfg.WorkingDir), + sb.builderCfg.ContainerCfg.BaseImage, + "alpha", + "render-template", + "semver", + path.Join(sb.builderCfg.ContainerCfg.WorkingDir, semverConfig.Input)) + + return build(containerCmd, path.Join(dir, semverConfig.Output), sb.builderCfg.OutputType) +} + +func (sb *SemverBuilder) Validate(dir string) error { + return validate(sb.builderCfg.ContainerCfg, path.Join(sb.builderCfg.CurrentDirectory, dir)) +} + +type RawBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &RawBuilder{} + +func NewRawBuilder(builderCfg BuilderConfig) *RawBuilder { + return &RawBuilder{ + builderCfg: builderCfg, + } +} + +func (rb *RawBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != RawBuilderSchema { + return fmt.Errorf("schema %q does not match the raw template builder schema %q", td.Schema, RawBuilderSchema) + } + // Parse out the raw template configuration + rawConfig := &RawConfig{} + err := yaml.UnmarshalStrict(td.Config, rawConfig) + if err != nil { + return fmt.Errorf("unmarshalling raw template config: %w", err) + } + + // validate the raw config fields + valid := true + validationErrs := []string{} + if rawConfig.Input == "" { + valid = false + validationErrs = append(validationErrs, "raw template config must have a non-empty input (templateDefinition.config.input)") + } + + if rawConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "raw template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("raw template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + + // build the container command + containerCmd := exec.Command(rb.builderCfg.ContainerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", rb.builderCfg.CurrentDirectory, rb.builderCfg.ContainerCfg.WorkingDir), + "--entrypoint=cat", // This assumes that the `cat` command is available in the container -- Should we also build a `... render-template raw` command to ensure consistent operation? Does OPM already have a way to render a raw FBC? + rb.builderCfg.ContainerCfg.BaseImage, + path.Join(rb.builderCfg.ContainerCfg.WorkingDir, rawConfig.Input)) + + return build(containerCmd, path.Join(dir, rawConfig.Output), rb.builderCfg.OutputType) +} + +func (rb *RawBuilder) Validate(dir string) error { + return validate(rb.builderCfg.ContainerCfg, path.Join(rb.builderCfg.CurrentDirectory, dir)) +} + +type CustomBuilder struct { + builderCfg BuilderConfig +} + +var _ Builder = &CustomBuilder{} + +func NewCustomBuilder(builderCfg BuilderConfig) *CustomBuilder { + return &CustomBuilder{ + builderCfg: builderCfg, + } +} + +func (cb *CustomBuilder) Build(dir string, td TemplateDefinition) error { + if td.Schema != CustomBuilderSchema { + return fmt.Errorf("schema %q does not match the custom template builder schema %q", td.Schema, CustomBuilderSchema) + } + // Parse out the raw template configuration + customConfig := &CustomConfig{} + err := yaml.UnmarshalStrict(td.Config, customConfig) + if err != nil { + return fmt.Errorf("unmarshalling custom template config: %w", err) + } + + // validate the custom config fields + valid := true + validationErrs := []string{} + if customConfig.Command == "" { + valid = false + validationErrs = append(validationErrs, "custom template config must have a non-empty command (templateDefinition.config.command)") + } + + if customConfig.Output == "" { + valid = false + validationErrs = append(validationErrs, "custom template config must have a non-empty output (templateDefinition.config.output)") + } + + if !valid { + return fmt.Errorf("custom template configuration is invalid: %s", strings.Join(validationErrs, ",")) + } + // build the command to execute + cmd := exec.Command(customConfig.Command, customConfig.Args...) + cmd.Dir = cb.builderCfg.CurrentDirectory + + // custom template should output a valid FBC to STDOUT so we can + // build the FBC just like all the other templates. + return build(cmd, path.Join(dir, customConfig.Output), cb.builderCfg.OutputType) +} + +func (cb *CustomBuilder) Validate(dir string) error { + return validate(cb.builderCfg.ContainerCfg, path.Join(cb.builderCfg.CurrentDirectory, dir)) +} + +func writeDeclCfg(dcfg declcfg.DeclarativeConfig, w io.Writer, output string) error { + switch output { + case "yaml": + return declcfg.WriteYAML(dcfg, w) + case "json": + return declcfg.WriteJSON(dcfg, w) + default: + return fmt.Errorf("invalid --output value %q, expected (json|yaml)", output) + } +} + +func validate(containerCfg ContainerConfig, dir string) error { + // build the container command + containerCmd := exec.Command(containerCfg.ContainerTool, + "run", + "--rm", + "-v", + fmt.Sprintf("%s:%s:Z", dir, containerCfg.WorkingDir), + containerCfg.BaseImage, + "validate", + containerCfg.WorkingDir) + + _, err := containerCmd.Output() + if err != nil { + return fmt.Errorf("running command %q: %w", containerCmd.String(), err) + } + return nil +} + +func build(cmd *exec.Cmd, outPath string, outType string) error { + out, err := cmd.Output() + if err != nil { + return fmt.Errorf("running command %q: %w", cmd.String(), err) + } + + // parse out to dcfg + dcfg, err := declcfg.LoadReader(bytes.NewReader(out)) + if err != nil { + return fmt.Errorf("parsing builder output: %w", err) + } + + // write the dcfg + file, err := os.Create(outPath) + if err != nil { + return fmt.Errorf("creating output file %q: %w", outPath, err) + } + defer file.Close() + + err = writeDeclCfg(*dcfg, file, outType) + if err != nil { + return fmt.Errorf("writing to output file %q: %w", outPath, err) + } + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/composite.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/composite.go new file mode 100644 index 0000000000..537db48afe --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/composite.go @@ -0,0 +1,47 @@ +package composite + +import ( + "context" + "fmt" +) + +type BuilderMap map[string]Builder + +type CatalogBuilderMap map[string]BuilderMap + +type Template struct { + CatalogBuilders CatalogBuilderMap +} + +// TODO(everettraven): do we need the context here? If so, how should it be used? +func (t *Template) Render(ctx context.Context, config *CompositeConfig, validate bool) error { + // TODO(everettraven): should we return aggregated errors? + for _, component := range config.Components { + if builderMap, ok := t.CatalogBuilders[component.Name]; ok { + if builder, ok := builderMap[component.Strategy.Template.Schema]; ok { + // run the builder corresponding to the schema + err := builder.Build(component.Destination.Path, component.Strategy.Template) + if err != nil { + return fmt.Errorf("building component %q: %w", component.Name, err) + } + + if validate { + // run the validation for the builder + err = builder.Validate(component.Destination.Path) + if err != nil { + return fmt.Errorf("validating component %q: %w", component.Name, err) + } + } + } else { + return fmt.Errorf("building component %q: no builder found for template schema %q", component.Name, component.Strategy.Template.Schema) + } + } else { + allowedComponents := []string{} + for k := range t.CatalogBuilders { + allowedComponents = append(allowedComponents, k) + } + return fmt.Errorf("building component %q: component does not exist in the catalog configuration. Available components are: %s", component.Name, allowedComponents) + } + } + return nil +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/config.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/config.go new file mode 100644 index 0000000000..70a480d4e8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/config.go @@ -0,0 +1,42 @@ +package composite + +const ( + CompositeSchema = "olm.composite" + CatalogSchema = "olm.composite.catalogs" +) + +type CompositeConfig struct { + Schema string + Components []Component +} + +type Component struct { + Name string + Destination ComponentDestination + Strategy BuildStrategy +} + +type ComponentDestination struct { + Path string +} + +type BuildStrategy struct { + Name string + Template TemplateDefinition +} + +type CatalogConfig struct { + Schema string + Catalogs []Catalog +} + +type Catalog struct { + Name string + Destination CatalogDestination + Builders []string +} + +type CatalogDestination struct { + BaseImage string + WorkingDir string +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/types.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/types.go new file mode 100644 index 0000000000..5295a5ddfd --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/composite/types.go @@ -0,0 +1,29 @@ +package composite + +import "encoding/json" + +type TemplateDefinition struct { + Schema string + Config json.RawMessage +} + +type BasicConfig struct { + Input string + Output string +} + +type SemverConfig struct { + Input string + Output string +} + +type RawConfig struct { + Input string + Output string +} + +type CustomConfig struct { + Command string + Args []string + Output string +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/README.md b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/README.md new file mode 100644 index 0000000000..2bab90c1c0 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/README.md @@ -0,0 +1,259 @@ +## Semver Template: + +Since a `catalog template` is identified as an input schema which may be processed to generate a valid FBC, we can define a `semver template` as a schema which uses channel conventions to facilitate the auto-generation of channels along `semver` delimiters. + +[**DISCLAIMER:** since version build metadata [MUST be ignored when determining version precedence](https://semver.org) when using semver, it cannot be used in any bundle included in the `semver template` and will result in a fatal error.] + +### Schema Goals +The `semver template` must have: +- terse grammar to minimize creation/maintenance effort +- deterministic output +- simple channel promotion for maturing bundles +- demonstration of a common type of channel maturity model +- minor-version (Y-stream), major-version (X-stream) versioning optionality + +The resulting FBC must clearly indicate how generated channels relate to template entities + +### Schema Anatomy +For convenience and simplicity, this template currently supports hard-coded channel names `Candidate`, `Fast`, and `Stable`, in order of increasing channel stability. We leverage this relationship to calculate the default channel for the package. + +`GenerateMajorChannels` and `GenerateMinorChannels` dictate whether this template will generate X-stream or Y-stream channels (attributes can be set independently). If omitted, only minor (Y-stream) channels will be generated. + +Under each channel are a list of bundle image references which contribute to that channel. + +With the following (hypothetical) example we define a mock bundle which has 11 versions, represented across each of the channel types: +```yaml +Schema: olm.semver +GenerateMajorChannels: true +GenerateMinorChannels: true +Candidate: + Bundles: + - Image: quay.io/foo/olm:testoperator.v0.1.0 + - Image: quay.io/foo/olm:testoperator.v0.1.1 + - Image: quay.io/foo/olm:testoperator.v0.1.2 + - Image: quay.io/foo/olm:testoperator.v0.1.3 + - Image: quay.io/foo/olm:testoperator.v0.2.0 + - Image: quay.io/foo/olm:testoperator.v0.2.1 + - Image: quay.io/foo/olm:testoperator.v0.2.2 + - Image: quay.io/foo/olm:testoperator.v0.3.0 + - Image: quay.io/foo/olm:testoperator.v1.0.0 + - Image: quay.io/foo/olm:testoperator.v1.0.1 + - Image: quay.io/foo/olm:testoperator.v1.1.0 +Fast: + Bundles: + - Image: quay.io/foo/olm:testoperator.v0.2.1 + - Image: quay.io/foo/olm:testoperator.v0.2.2 + - Image: quay.io/foo/olm:testoperator.v0.3.0 + - Image: quay.io/foo/olm:testoperator.v1.0.1 + - Image: quay.io/foo/olm:testoperator.v1.1.0 +Stable: + Bundles: + - Image: quay.io/foo/olm:testoperator.v1.0.1 +``` +In this example, `Candidate` has the entire version range of bundles, `Fast` has a mix of older and more-recent versions, and `Stable` channel only has a single published entry. + +### CLI Tool Usage +``` +% ./bin/opm alpha render-template semver -h +Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input + +Usage: + opm alpha render-template semver [FILE] [flags] + +Flags: + -h, --help help for semver + -o, --output string Output format (json|yaml|mermaid) (default "json") + +Global Flags: + --skip-tls-verify skip TLS certificate verification for container image registries while pulling bundles + --use-http use plain HTTP for container image registries while pulling bundles +``` + +Example command usage: +``` +# Example with file argument passed in +opm alpha render-template semver infile.semver.template.yaml + +# Example with no file argument passed in +opm alpha render-template semver -o yaml < infile.semver.template.yaml > outfile.yaml + +# Example with "-" as the file argument passed in +cat infile.semver.template.yaml | opm alpha render-template semver -o mermaid - +``` +Note that if the command is called without a file argument and nothing passed in on standard input, +the command will hang indefinitely. Either a file argument or file information passed +in on standard input is required by the command. + +With the template attribute `GenerateMajorChannels: true` resulting major channels from the command are (skipping the rendered bundle image output): +```yaml +--- +defaultChannel: stable-v1 +name: testoperator +schema: olm.package +--- +entries: +- name: testoperator.v0.1.0 +- name: testoperator.v0.1.1 +- name: testoperator.v0.1.2 +- name: testoperator.v0.1.3 + skips: + - testoperator.v0.1.0 + - testoperator.v0.1.1 + - testoperator.v0.1.2 +- name: testoperator.v0.2.0 +- name: testoperator.v0.2.1 +- name: testoperator.v0.2.2 + replaces: testoperator.v0.1.3 + skips: + - testoperator.v0.2.0 + - testoperator.v0.2.1 +- name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: candidate-v0 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.0 +- name: testoperator.v1.0.1 + skips: + - testoperator.v1.0.0 +- name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: candidate-v1 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v0.2.1 +- name: testoperator.v0.2.2 + skips: + - testoperator.v0.2.1 +- name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: fast-v0 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.1 +- name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: fast-v1 +package: testoperator +schema: olm.channel +--- +entries: +- name: testoperator.v1.0.1 +name: stable-v1 +package: testoperator +schema: olm.channel +``` + +We generated a channel for each template channel entity corresponding to each of the 0.\#.\#, 1.\#.\# major version ranges with skips to the head of the highest semver in a channel. We also generated a replaces edge to traverse across minor version transitions within each major channel. Finally, we generated an `olm.package` object, setting as default the most-stable channel head we created. This process will prefer `Stable` channel over `Fast`, over `Candidate` and then a higher bundle version over a lower version. +(Please note that the naming of the generated channels indicates the digits of significance for that channel. For example, `fast-v1` is a decomposed channel of the `fast` type which contains only major versions of contributing bundles matching `v1`.) + +For contrast, with the template attribute `GenerateMinorChannels: true` and running the command again (again skipping rendered bundle image output) we get a bunch more channels: +```yaml +--- +defaultChannel: stable-v1.0 +name: testoperator +schema: olm.package +--- +entries: + - name: testoperator.v0.1.0 + - name: testoperator.v0.1.1 + - name: testoperator.v0.1.2 + - name: testoperator.v0.1.3 + skips: + - testoperator.v0.1.0 + - testoperator.v0.1.1 + - testoperator.v0.1.2 +name: candidate-v0.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.2.0 + - name: testoperator.v0.2.1 + - name: testoperator.v0.2.2 + replaces: testoperator.v0.1.3 + skips: + - testoperator.v0.2.0 + - testoperator.v0.2.1 +name: candidate-v0.2 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: candidate-v0.3 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.0 + - name: testoperator.v1.0.1 + skips: + - testoperator.v1.0.0 +name: candidate-v1.0 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: candidate-v1.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.2.1 + - name: testoperator.v0.2.2 + skips: + - testoperator.v0.2.1 +name: fast-v0.2 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v0.3.0 + replaces: testoperator.v0.2.2 +name: fast-v0.3 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.1 +name: fast-v1.0 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.1.0 + replaces: testoperator.v1.0.1 +name: fast-v1.1 +package: testoperator +schema: olm.channel +--- +entries: + - name: testoperator.v1.0.1 +name: stable-v1.0 +package: testoperator +schema: olm.channel + +``` +Here, a channel is generated for each template channel which differs by minor version, and each channel has a `replaces` edge from the predecessor channel to the next-lesser minor bundle version. Please note that at no time do we transgress across major-version boundaries with the channels, to be consistent with [the semver convention](https://semver.org/) for major versions, where the purpose is to make incompatible API changes. + + +### DEMOS + +#### Major Channel Generation +![`GenerateMajorChannels`](./major-version-demo.gif) + +#### Minor Channel Generation +![`GenerateMinorChannels`](./minor-version-demo.gif) + + diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/major-version-demo.gif b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/major-version-demo.gif new file mode 100644 index 0000000000..244ecd6dbb Binary files /dev/null and b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/major-version-demo.gif differ diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/minor-version-demo.gif b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/minor-version-demo.gif new file mode 100644 index 0000000000..af0fea0b36 Binary files /dev/null and b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/minor-version-demo.gif differ diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/semver.go b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/semver.go new file mode 100644 index 0000000000..601047d261 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/alpha/template/semver/semver.go @@ -0,0 +1,477 @@ +package semver + +import ( + "context" + "encoding/json" + "fmt" + "io" + "sort" + + "github.com/blang/semver/v4" + "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "sigs.k8s.io/yaml" + + "github.com/operator-framework/operator-registry/alpha/action" + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/property" + "github.com/operator-framework/operator-registry/pkg/image" +) + +// data passed into this module externally +type Template struct { + Data io.Reader + Registry image.Registry +} + +// IO structs -- BEGIN +type semverTemplateBundleEntry struct { + Image string `json:"image,omitempty"` +} + +type candidateBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} +type fastBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} +type stableBundles struct { + Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` +} + +type semverTemplate struct { + Schema string `json:"schema"` + GenerateMajorChannels bool `json:"generateMajorChannels,omitempty"` + GenerateMinorChannels bool `json:"generateMinorChannels,omitempty"` + AvoidSkipPatch bool `json:"avoidSkipPatch,omitempty"` + Candidate candidateBundles `json:"candidate,omitempty"` + Fast fastBundles `json:"fast,omitempty"` + Stable stableBundles `json:"stable,omitempty"` + + pkg string `json:"-"` // the derived package name + defaultChannel string `json:"-"` // detected "most stable" channel head +} + +// IO structs -- END + +// channel "kinds", restricted in this iteration to just these +const ( + candidateChannelName string = "candidate" + fastChannelName string = "fast" + stableChannelName string = "stable" +) + +// mapping channel name --> stability, where higher values indicate greater stability +var channelPriorities = map[string]int{candidateChannelName: 0, fastChannelName: 1, stableChannelName: 2} + +// sorting capability for a slice according to the assigned channelPriorities +type byChannelPriority []string + +func (b byChannelPriority) Len() int { return len(b) } +func (b byChannelPriority) Less(i, j int) bool { + return channelPriorities[b[i]] < channelPriorities[b[j]] +} +func (b byChannelPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] } + +// map of channels : bundles : bundle-version +// channels --> bundles --> version +type semverRenderedChannelVersions map[string]map[string]semver.Version // e.g. d["stable-v1"]["example-operator/v1.0.0"] = 1.0.0 + +func (t Template) Render(ctx context.Context) (*declcfg.DeclarativeConfig, error) { + var out declcfg.DeclarativeConfig + + sv, err := readFile(t.Data) + if err != nil { + return nil, fmt.Errorf("semver-render: unable to read file: %v", err) + } + + var cfgs []declcfg.DeclarativeConfig + + bundleDict := make(map[string]struct{}) + buildBundleList(&sv.Candidate.Bundles, &bundleDict) + buildBundleList(&sv.Fast.Bundles, &bundleDict) + buildBundleList(&sv.Stable.Bundles, &bundleDict) + + for b, _ := range bundleDict { + r := action.Render{ + AllowedRefMask: action.RefBundleImage, + Refs: []string{b}, + Registry: t.Registry, + } + c, err := r.Run(ctx) + if err != nil { + return nil, err + } + cfgs = append(cfgs, *c) + } + out = *combineConfigs(cfgs) + + if len(out.Bundles) == 0 { + return nil, fmt.Errorf("semver-render: no bundles specified or no bundles could be rendered") + } + + channelBundleVersions, err := sv.getVersionsFromStandardChannels(&out) + if err != nil { + return nil, fmt.Errorf("semver-render: unable to post-process bundle info: %v", err) + } + + channels := sv.generateChannels(channelBundleVersions) + out.Channels = channels + out.Packages[0].DefaultChannel = sv.defaultChannel + + return &out, nil +} + +func buildBundleList(bundles *[]semverTemplateBundleEntry, dict *map[string]struct{}) { + for _, b := range *bundles { + if _, ok := (*dict)[b.Image]; !ok { + (*dict)[b.Image] = struct{}{} + } + } +} + +func readFile(reader io.Reader) (*semverTemplate, error) { + data, err := io.ReadAll(reader) + if err != nil { + return nil, err + } + + // default behavior is to generate only minor channels and to use skips over replaces + sv := semverTemplate{ + GenerateMajorChannels: false, + GenerateMinorChannels: true, + AvoidSkipPatch: false, + } + if err := yaml.Unmarshal(data, &sv, func(decoder *json.Decoder) *json.Decoder { + decoder.DisallowUnknownFields() + return decoder + }); err != nil { + return nil, err + } + return &sv, nil +} + +func (sv *semverTemplate) getVersionsFromStandardChannels(cfg *declcfg.DeclarativeConfig) (*semverRenderedChannelVersions, error) { + versions := semverRenderedChannelVersions{} + + bdm, err := sv.getVersionsFromChannel(sv.Candidate.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[candidateChannelName] = bdm + + bdm, err = sv.getVersionsFromChannel(sv.Fast.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[fastChannelName] = bdm + + bdm, err = sv.getVersionsFromChannel(sv.Stable.Bundles, cfg) + if err != nil { + return nil, err + } + if err = validateVersions(&bdm); err != nil { + return nil, err + } + versions[stableChannelName] = bdm + + return &versions, nil +} + +func (sv *semverTemplate) getVersionsFromChannel(semverBundles []semverTemplateBundleEntry, cfg *declcfg.DeclarativeConfig) (map[string]semver.Version, error) { + entries := make(map[string]semver.Version) + + // we iterate over the channel bundles from the template, to: + // - identify if any required bundles for the channel are missing/not rendered/otherwise unavailable + // - maintain the channel-bundle relationship as we map from un-rendered semver template bundles to rendered bundles in `entries` which is accumulated by the caller + // in a per-channel structure to which we can safely refer when generating/linking channels + for _, semverBundle := range semverBundles { + // test if the bundle specified in the template is present in the successfully-rendered bundles + index := 0 + for index < len(cfg.Bundles) { + if cfg.Bundles[index].Image == semverBundle.Image { + break + } + index++ + } + if index == len(cfg.Bundles) { + return nil, fmt.Errorf("supplied bundle image name %q not found in rendered bundle images", semverBundle.Image) + } + b := cfg.Bundles[index] + + props, err := property.Parse(b.Properties) + if err != nil { + return nil, fmt.Errorf("parse properties for bundle %q: %v", b.Name, err) + } + if len(props.Packages) != 1 { + return nil, fmt.Errorf("bundle %q has multiple %q properties, expected exactly 1", b.Name, property.TypePackage) + } + v, err := semver.Parse(props.Packages[0].Version) + if err != nil { + return nil, fmt.Errorf("bundle %q has invalid version %q: %v", b.Name, props.Packages[0].Version, err) + } + + // package name detection + if sv.pkg != "" { + // if we have a known package name, then ensure all subsequent packages match + if props.Packages[0].PackageName != sv.pkg { + return nil, fmt.Errorf("bundle %q does not belong to this package: %q", props.Packages[0].PackageName, sv.pkg) + } + } else { + // else cache the first + p := newPackage(props.Packages[0].PackageName) + cfg.Packages = append(cfg.Packages, *p) + sv.pkg = props.Packages[0].PackageName + } + + if _, ok := entries[b.Name]; ok { + return nil, fmt.Errorf("duplicate bundle name %q", b.Name) + } + + entries[b.Name] = v + } + + return entries, nil +} + +// the "high-water channel" struct functions as a freely-rising indicator of the "most stable" channel head, so we can use that +// later as the package's defaultChannel attribute +type highwaterChannel struct { + kind string + version semver.Version + name string +} + +func (h *highwaterChannel) gt(ih *highwaterChannel) bool { + return (channelPriorities[h.kind] > channelPriorities[ih.kind]) || (h.version.GT(ih.version)) +} + +// generates an unlinked channel for each channel as per the input template config (major || minor), then link up the edges of the set of channels so that: +// - (for major channels) iterating to a new minor version channel (traversing between Y-streams) creates a 'replaces' edge between the predecessor and successor bundles +// - within the same minor version (Y-stream), the head of the channel should have a 'skips' encompassing all lesser minor versions of the bundle enumerated in the template. +// along the way, uses a highwaterChannel marker to identify the "most stable" channel head to be used as the default channel for the generated package +func (sv *semverTemplate) generateChannels(semverChannels *semverRenderedChannelVersions) []declcfg.Channel { + outChannels := []declcfg.Channel{} + + // sort the channelkinds in ascending order so we can traverse the bundles in order of + // their source channel's priority + var keysByPriority []string + for k, _ := range channelPriorities { + keysByPriority = append(keysByPriority, k) + } + sort.Sort(byChannelPriority(keysByPriority)) + + // set to the least-priority channel + hwc := highwaterChannel{kind: keysByPriority[0], version: semver.Version{Major: 0, Minor: 0}} + + // mapping the generated channel name to the original semver name (i.e. channel kind), so we can do generated-channel-name --> original-semver-name --> version mapping, later + channelMapping := map[string]string{} + + for _, k := range keysByPriority { + bundles := (*semverChannels)[k] + + // skip channel if empty + if len(bundles) == 0 { + continue + } + + // sort the bundle names according to their semver, so we can walk in ascending order + bundleNamesByVersion := []string{} + for b := range bundles { + bundleNamesByVersion = append(bundleNamesByVersion, b) + } + sort.Slice(bundleNamesByVersion, func(i, j int) bool { + return bundles[bundleNamesByVersion[i]].LT(bundles[bundleNamesByVersion[j]]) + }) + + majors := map[string]*declcfg.Channel{} + minors := map[string]*declcfg.Channel{} + + for _, b := range bundleNamesByVersion { + if sv.GenerateMajorChannels { + testChannelName := channelNameFromMajor(k, bundles[b]) + ch, ok := majors[testChannelName] + if !ok { + ch = newChannel(sv.pkg, testChannelName) + majors[testChannelName] = ch + } + ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) + + channelMapping[testChannelName] = k + + hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} + if hwcCandidate.gt(&hwc) { + hwc = hwcCandidate + } + } + if sv.GenerateMinorChannels { + testChannelName := channelNameFromMinor(k, bundles[b]) + ch, ok := minors[testChannelName] + if !ok { + ch = newChannel(sv.pkg, testChannelName) + minors[testChannelName] = ch + } + ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) + + channelMapping[testChannelName] = k + + hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} + if hwcCandidate.gt(&hwc) { + hwc = hwcCandidate + } + } + } + + outChannels = append(outChannels, sv.linkChannels(majors, sv.pkg, semverChannels, &channelMapping)...) + outChannels = append(outChannels, sv.linkChannels(minors, sv.pkg, semverChannels, &channelMapping)...) + } + + // save off the name of the high-water-mark channel for the default for this package + sv.defaultChannel = hwc.name + + return outChannels +} + +// all channels that come to linkChannels MUST have the same prefix. This adds replaces edges of minor versions of the largest major version. +func (sv *semverTemplate) linkChannels(unlinkedChannels map[string]*declcfg.Channel, pkg string, semverChannels *semverRenderedChannelVersions, channelMapping *map[string]string) []declcfg.Channel { + channels := []declcfg.Channel{} + + for channelName, channel := range unlinkedChannels { + // sort the channel entries in ascending order, according to the corresponding bundle versions for the channelName stored in the semverRenderedChannelVersions + // convenience function, to make this more clear + versionLookup := func(generatedChannelName string, channelEdgeIndex int) semver.Version { + channelKind := (*channelMapping)[generatedChannelName] + bundleVersions := (*semverChannels)[channelKind] + bundleName := channel.Entries[channelEdgeIndex].Name + return bundleVersions[bundleName] + } + + sort.Slice(channel.Entries, func(i, j int) bool { + return versionLookup(channelName, i).LT(versionLookup(channelName, j)) + }) + + // link up the edges according to config + if sv.AvoidSkipPatch { + for i := 1; i < len(channel.Entries); i++ { + channel.Entries[i] = declcfg.ChannelEntry{ + Name: channel.Entries[i].Name, + Replaces: channel.Entries[i-1].Name, + } + } + } else { + curIndex := len(channel.Entries) - 1 + curMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][channel.Entries[curIndex].Name]) + curSkips := sets.NewString() + for i := len(channel.Entries) - 2; i >= 0; i-- { + thisName := channel.Entries[i].Name + thisMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][thisName]) + if thisMinor.EQ(curMinor) { + channel.Entries[i] = declcfg.ChannelEntry{Name: thisName} + curSkips = curSkips.Insert(thisName) + } else { + channel.Entries[curIndex] = declcfg.ChannelEntry{ + Name: channel.Entries[curIndex].Name, + Replaces: thisName, + Skips: curSkips.List(), + } + curSkips = sets.NewString() + curIndex = i + curMinor = thisMinor + } + } + channel.Entries[curIndex] = declcfg.ChannelEntry{ + Name: channel.Entries[curIndex].Name, + Skips: curSkips.List(), + } + } + channels = append(channels, *channel) + } + return channels +} + +func channelNameFromMinor(prefix string, version semver.Version) string { + return fmt.Sprintf("%s-v%d.%d", prefix, version.Major, version.Minor) +} + +func channelNameFromMajor(prefix string, version semver.Version) string { + return fmt.Sprintf("%s-v%d", prefix, version.Major) +} + +func newPackage(name string) *declcfg.Package { + return &declcfg.Package{ + Schema: "olm.package", + Name: name, + DefaultChannel: "", + } +} + +func newChannel(pkgName string, chName string) *declcfg.Channel { + return &declcfg.Channel{ + Schema: "olm.channel", + Name: string(chName), + Package: pkgName, + Entries: []declcfg.ChannelEntry{}, + } +} + +func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig { + out := &declcfg.DeclarativeConfig{} + for _, in := range cfgs { + out.Packages = append(out.Packages, in.Packages...) + out.Channels = append(out.Channels, in.Channels...) + out.Bundles = append(out.Bundles, in.Bundles...) + out.Others = append(out.Others, in.Others...) + } + return out +} + +func getMinorVersion(v semver.Version) semver.Version { + return semver.Version{ + Major: v.Major, + Minor: v.Minor, + } +} + +func withoutBuildMetadataConflict(versions *map[string]semver.Version) error { + errs := []error{} + + // using the stringified semver because the semver package generates deterministic representations, + // and because the semver.Version contains slice fields which make it unsuitable as a map key + // stringified-semver.Version ==> incidence count + seen := make(map[string]int) + for b := range *versions { + stripped := stripBuildMetadata((*versions)[b]) + if _, ok := seen[stripped]; !ok { + seen[stripped] = 1 + } else { + seen[stripped] = seen[stripped] + 1 + errs = append(errs, fmt.Errorf("bundle version %q cannot be compared to %q", (*versions)[b].String(), stripped)) + } + } + + if len(errs) != 0 { + return fmt.Errorf("encountered bundle versions which differ only by build metadata, which cannot be ordered: %v", errors.NewAggregate(errs)) + } + + return nil +} + +func validateVersions(versions *map[string]semver.Version) error { + // short-circuit if empty, since that is not an error + if len(*versions) == 0 { + return nil + } + return withoutBuildMetadataConflict(versions) +} + +// strips out the build metadata from a semver.Version and then stringifies it to make it suitable for collision detection +func stripBuildMetadata(v semver.Version) string { + v.Build = nil + return v.String() +} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/basic/basic.go b/vendor/github.com/operator-framework/operator-registry/alpha/veneer/basic/basic.go deleted file mode 100644 index 26c2788b57..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/basic/basic.go +++ /dev/null @@ -1,50 +0,0 @@ -package basic - -import ( - "context" - "fmt" - "io" - - "github.com/operator-framework/operator-registry/alpha/action" - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/pkg/image" -) - -type Veneer struct { - Registry image.Registry -} - -func (v Veneer) Render(ctx context.Context, reader io.Reader) (*declcfg.DeclarativeConfig, error) { - cfg, err := declcfg.LoadReader(reader) - if err != nil { - return cfg, err - } - - outb := cfg.Bundles[:0] // allocate based on max size of input, but empty slice - // populate registry, incl any flags from CLI, and enforce only rendering bundle images - r := action.Render{ - Registry: v.Registry, - AllowedRefMask: action.RefBundleImage, - } - - for _, b := range cfg.Bundles { - if !isBundleVeneer(&b) { - return nil, fmt.Errorf("unexpected fields present in basic veneer bundle") - } - r.Refs = []string{b.Image} - contributor, err := r.Run(ctx) - if err != nil { - return nil, err - } - outb = append(outb, contributor.Bundles...) - } - - cfg.Bundles = outb - return cfg, nil -} - -// isBundleVeneer identifies a Bundle veneer source as having a Schema and Image defined -// but no Properties, RelatedImages or Package defined -func isBundleVeneer(b *declcfg.Bundle) bool { - return b.Schema != "" && b.Image != "" && b.Package == "" && len(b.Properties) == 0 && len(b.RelatedImages) == 0 -} diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/README.md b/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/README.md deleted file mode 100644 index e69726c487..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/README.md +++ /dev/null @@ -1,259 +0,0 @@ -## Semver Veneer: - -Since a `veneer` is identified as an input schema which may be processed to generate a valid FBC, we can define a `semver veneer` as a schema which uses channel conventions to facilitate the auto-generation of channels along `semver` delimiters. - -[**DISCLAIMER:** since version build metadata [MUST be ignored when determining version precedence](https://semver.org) when using semver, it cannot be used in any bundle included in the `semver veneer` and will result in a fatal error.] - -### Schema Goals -The `semver veneer` must have: -- terse grammar to minimize creation/maintenance effort -- deterministic output -- simple channel promotion for maturing bundles -- demonstration of a common type of channel maturity model -- minor-version (Y-stream), major-version (X-stream) versioning optionality - -The resulting FBC must clearly indicate how generated channels relate to veneer entities - -### Schema Anatomy -For convenience and simplicity, this veneer currently supports hard-coded channel names `Candidate`, `Fast`, and `Stable`, in order of increasing channel stability. We leverage this relationship to calculate the default channel for the package. - -`GenerateMajorChannels` and `GenerateMinorChannels` dictate whether this veneer will generate X-stream or Y-stream channels (attributes can be set independently). If omitted, only minor (Y-stream) channels will be generated. - -Under each channel are a list of bundle image references which contribute to that channel. - -With the following (hypothetical) example we define a mock bundle which has 11 versions, represented across each of the channel types: -```yaml -Schema: olm.semver -GenerateMajorChannels: true -GenerateMinorChannels: true -Candidate: - Bundles: - - Image: quay.io/foo/olm:testoperator.v0.1.0 - - Image: quay.io/foo/olm:testoperator.v0.1.1 - - Image: quay.io/foo/olm:testoperator.v0.1.2 - - Image: quay.io/foo/olm:testoperator.v0.1.3 - - Image: quay.io/foo/olm:testoperator.v0.2.0 - - Image: quay.io/foo/olm:testoperator.v0.2.1 - - Image: quay.io/foo/olm:testoperator.v0.2.2 - - Image: quay.io/foo/olm:testoperator.v0.3.0 - - Image: quay.io/foo/olm:testoperator.v1.0.0 - - Image: quay.io/foo/olm:testoperator.v1.0.1 - - Image: quay.io/foo/olm:testoperator.v1.1.0 -Fast: - Bundles: - - Image: quay.io/foo/olm:testoperator.v0.2.1 - - Image: quay.io/foo/olm:testoperator.v0.2.2 - - Image: quay.io/foo/olm:testoperator.v0.3.0 - - Image: quay.io/foo/olm:testoperator.v1.0.1 - - Image: quay.io/foo/olm:testoperator.v1.1.0 -Stable: - Bundles: - - Image: quay.io/foo/olm:testoperator.v1.0.1 -``` -In this example, `Candidate` has the entire version range of bundles, `Fast` has a mix of older and more-recent versions, and `Stable` channel only has a single published entry. - -### CLI Tool Usage -``` -% ./bin/opm alpha render-veneer semver -h -Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input - -Usage: - opm alpha render-veneer semver [FILE] [flags] - -Flags: - -h, --help help for semver - -o, --output string Output format (json|yaml|mermaid) (default "json") - -Global Flags: - --skip-tls-verify skip TLS certificate verification for container image registries while pulling bundles - --use-http use plain HTTP for container image registries while pulling bundles -``` - -Example command usage: -``` -# Example with file argument passed in -opm alpha render-veneer semver infile.semver.veneer.yaml - -# Example with no file argument passed in -opm alpha render-veneer semver -o yaml < infile.semver.veneer.yaml > outfile.yaml - -# Example with "-" as the file argument passed in -cat infile.semver.veneer.yaml | opm alpha render-veneer semver -o mermaid - -``` -Note that if the command is called without a file argument and nothing passed in on standard input, -the command will hang indefinitely. Either a file argument or file information passed -in on standard input is required by the command. - -With the veneer attribute `GenerateMajorChannels: true` resulting major channels from the command are (skipping the rendered bundle image output): -```yaml ---- -defaultChannel: stable-v1 -name: testoperator -schema: olm.package ---- -entries: -- name: testoperator.v0.1.0 -- name: testoperator.v0.1.1 -- name: testoperator.v0.1.2 -- name: testoperator.v0.1.3 - skips: - - testoperator.v0.1.0 - - testoperator.v0.1.1 - - testoperator.v0.1.2 -- name: testoperator.v0.2.0 -- name: testoperator.v0.2.1 -- name: testoperator.v0.2.2 - replaces: testoperator.v0.1.3 - skips: - - testoperator.v0.2.0 - - testoperator.v0.2.1 -- name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: candidate-v0 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.0 -- name: testoperator.v1.0.1 - skips: - - testoperator.v1.0.0 -- name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: candidate-v1 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v0.2.1 -- name: testoperator.v0.2.2 - skips: - - testoperator.v0.2.1 -- name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: fast-v0 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.1 -- name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: fast-v1 -package: testoperator -schema: olm.channel ---- -entries: -- name: testoperator.v1.0.1 -name: stable-v1 -package: testoperator -schema: olm.channel -``` - -We generated a channel for each veneer channel entity corresponding to each of the 0.\#.\#, 1.\#.\# major version ranges with skips to the head of the highest semver in a channel. We also generated a replaces edge to traverse across minor version transitions within each major channel. Finally, we generated an `olm.package` object, setting as default the most-stable channel head we created. This process will prefer `Stable` channel over `Fast`, over `Candidate` and then a higher bundle version over a lower version. -(Please note that the naming of the generated channels indicates the digits of significance for that channel. For example, `fast-v1` is a decomposed channel of the `fast` type which contains only major versions of contributing bundles matching `v1`.) - -For contrast, with the veneer attribute `GenerateMinorChannels: true` and running the command again (again skipping rendered bundle image output) we get a bunch more channels: -```yaml ---- -defaultChannel: stable-v1.0 -name: testoperator -schema: olm.package ---- -entries: - - name: testoperator.v0.1.0 - - name: testoperator.v0.1.1 - - name: testoperator.v0.1.2 - - name: testoperator.v0.1.3 - skips: - - testoperator.v0.1.0 - - testoperator.v0.1.1 - - testoperator.v0.1.2 -name: candidate-v0.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.2.0 - - name: testoperator.v0.2.1 - - name: testoperator.v0.2.2 - replaces: testoperator.v0.1.3 - skips: - - testoperator.v0.2.0 - - testoperator.v0.2.1 -name: candidate-v0.2 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: candidate-v0.3 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.0 - - name: testoperator.v1.0.1 - skips: - - testoperator.v1.0.0 -name: candidate-v1.0 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: candidate-v1.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.2.1 - - name: testoperator.v0.2.2 - skips: - - testoperator.v0.2.1 -name: fast-v0.2 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v0.3.0 - replaces: testoperator.v0.2.2 -name: fast-v0.3 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.1 -name: fast-v1.0 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.1.0 - replaces: testoperator.v1.0.1 -name: fast-v1.1 -package: testoperator -schema: olm.channel ---- -entries: - - name: testoperator.v1.0.1 -name: stable-v1.0 -package: testoperator -schema: olm.channel - -``` -Here, a channel is generated for each veneer channel which differs by minor version, and each channel has a `replaces` edge from the predecessor channel to the next-lesser minor bundle version. Please note that at no time do we transgress across major-version boundaries with the channels, to be consistent with [the semver convention](https://semver.org/) for major versions, where the purpose is to make incompatible API changes. - - -### DEMOS - -#### Major Channel Generation -![`GenerateMajorChannels`](./major-version-demo.gif) - -#### Minor Channel Generation -![`GenerateMinorChannels`](./minor-version-demo.gif) - - diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/major-version-demo.gif b/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/major-version-demo.gif deleted file mode 100644 index bf2faa3795..0000000000 Binary files a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/major-version-demo.gif and /dev/null differ diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/minor-version-demo.gif b/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/minor-version-demo.gif deleted file mode 100644 index 3644292b92..0000000000 Binary files a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/minor-version-demo.gif and /dev/null differ diff --git a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/semver.go b/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/semver.go deleted file mode 100644 index 00edcc64f4..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/alpha/veneer/semver/semver.go +++ /dev/null @@ -1,472 +0,0 @@ -package semver - -import ( - "context" - "fmt" - "io" - "sort" - - "github.com/blang/semver/v4" - "github.com/operator-framework/operator-registry/alpha/action" - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/property" - "github.com/operator-framework/operator-registry/pkg/image" - "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/yaml" -) - -// data passed into this module externally -type Veneer struct { - Data io.Reader - Registry image.Registry -} - -// IO structs -- BEGIN -type semverVeneerBundleEntry struct { - Image string `json:"image,omitempty"` -} - -type candidateBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} -type fastBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} -type stableBundles struct { - Bundles []semverVeneerBundleEntry `json:"bundles,omitempty"` -} - -type semverVeneer struct { - Schema string `json:"schema"` - GenerateMajorChannels bool `json:"generateMajorChannels,omitempty"` - GenerateMinorChannels bool `json:"generateMinorChannels,omitempty"` - AvoidSkipPatch bool `json:"avoidSkipPatch,omitempty"` - Candidate candidateBundles `json:"candidate,omitempty"` - Fast fastBundles `json:"fast,omitempty"` - Stable stableBundles `json:"stable,omitempty"` - - pkg string `json:"-"` // the derived package name - defaultChannel string `json:"-"` // detected "most stable" channel head -} - -// IO structs -- END - -// channel "kinds", restricted in this iteration to just these -const ( - candidateChannelName string = "candidate" - fastChannelName string = "fast" - stableChannelName string = "stable" -) - -// mapping channel name --> stability, where higher values indicate greater stability -var channelPriorities = map[string]int{candidateChannelName: 0, fastChannelName: 1, stableChannelName: 2} - -// sorting capability for a slice according to the assigned channelPriorities -type byChannelPriority []string - -func (b byChannelPriority) Len() int { return len(b) } -func (b byChannelPriority) Less(i, j int) bool { - return channelPriorities[b[i]] < channelPriorities[b[j]] -} -func (b byChannelPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] } - -// map of channels : bundles : bundle-version -// channels --> bundles --> version -type semverRenderedChannelVersions map[string]map[string]semver.Version // e.g. d["stable-v1"]["example-operator/v1.0.0"] = 1.0.0 - -func (v Veneer) Render(ctx context.Context) (*declcfg.DeclarativeConfig, error) { - var out declcfg.DeclarativeConfig - - sv, err := readFile(v.Data) - if err != nil { - return nil, fmt.Errorf("semver-render: unable to read file: %v", err) - } - - var cfgs []declcfg.DeclarativeConfig - - bundleDict := make(map[string]struct{}) - buildBundleList(&sv.Candidate.Bundles, &bundleDict) - buildBundleList(&sv.Fast.Bundles, &bundleDict) - buildBundleList(&sv.Stable.Bundles, &bundleDict) - - for b, _ := range bundleDict { - r := action.Render{ - AllowedRefMask: action.RefBundleImage, - Refs: []string{b}, - Registry: v.Registry, - } - c, err := r.Run(ctx) - if err != nil { - return nil, err - } - cfgs = append(cfgs, *c) - } - out = *combineConfigs(cfgs) - - if len(out.Bundles) == 0 { - return nil, fmt.Errorf("semver-render: no bundles specified or no bundles could be rendered") - } - - channelBundleVersions, err := sv.getVersionsFromStandardChannels(&out) - if err != nil { - return nil, fmt.Errorf("semver-render: unable to post-process bundle info: %v", err) - } - - channels := sv.generateChannels(channelBundleVersions) - out.Channels = channels - out.Packages[0].DefaultChannel = sv.defaultChannel - - return &out, nil -} - -func buildBundleList(bundles *[]semverVeneerBundleEntry, dict *map[string]struct{}) { - for _, b := range *bundles { - if _, ok := (*dict)[b.Image]; !ok { - (*dict)[b.Image] = struct{}{} - } - } -} - -func readFile(data io.Reader) (*semverVeneer, error) { - fileData, err := io.ReadAll(data) - if err != nil { - return nil, err - } - - // default behavior is to generate only minor channels and to use skips over replaces - sv := semverVeneer{ - GenerateMajorChannels: false, - GenerateMinorChannels: true, - AvoidSkipPatch: false, - } - if err := yaml.Unmarshal(fileData, &sv); err != nil { - return nil, err - } - return &sv, nil -} - -func (sv *semverVeneer) getVersionsFromStandardChannels(cfg *declcfg.DeclarativeConfig) (*semverRenderedChannelVersions, error) { - versions := semverRenderedChannelVersions{} - - bdm, err := sv.getVersionsFromChannel(sv.Candidate.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[candidateChannelName] = bdm - - bdm, err = sv.getVersionsFromChannel(sv.Fast.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[fastChannelName] = bdm - - bdm, err = sv.getVersionsFromChannel(sv.Stable.Bundles, cfg) - if err != nil { - return nil, err - } - if err = validateVersions(&bdm); err != nil { - return nil, err - } - versions[stableChannelName] = bdm - - return &versions, nil -} - -func (sv *semverVeneer) getVersionsFromChannel(semverBundles []semverVeneerBundleEntry, cfg *declcfg.DeclarativeConfig) (map[string]semver.Version, error) { - entries := make(map[string]semver.Version) - - // we iterate over the channel bundles from the veneer, to: - // - identify if any required bundles for the channel are missing/not rendered/otherwise unavailable - // - maintain the channel-bundle relationship as we map from un-rendered semver veneer bundles to rendered bundles in `entries` which is accumulated by the caller - // in a per-channel structure to which we can safely refer when generating/linking channels - for _, semverBundle := range semverBundles { - // test if the bundle specified in the veneer is present in the successfully-rendered bundles - index := 0 - for index < len(cfg.Bundles) { - if cfg.Bundles[index].Image == semverBundle.Image { - break - } - index++ - } - if index == len(cfg.Bundles) { - return nil, fmt.Errorf("supplied bundle image name %q not found in rendered bundle images", semverBundle.Image) - } - b := cfg.Bundles[index] - - props, err := property.Parse(b.Properties) - if err != nil { - return nil, fmt.Errorf("parse properties for bundle %q: %v", b.Name, err) - } - if len(props.Packages) != 1 { - return nil, fmt.Errorf("bundle %q has multiple %q properties, expected exactly 1", b.Name, property.TypePackage) - } - v, err := semver.Parse(props.Packages[0].Version) - if err != nil { - return nil, fmt.Errorf("bundle %q has invalid version %q: %v", b.Name, props.Packages[0].Version, err) - } - - // package name detection - if sv.pkg != "" { - // if we have a known package name, then ensure all subsequent packages match - if props.Packages[0].PackageName != sv.pkg { - return nil, fmt.Errorf("bundle %q does not belong to this package: %q", props.Packages[0].PackageName, sv.pkg) - } - } else { - // else cache the first - p := newPackage(props.Packages[0].PackageName) - cfg.Packages = append(cfg.Packages, *p) - sv.pkg = props.Packages[0].PackageName - } - - if _, ok := entries[b.Name]; ok { - return nil, fmt.Errorf("duplicate bundle name %q", b.Name) - } - - entries[b.Name] = v - } - - return entries, nil -} - -// the "high-water channel" struct functions as a freely-rising indicator of the "most stable" channel head, so we can use that -// later as the package's defaultChannel attribute -type highwaterChannel struct { - kind string - version semver.Version - name string -} - -func (h *highwaterChannel) gt(ih *highwaterChannel) bool { - return (channelPriorities[h.kind] > channelPriorities[ih.kind]) || (h.version.GT(ih.version)) -} - -// generates an unlinked channel for each channel as per the input veneer config (major || minor), then link up the edges of the set of channels so that: -// - (for major channels) iterating to a new minor version channel (traversing between Y-streams) creates a 'replaces' edge between the predecessor and successor bundles -// - within the same minor version (Y-stream), the head of the channel should have a 'skips' encompassing all lesser minor versions of the bundle enumerated in the veneer. -// along the way, uses a highwaterChannel marker to identify the "most stable" channel head to be used as the default channel for the generated package -func (sv *semverVeneer) generateChannels(semverChannels *semverRenderedChannelVersions) []declcfg.Channel { - outChannels := []declcfg.Channel{} - - // sort the channelkinds in ascending order so we can traverse the bundles in order of - // their source channel's priority - var keysByPriority []string - for k, _ := range channelPriorities { - keysByPriority = append(keysByPriority, k) - } - sort.Sort(byChannelPriority(keysByPriority)) - - // set to the least-priority channel - hwc := highwaterChannel{kind: keysByPriority[0], version: semver.Version{Major: 0, Minor: 0}} - - // mapping the generated channel name to the original semver name (i.e. channel kind), so we can do generated-channel-name --> original-semver-name --> version mapping, later - channelMapping := map[string]string{} - - for _, k := range keysByPriority { - bundles := (*semverChannels)[k] - - // skip channel if empty - if len(bundles) == 0 { - continue - } - - // sort the bundle names according to their semver, so we can walk in ascending order - bundleNamesByVersion := []string{} - for b := range bundles { - bundleNamesByVersion = append(bundleNamesByVersion, b) - } - sort.Slice(bundleNamesByVersion, func(i, j int) bool { - return bundles[bundleNamesByVersion[i]].LT(bundles[bundleNamesByVersion[j]]) - }) - - majors := map[string]*declcfg.Channel{} - minors := map[string]*declcfg.Channel{} - - for _, b := range bundleNamesByVersion { - if sv.GenerateMajorChannels { - testChannelName := channelNameFromMajor(k, bundles[b]) - ch, ok := majors[testChannelName] - if !ok { - ch = newChannel(sv.pkg, testChannelName) - majors[testChannelName] = ch - } - ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) - - channelMapping[testChannelName] = k - - hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} - if hwcCandidate.gt(&hwc) { - hwc = hwcCandidate - } - } - if sv.GenerateMinorChannels { - testChannelName := channelNameFromMinor(k, bundles[b]) - ch, ok := minors[testChannelName] - if !ok { - ch = newChannel(sv.pkg, testChannelName) - minors[testChannelName] = ch - } - ch.Entries = append(ch.Entries, declcfg.ChannelEntry{Name: b}) - - channelMapping[testChannelName] = k - - hwcCandidate := highwaterChannel{kind: k, version: bundles[b], name: testChannelName} - if hwcCandidate.gt(&hwc) { - hwc = hwcCandidate - } - } - } - - outChannels = append(outChannels, sv.linkChannels(majors, sv.pkg, semverChannels, &channelMapping)...) - outChannels = append(outChannels, sv.linkChannels(minors, sv.pkg, semverChannels, &channelMapping)...) - } - - // save off the name of the high-water-mark channel for the default for this package - sv.defaultChannel = hwc.name - - return outChannels -} - -// all channels that come to linkChannels MUST have the same prefix. This adds replaces edges of minor versions of the largest major version. -func (sv *semverVeneer) linkChannels(unlinkedChannels map[string]*declcfg.Channel, pkg string, semverChannels *semverRenderedChannelVersions, channelMapping *map[string]string) []declcfg.Channel { - channels := []declcfg.Channel{} - - for channelName, channel := range unlinkedChannels { - // sort the channel entries in ascending order, according to the corresponding bundle versions for the channelName stored in the semverRenderedChannelVersions - // convenience function, to make this more clear - versionLookup := func(generatedChannelName string, channelEdgeIndex int) semver.Version { - channelKind := (*channelMapping)[generatedChannelName] - bundleVersions := (*semverChannels)[channelKind] - bundleName := channel.Entries[channelEdgeIndex].Name - return bundleVersions[bundleName] - } - - sort.Slice(channel.Entries, func(i, j int) bool { - return versionLookup(channelName, i).LT(versionLookup(channelName, j)) - }) - - // link up the edges according to config - if sv.AvoidSkipPatch { - for i := 1; i < len(channel.Entries); i++ { - channel.Entries[i] = declcfg.ChannelEntry{ - Name: channel.Entries[i].Name, - Replaces: channel.Entries[i-1].Name, - } - } - } else { - curIndex := len(channel.Entries) - 1 - curMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][channel.Entries[curIndex].Name]) - curSkips := sets.NewString() - for i := len(channel.Entries) - 2; i >= 0; i-- { - thisName := channel.Entries[i].Name - thisMinor := getMinorVersion((*semverChannels)[(*channelMapping)[channelName]][thisName]) - if thisMinor.EQ(curMinor) { - channel.Entries[i] = declcfg.ChannelEntry{Name: thisName} - curSkips = curSkips.Insert(thisName) - } else { - channel.Entries[curIndex] = declcfg.ChannelEntry{ - Name: channel.Entries[curIndex].Name, - Replaces: thisName, - Skips: curSkips.List(), - } - curSkips = sets.NewString() - curIndex = i - curMinor = thisMinor - } - } - channel.Entries[curIndex] = declcfg.ChannelEntry{ - Name: channel.Entries[curIndex].Name, - Skips: curSkips.List(), - } - } - channels = append(channels, *channel) - } - return channels -} - -func channelNameFromMinor(prefix string, version semver.Version) string { - return fmt.Sprintf("%s-v%d.%d", prefix, version.Major, version.Minor) -} - -func channelNameFromMajor(prefix string, version semver.Version) string { - return fmt.Sprintf("%s-v%d", prefix, version.Major) -} - -func newPackage(name string) *declcfg.Package { - return &declcfg.Package{ - Schema: "olm.package", - Name: name, - DefaultChannel: "", - } -} - -func newChannel(pkgName string, chName string) *declcfg.Channel { - return &declcfg.Channel{ - Schema: "olm.channel", - Name: string(chName), - Package: pkgName, - Entries: []declcfg.ChannelEntry{}, - } -} - -func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig { - out := &declcfg.DeclarativeConfig{} - for _, in := range cfgs { - out.Packages = append(out.Packages, in.Packages...) - out.Channels = append(out.Channels, in.Channels...) - out.Bundles = append(out.Bundles, in.Bundles...) - out.Others = append(out.Others, in.Others...) - } - return out -} - -func getMinorVersion(v semver.Version) semver.Version { - return semver.Version{ - Major: v.Major, - Minor: v.Minor, - } -} - -func withoutBuildMetadataConflict(versions *map[string]semver.Version) error { - errs := []error{} - - // using the stringified semver because the semver package generates deterministic representations, - // and because the semver.Version contains slice fields which make it unsuitable as a map key - // stringified-semver.Version ==> incidence count - seen := make(map[string]int) - for b := range *versions { - stripped := stripBuildMetadata((*versions)[b]) - if _, ok := seen[stripped]; !ok { - seen[stripped] = 1 - } else { - seen[stripped] = seen[stripped] + 1 - errs = append(errs, fmt.Errorf("bundle version %q cannot be compared to %q", (*versions)[b].String(), stripped)) - } - } - - if len(errs) != 0 { - return fmt.Errorf("encountered bundle versions which differ only by build metadata, which cannot be ordered: %v", errors.NewAggregate(errs)) - } - - return nil -} - -func validateVersions(versions *map[string]semver.Version) error { - // short-circuit if empty, since that is not an error - if len(*versions) == 0 { - return nil - } - return withoutBuildMetadataConflict(versions) -} - -// strips out the build metadata from a semver.Version and then stringifies it to make it suitable for collision detection -func stripBuildMetadata(v semver.Version) string { - v.Build = nil - return v.String() -} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/cmd.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/cmd.go index 74e88edbe7..55511cb2ea 100644 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/cmd.go +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/cmd.go @@ -6,7 +6,7 @@ import ( "github.com/operator-framework/operator-registry/cmd/opm/alpha/bundle" "github.com/operator-framework/operator-registry/cmd/opm/alpha/list" rendergraph "github.com/operator-framework/operator-registry/cmd/opm/alpha/render-graph" - "github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer" + "github.com/operator-framework/operator-registry/cmd/opm/alpha/template" ) func NewCmd() *cobra.Command { @@ -15,13 +15,14 @@ func NewCmd() *cobra.Command { Use: "alpha", Short: "Run an alpha subcommand", Args: cobra.NoArgs, + Run: func(_ *cobra.Command, _ []string) {}, // adding an empty function here to preserve non-zero exit status for misstated subcommands/flags for the command hierarchy } runCmd.AddCommand( bundle.NewCmd(), list.NewCmd(), rendergraph.NewCmd(), - veneer.NewCmd(), + template.NewCmd(), ) return runCmd } diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/basic.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/basic.go new file mode 100644 index 0000000000..2510a4fa74 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/basic.go @@ -0,0 +1,76 @@ +package template + +import ( + "io" + "io/ioutil" + "log" + "os" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/template/basic" + "github.com/operator-framework/operator-registry/cmd/opm/internal/util" +) + +func newBasicTemplateCmd() *cobra.Command { + var ( + template basic.Template + output string + ) + cmd := &cobra.Command{ + Use: "basic basic-template-file", + Short: `Generate a file-based catalog from a single 'basic template' file +When FILE is '-' or not provided, the template is read from standard input`, + Long: `Generate a file-based catalog from a single 'basic template' file +When FILE is '-' or not provided, the template is read from standard input`, + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + // Handle different input argument types + // When no arguments or "-" is passed to the command, + // assume input is coming from stdin + // Otherwise open the file passed to the command + data, source, err := openFileOrStdin(cmd, args) + if err != nil { + log.Fatalf("unable to open %q: %v", source, err) + } + defer data.Close() + + var write func(declcfg.DeclarativeConfig, io.Writer) error + switch output { + case "yaml": + write = declcfg.WriteYAML + case "json": + write = declcfg.WriteJSON + default: + log.Fatalf("invalid --output value %q, expected (json|yaml)", output) + } + + // The bundle loading impl is somewhat verbose, even on the happy path, + // so discard all logrus default logger logs. Any important failures will be + // returned from template.Render and logged as fatal errors. + logrus.SetOutput(ioutil.Discard) + + reg, err := util.CreateCLIRegistry(cmd) + if err != nil { + log.Fatalf("creating containerd registry: %v", err) + } + defer reg.Destroy() + + template.Registry = reg + + // only taking first file argument + cfg, err := template.Render(cmd.Context(), data) + if err != nil { + log.Fatal(err) + } + + if err := write(*cfg, os.Stdout); err != nil { + log.Fatal(err) + } + }, + } + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") + return cmd +} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/cmd.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/cmd.go new file mode 100644 index 0000000000..1c435e6fa2 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/cmd.go @@ -0,0 +1,30 @@ +package template + +import ( + "io" + "os" + + "github.com/spf13/cobra" +) + +func NewCmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "render-template", + Short: "Render a catalog template type", + Args: cobra.NoArgs, + } + + runCmd.AddCommand(newBasicTemplateCmd()) + runCmd.AddCommand(newSemverTemplateCmd()) + runCmd.AddCommand(newCompositeTemplateCmd()) + + return runCmd +} + +func openFileOrStdin(cmd *cobra.Command, args []string) (io.ReadCloser, string, error) { + if len(args) == 0 || args[0] == "-" { + return io.NopCloser(cmd.InOrStdin()), "stdin", nil + } + reader, err := os.Open(args[0]) + return reader, args[0], err +} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/composite.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/composite.go new file mode 100644 index 0000000000..9cac25c6cf --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/composite.go @@ -0,0 +1,173 @@ +package template + +import ( + "encoding/json" + "fmt" + "log" + "os" + + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/util/yaml" + + "github.com/operator-framework/operator-registry/alpha/template/composite" +) + +func newCompositeTemplateCmd() *cobra.Command { + var ( + template composite.Template + output string + containerTool string + validate bool + compositeFile string + catalogFile string + ) + cmd := &cobra.Command{ + Use: "composite", + Short: `Generate file-based catalogs from a catalog configuration file +and a 'composite template' file`, + Long: `Generate file-based catalogs from a catalog configuration file +and a 'composite template' file`, + Args: cobra.MaximumNArgs(0), + Run: func(cmd *cobra.Command, args []string) { + containerTool = "docker" + catalogData, err := os.Open(catalogFile) + if err != nil { + log.Fatalf("opening catalog config file %q: %s", catalogFile, err) + } + defer catalogData.Close() + + // get catalog configurations + catalogConfig := &composite.CatalogConfig{} + catalogDoc := json.RawMessage{} + catalogDecoder := yaml.NewYAMLOrJSONDecoder(catalogData, 4096) + err = catalogDecoder.Decode(&catalogDoc) + if err != nil { + log.Fatalf("decoding catalog config: %s", err) + } + err = json.Unmarshal(catalogDoc, catalogConfig) + if err != nil { + log.Fatalf("unmarshalling catalog config: %s", err) + } + + if catalogConfig.Schema != composite.CatalogSchema { + log.Fatalf("catalog configuration file has unknown schema, should be %q", composite.CatalogSchema) + } + + catalogBuilderMap := make(composite.CatalogBuilderMap) + + wd, err := os.Getwd() + if err != nil { + log.Fatalf("getting current working directory: %s", err) + } + + // setup the builders for each catalog + setupFailed := false + setupErrors := map[string][]string{} + for _, catalog := range catalogConfig.Catalogs { + errs := []string{} + if catalog.Destination.BaseImage == "" { + errs = append(errs, "destination.baseImage must not be an empty string") + } + + if catalog.Destination.WorkingDir == "" { + errs = append(errs, "destination.workingDir must not be an empty string") + } + + // check for validation errors and skip builder creation if there are any errors + if len(errs) > 0 { + setupFailed = true + setupErrors[catalog.Name] = errs + continue + } + + if _, ok := catalogBuilderMap[catalog.Name]; !ok { + builderMap := make(composite.BuilderMap) + for _, schema := range catalog.Builders { + builder, err := builderForSchema(schema, composite.BuilderConfig{ + ContainerCfg: composite.ContainerConfig{ + ContainerTool: containerTool, + BaseImage: catalog.Destination.BaseImage, + WorkingDir: catalog.Destination.WorkingDir, + }, + OutputType: output, + CurrentDirectory: wd, + }) + if err != nil { + log.Fatalf("getting builder %q for catalog %q: %s", schema, catalog.Name, err) + } + builderMap[schema] = builder + } + catalogBuilderMap[catalog.Name] = builderMap + } + } + + // if there were errors validating the catalog configuration then exit + if setupFailed { + //build the error message + var errMsg string + for cat, errs := range setupErrors { + errMsg += fmt.Sprintf("\nCatalog %s:\n", cat) + for _, err := range errs { + errMsg += fmt.Sprintf(" - %s\n", err) + } + } + log.Fatalf("catalog configuration file field validation failed: %s", errMsg) + } + + template.CatalogBuilders = catalogBuilderMap + + compositeData, err := os.Open(compositeFile) + if err != nil { + log.Fatalf("opening composite config file %q: %s", compositeFile, err) + } + defer compositeData.Close() + + // parse data to composite config + compositeConfig := &composite.CompositeConfig{} + compositeDoc := json.RawMessage{} + compositeDecoder := yaml.NewYAMLOrJSONDecoder(compositeData, 4096) + err = compositeDecoder.Decode(&compositeDoc) + if err != nil { + log.Fatalf("decoding composite config: %s", err) + } + err = json.Unmarshal(compositeDoc, compositeConfig) + if err != nil { + log.Fatalf("unmarshalling composite config: %s", err) + } + + if compositeConfig.Schema != composite.CompositeSchema { + log.Fatalf("%q has unknown schema, should be %q", compositeFile, composite.CompositeSchema) + } + + err = template.Render(cmd.Context(), compositeConfig, validate) + if err != nil { + log.Fatalf("rendering the composite template: %s", err) + } + }, + } + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") + // TODO: Investigate ways to do this without using a cli tool like docker/podman + // cmd.Flags().StringVar(&containerTool, "container-tool", "docker", "container tool to be used when rendering templates (should be an equivalent replacement to docker - similar to podman)") + cmd.Flags().BoolVar(&validate, "validate", true, "whether or not the created FBC should be validated (i.e 'opm validate')") + cmd.Flags().StringVarP(&compositeFile, "composite-config", "c", "catalog/config.yaml", "File to use as the composite configuration file") + cmd.Flags().StringVarP(&catalogFile, "catalog-config", "f", "catalogs.yaml", "File to use as the catalog configuration file") + return cmd +} + +func builderForSchema(schema string, builderCfg composite.BuilderConfig) (composite.Builder, error) { + var builder composite.Builder + switch schema { + case composite.BasicBuilderSchema: + builder = composite.NewBasicBuilder(builderCfg) + case composite.SemverBuilderSchema: + builder = composite.NewSemverBuilder(builderCfg) + case composite.RawBuilderSchema: + builder = composite.NewRawBuilder(builderCfg) + case composite.CustomBuilderSchema: + builder = composite.NewCustomBuilder(builderCfg) + default: + return nil, fmt.Errorf("unknown schema %q", schema) + } + + return builder, nil +} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/semver.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/semver.go new file mode 100644 index 0000000000..dd27fda074 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/template/semver.go @@ -0,0 +1,85 @@ +package template + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "os" + + "github.com/sirupsen/logrus" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/template/semver" + "github.com/operator-framework/operator-registry/cmd/opm/internal/util" + "github.com/spf13/cobra" +) + +func newSemverTemplateCmd() *cobra.Command { + output := "" + cmd := &cobra.Command{ + Use: "semver [FILE]", + Short: `Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input`, + Long: `Generate a file-based catalog from a single 'semver template' file +When FILE is '-' or not provided, the template is read from standard input`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + // Handle different input argument types + // When no arguments or "-" is passed to the command, + // assume input is coming from stdin + // Otherwise open the file passed to the command + data, source, err := openFileOrStdin(cmd, args) + if err != nil { + return err + } + defer data.Close() + + var write func(declcfg.DeclarativeConfig, io.Writer) error + switch output { + case "json": + write = declcfg.WriteJSON + case "yaml": + write = declcfg.WriteYAML + case "mermaid": + write = func(cfg declcfg.DeclarativeConfig, writer io.Writer) error { + mermaidWriter := declcfg.NewMermaidWriter() + return mermaidWriter.WriteChannels(cfg, writer) + } + default: + return fmt.Errorf("invalid output format %q", output) + } + + // The bundle loading impl is somewhat verbose, even on the happy path, + // so discard all logrus default logger logs. Any important failures will be + // returned from template.Render and logged as fatal errors. + logrus.SetOutput(ioutil.Discard) + + reg, err := util.CreateCLIRegistry(cmd) + if err != nil { + log.Fatalf("creating containerd registry: %v", err) + } + defer reg.Destroy() + + template := semver.Template{ + Data: data, + Registry: reg, + } + out, err := template.Render(cmd.Context()) + if err != nil { + log.Fatalf("semver %q: %v", source, err) + } + + if out != nil { + if err := write(*out, os.Stdout); err != nil { + log.Fatal(err) + } + } + + return nil + }, + } + + cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml|mermaid)") + return cmd +} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/basic.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/basic.go deleted file mode 100644 index 40311c0eb2..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/basic.go +++ /dev/null @@ -1,76 +0,0 @@ -package veneer - -import ( - "io" - "io/ioutil" - "log" - "os" - - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/veneer/basic" - "github.com/operator-framework/operator-registry/cmd/opm/internal/util" -) - -func newBasicVeneerRenderCmd() *cobra.Command { - var ( - veneer basic.Veneer - output string - ) - cmd := &cobra.Command{ - Use: "basic basic-veneer-file", - Short: `Generate a file-based catalog from a single 'basic veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Long: `Generate a file-based catalog from a single 'basic veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { - // Handle different input argument types - // When no arguments or "-" is passed to the command, - // assume input is coming from stdin - // Otherwise open the file passed to the command - data, source, err := openFileOrStdin(cmd, args) - if err != nil { - log.Fatalf("unable to open %q: %v", source, err) - } - defer data.Close() - - var write func(declcfg.DeclarativeConfig, io.Writer) error - switch output { - case "yaml": - write = declcfg.WriteYAML - case "json": - write = declcfg.WriteJSON - default: - log.Fatalf("invalid --output value %q, expected (json|yaml)", output) - } - - // The bundle loading impl is somewhat verbose, even on the happy path, - // so discard all logrus default logger logs. Any important failures will be - // returned from veneer.Render and logged as fatal errors. - logrus.SetOutput(ioutil.Discard) - - reg, err := util.CreateCLIRegistry(cmd) - if err != nil { - log.Fatalf("creating containerd registry: %v", err) - } - defer reg.Destroy() - - veneer.Registry = reg - - // only taking first file argument - cfg, err := veneer.Render(cmd.Context(), data) - if err != nil { - log.Fatal(err) - } - - if err := write(*cfg, os.Stdout); err != nil { - log.Fatal(err) - } - }, - } - cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml)") - return cmd -} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/cmd.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/cmd.go deleted file mode 100644 index 2bdec4e1f7..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/cmd.go +++ /dev/null @@ -1,29 +0,0 @@ -package veneer - -import ( - "io" - "os" - - "github.com/spf13/cobra" -) - -func NewCmd() *cobra.Command { - runCmd := &cobra.Command{ - Use: "render-veneer", - Short: "Render a veneer type", - Args: cobra.NoArgs, - } - - runCmd.AddCommand(newBasicVeneerRenderCmd()) - runCmd.AddCommand(newSemverCmd()) - - return runCmd -} - -func openFileOrStdin(cmd *cobra.Command, args []string) (io.ReadCloser, string, error) { - if len(args) == 0 || args[0] == "-" { - return io.NopCloser(cmd.InOrStdin()), "stdin", nil - } - reader, err := os.Open(args[0]) - return reader, args[0], err -} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/semver.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/semver.go deleted file mode 100644 index 0dd4bd122d..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/alpha/veneer/semver.go +++ /dev/null @@ -1,85 +0,0 @@ -package veneer - -import ( - "fmt" - "io" - "io/ioutil" - "log" - "os" - - "github.com/sirupsen/logrus" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/veneer/semver" - "github.com/operator-framework/operator-registry/cmd/opm/internal/util" - "github.com/spf13/cobra" -) - -func newSemverCmd() *cobra.Command { - output := "" - cmd := &cobra.Command{ - Use: "semver [FILE]", - Short: `Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Long: `Generate a file-based catalog from a single 'semver veneer' file -When FILE is '-' or not provided, the veneer is read from standard input`, - Args: cobra.MaximumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - // Handle different input argument types - // When no arguments or "-" is passed to the command, - // assume input is coming from stdin - // Otherwise open the file passed to the command - data, source, err := openFileOrStdin(cmd, args) - if err != nil { - return err - } - defer data.Close() - - var write func(declcfg.DeclarativeConfig, io.Writer) error - switch output { - case "json": - write = declcfg.WriteJSON - case "yaml": - write = declcfg.WriteYAML - case "mermaid": - write = func(cfg declcfg.DeclarativeConfig, writer io.Writer) error { - mermaidWriter := declcfg.NewMermaidWriter() - return mermaidWriter.WriteChannels(cfg, writer) - } - default: - return fmt.Errorf("invalid output format %q", output) - } - - // The bundle loading impl is somewhat verbose, even on the happy path, - // so discard all logrus default logger logs. Any important failures will be - // returned from veneer.Render and logged as fatal errors. - logrus.SetOutput(ioutil.Discard) - - reg, err := util.CreateCLIRegistry(cmd) - if err != nil { - log.Fatalf("creating containerd registry: %v", err) - } - defer reg.Destroy() - - veneer := semver.Veneer{ - Data: data, - Registry: reg, - } - out, err := veneer.Render(cmd.Context()) - if err != nil { - log.Fatalf("semver %q: %v", source, err) - } - - if out != nil { - if err := write(*out, os.Stdout); err != nil { - log.Fatal(err) - } - } - - return nil - }, - } - - cmd.Flags().StringVarP(&output, "output", "o", "json", "Output format (json|yaml|mermaid)") - return cmd -} diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/migrate/cmd.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/migrate/cmd.go index 6405060b0a..36c73abc7a 100644 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/migrate/cmd.go +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/migrate/cmd.go @@ -21,6 +21,10 @@ func NewCmd() *cobra.Command { Short: "Migrate a sqlite-based index image or database file to a file-based catalog", Long: `Migrate a sqlite-based index image or database file to a file-based catalog. +NOTE: the --output=json format produces streamable, concatenated JSON files. +These are suitable to opm and jq, but may not be supported by arbitrary JSON +parsers that assume that a file contains exactly one valid JSON object. + ` + sqlite.DeprecationMessage, Args: cobra.ExactArgs(2), PersistentPreRun: func(_ *cobra.Command, _ []string) { diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/root/cmd.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/root/cmd.go index 9a551f1457..71631c6129 100644 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/root/cmd.go +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/root/cmd.go @@ -28,6 +28,7 @@ func NewCmd() *cobra.Command { return nil }, Args: cobra.NoArgs, + Run: func(_ *cobra.Command, _ []string) {}, // adding an empty function here to preserve non-zero exit status for misstated subcommands/flags for the command hierarchy } cmd.PersistentFlags().Bool("skip-tls", false, "skip TLS certificate verification for container image registries while pulling bundles or index") diff --git a/vendor/github.com/operator-framework/operator-registry/cmd/opm/serve/serve.go b/vendor/github.com/operator-framework/operator-registry/cmd/opm/serve/serve.go index 8b7d280764..633ad9ef3f 100644 --- a/vendor/github.com/operator-framework/operator-registry/cmd/opm/serve/serve.go +++ b/vendor/github.com/operator-framework/operator-registry/cmd/opm/serve/serve.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "io" "net" "net/http" endpoint "net/http/pprof" @@ -20,18 +19,17 @@ import ( "github.com/operator-framework/operator-registry/pkg/api" health "github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1" - "github.com/operator-framework/operator-registry/pkg/cache" "github.com/operator-framework/operator-registry/pkg/lib/dns" "github.com/operator-framework/operator-registry/pkg/lib/graceful" "github.com/operator-framework/operator-registry/pkg/lib/log" + "github.com/operator-framework/operator-registry/pkg/registry" "github.com/operator-framework/operator-registry/pkg/server" ) type serve struct { - configDir string - cacheDir string - cacheOnly bool - cacheEnforceIntegrity bool + configDir string + cacheDir string + cacheOnly bool port string terminationLog string @@ -61,19 +59,15 @@ startup. Changes made to the declarative config after the this command starts will not be reflected in the served content. `, Args: cobra.ExactArgs(1), - PreRun: func(_ *cobra.Command, args []string) { + PreRunE: func(_ *cobra.Command, args []string) error { s.configDir = args[0] if s.debug { logger.SetLevel(logrus.DebugLevel) } + return nil }, - Run: func(cmd *cobra.Command, _ []string) { - if !cmd.Flags().Changed("cache-enforce-integrity") { - s.cacheEnforceIntegrity = s.cacheDir != "" && !s.cacheOnly - } - if err := s.run(cmd.Context()); err != nil { - logger.Fatal(err) - } + RunE: func(cmd *cobra.Command, _ []string) error { + return s.run(cmd.Context()) }, } @@ -83,7 +77,6 @@ will not be reflected in the served content. cmd.Flags().StringVar(&s.pprofAddr, "pprof-addr", "", "address of startup profiling endpoint (addr:port format)") cmd.Flags().StringVar(&s.cacheDir, "cache-dir", "", "if set, sync and persist server cache directory") cmd.Flags().BoolVar(&s.cacheOnly, "cache-only", false, "sync the serve cache and exit without serving") - cmd.Flags().BoolVar(&s.cacheEnforceIntegrity, "cache-enforce-integrity", false, "exit with error if cache is not present or has been invalidated. (default: true when --cache-dir is set and --cache-only is false, false otherwise), ") return cmd } @@ -109,38 +102,11 @@ func (s *serve) run(ctx context.Context) error { s.logger = s.logger.WithFields(logrus.Fields{"configs": s.configDir, "port": s.port}) - if s.cacheDir == "" && s.cacheEnforceIntegrity { - return fmt.Errorf("--cache-dir must be specified with --cache-enforce-integrity") - } - - if s.cacheDir == "" { - s.cacheDir, err = os.MkdirTemp("", "opm-serve-cache-") - if err != nil { - return err - } - defer os.RemoveAll(s.cacheDir) - } - - store, err := cache.New(s.cacheDir) + store, err := registry.NewQuerierFromFS(os.DirFS(s.configDir), s.cacheDir) + defer store.Close() if err != nil { return err } - if storeCloser, ok := store.(io.Closer); ok { - defer storeCloser.Close() - } - if s.cacheEnforceIntegrity { - if err := store.CheckIntegrity(os.DirFS(s.configDir)); err != nil { - return err - } - if err := store.Load(); err != nil { - return err - } - } else { - if err := cache.LoadOrRebuild(store, os.DirFS(s.configDir)); err != nil { - return err - } - } - if s.cacheOnly { return nil } diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/cache.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/cache.go deleted file mode 100644 index 7df08d6f50..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/cache.go +++ /dev/null @@ -1,104 +0,0 @@ -package cache - -import ( - "context" - "errors" - "fmt" - "io/fs" - "os" - "path/filepath" - - "k8s.io/apimachinery/pkg/util/sets" - - "github.com/operator-framework/operator-registry/pkg/api" - "github.com/operator-framework/operator-registry/pkg/registry" -) - -type Cache interface { - registry.GRPCQuery - - CheckIntegrity(fbc fs.FS) error - Build(fbc fs.FS) error - Load() error -} - -func LoadOrRebuild(c Cache, fbc fs.FS) error { - if err := c.CheckIntegrity(fbc); err != nil { - if err := c.Build(fbc); err != nil { - return err - } - } - return c.Load() -} - -// New creates a new Cache. It chooses a cache implementation based -// on the files it finds in the cache directory, with a preference for the -// latest iteration of the cache implementation. It returns an error if -// cacheDir exists and contains unexpected files. -func New(cacheDir string) (Cache, error) { - entries, err := os.ReadDir(cacheDir) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("detect cache format: read cache directory: %v", err) - } - jsonCache := sets.NewString(jsonDir, jsonDigestFile) - - found := sets.NewString() - for _, e := range entries { - found.Insert(e.Name()) - } - - // Preference (and currently only supported) is the JSON-based cache implementation. - if found.IsSuperset(jsonCache) || len(entries) == 0 { - return NewJSON(cacheDir), nil - } - - // Anything else is unexpected. - return nil, fmt.Errorf("cache directory has unexpected contents") -} - -func ensureEmptyDir(dir string, mode os.FileMode) error { - if err := os.MkdirAll(dir, mode); err != nil { - return err - } - entries, err := os.ReadDir(dir) - if err != nil { - return err - } - for _, entry := range entries { - if err := os.RemoveAll(filepath.Join(dir, entry.Name())); err != nil { - return err - } - } - return nil -} - -func doesBundleProvide(ctx context.Context, c Cache, pkgName, chName, bundleName, group, version, kind string) (bool, error) { - apiBundle, err := c.GetBundle(ctx, pkgName, chName, bundleName) - if err != nil { - return false, fmt.Errorf("get bundle %q: %v", bundleName, err) - } - for _, gvk := range apiBundle.ProvidedApis { - if gvk.Group == group && gvk.Version == version && gvk.Kind == kind { - return true, nil - } - } - return false, nil -} - -type sliceBundleSender []*api.Bundle - -func (s *sliceBundleSender) Send(b *api.Bundle) error { - *s = append(*s, b) - return nil -} - -func listBundles(ctx context.Context, c Cache) ([]*api.Bundle, error) { - var bundleSender sliceBundleSender - - err := c.SendBundles(ctx, &bundleSender) - if err != nil { - return nil, err - } - - return bundleSender, nil -} diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/json.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/json.go deleted file mode 100644 index 47a54952ba..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/json.go +++ /dev/null @@ -1,257 +0,0 @@ -package cache - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "hash/fnv" - "io/fs" - "os" - "path/filepath" - "strings" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/pkg/api" - "github.com/operator-framework/operator-registry/pkg/registry" -) - -var _ Cache = &JSON{} - -type JSON struct { - baseDir string - - packageIndex - apiBundles map[apiBundleKey]string -} - -const ( - jsonCacheModeDir = 0750 - jsonCacheModeFile = 0640 -) - -type apiBundleKey struct { - pkgName string - chName string - name string -} - -func (q *JSON) loadAPIBundle(k apiBundleKey) (*api.Bundle, error) { - filename, ok := q.apiBundles[k] - if !ok { - return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", k.pkgName, k.chName, k.name) - } - d, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - var b api.Bundle - if err := json.Unmarshal(d, &b); err != nil { - return nil, err - } - return &b, nil -} - -func (q *JSON) ListBundles(ctx context.Context) ([]*api.Bundle, error) { - return listBundles(ctx, q) -} - -func (q *JSON) SendBundles(_ context.Context, s registry.BundleSender) error { - for _, pkg := range q.packageIndex { - for _, ch := range pkg.Channels { - for _, b := range ch.Bundles { - apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) - if err != nil { - return fmt.Errorf("convert bundle %q: %v", b.Name, err) - } - if apiBundle.BundlePath != "" { - // The SQLite-based server - // configures its querier to - // omit these fields when - // bundle path is set. - apiBundle.CsvJson = "" - apiBundle.Object = nil - } - if err := s.Send(apiBundle); err != nil { - return err - } - } - } - } - return nil -} - -func (q *JSON) GetBundle(_ context.Context, pkgName, channelName, csvName string) (*api.Bundle, error) { - pkg, ok := q.packageIndex[pkgName] - if !ok { - return nil, fmt.Errorf("package %q not found", pkgName) - } - ch, ok := pkg.Channels[channelName] - if !ok { - return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) - } - b, ok := ch.Bundles[csvName] - if !ok { - return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", pkgName, channelName, csvName) - } - apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) - if err != nil { - return nil, fmt.Errorf("convert bundle %q: %v", b.Name, err) - } - - // unset Replaces and Skips (sqlite query does not populate these fields) - apiBundle.Replaces = "" - apiBundle.Skips = nil - return apiBundle, nil -} - -func (q *JSON) GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (*api.Bundle, error) { - return q.packageIndex.GetBundleForChannel(ctx, q, pkgName, channelName) -} - -func (q *JSON) GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (*api.Bundle, error) { - return q.packageIndex.GetBundleThatReplaces(ctx, q, name, pkgName, channelName) -} - -func (q *JSON) GetChannelEntriesThatProvide(ctx context.Context, group, version, kind string) ([]*registry.ChannelEntry, error) { - return q.packageIndex.GetChannelEntriesThatProvide(ctx, q, group, version, kind) -} - -func (q *JSON) GetLatestChannelEntriesThatProvide(ctx context.Context, group, version, kind string) ([]*registry.ChannelEntry, error) { - return q.packageIndex.GetLatestChannelEntriesThatProvide(ctx, q, group, version, kind) -} - -func (q *JSON) GetBundleThatProvides(ctx context.Context, group, version, kind string) (*api.Bundle, error) { - return q.packageIndex.GetBundleThatProvides(ctx, q, group, version, kind) -} - -func NewJSON(baseDir string) *JSON { - return &JSON{baseDir: baseDir} -} - -const ( - jsonDigestFile = "digest" - jsonDir = "cache" - packagesFile = jsonDir + string(filepath.Separator) + "packages.json" -) - -func (q *JSON) CheckIntegrity(fbcFsys fs.FS) error { - existingDigest, err := q.existingDigest() - if err != nil { - return fmt.Errorf("read existing cache digest: %v", err) - } - computedDigest, err := q.computeDigest(fbcFsys) - if err != nil { - return fmt.Errorf("compute digest: %v", err) - } - if existingDigest != computedDigest { - return fmt.Errorf("cache requires rebuild: cache reports digest as %q, but computed digest is %q", existingDigest, computedDigest) - } - return nil -} - -func (q *JSON) existingDigest() (string, error) { - existingDigestBytes, err := os.ReadFile(filepath.Join(q.baseDir, jsonDigestFile)) - if err != nil { - return "", err - } - return strings.TrimSpace(string(existingDigestBytes)), nil -} - -func (q *JSON) computeDigest(fbcFsys fs.FS) (string, error) { - computedHasher := fnv.New64a() - if err := fsToTar(computedHasher, fbcFsys); err != nil { - return "", err - } - - if cacheFS, err := fs.Sub(os.DirFS(q.baseDir), jsonDir); err == nil { - if err := fsToTar(computedHasher, cacheFS); err != nil && !errors.Is(err, os.ErrNotExist) { - return "", fmt.Errorf("compute hash: %v", err) - } - } - return fmt.Sprintf("%x", computedHasher.Sum(nil)), nil -} - -func (q *JSON) Build(fbcFsys fs.FS) error { - // ensure that generated cache is available to all future users - oldUmask := umask(000) - defer umask(oldUmask) - - if err := ensureEmptyDir(q.baseDir, jsonCacheModeDir); err != nil { - return fmt.Errorf("ensure clean base directory: %v", err) - } - if err := ensureEmptyDir(filepath.Join(q.baseDir, jsonDir), jsonCacheModeDir); err != nil { - return fmt.Errorf("ensure clean base directory: %v", err) - } - - fbc, err := declcfg.LoadFS(fbcFsys) - if err != nil { - return err - } - fbcModel, err := declcfg.ConvertToModel(*fbc) - if err != nil { - return err - } - - pkgs, err := packagesFromModel(fbcModel) - if err != nil { - return err - } - - packageJson, err := json.Marshal(pkgs) - if err != nil { - return err - } - if err := os.WriteFile(filepath.Join(q.baseDir, packagesFile), packageJson, jsonCacheModeFile); err != nil { - return err - } - - q.apiBundles = map[apiBundleKey]string{} - for _, p := range fbcModel { - for _, ch := range p.Channels { - for _, b := range ch.Bundles { - apiBundle, err := api.ConvertModelBundleToAPIBundle(*b) - if err != nil { - return err - } - jsonBundle, err := json.Marshal(apiBundle) - if err != nil { - return err - } - filename := filepath.Join(q.baseDir, jsonDir, fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) - if err := os.WriteFile(filename, jsonBundle, jsonCacheModeFile); err != nil { - return err - } - q.apiBundles[apiBundleKey{p.Name, ch.Name, b.Name}] = filename - } - } - } - digest, err := q.computeDigest(fbcFsys) - if err != nil { - return err - } - if err := os.WriteFile(filepath.Join(q.baseDir, jsonDigestFile), []byte(digest), jsonCacheModeFile); err != nil { - return err - } - return nil -} - -func (q *JSON) Load() error { - packagesData, err := os.ReadFile(filepath.Join(q.baseDir, packagesFile)) - if err != nil { - return err - } - if err := json.Unmarshal(packagesData, &q.packageIndex); err != nil { - return err - } - q.apiBundles = map[apiBundleKey]string{} - for _, p := range q.packageIndex { - for _, ch := range p.Channels { - for _, b := range ch.Bundles { - filename := filepath.Join(q.baseDir, jsonDir, fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) - q.apiBundles[apiBundleKey{pkgName: p.Name, chName: ch.Name, name: b.Name}] = filename - } - } - } - return nil -} diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/pkgs.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/pkgs.go deleted file mode 100644 index d387ddbd09..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/pkgs.go +++ /dev/null @@ -1,297 +0,0 @@ -package cache - -import ( - "context" - "fmt" - "sort" - - "github.com/operator-framework/operator-registry/alpha/declcfg" - "github.com/operator-framework/operator-registry/alpha/model" - "github.com/operator-framework/operator-registry/pkg/api" - "github.com/operator-framework/operator-registry/pkg/registry" -) - -type packageIndex map[string]cPkg - -func (pkgs packageIndex) ListPackages(_ context.Context) ([]string, error) { - var packages []string - for pkgName := range pkgs { - packages = append(packages, pkgName) - } - return packages, nil -} - -func (pkgs packageIndex) GetPackage(_ context.Context, name string) (*registry.PackageManifest, error) { - pkg, ok := pkgs[name] - if !ok { - return nil, fmt.Errorf("package %q not found", name) - } - - var channels []registry.PackageChannel - for _, ch := range pkg.Channels { - channels = append(channels, registry.PackageChannel{ - Name: ch.Name, - CurrentCSVName: ch.Head, - }) - } - return ®istry.PackageManifest{ - PackageName: pkg.Name, - Channels: channels, - DefaultChannelName: pkg.DefaultChannel, - }, nil -} - -func (pkgs packageIndex) GetChannelEntriesThatReplace(_ context.Context, name string) ([]*registry.ChannelEntry, error) { - var entries []*registry.ChannelEntry - - for _, pkg := range pkgs { - for _, ch := range pkg.Channels { - for _, b := range ch.Bundles { - entries = append(entries, channelEntriesThatReplace(b, name)...) - } - } - } - if len(entries) == 0 { - return nil, fmt.Errorf("no channel entries found that replace %s", name) - } - return entries, nil -} - -func (pkgs packageIndex) GetBundleForChannel(ctx context.Context, c Cache, pkgName string, channelName string) (*api.Bundle, error) { - pkg, ok := pkgs[pkgName] - if !ok { - return nil, fmt.Errorf("package %q not found", pkgName) - } - ch, ok := pkg.Channels[channelName] - if !ok { - return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) - } - return c.GetBundle(ctx, pkg.Name, ch.Name, ch.Head) -} - -func (pkgs packageIndex) GetBundleThatReplaces(ctx context.Context, c Cache, name, pkgName, channelName string) (*api.Bundle, error) { - pkg, ok := pkgs[pkgName] - if !ok { - return nil, fmt.Errorf("package %s not found", pkgName) - } - ch, ok := pkg.Channels[channelName] - if !ok { - return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) - } - - // NOTE: iterating over a map is non-deterministic in Go, so if multiple bundles replace this one, - // the bundle returned by this function is also non-deterministic. The sqlite implementation - // is ALSO non-deterministic because it doesn't use ORDER BY, so its probably okay for this - // implementation to be non-deterministic as well. - for _, b := range ch.Bundles { - if bundleReplaces(b, name) { - return c.GetBundle(ctx, pkg.Name, ch.Name, b.Name) - } - } - return nil, fmt.Errorf("no entry found for package %q, channel %q", pkgName, channelName) -} - -func (pkgs packageIndex) GetChannelEntriesThatProvide(ctx context.Context, c Cache, group, version, kind string) ([]*registry.ChannelEntry, error) { - var entries []*registry.ChannelEntry - - for _, pkg := range pkgs { - for _, ch := range pkg.Channels { - for _, b := range ch.Bundles { - provides, err := doesBundleProvide(ctx, c, b.Package, b.Channel, b.Name, group, version, kind) - if err != nil { - return nil, err - } - if provides { - // TODO(joelanford): It seems like the SQLite query returns - // invalid entries (i.e. where bundle `Replaces` isn't actually - // in channel `ChannelName`). Is that a bug? For now, this mimics - // the sqlite server and returns seemingly invalid channel entries. - // Don't worry about this. Not used anymore. - - entries = append(entries, pkgs.channelEntriesForBundle(b, true)...) - } - } - } - } - if len(entries) == 0 { - return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) - } - return entries, nil -} - -// TODO(joelanford): Need to review the expected functionality of this function. I ran -// -// some experiments with the sqlite version of this function and it seems to only return -// channel heads that provide the GVK (rather than searching down the graph if parent bundles -// don't provide the API). Based on that, this function currently looks at channel heads only. -// --- -// Separate, but possibly related, I noticed there are several channels in the channel entry -// table who's minimum depth is 1. What causes 1 to be minimum depth in some cases and 0 in others? -func (pkgs packageIndex) GetLatestChannelEntriesThatProvide(ctx context.Context, c Cache, group, version, kind string) ([]*registry.ChannelEntry, error) { - var entries []*registry.ChannelEntry - - for _, pkg := range pkgs { - for _, ch := range pkg.Channels { - b := ch.Bundles[ch.Head] - provides, err := doesBundleProvide(ctx, c, b.Package, b.Channel, b.Name, group, version, kind) - if err != nil { - return nil, err - } - if provides { - entries = append(entries, pkgs.channelEntriesForBundle(b, false)...) - } - } - } - if len(entries) == 0 { - return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) - } - return entries, nil -} - -func (pkgs packageIndex) GetBundleThatProvides(ctx context.Context, c Cache, group, version, kind string) (*api.Bundle, error) { - latestEntries, err := c.GetLatestChannelEntriesThatProvide(ctx, group, version, kind) - if err != nil { - return nil, err - } - - // It's possible for multiple packages to provide an API, but this function is forced to choose one. - // To do that deterministically, we'll pick the the bundle based on a lexicographical sort of its - // package name. - sort.Slice(latestEntries, func(i, j int) bool { - return latestEntries[i].PackageName < latestEntries[j].PackageName - }) - - for _, entry := range latestEntries { - pkg, ok := pkgs[entry.PackageName] - if !ok { - // This should never happen because the latest entries were - // collected based on iterating over the packages in q.packageIndex. - continue - } - if entry.ChannelName == pkg.DefaultChannel { - return c.GetBundle(ctx, entry.PackageName, entry.ChannelName, entry.BundleName) - } - } - return nil, fmt.Errorf("no entry found that provides group:%q version:%q kind:%q", group, version, kind) -} - -type cPkg struct { - Name string `json:"name"` - Description string `json:"description"` - Icon *declcfg.Icon `json:"icon"` - DefaultChannel string `json:"defaultChannel"` - Channels map[string]cChannel -} - -type cChannel struct { - Name string - Head string - Bundles map[string]cBundle -} - -type cBundle struct { - Package string `json:"package"` - Channel string `json:"channel"` - Name string `json:"name"` - Replaces string `json:"replaces"` - Skips []string `json:"skips"` -} - -func packagesFromModel(m model.Model) (map[string]cPkg, error) { - pkgs := map[string]cPkg{} - for _, p := range m { - newP := cPkg{ - Name: p.Name, - Description: p.Description, - DefaultChannel: p.DefaultChannel.Name, - Channels: map[string]cChannel{}, - } - if p.Icon != nil { - newP.Icon = &declcfg.Icon{ - Data: p.Icon.Data, - MediaType: p.Icon.MediaType, - } - } - for _, ch := range p.Channels { - head, err := ch.Head() - if err != nil { - return nil, err - } - newCh := cChannel{ - Name: ch.Name, - Head: head.Name, - Bundles: map[string]cBundle{}, - } - for _, b := range ch.Bundles { - newB := cBundle{ - Package: b.Package.Name, - Channel: b.Channel.Name, - Name: b.Name, - Replaces: b.Replaces, - Skips: b.Skips, - } - newCh.Bundles[b.Name] = newB - } - newP.Channels[ch.Name] = newCh - } - pkgs[p.Name] = newP - } - return pkgs, nil -} - -func bundleReplaces(b cBundle, name string) bool { - if b.Replaces == name { - return true - } - for _, s := range b.Skips { - if s == name { - return true - } - } - return false -} - -func channelEntriesThatReplace(b cBundle, name string) []*registry.ChannelEntry { - var entries []*registry.ChannelEntry - if b.Replaces == name { - entries = append(entries, ®istry.ChannelEntry{ - PackageName: b.Package, - ChannelName: b.Channel, - BundleName: b.Name, - Replaces: b.Replaces, - }) - } - for _, s := range b.Skips { - if s == name && s != b.Replaces { - entries = append(entries, ®istry.ChannelEntry{ - PackageName: b.Package, - ChannelName: b.Channel, - BundleName: b.Name, - Replaces: b.Replaces, - }) - } - } - return entries -} - -func (pkgs packageIndex) channelEntriesForBundle(b cBundle, ignoreChannel bool) []*registry.ChannelEntry { - entries := []*registry.ChannelEntry{{ - PackageName: b.Package, - ChannelName: b.Channel, - BundleName: b.Name, - Replaces: b.Replaces, - }} - for _, s := range b.Skips { - // Ignore skips that duplicate b.Replaces. Also, only add it if its - // in the same channel as b (or we're ignoring channel presence). - if _, inChannel := pkgs[b.Package].Channels[b.Channel].Bundles[s]; s != b.Replaces && (ignoreChannel || inChannel) { - entries = append(entries, ®istry.ChannelEntry{ - PackageName: b.Package, - ChannelName: b.Channel, - BundleName: b.Name, - Replaces: s, - }) - } - } - return entries -} diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_unix.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_unix.go deleted file mode 100644 index 93372adb4e..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_unix.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !windows -// +build !windows - -package cache - -import "golang.org/x/sys/unix" - -var umask = unix.Umask diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_windows.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_windows.go deleted file mode 100644 index 7ff5ad8e86..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/syscall_windows.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build windows -// +build windows - -package cache - -var umask = func(i int) int { return 0 } diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/cache/tar.go b/vendor/github.com/operator-framework/operator-registry/pkg/cache/tar.go deleted file mode 100644 index b368e011e9..0000000000 --- a/vendor/github.com/operator-framework/operator-registry/pkg/cache/tar.go +++ /dev/null @@ -1,66 +0,0 @@ -package cache - -import ( - "archive/tar" - "fmt" - "io" - "io/fs" - "os" - "time" -) - -// fsToTar writes the filesystem represented by fsys to w as a tar archive. -// This function unsets user and group information in the tar archive so that readers -// of archives produced by this function do not need to account for differences in -// permissions between source and destination filesystems. -func fsToTar(w io.Writer, fsys fs.FS) error { - tw := tar.NewWriter(w) - if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - - if d.Type()&os.ModeSymlink != 0 { - return nil - } - info, err := d.Info() - if err != nil { - return fmt.Errorf("get file info for %q: %v", path, err) - } - - h, err := tar.FileInfoHeader(info, "") - if err != nil { - return fmt.Errorf("build tar file info header for %q: %v", path, err) - } - h.Uid = 0 - h.Gid = 0 - h.Uname = "" - h.Gname = "" - h.AccessTime = time.Time{} - h.ChangeTime = time.Time{} - h.ModTime = time.Time{} - h.Name = path - - if err := tw.WriteHeader(h); err != nil { - return fmt.Errorf("write tar header for %q: %v", path, err) - } - if d.IsDir() { - return nil - } - f, err := fsys.Open(path) - if err != nil { - return fmt.Errorf("open file %q: %v", path, err) - } - defer f.Close() - if _, err := io.Copy(tw, f); err != nil { - return fmt.Errorf("write tar data for %q: %v", path, err) - } - return nil - }); err != nil { - return fmt.Errorf("write tar: %w", err) - } - if err := tw.Close(); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/image/containerdregistry/registry.go b/vendor/github.com/operator-framework/operator-registry/pkg/image/containerdregistry/registry.go index 6519539e5b..a5bacb4fab 100644 --- a/vendor/github.com/operator-framework/operator-registry/pkg/image/containerdregistry/registry.go +++ b/vendor/github.com/operator-framework/operator-registry/pkg/image/containerdregistry/registry.go @@ -47,7 +47,7 @@ func (r *Registry) Pull(ctx context.Context, ref image.Reference) error { name, root, err := r.resolver.Resolve(ctx, ref.String()) if err != nil { - return fmt.Errorf("error resolving name %s: %v", name, err) + return fmt.Errorf("error resolving name for image ref %s: %v", ref.String(), err) } r.log.Debugf("resolved name: %s", name) diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/index.Dockerfile1055301598 b/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/index.Dockerfile1055301598 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/interfaces.go b/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/interfaces.go index df9e6e47a2..5ebefdd1e3 100644 --- a/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/interfaces.go +++ b/vendor/github.com/operator-framework/operator-registry/pkg/lib/indexer/interfaces.go @@ -9,6 +9,7 @@ import ( // IndexAdder allows the creation of index container images from scratch or // based on previous index images +// //counterfeiter:generate . IndexAdder type IndexAdder interface { AddToIndex(AddToIndexRequest) error @@ -29,6 +30,7 @@ func NewIndexAdder(buildTool, pullTool containertools.ContainerTool, logger *log // IndexDeleter takes indexes and deletes all references to an operator // from them +// //counterfeiter:generate . IndexDeleter type IndexDeleter interface { DeleteFromIndex(DeleteFromIndexRequest) error diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/registry/query.go b/vendor/github.com/operator-framework/operator-registry/pkg/registry/query.go new file mode 100644 index 0000000000..3da8b16f45 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/pkg/registry/query.go @@ -0,0 +1,653 @@ +package registry + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "hash/fnv" + "io/fs" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/operator-framework/operator-registry/alpha/declcfg" + "github.com/operator-framework/operator-registry/alpha/model" + "github.com/operator-framework/operator-registry/pkg/api" +) + +type Querier struct { + *cache +} + +func (q Querier) Close() error { + return q.cache.close() +} + +type apiBundleKey struct { + pkgName string + chName string + name string +} + +type SliceBundleSender []*api.Bundle + +func (s *SliceBundleSender) Send(b *api.Bundle) error { + + *s = append(*s, b) + return nil +} + +var _ GRPCQuery = &Querier{} + +func NewQuerierFromFS(fbcFS fs.FS, cacheDir string) (*Querier, error) { + q := &Querier{} + var err error + q.cache, err = newCache(cacheDir, &fbcCacheModel{ + FBC: fbcFS, + Cache: os.DirFS(cacheDir), + }) + if err != nil { + return q, err + } + return q, nil +} + +func NewQuerier(m model.Model) (*Querier, error) { + q := &Querier{} + var err error + q.cache, err = newCache("", &nonDigestableModel{Model: m}) + if err != nil { + return q, err + } + return q, nil +} + +func (q Querier) loadAPIBundle(k apiBundleKey) (*api.Bundle, error) { + filename, ok := q.apiBundles[k] + if !ok { + return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", k.pkgName, k.chName, k.name) + } + d, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + var b api.Bundle + if err := json.Unmarshal(d, &b); err != nil { + return nil, err + } + return &b, nil +} + +func (q Querier) ListPackages(_ context.Context) ([]string, error) { + var packages []string + for pkgName := range q.pkgs { + packages = append(packages, pkgName) + } + return packages, nil +} + +func (q Querier) ListBundles(ctx context.Context) ([]*api.Bundle, error) { + var bundleSender SliceBundleSender + + err := q.SendBundles(ctx, &bundleSender) + if err != nil { + return nil, err + } + + return bundleSender, nil +} + +func (q Querier) SendBundles(_ context.Context, s BundleSender) error { + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + if apiBundle.BundlePath != "" { + // The SQLite-based server + // configures its querier to + // omit these fields when + // bundle path is set. + apiBundle.CsvJson = "" + apiBundle.Object = nil + } + if err := s.Send(apiBundle); err != nil { + return err + } + } + } + } + return nil +} + +func (q Querier) GetPackage(_ context.Context, name string) (*PackageManifest, error) { + pkg, ok := q.pkgs[name] + if !ok { + return nil, fmt.Errorf("package %q not found", name) + } + + var channels []PackageChannel + for _, ch := range pkg.Channels { + channels = append(channels, PackageChannel{ + Name: ch.Name, + CurrentCSVName: ch.Head, + }) + } + return &PackageManifest{ + PackageName: pkg.Name, + Channels: channels, + DefaultChannelName: pkg.DefaultChannel, + }, nil +} + +func (q Querier) GetBundle(_ context.Context, pkgName, channelName, csvName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %q not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + b, ok := ch.Bundles[csvName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q, bundle %q not found", pkgName, channelName, csvName) + } + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil +} + +func (q Querier) GetBundleForChannel(_ context.Context, pkgName string, channelName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %q not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, ch.Head}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", ch.Head, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil +} + +func (q Querier) GetChannelEntriesThatReplace(_ context.Context, name string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + entries = append(entries, channelEntriesThatReplace(b, name)...) + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that replace %s", name) + } + return entries, nil +} + +func (q Querier) GetBundleThatReplaces(_ context.Context, name, pkgName, channelName string) (*api.Bundle, error) { + pkg, ok := q.pkgs[pkgName] + if !ok { + return nil, fmt.Errorf("package %s not found", pkgName) + } + ch, ok := pkg.Channels[channelName] + if !ok { + return nil, fmt.Errorf("package %q, channel %q not found", pkgName, channelName) + } + + // NOTE: iterating over a map is non-deterministic in Go, so if multiple bundles replace this one, + // the bundle returned by this function is also non-deterministic. The sqlite implementation + // is ALSO non-deterministic because it doesn't use ORDER BY, so its probably okay for this + // implementation to be non-deterministic as well. + for _, b := range ch.Bundles { + if bundleReplaces(b, name) { + apiBundle, err := q.loadAPIBundle(apiBundleKey{pkg.Name, ch.Name, b.Name}) + if err != nil { + return nil, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + + // unset Replaces and Skips (sqlite query does not populate these fields) + apiBundle.Replaces = "" + apiBundle.Skips = nil + return apiBundle, nil + } + } + return nil, fmt.Errorf("no entry found for package %q, channel %q", pkgName, channelName) +} + +func (q Querier) GetChannelEntriesThatProvide(_ context.Context, group, version, kind string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + for _, b := range ch.Bundles { + provides, err := q.doesModelBundleProvide(b, group, version, kind) + if err != nil { + return nil, err + } + if provides { + // TODO(joelanford): It seems like the SQLite query returns + // invalid entries (i.e. where bundle `Replaces` isn't actually + // in channel `ChannelName`). Is that a bug? For now, this mimics + // the sqlite server and returns seemingly invalid channel entries. + // Don't worry about this. Not used anymore. + + entries = append(entries, q.channelEntriesForBundle(b, true)...) + } + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) + } + return entries, nil +} + +// TODO(joelanford): Need to review the expected functionality of this function. I ran +// +// some experiments with the sqlite version of this function and it seems to only return +// channel heads that provide the GVK (rather than searching down the graph if parent bundles +// don't provide the API). Based on that, this function currently looks at channel heads only. +// --- +// Separate, but possibly related, I noticed there are several channels in the channel entry +// table who's minimum depth is 1. What causes 1 to be minimum depth in some cases and 0 in others? +func (q Querier) GetLatestChannelEntriesThatProvide(_ context.Context, group, version, kind string) ([]*ChannelEntry, error) { + var entries []*ChannelEntry + + for _, pkg := range q.pkgs { + for _, ch := range pkg.Channels { + b := ch.Bundles[ch.Head] + provides, err := q.doesModelBundleProvide(b, group, version, kind) + if err != nil { + return nil, err + } + if provides { + entries = append(entries, q.channelEntriesForBundle(b, false)...) + } + } + } + if len(entries) == 0 { + return nil, fmt.Errorf("no channel entries found that provide group:%q version:%q kind:%q", group, version, kind) + } + return entries, nil +} + +func (q Querier) GetBundleThatProvides(ctx context.Context, group, version, kind string) (*api.Bundle, error) { + latestEntries, err := q.GetLatestChannelEntriesThatProvide(ctx, group, version, kind) + if err != nil { + return nil, err + } + + // It's possible for multiple packages to provide an API, but this function is forced to choose one. + // To do that deterministically, we'll pick the the bundle based on a lexicographical sort of its + // package name. + sort.Slice(latestEntries, func(i, j int) bool { + return latestEntries[i].PackageName < latestEntries[j].PackageName + }) + + for _, entry := range latestEntries { + pkg, ok := q.pkgs[entry.PackageName] + if !ok { + // This should never happen because the latest entries were + // collected based on iterating over the packages in q.pkgs. + continue + } + if entry.ChannelName == pkg.DefaultChannel { + return q.GetBundle(ctx, entry.PackageName, entry.ChannelName, entry.BundleName) + } + } + return nil, fmt.Errorf("no entry found that provides group:%q version:%q kind:%q", group, version, kind) +} + +func (q Querier) doesModelBundleProvide(b cBundle, group, version, kind string) (bool, error) { + apiBundle, err := q.loadAPIBundle(apiBundleKey{b.Package, b.Channel, b.Name}) + if err != nil { + return false, fmt.Errorf("convert bundle %q: %v", b.Name, err) + } + for _, gvk := range apiBundle.ProvidedApis { + if gvk.Group == group && gvk.Version == version && gvk.Kind == kind { + return true, nil + } + } + return false, nil +} + +func bundleReplaces(b cBundle, name string) bool { + if b.Replaces == name { + return true + } + for _, s := range b.Skips { + if s == name { + return true + } + } + return false +} + +func channelEntriesThatReplace(b cBundle, name string) []*ChannelEntry { + var entries []*ChannelEntry + if b.Replaces == name { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }) + } + for _, s := range b.Skips { + if s == name && s != b.Replaces { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }) + } + } + return entries +} + +func (q Querier) channelEntriesForBundle(b cBundle, ignoreChannel bool) []*ChannelEntry { + entries := []*ChannelEntry{{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: b.Replaces, + }} + for _, s := range b.Skips { + // Ignore skips that duplicate b.Replaces. Also, only add it if its + // in the same channel as b (or we're ignoring channel presence). + if _, inChannel := q.pkgs[b.Package].Channels[b.Channel].Bundles[s]; s != b.Replaces && (ignoreChannel || inChannel) { + entries = append(entries, &ChannelEntry{ + PackageName: b.Package, + ChannelName: b.Channel, + BundleName: b.Name, + Replaces: s, + }) + } + } + return entries +} + +type cache struct { + digest string + baseDir string + persist bool + pkgs map[string]cPkg + apiBundles map[apiBundleKey]string +} + +func newCache(baseDir string, model digestableModel) (*cache, error) { + var ( + qc *cache + err error + ) + if baseDir == "" { + qc, err = newEphemeralCache() + } else { + qc, err = newPersistentCache(baseDir) + } + if err != nil { + return nil, err + } + return qc, qc.load(model) +} + +func (qc cache) close() error { + if qc.persist { + return nil + } + return os.RemoveAll(qc.baseDir) +} + +func newEphemeralCache() (*cache, error) { + baseDir, err := os.MkdirTemp("", "opm-serve-cache-") + if err != nil { + return nil, err + } + if err := os.MkdirAll(filepath.Join(baseDir, "cache"), 0700); err != nil { + return nil, err + } + return &cache{ + digest: "", + baseDir: baseDir, + persist: false, + }, nil +} + +func newPersistentCache(baseDir string) (*cache, error) { + if err := os.MkdirAll(baseDir, 0700); err != nil { + return nil, err + } + qc := &cache{baseDir: baseDir, persist: true} + if digest, err := os.ReadFile(filepath.Join(baseDir, "digest")); err == nil { + qc.digest = strings.TrimSpace(string(digest)) + } + return qc, nil +} + +func (qc *cache) load(model digestableModel) error { + computedDigest, err := model.GetDigest() + if err != nil && !errors.Is(err, errNonDigestable) { + return fmt.Errorf("compute digest: %v", err) + } + if err == nil && computedDigest == qc.digest { + err = qc.loadFromCache() + if err == nil { + return nil + } + // if there _was_ an error loading from the cache, + // we'll drop down and repopulate from scratch. + } + return qc.repopulateCache(model) +} + +func (qc *cache) loadFromCache() error { + packagesData, err := os.ReadFile(filepath.Join(qc.baseDir, "cache", "packages.json")) + if err != nil { + return err + } + if err := json.Unmarshal(packagesData, &qc.pkgs); err != nil { + return err + } + qc.apiBundles = map[apiBundleKey]string{} + for _, p := range qc.pkgs { + for _, ch := range p.Channels { + for _, b := range ch.Bundles { + filename := filepath.Join(qc.baseDir, "cache", fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) + qc.apiBundles[apiBundleKey{pkgName: p.Name, chName: ch.Name, name: b.Name}] = filename + } + } + } + return nil +} + +func (qc *cache) repopulateCache(model digestableModel) error { + m, err := model.GetModel() + if err != nil { + return err + } + cacheDirEntries, err := os.ReadDir(qc.baseDir) + if err != nil { + return err + } + for _, e := range cacheDirEntries { + if err := os.RemoveAll(filepath.Join(qc.baseDir, e.Name())); err != nil { + return err + } + } + if err := os.MkdirAll(filepath.Join(qc.baseDir, "cache"), 0700); err != nil { + return err + } + + qc.pkgs, err = packagesFromModel(m) + if err != nil { + return err + } + + packageJson, err := json.Marshal(qc.pkgs) + if err != nil { + return err + } + if err := os.WriteFile(filepath.Join(qc.baseDir, "cache", "packages.json"), packageJson, 0600); err != nil { + return err + } + + qc.apiBundles = map[apiBundleKey]string{} + for _, p := range m { + for _, ch := range p.Channels { + for _, b := range ch.Bundles { + apiBundle, err := api.ConvertModelBundleToAPIBundle(*b) + if err != nil { + return err + } + jsonBundle, err := json.Marshal(apiBundle) + if err != nil { + return err + } + filename := filepath.Join(qc.baseDir, "cache", fmt.Sprintf("%s_%s_%s.json", p.Name, ch.Name, b.Name)) + if err := os.WriteFile(filename, jsonBundle, 0666); err != nil { + return err + } + qc.apiBundles[apiBundleKey{p.Name, ch.Name, b.Name}] = filename + } + } + } + computedHash, err := model.GetDigest() + if err == nil { + if err := os.WriteFile(filepath.Join(qc.baseDir, "digest"), []byte(computedHash), 0600); err != nil { + return err + } + } else if !errors.Is(err, errNonDigestable) { + return fmt.Errorf("compute digest: %v", err) + } + return nil +} + +func packagesFromModel(m model.Model) (map[string]cPkg, error) { + pkgs := map[string]cPkg{} + for _, p := range m { + newP := cPkg{ + Name: p.Name, + Description: p.Description, + DefaultChannel: p.DefaultChannel.Name, + Channels: map[string]cChannel{}, + } + if p.Icon != nil { + newP.Icon = &declcfg.Icon{ + Data: p.Icon.Data, + MediaType: p.Icon.MediaType, + } + } + for _, ch := range p.Channels { + head, err := ch.Head() + if err != nil { + return nil, err + } + newCh := cChannel{ + Name: ch.Name, + Head: head.Name, + Bundles: map[string]cBundle{}, + } + for _, b := range ch.Bundles { + newB := cBundle{ + Package: b.Package.Name, + Channel: b.Channel.Name, + Name: b.Name, + Replaces: b.Replaces, + Skips: b.Skips, + } + newCh.Bundles[b.Name] = newB + } + newP.Channels[ch.Name] = newCh + } + pkgs[p.Name] = newP + } + return pkgs, nil +} + +type cPkg struct { + Name string `json:"name"` + Description string `json:"description"` + Icon *declcfg.Icon `json:"icon"` + DefaultChannel string `json:"defaultChannel"` + Channels map[string]cChannel +} + +type cChannel struct { + Name string + Head string + Bundles map[string]cBundle +} + +type cBundle struct { + Package string `json:"package"` + Channel string `json:"channel"` + Name string `json:"name"` + Replaces string `json:"replaces"` + Skips []string `json:"skips"` +} + +type digestableModel interface { + GetModel() (model.Model, error) + GetDigest() (string, error) +} + +type fbcCacheModel struct { + FBC fs.FS + Cache fs.FS +} + +func (m *fbcCacheModel) GetModel() (model.Model, error) { + fbc, err := declcfg.LoadFS(m.FBC) + if err != nil { + return nil, err + } + return declcfg.ConvertToModel(*fbc) +} + +func (m *fbcCacheModel) GetDigest() (string, error) { + computedHasher := fnv.New64a() + if err := fsToTar(computedHasher, m.FBC); err != nil { + return "", err + } + if cacheFS, err := fs.Sub(m.Cache, "cache"); err == nil { + if err := fsToTar(computedHasher, cacheFS); err != nil && !errors.Is(err, os.ErrNotExist) { + return "", fmt.Errorf("compute hash: %v", err) + } + } + return fmt.Sprintf("%x", computedHasher.Sum(nil)), nil +} + +var errNonDigestable = errors.New("cannot generate digest") + +type nonDigestableModel struct { + model.Model +} + +func (m *nonDigestableModel) GetModel() (model.Model, error) { + return m.Model, nil +} + +func (m *nonDigestableModel) GetDigest() (string, error) { + return "", errNonDigestable +} diff --git a/vendor/github.com/operator-framework/operator-registry/pkg/registry/tar.go b/vendor/github.com/operator-framework/operator-registry/pkg/registry/tar.go new file mode 100644 index 0000000000..f62a15da85 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-registry/pkg/registry/tar.go @@ -0,0 +1,66 @@ +package registry + +import ( + "archive/tar" + "fmt" + "io" + "io/fs" + "os" + "time" +) + +// fsToTar writes the filesystem represented by fsys to w as a tar archive. +// This function unsets user and group information in the tar archive so that readers +// of archives produced by this function do not need to account for differences in +// permissions between source and destination filesystems. +func fsToTar(w io.Writer, fsys fs.FS) error { + tw := tar.NewWriter(w) + if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.Type()&os.ModeSymlink != 0 { + return nil + } + info, err := d.Info() + if err != nil { + return fmt.Errorf("get file info for %q: %v", path, err) + } + + h, err := tar.FileInfoHeader(info, "") + if err != nil { + return fmt.Errorf("build tar file info header for %q: %v", path, err) + } + h.Uid = 0 + h.Gid = 0 + h.Uname = "" + h.Gname = "" + h.AccessTime = time.Time{} + h.ChangeTime = time.Time{} + h.ModTime = time.Time{} + h.Name = path + + if err := tw.WriteHeader(h); err != nil { + return fmt.Errorf("write tar header for %q: %v", path, err) + } + if d.IsDir() { + return nil + } + f, err := fsys.Open(path) + if err != nil { + return fmt.Errorf("open file %q: %v", path, err) + } + defer f.Close() + if _, err := io.Copy(tw, f); err != nil { + return fmt.Errorf("write tar data for %q: %v", path, err) + } + return nil + }); err != nil { + return fmt.Errorf("write tar: %w", err) + } + if err := tw.Close(); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collector.go index ac1ca3cf5f..cf05079fb8 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collector.go @@ -69,9 +69,9 @@ type Collector interface { // If a Collector collects the same metrics throughout its lifetime, its // Describe method can simply be implemented as: // -// func (c customCollector) Describe(ch chan<- *Desc) { -// DescribeByCollect(c, ch) -// } +// func (c customCollector) Describe(ch chan<- *Desc) { +// DescribeByCollect(c, ch) +// } // // However, this will not work if the metrics collected change dynamically over // the lifetime of the Collector in a way that their combined set of descriptors diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go index e09f149d76..d5a7279fb9 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector.go @@ -101,7 +101,7 @@ func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.waitDuration ch <- c.maxIdleClosed ch <- c.maxLifetimeClosed - c.describeNewInGo115(ch) + ch <- c.maxIdleTimeClosed } // Collect implements Collector. @@ -115,5 +115,5 @@ func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds()) ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed)) ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed)) - c.collectNewInGo115(ch, stats) + ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed)) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go deleted file mode 100644 index 6d152fbf19..0000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_go115.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 The Prometheus 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. - -//go:build go1.15 -// +build go1.15 - -package collectors - -import ( - "database/sql" - - "github.com/prometheus/client_golang/prometheus" -) - -func (c *dbStatsCollector) describeNewInGo115(ch chan<- *prometheus.Desc) { - ch <- c.maxIdleTimeClosed -} - -func (c *dbStatsCollector) collectNewInGo115(ch chan<- prometheus.Metric, stats sql.DBStats) { - ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed)) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go deleted file mode 100644 index 65235069d6..0000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/dbstats_collector_pre_go115.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2021 The Prometheus 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. - -//go:build !go1.15 -// +build !go1.15 - -package collectors - -import ( - "database/sql" - - "github.com/prometheus/client_golang/prometheus" -) - -func (c *dbStatsCollector) describeNewInGo115(ch chan<- *prometheus.Desc) {} - -func (c *dbStatsCollector) collectNewInGo115(ch chan<- prometheus.Metric, stats sql.DBStats) {} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go index 01790e885d..246c5ea943 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go @@ -16,76 +16,145 @@ package collectors -import "github.com/prometheus/client_golang/prometheus" +import ( + "regexp" -//nolint:staticcheck // Ignore SA1019 until v2. -type goOptions = prometheus.GoCollectorOptions -type goOption func(o *goOptions) + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/internal" +) + +var ( + // MetricsAll allows all the metrics to be collected from Go runtime. + MetricsAll = GoRuntimeMetricsRule{regexp.MustCompile("/.*")} + // MetricsGC allows only GC metrics to be collected from Go runtime. + // e.g. go_gc_cycles_automatic_gc_cycles_total + MetricsGC = GoRuntimeMetricsRule{regexp.MustCompile(`^/gc/.*`)} + // MetricsMemory allows only memory metrics to be collected from Go runtime. + // e.g. go_memory_classes_heap_free_bytes + MetricsMemory = GoRuntimeMetricsRule{regexp.MustCompile(`^/memory/.*`)} + // MetricsScheduler allows only scheduler metrics to be collected from Go runtime. + // e.g. go_sched_goroutines_goroutines + MetricsScheduler = GoRuntimeMetricsRule{regexp.MustCompile(`^/sched/.*`)} +) +// WithGoCollectorMemStatsMetricsDisabled disables metrics that is gathered in runtime.MemStats structure such as: +// +// go_memstats_alloc_bytes +// go_memstats_alloc_bytes_total +// go_memstats_sys_bytes +// go_memstats_lookups_total +// go_memstats_mallocs_total +// go_memstats_frees_total +// go_memstats_heap_alloc_bytes +// go_memstats_heap_sys_bytes +// go_memstats_heap_idle_bytes +// go_memstats_heap_inuse_bytes +// go_memstats_heap_released_bytes +// go_memstats_heap_objects +// go_memstats_stack_inuse_bytes +// go_memstats_stack_sys_bytes +// go_memstats_mspan_inuse_bytes +// go_memstats_mspan_sys_bytes +// go_memstats_mcache_inuse_bytes +// go_memstats_mcache_sys_bytes +// go_memstats_buck_hash_sys_bytes +// go_memstats_gc_sys_bytes +// go_memstats_other_sys_bytes +// go_memstats_next_gc_bytes +// +// so the metrics known from pre client_golang v1.12.0, +// +// NOTE(bwplotka): The above represents runtime.MemStats statistics, but they are +// actually implemented using new runtime/metrics package. (except skipped go_memstats_gc_cpu_fraction +// -- see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 for explanation). +// +// Some users might want to disable this on collector level (although you can use scrape relabelling on Prometheus), +// because similar metrics can be now obtained using WithGoCollectorRuntimeMetrics. Note that the semantics of new +// metrics might be different, plus the names can be change over time with different Go version. +// +// NOTE(bwplotka): Changing metric names can be tedious at times as the alerts, recording rules and dashboards have to be adjusted. +// The old metrics are also very useful, with many guides and books written about how to interpret them. +// +// As a result our recommendation would be to stick with MemStats like metrics and enable other runtime/metrics if you are interested +// in advanced insights Go provides. See ExampleGoCollector_WithAdvancedGoMetrics. +func WithGoCollectorMemStatsMetricsDisabled() func(options *internal.GoCollectorOptions) { + return func(o *internal.GoCollectorOptions) { + o.DisableMemStatsLikeMetrics = true + } +} + +// GoRuntimeMetricsRule allow enabling and configuring particular group of runtime/metrics. +// TODO(bwplotka): Consider adding ability to adjust buckets. +type GoRuntimeMetricsRule struct { + // Matcher represents RE2 expression will match the runtime/metrics from https://golang.bg/src/runtime/metrics/description.go + // Use `regexp.MustCompile` or `regexp.Compile` to create this field. + Matcher *regexp.Regexp +} + +// WithGoCollectorRuntimeMetrics allows enabling and configuring particular group of runtime/metrics. +// See the list of metrics https://golang.bg/src/runtime/metrics/description.go (pick the Go version you use there!). +// You can use this option in repeated manner, which will add new rules. The order of rules is important, the last rule +// that matches particular metrics is applied. +func WithGoCollectorRuntimeMetrics(rules ...GoRuntimeMetricsRule) func(options *internal.GoCollectorOptions) { + rs := make([]internal.GoCollectorRule, len(rules)) + for i, r := range rules { + rs[i] = internal.GoCollectorRule{ + Matcher: r.Matcher, + } + } + + return func(o *internal.GoCollectorOptions) { + o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...) + } +} + +// WithoutGoCollectorRuntimeMetrics allows disabling group of runtime/metrics that you might have added in WithGoCollectorRuntimeMetrics. +// It behaves similarly to WithGoCollectorRuntimeMetrics just with deny-list semantics. +func WithoutGoCollectorRuntimeMetrics(matchers ...*regexp.Regexp) func(options *internal.GoCollectorOptions) { + rs := make([]internal.GoCollectorRule, len(matchers)) + for i, m := range matchers { + rs[i] = internal.GoCollectorRule{ + Matcher: m, + Deny: true, + } + } + + return func(o *internal.GoCollectorOptions) { + o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...) + } +} + +// GoCollectionOption represents Go collection option flag. +// Deprecated. type GoCollectionOption uint32 const ( - // GoRuntimeMemStatsCollection represents the metrics represented by runtime.MemStats structure such as - // go_memstats_alloc_bytes - // go_memstats_alloc_bytes_total - // go_memstats_sys_bytes - // go_memstats_lookups_total - // go_memstats_mallocs_total - // go_memstats_frees_total - // go_memstats_heap_alloc_bytes - // go_memstats_heap_sys_bytes - // go_memstats_heap_idle_bytes - // go_memstats_heap_inuse_bytes - // go_memstats_heap_released_bytes - // go_memstats_heap_objects - // go_memstats_stack_inuse_bytes - // go_memstats_stack_sys_bytes - // go_memstats_mspan_inuse_bytes - // go_memstats_mspan_sys_bytes - // go_memstats_mcache_inuse_bytes - // go_memstats_mcache_sys_bytes - // go_memstats_buck_hash_sys_bytes - // go_memstats_gc_sys_bytes - // go_memstats_other_sys_bytes - // go_memstats_next_gc_bytes - // so the metrics known from pre client_golang v1.12.0, except skipped go_memstats_gc_cpu_fraction (see - // https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 for explanation. - // - // NOTE that this mode represents runtime.MemStats statistics, but they are - // actually implemented using new runtime/metrics package. - // Deprecated: Use GoRuntimeMetricsCollection instead going forward. + // GoRuntimeMemStatsCollection represents the metrics represented by runtime.MemStats structure. + // Deprecated. Use WithGoCollectorMemStatsMetricsDisabled() function to disable those metrics in the collector. GoRuntimeMemStatsCollection GoCollectionOption = 1 << iota - // GoRuntimeMetricsCollection is the new set of metrics represented by runtime/metrics package and follows - // consistent naming. The exposed metric set depends on Go version, but it is controlled against - // unexpected cardinality. This set has overlapping information with GoRuntimeMemStatsCollection, just with - // new names. GoRuntimeMetricsCollection is what is recommended for using going forward. + // GoRuntimeMetricsCollection is the new set of metrics represented by runtime/metrics package. + // Deprecated. Use WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")}) + // function to enable those metrics in the collector. GoRuntimeMetricsCollection ) -// WithGoCollections allows enabling different collections for Go collector on top of base metrics -// like go_goroutines, go_threads, go_gc_duration_seconds, go_memstats_last_gc_time_seconds, go_info. -// -// Check GoRuntimeMemStatsCollection and GoRuntimeMetricsCollection for more details. You can use none, -// one or more collections at once. For example: -// WithGoCollections(GoRuntimeMemStatsCollection | GoRuntimeMetricsCollection) means both GoRuntimeMemStatsCollection -// metrics and GoRuntimeMetricsCollection will be exposed. -// -// The current default is GoRuntimeMemStatsCollection, so the compatibility mode with -// client_golang pre v1.12 (move to runtime/metrics). -func WithGoCollections(flags GoCollectionOption) goOption { - return func(o *goOptions) { - o.EnabledCollections = uint32(flags) +// WithGoCollections allows enabling different collections for Go collector on top of base metrics. +// Deprecated. Use WithGoCollectorRuntimeMetrics() and WithGoCollectorMemStatsMetricsDisabled() instead to control metrics. +func WithGoCollections(flags GoCollectionOption) func(options *internal.GoCollectorOptions) { + return func(options *internal.GoCollectorOptions) { + if flags&GoRuntimeMemStatsCollection == 0 { + WithGoCollectorMemStatsMetricsDisabled()(options) + } + + if flags&GoRuntimeMetricsCollection != 0 { + WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")})(options) + } } } // NewGoCollector returns a collector that exports metrics about the current Go -// process using debug.GCStats using runtime/metrics. -func NewGoCollector(opts ...goOption) prometheus.Collector { - //nolint:staticcheck // Ignore SA1019 until v2. - promPkgOpts := make([]func(o *prometheus.GoCollectorOptions), len(opts)) - for i, opt := range opts { - promPkgOpts[i] = opt - } +// process using debug.GCStats (base metrics) and runtime/metrics (both in MemStats style and new ones). +func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) prometheus.Collector { //nolint:staticcheck // Ignore SA1019 until v2. - return prometheus.NewGoCollector(promPkgOpts...) + return prometheus.NewGoCollector(opts...) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go index 00d70f09b6..a912b75a05 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go @@ -51,7 +51,7 @@ type Counter interface { // will lead to a valid (label-less) exemplar. But if Labels is nil, the current // exemplar is left in place. AddWithExemplar panics if the value is < 0, if any // of the provided labels are invalid, or if the provided labels contain more -// than 64 runes in total. +// than 128 runes in total. type ExemplarAdder interface { AddWithExemplar(value float64, exemplar Labels) } @@ -140,12 +140,13 @@ func (c *counter) get() float64 { } func (c *counter) Write(out *dto.Metric) error { - val := c.get() - + // Read the Exemplar first and the value second. This is to avoid a race condition + // where users see an exemplar for a not-yet-existing observation. var exemplar *dto.Exemplar if e := c.exemplar.Load(); e != nil { exemplar = e.(*dto.Exemplar) } + val := c.get() return populateMetric(CounterValue, val, c.labelPairs, exemplar, out) } @@ -245,7 +246,8 @@ func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) { // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like -// myVec.WithLabelValues("404", "GET").Add(42) +// +// myVec.WithLabelValues("404", "GET").Add(42) func (v *CounterVec) WithLabelValues(lvs ...string) Counter { c, err := v.GetMetricWithLabelValues(lvs...) if err != nil { @@ -256,7 +258,8 @@ func (v *CounterVec) WithLabelValues(lvs ...string) Counter { // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) +// +// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) func (v *CounterVec) With(labels Labels) Counter { c, err := v.GetMetricWith(labels) if err != nil { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go index 4bb816ab75..8bc5e44e2f 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go @@ -20,6 +20,9 @@ import ( "strings" "github.com/cespare/xxhash/v2" + + "github.com/prometheus/client_golang/prometheus/internal" + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" @@ -154,7 +157,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * Value: proto.String(v), }) } - sort.Sort(labelPairSorter(d.constLabelPairs)) + sort.Sort(internal.LabelPairSorter(d.constLabelPairs)) return d } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go index 98450125d6..811072cbd5 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/doc.go @@ -21,55 +21,66 @@ // All exported functions and methods are safe to be used concurrently unless // specified otherwise. // -// A Basic Example +// # A Basic Example // // As a starting point, a very basic usage example: // -// package main -// -// import ( -// "log" -// "net/http" -// -// "github.com/prometheus/client_golang/prometheus" -// "github.com/prometheus/client_golang/prometheus/promhttp" -// ) -// -// var ( -// cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ -// Name: "cpu_temperature_celsius", -// Help: "Current temperature of the CPU.", -// }) -// hdFailures = prometheus.NewCounterVec( -// prometheus.CounterOpts{ -// Name: "hd_errors_total", -// Help: "Number of hard-disk errors.", -// }, -// []string{"device"}, -// ) -// ) -// -// func init() { -// // Metrics have to be registered to be exposed: -// prometheus.MustRegister(cpuTemp) -// prometheus.MustRegister(hdFailures) -// } -// -// func main() { -// cpuTemp.Set(65.3) -// hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() -// -// // The Handler function provides a default handler to expose metrics -// // via an HTTP server. "/metrics" is the usual endpoint for that. -// http.Handle("/metrics", promhttp.Handler()) -// log.Fatal(http.ListenAndServe(":8080", nil)) -// } -// +// package main +// +// import ( +// "log" +// "net/http" +// +// "github.com/prometheus/client_golang/prometheus" +// "github.com/prometheus/client_golang/prometheus/promhttp" +// ) +// +// type metrics struct { +// cpuTemp prometheus.Gauge +// hdFailures *prometheus.CounterVec +// } +// +// func NewMetrics(reg prometheus.Registerer) *metrics { +// m := &metrics{ +// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ +// Name: "cpu_temperature_celsius", +// Help: "Current temperature of the CPU.", +// }), +// hdFailures: prometheus.NewCounterVec( +// prometheus.CounterOpts{ +// Name: "hd_errors_total", +// Help: "Number of hard-disk errors.", +// }, +// []string{"device"}, +// ), +// } +// reg.MustRegister(m.cpuTemp) +// reg.MustRegister(m.hdFailures) +// return m +// } +// +// func main() { +// // Create a non-global registry. +// reg := prometheus.NewRegistry() +// +// // Create new metrics and register them using the custom registry. +// m := NewMetrics(reg) +// // Set values for the new created metrics. +// m.cpuTemp.Set(65.3) +// m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() +// +// // Expose metrics and custom registry via an HTTP server +// // using the HandleFor function. "/metrics" is the usual endpoint for that. +// http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) +// log.Fatal(http.ListenAndServe(":8080", nil)) +// } // // This is a complete program that exports two metrics, a Gauge and a Counter, // the latter with a label attached to turn it into a (one-dimensional) vector. +// It register the metrics using a custom registry and exposes them via an HTTP server +// on the /metrics endpoint. // -// Metrics +// # Metrics // // The number of exported identifiers in this package might appear a bit // overwhelming. However, in addition to the basic plumbing shown in the example @@ -100,7 +111,7 @@ // To create instances of Metrics and their vector versions, you need a suitable // …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts. // -// Custom Collectors and constant Metrics +// # Custom Collectors and constant Metrics // // While you could create your own implementations of Metric, most likely you // will only ever implement the Collector interface on your own. At a first @@ -141,7 +152,7 @@ // a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting // shortcuts. // -// Advanced Uses of the Registry +// # Advanced Uses of the Registry // // While MustRegister is the by far most common way of registering a Collector, // sometimes you might want to handle the errors the registration might cause. @@ -176,23 +187,23 @@ // NewProcessCollector). With a custom registry, you are in control and decide // yourself about the Collectors to register. // -// HTTP Exposition +// # HTTP Exposition // // The Registry implements the Gatherer interface. The caller of the Gather // method can then expose the gathered metrics in some way. Usually, the metrics // are served via HTTP on the /metrics endpoint. That's happening in the example // above. The tools to expose metrics via HTTP are in the promhttp sub-package. // -// Pushing to the Pushgateway +// # Pushing to the Pushgateway // // Function for pushing to the Pushgateway can be found in the push sub-package. // -// Graphite Bridge +// # Graphite Bridge // // Functions and examples to push metrics from a Gatherer to Graphite can be // found in the graphite sub-package. // -// Other Means of Exposition +// # Other Means of Exposition // // More ways of exposing metrics can easily be added by following the approaches // of the existing implementations. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go index bd0733d6a7..21271a5bb4 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go @@ -210,7 +210,8 @@ func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like -// myVec.WithLabelValues("404", "GET").Add(42) +// +// myVec.WithLabelValues("404", "GET").Add(42) func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { g, err := v.GetMetricWithLabelValues(lvs...) if err != nil { @@ -221,7 +222,8 @@ func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) +// +// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) func (v *GaugeVec) With(labels Labels) Gauge { g, err := v.GetMetricWith(labels) if err != nil { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go new file mode 100644 index 0000000000..614fd61be9 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go @@ -0,0 +1,26 @@ +// Copyright 2015 The Prometheus 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. + +//go:build !js || wasm +// +build !js wasm + +package prometheus + +import "os" + +func getPIDFn() func() (int, error) { + pid := os.Getpid() + return func() (int, error) { + return pid, nil + } +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go new file mode 100644 index 0000000000..eaf8059ee1 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go @@ -0,0 +1,23 @@ +// Copyright 2015 The Prometheus 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. + +//go:build js && !wasm +// +build js,!wasm + +package prometheus + +func getPIDFn() func() (int, error) { + return func() (int, error) { + return 1, nil + } +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go index 4d792aa29e..ad9a71a5e0 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -19,6 +19,10 @@ import ( "time" ) +// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. +// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so +// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is +// populated using runtime/metrics. func goRuntimeMemStats() memStatsMetrics { return memStatsMetrics{ { @@ -224,7 +228,7 @@ func newBaseGoCollector() baseGoCollector { "A summary of the pause duration of garbage collection cycles.", nil, nil), gcLastTimeDesc: NewDesc( - memstatNamespace("last_gc_time_seconds"), + "go_memstats_last_gc_time_seconds", "Number of seconds since 1970 of last garbage collection.", nil, nil), goInfoDesc: NewDesc( @@ -246,8 +250,9 @@ func (c *baseGoCollector) Describe(ch chan<- *Desc) { // Collect returns the current state of all metrics of the collector. func (c *baseGoCollector) Collect(ch chan<- Metric) { ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine())) - n, _ := runtime.ThreadCreateProfile(nil) - ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n)) + + n := getRuntimeNumThreads() + ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n) var stats debug.GCStats stats.PauseQuantiles = make([]time.Duration, 5) @@ -269,7 +274,6 @@ func memstatNamespace(s string) string { // memStatsMetrics provide description, evaluator, runtime/metrics name, and // value type for memstat metrics. -// TODO(bwplotka): Remove with end Go 1.16 EOL and replace with runtime/metrics.Description type memStatsMetrics []struct { desc *Desc eval func(*runtime.MemStats) float64 diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go index a0fe95eb11..3a2d55e84b 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go @@ -31,9 +31,11 @@ import ( ) const ( + // constants for strings referenced more than once. goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects" goGCHeapAllocsObjects = "/gc/heap/allocs:objects" goGCHeapFreesObjects = "/gc/heap/frees:objects" + goGCHeapFreesBytes = "/gc/heap/frees:bytes" goGCHeapAllocsBytes = "/gc/heap/allocs:bytes" goGCHeapObjects = "/gc/heap/objects:objects" goGCHeapGoalBytes = "/gc/heap/goal:bytes" @@ -53,8 +55,9 @@ const ( goMemoryClassesOtherBytes = "/memory/classes/other:bytes" ) -// runtime/metrics names required for runtimeMemStats like logic. -var rmForMemStats = []string{goGCHeapTinyAllocsObjects, +// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic. +var rmNamesForMemStatsMetrics = []string{ + goGCHeapTinyAllocsObjects, goGCHeapAllocsObjects, goGCHeapFreesObjects, goGCHeapAllocsBytes, @@ -89,74 +92,90 @@ func bestEffortLookupRM(lookup []string) []metrics.Description { } type goCollector struct { - opt GoCollectorOptions base baseGoCollector // mu protects updates to all fields ensuring a consistent // snapshot is always produced by Collect. mu sync.Mutex - // rm... fields all pertain to the runtime/metrics package. - rmSampleBuf []metrics.Sample - rmSampleMap map[string]*metrics.Sample - rmMetrics []collectorMetric + // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed). + sampleBuf []metrics.Sample + // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums. + sampleMap map[string]*metrics.Sample + + // rmExposedMetrics represents all runtime/metrics package metrics + // that were configured to be exposed. + rmExposedMetrics []collectorMetric + rmExactSumMapForHist map[string]string // With Go 1.17, the runtime/metrics package was introduced. // From that point on, metric names produced by the runtime/metrics // package could be generated from runtime/metrics names. However, // these differ from the old names for the same values. // - // This field exist to export the same values under the old names + // This field exists to export the same values under the old names // as well. - msMetrics memStatsMetrics + msMetrics memStatsMetrics + msMetricsEnabled bool } -const ( - // Those are not exposed due to need to move Go collector to another package in v2. - // See issue https://github.com/prometheus/client_golang/issues/1030. - goRuntimeMemStatsCollection uint32 = 1 << iota - goRuntimeMetricsCollection -) - -// GoCollectorOptions should not be used be directly by anything, except `collectors` package. -// Use it via collectors package instead. See issue -// https://github.com/prometheus/client_golang/issues/1030. -// -// Deprecated: Use collectors.WithGoCollections -type GoCollectorOptions struct { - // EnabledCollection sets what type of collections collector should expose on top of base collection. - // By default it's goMemStatsCollection | goRuntimeMetricsCollection. - EnabledCollections uint32 +type rmMetricDesc struct { + metrics.Description } -func (c GoCollectorOptions) isEnabled(flag uint32) bool { - return c.EnabledCollections&flag != 0 +func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc { + var descs []rmMetricDesc + for _, d := range metrics.All() { + var ( + deny = true + desc rmMetricDesc + ) + + for _, r := range rules { + if !r.Matcher.MatchString(d.Name) { + continue + } + deny = r.Deny + } + if deny { + continue + } + + desc.Description = d + descs = append(descs, desc) + } + return descs } -const defaultGoCollections = goRuntimeMemStatsCollection +func defaultGoCollectorOptions() internal.GoCollectorOptions { + return internal.GoCollectorOptions{ + RuntimeMetricSumForHist: map[string]string{ + "/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes, + "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, + }, + RuntimeMetricRules: []internal.GoCollectorRule{ + //{Matcher: regexp.MustCompile("")}, + }, + } +} // NewGoCollector is the obsolete version of collectors.NewGoCollector. // See there for documentation. // // Deprecated: Use collectors.NewGoCollector instead. -func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector { - opt := GoCollectorOptions{EnabledCollections: defaultGoCollections} +func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { + opt := defaultGoCollectorOptions() for _, o := range opts { o(&opt) } - var descriptions []metrics.Description - if opt.isEnabled(goRuntimeMetricsCollection) { - descriptions = metrics.All() - } else if opt.isEnabled(goRuntimeMemStatsCollection) { - descriptions = bestEffortLookupRM(rmForMemStats) - } + exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules) // Collect all histogram samples so that we can get their buckets. // The API guarantees that the buckets are always fixed for the lifetime // of the process. var histograms []metrics.Sample - for _, d := range descriptions { + for _, d := range exposedDescriptions { if d.Kind == metrics.KindFloat64Histogram { histograms = append(histograms, metrics.Sample{Name: d.Name}) } @@ -171,13 +190,14 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector { bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets } - // Generate a Desc and ValueType for each runtime/metrics metric. - metricSet := make([]collectorMetric, 0, len(descriptions)) - sampleBuf := make([]metrics.Sample, 0, len(descriptions)) - sampleMap := make(map[string]*metrics.Sample, len(descriptions)) - for i := range descriptions { - d := &descriptions[i] - namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(d) + // Generate a collector for each exposed runtime/metrics metric. + metricSet := make([]collectorMetric, 0, len(exposedDescriptions)) + // SampleBuf is used for reading from runtime/metrics. + // We are assuming the largest case to have stable pointers for sampleMap purposes. + sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics)) + sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions)) + for _, d := range exposedDescriptions { + namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description) if !ok { // Just ignore this metric; we can't do anything with it here. // If a user decides to use the latest version of Go, we don't want @@ -185,19 +205,17 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector { continue } - // Set up sample buffer for reading, and a map - // for quick lookup of sample values. sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] var m collectorMetric if d.Kind == metrics.KindFloat64Histogram { - _, hasSum := rmExactSumMap[d.Name] + _, hasSum := opt.RuntimeMetricSumForHist[d.Name] unit := d.Name[strings.IndexRune(d.Name, ':')+1:] m = newBatchHistogram( NewDesc( BuildFQName(namespace, subsystem, name), - d.Description, + d.Description.Description, nil, nil, ), @@ -209,30 +227,61 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector { Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description, - }) + Help: d.Description.Description, + }, + ) } else { m = NewGauge(GaugeOpts{ Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description, + Help: d.Description.Description, }) } metricSet = append(metricSet, m) } - var msMetrics memStatsMetrics - if opt.isEnabled(goRuntimeMemStatsCollection) { + // Add exact sum metrics to sampleBuf if not added before. + for _, h := range histograms { + sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name] + if !ok { + continue + } + + if _, ok := sampleMap[sumMetric]; ok { + continue + } + sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric}) + sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1] + } + + var ( + msMetrics memStatsMetrics + msDescriptions []metrics.Description + ) + + if !opt.DisableMemStatsLikeMetrics { msMetrics = goRuntimeMemStats() + msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics) + + // Check if metric was not exposed before and if not, add to sampleBuf. + for _, mdDesc := range msDescriptions { + if _, ok := sampleMap[mdDesc.Name]; ok { + continue + } + sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name}) + sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1] + } } + return &goCollector{ - opt: opt, - base: newBaseGoCollector(), - rmSampleBuf: sampleBuf, - rmSampleMap: sampleMap, - rmMetrics: metricSet, - msMetrics: msMetrics, + base: newBaseGoCollector(), + sampleBuf: sampleBuf, + sampleMap: sampleMap, + rmExposedMetrics: metricSet, + rmExactSumMapForHist: opt.RuntimeMetricSumForHist, + msMetrics: msMetrics, + msMetricsEnabled: !opt.DisableMemStatsLikeMetrics, } } @@ -242,7 +291,7 @@ func (c *goCollector) Describe(ch chan<- *Desc) { for _, i := range c.msMetrics { ch <- i.desc } - for _, m := range c.rmMetrics { + for _, m := range c.rmExposedMetrics { ch <- m.Desc() } } @@ -252,8 +301,12 @@ func (c *goCollector) Collect(ch chan<- Metric) { // Collect base non-memory metrics. c.base.Collect(ch) + if len(c.sampleBuf) == 0 { + return + } + // Collect must be thread-safe, so prevent concurrent use of - // rmSampleBuf. Just read into rmSampleBuf but write all the data + // sampleBuf elements. Just read into sampleBuf but write all the data // we get into our Metrics or MemStats. // // This lock also ensures that the Metrics we send out are all from @@ -267,44 +320,43 @@ func (c *goCollector) Collect(ch chan<- Metric) { c.mu.Lock() defer c.mu.Unlock() - if len(c.rmSampleBuf) > 0 { - // Populate runtime/metrics sample buffer. - metrics.Read(c.rmSampleBuf) - } - - if c.opt.isEnabled(goRuntimeMetricsCollection) { - // Collect all our metrics from rmSampleBuf. - for i, sample := range c.rmSampleBuf { - // N.B. switch on concrete type because it's significantly more efficient - // than checking for the Counter and Gauge interface implementations. In - // this case, we control all the types here. - switch m := c.rmMetrics[i].(type) { - case *counter: - // Guard against decreases. This should never happen, but a failure - // to do so will result in a panic, which is a harsh consequence for - // a metrics collection bug. - v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) - if v1 > v0 { - m.Add(unwrapScalarRMValue(sample.Value) - m.get()) - } - m.Collect(ch) - case *gauge: - m.Set(unwrapScalarRMValue(sample.Value)) - m.Collect(ch) - case *batchHistogram: - m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) - m.Collect(ch) - default: - panic("unexpected metric type") + // Populate runtime/metrics sample buffer. + metrics.Read(c.sampleBuf) + + // Collect all our runtime/metrics user chose to expose from sampleBuf (if any). + for i, metric := range c.rmExposedMetrics { + // We created samples for exposed metrics first in order, so indexes match. + sample := c.sampleBuf[i] + + // N.B. switch on concrete type because it's significantly more efficient + // than checking for the Counter and Gauge interface implementations. In + // this case, we control all the types here. + switch m := metric.(type) { + case *counter: + // Guard against decreases. This should never happen, but a failure + // to do so will result in a panic, which is a harsh consequence for + // a metrics collection bug. + v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) + if v1 > v0 { + m.Add(unwrapScalarRMValue(sample.Value) - m.get()) } + m.Collect(ch) + case *gauge: + m.Set(unwrapScalarRMValue(sample.Value)) + m.Collect(ch) + case *batchHistogram: + m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) + m.Collect(ch) + default: + panic("unexpected metric type") } } - // ms is a dummy MemStats that we populate ourselves so that we can - // populate the old metrics from it if goMemStatsCollection is enabled. - if c.opt.isEnabled(goRuntimeMemStatsCollection) { + if c.msMetricsEnabled { + // ms is a dummy MemStats that we populate ourselves so that we can + // populate the old metrics from it if goMemStatsCollection is enabled. var ms runtime.MemStats - memStatsFromRM(&ms, c.rmSampleMap) + memStatsFromRM(&ms, c.sampleMap) for _, i := range c.msMetrics { ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) } @@ -335,11 +387,6 @@ func unwrapScalarRMValue(v metrics.Value) float64 { } } -var rmExactSumMap = map[string]string{ - "/gc/heap/allocs-by-size:bytes": "/gc/heap/allocs:bytes", - "/gc/heap/frees-by-size:bytes": "/gc/heap/frees:bytes", -} - // exactSumFor takes a runtime/metrics metric name (that is assumed to // be of kind KindFloat64Histogram) and returns its exact sum and whether // its exact sum exists. @@ -347,11 +394,11 @@ var rmExactSumMap = map[string]string{ // The runtime/metrics API for histograms doesn't currently expose exact // sums, but some of the other metrics are in fact exact sums of histograms. func (c *goCollector) exactSumFor(rmName string) float64 { - sumName, ok := rmExactSumMap[rmName] + sumName, ok := c.rmExactSumMapForHist[rmName] if !ok { return 0 } - s, ok := c.rmSampleMap[sumName] + s, ok := c.sampleMap[sumName] if !ok { return 0 } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index 893802fd6b..4c873a01c3 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -28,19 +28,216 @@ import ( dto "github.com/prometheus/client_model/go" ) +// nativeHistogramBounds for the frac of observed values. Only relevant for +// schema > 0. The position in the slice is the schema. (0 is never used, just +// here for convenience of using the schema directly as the index.) +// +// TODO(beorn7): Currently, we do a binary search into these slices. There are +// ways to turn it into a small number of simple array lookups. It probably only +// matters for schema 5 and beyond, but should be investigated. See this comment +// as a starting point: +// https://github.com/open-telemetry/opentelemetry-specification/issues/1776#issuecomment-870164310 +var nativeHistogramBounds = [][]float64{ + // Schema "0": + {0.5}, + // Schema 1: + {0.5, 0.7071067811865475}, + // Schema 2: + {0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144}, + // Schema 3: + { + 0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048, + 0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711, + }, + // Schema 4: + { + 0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458, + 0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463, + 0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627, + 0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735, + }, + // Schema 5: + { + 0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117, + 0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887, + 0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666, + 0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159, + 0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112, + 0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823, + 0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533, + 0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999, + }, + // Schema 6: + { + 0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142, + 0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598, + 0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209, + 0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406, + 0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349, + 0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891, + 0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515, + 0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555, + 0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234, + 0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269, + 0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334, + 0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681, + 0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529, + 0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991, + 0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827, + 0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752, + }, + // Schema 7: + { + 0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764, + 0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894, + 0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309, + 0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545, + 0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393, + 0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595, + 0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754, + 0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704, + 0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907, + 0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665, + 0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253, + 0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329, + 0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032, + 0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728, + 0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265, + 0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076, + 0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491, + 0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908, + 0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126, + 0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777, + 0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764, + 0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465, + 0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821, + 0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981, + 0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312, + 0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842, + 0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671, + 0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263, + 0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943, + 0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368, + 0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164, + 0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328, + }, + // Schema 8: + { + 0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088, + 0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869, + 0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205, + 0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158, + 0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313, + 0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321, + 0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954, + 0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847, + 0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111, + 0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088, + 0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098, + 0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026, + 0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894, + 0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493, + 0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185, + 0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968, + 0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903, + 0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005, + 0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725, + 0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082, + 0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581, + 0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031, + 0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346, + 0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447, + 0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385, + 0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788, + 0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727, + 0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171, + 0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058, + 0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119, + 0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999, + 0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352, + 0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471, + 0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126, + 0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218, + 0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837, + 0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984, + 0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031, + 0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071, + 0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282, + 0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442, + 0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707, + 0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818, + 0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853, + 0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642, + 0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003, + 0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079, + 0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391, + 0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661, + 0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629, + 0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553, + 0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389, + 0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771, + 0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002, + 0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155, + 0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483, + 0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253, + 0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191, + 0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693, + 0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947, + 0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133, + 0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889, + 0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168, + 0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698, + }, +} + +// The nativeHistogramBounds above can be generated with the code below. +// +// TODO(beorn7): It's tempting to actually use `go generate` to generate the +// code above. However, this could lead to slightly different numbers on +// different architectures. We still need to come to terms if we are fine with +// that, or if we might prefer to specify precise numbers in the standard. +// +// var nativeHistogramBounds [][]float64 = make([][]float64, 9) +// +// func init() { +// // Populate nativeHistogramBounds. +// numBuckets := 1 +// for i := range nativeHistogramBounds { +// bounds := []float64{0.5} +// factor := math.Exp2(math.Exp2(float64(-i))) +// for j := 0; j < numBuckets-1; j++ { +// var bound float64 +// if (j+1)%2 == 0 { +// // Use previously calculated value for increased precision. +// bound = nativeHistogramBounds[i-1][j/2+1] +// } else { +// bound = bounds[j] * factor +// } +// bounds = append(bounds, bound) +// } +// numBuckets *= 2 +// nativeHistogramBounds[i] = bounds +// } +// } + // A Histogram counts individual observations from an event or sample stream in -// configurable buckets. Similar to a summary, it also provides a sum of -// observations and an observation count. +// configurable static buckets (or in dynamic sparse buckets as part of the +// experimental Native Histograms, see below for more details). Similar to a +// Summary, it also provides a sum of observations and an observation count. // // On the Prometheus server, quantiles can be calculated from a Histogram using -// the histogram_quantile function in the query language. +// the histogram_quantile PromQL function. +// +// Note that Histograms, in contrast to Summaries, can be aggregated in PromQL +// (see the documentation for detailed procedures). However, Histograms require +// the user to pre-define suitable buckets, and they are in general less +// accurate. (Both problems are addressed by the experimental Native +// Histograms. To use them, configure a NativeHistogramBucketFactor in the +// HistogramOpts. They also require a Prometheus server v2.40+ with the +// corresponding feature flag enabled.) // -// Note that Histograms, in contrast to Summaries, can be aggregated with the -// Prometheus query language (see the documentation for detailed -// procedures). However, Histograms require the user to pre-define suitable -// buckets, and they are in general less accurate. The Observe method of a -// Histogram has a very low performance overhead in comparison with the Observe -// method of a Summary. +// The Observe method of a Histogram has a very low performance overhead in +// comparison with the Observe method of a Summary. // // To create Histogram instances, use NewHistogram. type Histogram interface { @@ -50,7 +247,8 @@ type Histogram interface { // Observe adds a single observation to the histogram. Observations are // usually positive or zero. Negative observations are accepted but // prevent current versions of Prometheus from properly detecting - // counter resets in the sum of observations. See + // counter resets in the sum of observations. (The experimental Native + // Histograms handle negative observations properly.) See // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations // for details. Observe(float64) @@ -64,18 +262,28 @@ const bucketLabel = "le" // tailored to broadly measure the response time (in seconds) of a network // service. Most likely, however, you will be required to define buckets // customized to your use case. -var ( - DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} +var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - errBucketLabelNotAllowed = fmt.Errorf( - "%q is not allowed as label name in histograms", bucketLabel, - ) +// DefNativeHistogramZeroThreshold is the default value for +// NativeHistogramZeroThreshold in the HistogramOpts. +// +// The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation), +// which is a bucket boundary at all possible resolutions. +const DefNativeHistogramZeroThreshold = 2.938735877055719e-39 + +// NativeHistogramZeroThresholdZero can be used as NativeHistogramZeroThreshold +// in the HistogramOpts to create a zero bucket of width zero, i.e. a zero +// bucket that only receives observations of precisely zero. +const NativeHistogramZeroThresholdZero = -1 + +var errBucketLabelNotAllowed = fmt.Errorf( + "%q is not allowed as label name in histograms", bucketLabel, ) -// LinearBuckets creates 'count' buckets, each 'width' wide, where the lowest -// bucket has an upper bound of 'start'. The final +Inf bucket is not counted -// and not included in the returned slice. The returned slice is meant to be -// used for the Buckets field of HistogramOpts. +// LinearBuckets creates 'count' regular buckets, each 'width' wide, where the +// lowest bucket has an upper bound of 'start'. The final +Inf bucket is not +// counted and not included in the returned slice. The returned slice is meant +// to be used for the Buckets field of HistogramOpts. // // The function panics if 'count' is zero or negative. func LinearBuckets(start, width float64, count int) []float64 { @@ -90,11 +298,11 @@ func LinearBuckets(start, width float64, count int) []float64 { return buckets } -// ExponentialBuckets creates 'count' buckets, where the lowest bucket has an -// upper bound of 'start' and each following bucket's upper bound is 'factor' -// times the previous bucket's upper bound. The final +Inf bucket is not counted -// and not included in the returned slice. The returned slice is meant to be -// used for the Buckets field of HistogramOpts. +// ExponentialBuckets creates 'count' regular buckets, where the lowest bucket +// has an upper bound of 'start' and each following bucket's upper bound is +// 'factor' times the previous bucket's upper bound. The final +Inf bucket is +// not counted and not included in the returned slice. The returned slice is +// meant to be used for the Buckets field of HistogramOpts. // // The function panics if 'count' is 0 or negative, if 'start' is 0 or negative, // or if 'factor' is less than or equal 1. @@ -180,8 +388,85 @@ type HistogramOpts struct { // element in the slice is the upper inclusive bound of a bucket. The // values must be sorted in strictly increasing order. There is no need // to add a highest bucket with +Inf bound, it will be added - // implicitly. The default value is DefBuckets. + // implicitly. If Buckets is left as nil or set to a slice of length + // zero, it is replaced by default buckets. The default buckets are + // DefBuckets if no buckets for a native histogram (see below) are used, + // otherwise the default is no buckets. (In other words, if you want to + // use both reguler buckets and buckets for a native histogram, you have + // to define the regular buckets here explicitly.) Buckets []float64 + + // If NativeHistogramBucketFactor is greater than one, so-called sparse + // buckets are used (in addition to the regular buckets, if defined + // above). A Histogram with sparse buckets will be ingested as a Native + // Histogram by a Prometheus server with that feature enabled (requires + // Prometheus v2.40+). Sparse buckets are exponential buckets covering + // the whole float64 range (with the exception of the “zero” bucket, see + // SparseBucketsZeroThreshold below). From any one bucket to the next, + // the width of the bucket grows by a constant + // factor. NativeHistogramBucketFactor provides an upper bound for this + // factor (exception see below). The smaller + // NativeHistogramBucketFactor, the more buckets will be used and thus + // the more costly the histogram will become. A generally good trade-off + // between cost and accuracy is a value of 1.1 (each bucket is at most + // 10% wider than the previous one), which will result in each power of + // two divided into 8 buckets (e.g. there will be 8 buckets between 1 + // and 2, same as between 2 and 4, and 4 and 8, etc.). + // + // Details about the actually used factor: The factor is calculated as + // 2^(2^n), where n is an integer number between (and including) -8 and + // 4. n is chosen so that the resulting factor is the largest that is + // still smaller or equal to NativeHistogramBucketFactor. Note that the + // smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8) + // ). If NativeHistogramBucketFactor is greater than 1 but smaller than + // 2^(2^-8), then the actually used factor is still 2^(2^-8) even though + // it is larger than the provided NativeHistogramBucketFactor. + // + // NOTE: Native Histograms are still an experimental feature. Their + // behavior might still change without a major version + // bump. Subsequently, all NativeHistogram... options here might still + // change their behavior or name (or might completely disappear) without + // a major version bump. + NativeHistogramBucketFactor float64 + // All observations with an absolute value of less or equal + // NativeHistogramZeroThreshold are accumulated into a “zero” + // bucket. For best results, this should be close to a bucket + // boundary. This is usually the case if picking a power of two. If + // NativeHistogramZeroThreshold is left at zero, + // DefSparseBucketsZeroThreshold is used as the threshold. To configure + // a zero bucket with an actual threshold of zero (i.e. only + // observations of precisely zero will go into the zero bucket), set + // NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero + // constant (or any negative float value). + NativeHistogramZeroThreshold float64 + + // The remaining fields define a strategy to limit the number of + // populated sparse buckets. If NativeHistogramMaxBucketNumber is left + // at zero, the number of buckets is not limited. (Note that this might + // lead to unbounded memory consumption if the values observed by the + // Histogram are sufficiently wide-spread. In particular, this could be + // used as a DoS attack vector. Where the observed values depend on + // external inputs, it is highly recommended to set a + // NativeHistogramMaxBucketNumber.) Once the set + // NativeHistogramMaxBucketNumber is exceeded, the following strategy is + // enacted: First, if the last reset (or the creation) of the histogram + // is at least NativeHistogramMinResetDuration ago, then the whole + // histogram is reset to its initial state (including regular + // buckets). If less time has passed, or if + // NativeHistogramMinResetDuration is zero, no reset is + // performed. Instead, the zero threshold is increased sufficiently to + // reduce the number of buckets to or below + // NativeHistogramMaxBucketNumber, but not to more than + // NativeHistogramMaxZeroThreshold. Thus, if + // NativeHistogramMaxZeroThreshold is already at or below the current + // zero threshold, nothing happens at this step. After that, if the + // number of buckets still exceeds NativeHistogramMaxBucketNumber, the + // resolution of the histogram is reduced by doubling the width of the + // sparse buckets (up to a growth factor between one bucket to the next + // of 2^(2^4) = 65536, see above). + NativeHistogramMaxBucketNumber uint32 + NativeHistogramMinResetDuration time.Duration + NativeHistogramMaxZeroThreshold float64 } // NewHistogram creates a new Histogram based on the provided HistogramOpts. It @@ -218,16 +503,29 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } } - if len(opts.Buckets) == 0 { - opts.Buckets = DefBuckets - } - h := &histogram{ - desc: desc, - upperBounds: opts.Buckets, - labelPairs: MakeLabelPairs(desc, labelValues), - counts: [2]*histogramCounts{{}, {}}, - now: time.Now, + desc: desc, + upperBounds: opts.Buckets, + labelPairs: MakeLabelPairs(desc, labelValues), + nativeHistogramMaxBuckets: opts.NativeHistogramMaxBucketNumber, + nativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold, + nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration, + lastResetTime: time.Now(), + now: time.Now, + } + if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 { + h.upperBounds = DefBuckets + } + if opts.NativeHistogramBucketFactor <= 1 { + h.nativeHistogramSchema = math.MinInt32 // To mark that there are no sparse buckets. + } else { + switch { + case opts.NativeHistogramZeroThreshold > 0: + h.nativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold + case opts.NativeHistogramZeroThreshold == 0: + h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold + } // Leave h.nativeHistogramZeroThreshold at 0 otherwise. + h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor) } for i, upperBound := range h.upperBounds { if i < len(h.upperBounds)-1 { @@ -246,8 +544,16 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } // Finally we know the final length of h.upperBounds and can make buckets // for both counts as well as exemplars: - h.counts[0].buckets = make([]uint64, len(h.upperBounds)) - h.counts[1].buckets = make([]uint64, len(h.upperBounds)) + h.counts[0] = &histogramCounts{ + buckets: make([]uint64, len(h.upperBounds)), + nativeHistogramZeroThresholdBits: math.Float64bits(h.nativeHistogramZeroThreshold), + nativeHistogramSchema: h.nativeHistogramSchema, + } + h.counts[1] = &histogramCounts{ + buckets: make([]uint64, len(h.upperBounds)), + nativeHistogramZeroThresholdBits: math.Float64bits(h.nativeHistogramZeroThreshold), + nativeHistogramSchema: h.nativeHistogramSchema, + } h.exemplars = make([]atomic.Value, len(h.upperBounds)+1) h.init(h) // Init self-collection. @@ -255,13 +561,98 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } type histogramCounts struct { + // Order in this struct matters for the alignment required by atomic + // operations, see http://golang.org/pkg/sync/atomic/#pkg-note-BUG + // sumBits contains the bits of the float64 representing the sum of all - // observations. sumBits and count have to go first in the struct to - // guarantee alignment for atomic operations. - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG + // observations. sumBits uint64 count uint64 + + // nativeHistogramZeroBucket counts all (positive and negative) + // observations in the zero bucket (with an absolute value less or equal + // the current threshold, see next field. + nativeHistogramZeroBucket uint64 + // nativeHistogramZeroThresholdBits is the bit pattern of the current + // threshold for the zero bucket. It's initially equal to + // nativeHistogramZeroThreshold but may change according to the bucket + // count limitation strategy. + nativeHistogramZeroThresholdBits uint64 + // nativeHistogramSchema may change over time according to the bucket + // count limitation strategy and therefore has to be saved here. + nativeHistogramSchema int32 + // Number of (positive and negative) sparse buckets. + nativeHistogramBucketsNumber uint32 + + // Regular buckets. buckets []uint64 + + // The sparse buckets for native histograms are implemented with a + // sync.Map for now. A dedicated data structure will likely be more + // efficient. There are separate maps for negative and positive + // observations. The map's value is an *int64, counting observations in + // that bucket. (Note that we don't use uint64 as an int64 won't + // overflow in practice, and working with signed numbers from the + // beginning simplifies the handling of deltas.) The map's key is the + // index of the bucket according to the used + // nativeHistogramSchema. Index 0 is for an upper bound of 1. + nativeHistogramBucketsPositive, nativeHistogramBucketsNegative sync.Map +} + +// observe manages the parts of observe that only affects +// histogramCounts. doSparse is true if sparse buckets should be done, +// too. +func (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) { + if bucket < len(hc.buckets) { + atomic.AddUint64(&hc.buckets[bucket], 1) + } + atomicAddFloat(&hc.sumBits, v) + if doSparse && !math.IsNaN(v) { + var ( + key int + schema = atomic.LoadInt32(&hc.nativeHistogramSchema) + zeroThreshold = math.Float64frombits(atomic.LoadUint64(&hc.nativeHistogramZeroThresholdBits)) + bucketCreated, isInf bool + ) + if math.IsInf(v, 0) { + // Pretend v is MaxFloat64 but later increment key by one. + if math.IsInf(v, +1) { + v = math.MaxFloat64 + } else { + v = -math.MaxFloat64 + } + isInf = true + } + frac, exp := math.Frexp(math.Abs(v)) + if schema > 0 { + bounds := nativeHistogramBounds[schema] + key = sort.SearchFloat64s(bounds, frac) + (exp-1)*len(bounds) + } else { + key = exp + if frac == 0.5 { + key-- + } + div := 1 << -schema + key = (key + div - 1) / div + } + if isInf { + key++ + } + switch { + case v > zeroThreshold: + bucketCreated = addToBucket(&hc.nativeHistogramBucketsPositive, key, 1) + case v < -zeroThreshold: + bucketCreated = addToBucket(&hc.nativeHistogramBucketsNegative, key, 1) + default: + atomic.AddUint64(&hc.nativeHistogramZeroBucket, 1) + } + if bucketCreated { + atomic.AddUint32(&hc.nativeHistogramBucketsNumber, 1) + } + } + // Increment count last as we take it as a signal that the observation + // is complete. + atomic.AddUint64(&hc.count, 1) } type histogram struct { @@ -276,7 +667,7 @@ type histogram struct { // perspective of the histogram) swap the hot–cold under the writeMtx // lock. A cooldown is awaited (while locked) by comparing the number of // observations with the initiation count. Once they match, then the - // last observation on the now cool one has completed. All cool fields must + // last observation on the now cool one has completed. All cold fields must // be merged into the new hot before releasing writeMtx. // // Fields with atomic access first! See alignment constraint: @@ -284,8 +675,10 @@ type histogram struct { countAndHotIdx uint64 selfCollector - desc *Desc - writeMtx sync.Mutex // Only used in the Write method. + desc *Desc + + // Only used in the Write method and for sparse bucket management. + mtx sync.Mutex // Two counts, one is "hot" for lock-free observations, the other is // "cold" for writing out a dto.Metric. It has to be an array of @@ -293,9 +686,15 @@ type histogram struct { // http://golang.org/pkg/sync/atomic/#pkg-note-BUG. counts [2]*histogramCounts - upperBounds []float64 - labelPairs []*dto.LabelPair - exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar. + upperBounds []float64 + labelPairs []*dto.LabelPair + exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar. + nativeHistogramSchema int32 // The initial schema. Set to math.MinInt32 if no sparse buckets are used. + nativeHistogramZeroThreshold float64 // The initial zero threshold. + nativeHistogramMaxZeroThreshold float64 + nativeHistogramMaxBuckets uint32 + nativeHistogramMinResetDuration time.Duration + lastResetTime time.Time // Protected by mtx. now func() time.Time // To mock out time.Now() for testing. } @@ -319,8 +718,8 @@ func (h *histogram) Write(out *dto.Metric) error { // the hot path, i.e. Observe is called much more often than Write. The // complication of making Write lock-free isn't worth it, if possible at // all. - h.writeMtx.Lock() - defer h.writeMtx.Unlock() + h.mtx.Lock() + defer h.mtx.Unlock() // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0) // without touching the count bits. See the struct comments for a full @@ -333,16 +732,16 @@ func (h *histogram) Write(out *dto.Metric) error { hotCounts := h.counts[n>>63] coldCounts := h.counts[(^n)>>63] - // Await cooldown. - for count != atomic.LoadUint64(&coldCounts.count) { - runtime.Gosched() // Let observations get work done. - } + waitForCooldown(count, coldCounts) his := &dto.Histogram{ Bucket: make([]*dto.Bucket, len(h.upperBounds)), SampleCount: proto.Uint64(count), SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))), } + out.Histogram = his + out.Label = h.labelPairs + var cumCount uint64 for i, upperBound := range h.upperBounds { cumCount += atomic.LoadUint64(&coldCounts.buckets[i]) @@ -363,25 +762,21 @@ func (h *histogram) Write(out *dto.Metric) error { } his.Bucket = append(his.Bucket, b) } - - out.Histogram = his - out.Label = h.labelPairs - - // Finally add all the cold counts to the new hot counts and reset the cold counts. - atomic.AddUint64(&hotCounts.count, count) - atomic.StoreUint64(&coldCounts.count, 0) - for { - oldBits := atomic.LoadUint64(&hotCounts.sumBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + his.GetSampleSum()) - if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { - atomic.StoreUint64(&coldCounts.sumBits, 0) - break - } - } - for i := range h.upperBounds { - atomic.AddUint64(&hotCounts.buckets[i], atomic.LoadUint64(&coldCounts.buckets[i])) - atomic.StoreUint64(&coldCounts.buckets[i], 0) + if h.nativeHistogramSchema > math.MinInt32 { + his.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.nativeHistogramZeroThresholdBits))) + his.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.nativeHistogramSchema)) + zeroBucket := atomic.LoadUint64(&coldCounts.nativeHistogramZeroBucket) + + defer func() { + coldCounts.nativeHistogramBucketsPositive.Range(addAndReset(&hotCounts.nativeHistogramBucketsPositive, &hotCounts.nativeHistogramBucketsNumber)) + coldCounts.nativeHistogramBucketsNegative.Range(addAndReset(&hotCounts.nativeHistogramBucketsNegative, &hotCounts.nativeHistogramBucketsNumber)) + }() + + his.ZeroCount = proto.Uint64(zeroBucket) + his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative) + his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive) } + addAndResetCounts(hotCounts, coldCounts) return nil } @@ -402,25 +797,216 @@ func (h *histogram) findBucket(v float64) int { // observe is the implementation for Observe without the findBucket part. func (h *histogram) observe(v float64, bucket int) { + // Do not add to sparse buckets for NaN observations. + doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) // We increment h.countAndHotIdx so that the counter in the lower // 63 bits gets incremented. At the same time, we get the new value // back, which we can use to find the currently-hot counts. n := atomic.AddUint64(&h.countAndHotIdx, 1) hotCounts := h.counts[n>>63] + hotCounts.observe(v, bucket, doSparse) + if doSparse { + h.limitBuckets(hotCounts, v, bucket) + } +} - if bucket < len(h.upperBounds) { - atomic.AddUint64(&hotCounts.buckets[bucket], 1) +// limitSparsebuckets applies a strategy to limit the number of populated sparse +// buckets. It's generally best effort, and there are situations where the +// number can go higher (if even the lowest resolution isn't enough to reduce +// the number sufficiently, or if the provided counts aren't fully updated yet +// by a concurrently happening Write call). +func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket int) { + if h.nativeHistogramMaxBuckets == 0 { + return // No limit configured. } - for { - oldBits := atomic.LoadUint64(&hotCounts.sumBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + v) - if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { - break + if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&counts.nativeHistogramBucketsNumber) { + return // Bucket limit not exceeded yet. + } + + h.mtx.Lock() + defer h.mtx.Unlock() + + // The hot counts might have been swapped just before we acquired the + // lock. Re-fetch the hot counts first... + n := atomic.LoadUint64(&h.countAndHotIdx) + hotIdx := n >> 63 + coldIdx := (^n) >> 63 + hotCounts := h.counts[hotIdx] + coldCounts := h.counts[coldIdx] + // ...and then check again if we really have to reduce the bucket count. + if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&hotCounts.nativeHistogramBucketsNumber) { + return // Bucket limit not exceeded after all. + } + // Try the various strategies in order. + if h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) { + return + } + if h.maybeWidenZeroBucket(hotCounts, coldCounts) { + return + } + h.doubleBucketWidth(hotCounts, coldCounts) +} + +// maybeReset resests the whole histogram if at least h.nativeHistogramMinResetDuration +// has been passed. It returns true if the histogram has been reset. The caller +// must have locked h.mtx. +func (h *histogram) maybeReset(hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int) bool { + // We are using the possibly mocked h.now() rather than + // time.Since(h.lastResetTime) to enable testing. + if h.nativeHistogramMinResetDuration == 0 || h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration { + return false + } + // Completely reset coldCounts. + h.resetCounts(cold) + // Repeat the latest observation to not lose it completely. + cold.observe(value, bucket, true) + // Make coldCounts the new hot counts while ressetting countAndHotIdx. + n := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1) + count := n & ((1 << 63) - 1) + waitForCooldown(count, hot) + // Finally, reset the formerly hot counts, too. + h.resetCounts(hot) + h.lastResetTime = h.now() + return true +} + +// maybeWidenZeroBucket widens the zero bucket until it includes the existing +// buckets closest to the zero bucket (which could be two, if an equidistant +// negative and a positive bucket exists, but usually it's only one bucket to be +// merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold +// limits how far the zero bucket can be extended, and if that's not enough to +// include an existing bucket, the method returns false. The caller must have +// locked h.mtx. +func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool { + currentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits)) + if currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold { + return false + } + // Find the key of the bucket closest to zero. + smallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive) + smallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative) + if smallestNegativeKey < smallestKey { + smallestKey = smallestNegativeKey + } + if smallestKey == math.MaxInt32 { + return false + } + newZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema)) + if newZeroThreshold > h.nativeHistogramMaxZeroThreshold { + return false // New threshold would exceed the max threshold. + } + atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) + // Remove applicable buckets. + if _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded { + atomicDecUint32(&cold.nativeHistogramBucketsNumber) + } + if _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded { + atomicDecUint32(&cold.nativeHistogramBucketsNumber) + } + // Make cold counts the new hot counts. + n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) + count := n & ((1 << 63) - 1) + // Swap the pointer names to represent the new roles and make + // the rest less confusing. + hot, cold = cold, hot + waitForCooldown(count, cold) + // Add all the now cold counts to the new hot counts... + addAndResetCounts(hot, cold) + // ...adjust the new zero threshold in the cold counts, too... + atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) + // ...and then merge the newly deleted buckets into the wider zero + // bucket. + mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool { + return func(k, v interface{}) bool { + key := k.(int) + bucket := v.(*int64) + if key == smallestKey { + // Merge into hot zero bucket... + atomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket))) + // ...and delete from cold counts. + coldBuckets.Delete(key) + atomicDecUint32(&cold.nativeHistogramBucketsNumber) + } else { + // Add to corresponding hot bucket... + if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { + atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) + } + // ...and reset cold bucket. + atomic.StoreInt64(bucket, 0) + } + return true } } - // Increment count last as we take it as a signal that the observation - // is complete. - atomic.AddUint64(&hotCounts.count, 1) + + cold.nativeHistogramBucketsPositive.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsPositive, &cold.nativeHistogramBucketsPositive)) + cold.nativeHistogramBucketsNegative.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsNegative, &cold.nativeHistogramBucketsNegative)) + return true +} + +// doubleBucketWidth doubles the bucket width (by decrementing the schema +// number). Note that very sparse buckets could lead to a low reduction of the +// bucket count (or even no reduction at all). The method does nothing if the +// schema is already -4. +func (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) { + coldSchema := atomic.LoadInt32(&cold.nativeHistogramSchema) + if coldSchema == -4 { + return // Already at lowest resolution. + } + coldSchema-- + atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) + // Play it simple and just delete all cold buckets. + atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) + deleteSyncMap(&cold.nativeHistogramBucketsNegative) + deleteSyncMap(&cold.nativeHistogramBucketsPositive) + // Make coldCounts the new hot counts. + n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) + count := n & ((1 << 63) - 1) + // Swap the pointer names to represent the new roles and make + // the rest less confusing. + hot, cold = cold, hot + waitForCooldown(count, cold) + // Add all the now cold counts to the new hot counts... + addAndResetCounts(hot, cold) + // ...adjust the schema in the cold counts, too... + atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) + // ...and then merge the cold buckets into the wider hot buckets. + merge := func(hotBuckets *sync.Map) func(k, v interface{}) bool { + return func(k, v interface{}) bool { + key := k.(int) + bucket := v.(*int64) + // Adjust key to match the bucket to merge into. + if key > 0 { + key++ + } + key /= 2 + // Add to corresponding hot bucket. + if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { + atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) + } + return true + } + } + + cold.nativeHistogramBucketsPositive.Range(merge(&hot.nativeHistogramBucketsPositive)) + cold.nativeHistogramBucketsNegative.Range(merge(&hot.nativeHistogramBucketsNegative)) + // Play it simple again and just delete all cold buckets. + atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) + deleteSyncMap(&cold.nativeHistogramBucketsNegative) + deleteSyncMap(&cold.nativeHistogramBucketsPositive) +} + +func (h *histogram) resetCounts(counts *histogramCounts) { + atomic.StoreUint64(&counts.sumBits, 0) + atomic.StoreUint64(&counts.count, 0) + atomic.StoreUint64(&counts.nativeHistogramZeroBucket, 0) + atomic.StoreUint64(&counts.nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) + atomic.StoreInt32(&counts.nativeHistogramSchema, h.nativeHistogramSchema) + atomic.StoreUint32(&counts.nativeHistogramBucketsNumber, 0) + for i := range h.upperBounds { + atomic.StoreUint64(&counts.buckets[i], 0) + } + deleteSyncMap(&counts.nativeHistogramBucketsNegative) + deleteSyncMap(&counts.nativeHistogramBucketsPositive) } // updateExemplar replaces the exemplar for the provided bucket. With empty @@ -516,7 +1102,8 @@ func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like -// myVec.WithLabelValues("404", "GET").Observe(42.21) +// +// myVec.WithLabelValues("404", "GET").Observe(42.21) func (v *HistogramVec) WithLabelValues(lvs ...string) Observer { h, err := v.GetMetricWithLabelValues(lvs...) if err != nil { @@ -527,7 +1114,8 @@ func (v *HistogramVec) WithLabelValues(lvs ...string) Observer { // With works as GetMetricWith but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) +// +// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) func (v *HistogramVec) With(labels Labels) Observer { h, err := v.GetMetricWith(labels) if err != nil { @@ -581,11 +1169,11 @@ func (h *constHistogram) Desc() *Desc { func (h *constHistogram) Write(out *dto.Metric) error { his := &dto.Histogram{} + buckets := make([]*dto.Bucket, 0, len(h.buckets)) his.SampleCount = proto.Uint64(h.count) his.SampleSum = proto.Float64(h.sum) - for upperBound, count := range h.buckets { buckets = append(buckets, &dto.Bucket{ CumulativeCount: proto.Uint64(count), @@ -613,7 +1201,7 @@ func (h *constHistogram) Write(out *dto.Metric) error { // to send it to Prometheus in the Collect method. // // buckets is a map of upper bounds to cumulative counts, excluding the +Inf -// bucket. +// bucket. The +Inf bucket is implicit, and its value is equal to the provided count. // // NewConstHistogram returns an error if the length of labelValues is not // consistent with the variable labels in Desc or if Desc is invalid. @@ -668,3 +1256,229 @@ func (s buckSort) Swap(i, j int) { func (s buckSort) Less(i, j int) bool { return s[i].GetUpperBound() < s[j].GetUpperBound() } + +// pickSchema returns the largest number n between -4 and 8 such that +// 2^(2^-n) is less or equal the provided bucketFactor. +// +// Special cases: +// - bucketFactor <= 1: panics. +// - bucketFactor < 2^(2^-8) (but > 1): still returns 8. +func pickSchema(bucketFactor float64) int32 { + if bucketFactor <= 1 { + panic(fmt.Errorf("bucketFactor %f is <=1", bucketFactor)) + } + floor := math.Floor(math.Log2(math.Log2(bucketFactor))) + switch { + case floor <= -8: + return 8 + case floor >= 4: + return -4 + default: + return -int32(floor) + } +} + +func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) { + var ii []int + buckets.Range(func(k, v interface{}) bool { + ii = append(ii, k.(int)) + return true + }) + sort.Ints(ii) + + if len(ii) == 0 { + return nil, nil + } + + var ( + spans []*dto.BucketSpan + deltas []int64 + prevCount int64 + nextI int + ) + + appendDelta := func(count int64) { + *spans[len(spans)-1].Length++ + deltas = append(deltas, count-prevCount) + prevCount = count + } + + for n, i := range ii { + v, _ := buckets.Load(i) + count := atomic.LoadInt64(v.(*int64)) + // Multiple spans with only small gaps in between are probably + // encoded more efficiently as one larger span with a few empty + // buckets. Needs some research to find the sweet spot. For now, + // we assume that gaps of one ore two buckets should not create + // a new span. + iDelta := int32(i - nextI) + if n == 0 || iDelta > 2 { + // We have to create a new span, either because we are + // at the very beginning, or because we have found a gap + // of more than two buckets. + spans = append(spans, &dto.BucketSpan{ + Offset: proto.Int32(iDelta), + Length: proto.Uint32(0), + }) + } else { + // We have found a small gap (or no gap at all). + // Insert empty buckets as needed. + for j := int32(0); j < iDelta; j++ { + appendDelta(0) + } + } + appendDelta(count) + nextI = i + 1 + } + return spans, deltas +} + +// addToBucket increments the sparse bucket at key by the provided amount. It +// returns true if a new sparse bucket had to be created for that. +func addToBucket(buckets *sync.Map, key int, increment int64) bool { + if existingBucket, ok := buckets.Load(key); ok { + // Fast path without allocation. + atomic.AddInt64(existingBucket.(*int64), increment) + return false + } + // Bucket doesn't exist yet. Slow path allocating new counter. + newBucket := increment // TODO(beorn7): Check if this is sufficient to not let increment escape. + if actualBucket, loaded := buckets.LoadOrStore(key, &newBucket); loaded { + // The bucket was created concurrently in another goroutine. + // Have to increment after all. + atomic.AddInt64(actualBucket.(*int64), increment) + return false + } + return true +} + +// addAndReset returns a function to be used with sync.Map.Range of spare +// buckets in coldCounts. It increments the buckets in the provided hotBuckets +// according to the buckets ranged through. It then resets all buckets ranged +// through to 0 (but leaves them in place so that they don't need to get +// recreated on the next scrape). +func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool { + return func(k, v interface{}) bool { + bucket := v.(*int64) + if addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) { + atomic.AddUint32(bucketNumber, 1) + } + atomic.StoreInt64(bucket, 0) + return true + } +} + +func deleteSyncMap(m *sync.Map) { + m.Range(func(k, v interface{}) bool { + m.Delete(k) + return true + }) +} + +func findSmallestKey(m *sync.Map) int { + result := math.MaxInt32 + m.Range(func(k, v interface{}) bool { + key := k.(int) + if key < result { + result = key + } + return true + }) + return result +} + +func getLe(key int, schema int32) float64 { + // Here a bit of context about the behavior for the last bucket counting + // regular numbers (called simply "last bucket" below) and the bucket + // counting observations of ±Inf (called "inf bucket" below, with a key + // one higher than that of the "last bucket"): + // + // If we apply the usual formula to the last bucket, its upper bound + // would be calculated as +Inf. The reason is that the max possible + // regular float64 number (math.MaxFloat64) doesn't coincide with one of + // the calculated bucket boundaries. So the calculated boundary has to + // be larger than math.MaxFloat64, and the only float64 larger than + // math.MaxFloat64 is +Inf. However, we want to count actual + // observations of ±Inf in the inf bucket. Therefore, we have to treat + // the upper bound of the last bucket specially and set it to + // math.MaxFloat64. (The upper bound of the inf bucket, with its key + // being one higher than that of the last bucket, naturally comes out as + // +Inf by the usual formula. So that's fine.) + // + // math.MaxFloat64 has a frac of 0.9999999999999999 and an exp of + // 1024. If there were a float64 number following math.MaxFloat64, it + // would have a frac of 1.0 and an exp of 1024, or equivalently a frac + // of 0.5 and an exp of 1025. However, since frac must be smaller than + // 1, and exp must be smaller than 1025, either representation overflows + // a float64. (Which, in turn, is the reason that math.MaxFloat64 is the + // largest possible float64. Q.E.D.) However, the formula for + // calculating the upper bound from the idx and schema of the last + // bucket results in precisely that. It is either frac=1.0 & exp=1024 + // (for schema < 0) or frac=0.5 & exp=1025 (for schema >=0). (This is, + // by the way, a power of two where the exponent itself is a power of + // two, 2¹⁰ in fact, which coinicides with a bucket boundary in all + // schemas.) So these are the special cases we have to catch below. + if schema < 0 { + exp := key << -schema + if exp == 1024 { + // This is the last bucket before the overflow bucket + // (for ±Inf observations). Return math.MaxFloat64 as + // explained above. + return math.MaxFloat64 + } + return math.Ldexp(1, exp) + } + + fracIdx := key & ((1 << schema) - 1) + frac := nativeHistogramBounds[schema][fracIdx] + exp := (key >> schema) + 1 + if frac == 0.5 && exp == 1025 { + // This is the last bucket before the overflow bucket (for ±Inf + // observations). Return math.MaxFloat64 as explained above. + return math.MaxFloat64 + } + return math.Ldexp(frac, exp) +} + +// waitForCooldown returns after the count field in the provided histogramCounts +// has reached the provided count value. +func waitForCooldown(count uint64, counts *histogramCounts) { + for count != atomic.LoadUint64(&counts.count) { + runtime.Gosched() // Let observations get work done. + } +} + +// atomicAddFloat adds the provided float atomically to another float +// represented by the bit pattern the bits pointer is pointing to. +func atomicAddFloat(bits *uint64, v float64) { + for { + loadedBits := atomic.LoadUint64(bits) + newBits := math.Float64bits(math.Float64frombits(loadedBits) + v) + if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) { + break + } + } +} + +// atomicDecUint32 atomically decrements the uint32 p points to. See +// https://pkg.go.dev/sync/atomic#AddUint32 to understand how this is done. +func atomicDecUint32(p *uint32) { + atomic.AddUint32(p, ^uint32(0)) +} + +// addAndResetCounts adds certain fields (count, sum, conventional buckets, zero +// bucket) from the cold counts to the corresponding fields in the hot +// counts. Those fields are then reset to 0 in the cold counts. +func addAndResetCounts(hot, cold *histogramCounts) { + atomic.AddUint64(&hot.count, atomic.LoadUint64(&cold.count)) + atomic.StoreUint64(&cold.count, 0) + coldSum := math.Float64frombits(atomic.LoadUint64(&cold.sumBits)) + atomicAddFloat(&hot.sumBits, coldSum) + atomic.StoreUint64(&cold.sumBits, 0) + for i := range hot.buckets { + atomic.AddUint64(&hot.buckets[i], atomic.LoadUint64(&cold.buckets[i])) + atomic.StoreUint64(&cold.buckets[i], 0) + } + atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket)) + atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go new file mode 100644 index 0000000000..1ed5abe74c --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go @@ -0,0 +1,60 @@ +// Copyright (c) 2015 Björn Rabenstein +// +// 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. +// +// The code in this package is copy/paste to avoid a dependency. Hence this file +// carries the copyright of the original repo. +// https://github.com/beorn7/floats +package internal + +import ( + "math" +) + +// minNormalFloat64 is the smallest positive normal value of type float64. +var minNormalFloat64 = math.Float64frombits(0x0010000000000000) + +// AlmostEqualFloat64 returns true if a and b are equal within a relative error +// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the +// details of the applied method. +func AlmostEqualFloat64(a, b, epsilon float64) bool { + if a == b { + return true + } + absA := math.Abs(a) + absB := math.Abs(b) + diff := math.Abs(a - b) + if a == 0 || b == 0 || absA+absB < minNormalFloat64 { + return diff < epsilon*minNormalFloat64 + } + return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon +} + +// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64. +func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if !AlmostEqualFloat64(a[i], b[i], epsilon) { + return false + } + } + return true +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go new file mode 100644 index 0000000000..fd0750f2cf --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go @@ -0,0 +1,654 @@ +// Copyright 2022 The Prometheus 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. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// Maintaining `GetUnifiedDiffString` here because original repository +// (https://github.com/pmezard/go-difflib) is no loger maintained. +package internal + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool, +) *SequenceMatcher { + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// +// and for all (i',j',k') meeting those conditions, +// +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize++ + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize++ + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{ + c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n), + }) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s]++ + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches++ + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning-- // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return w.String(), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go new file mode 100644 index 0000000000..723b45d644 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go @@ -0,0 +1,32 @@ +// Copyright 2021 The Prometheus 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 internal + +import "regexp" + +type GoCollectorRule struct { + Matcher *regexp.Regexp + Deny bool +} + +// GoCollectorOptions should not be used be directly by anything, except `collectors` package. +// Use it via collectors package instead. See issue +// https://github.com/prometheus/client_golang/issues/1030. +// +// This is internal, so external users only can use it via `collector.WithGoCollector*` methods +type GoCollectorOptions struct { + DisableMemStatsLikeMetrics bool + RuntimeMetricSumForHist map[string]string + RuntimeMetricRules []GoCollectorRule +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go index 6cbe063a25..97d17d6cb6 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go @@ -61,9 +61,9 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) // name has - replaced with _ and is concatenated with the unit and // other data. name = strings.ReplaceAll(name, "-", "_") - name = name + "_" + unit + name += "_" + unit if d.Cumulative && d.Kind != metrics.KindFloat64Histogram { - name = name + "_total" + name += "_total" } valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name)) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go index 351c26e1ae..6515c11480 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go @@ -19,18 +19,34 @@ import ( dto "github.com/prometheus/client_model/go" ) -// metricSorter is a sortable slice of *dto.Metric. -type metricSorter []*dto.Metric +// LabelPairSorter implements sort.Interface. It is used to sort a slice of +// dto.LabelPair pointers. +type LabelPairSorter []*dto.LabelPair -func (s metricSorter) Len() int { +func (s LabelPairSorter) Len() int { return len(s) } -func (s metricSorter) Swap(i, j int) { +func (s LabelPairSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s metricSorter) Less(i, j int) bool { +func (s LabelPairSorter) Less(i, j int) bool { + return s[i].GetName() < s[j].GetName() +} + +// MetricSorter is a sortable slice of *dto.Metric. +type MetricSorter []*dto.Metric + +func (s MetricSorter) Len() int { + return len(s) +} + +func (s MetricSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s MetricSorter) Less(i, j int) bool { if len(s[i].Label) != len(s[j].Label) { // This should not happen. The metrics are // inconsistent. However, we have to deal with the fact, as @@ -68,7 +84,7 @@ func (s metricSorter) Less(i, j int) bool { // the slice, with the contained Metrics sorted within each MetricFamily. func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { for _, mf := range metricFamiliesByName { - sort.Sort(metricSorter(mf.Metric)) + sort.Sort(MetricSorter(mf.Metric)) } names := make([]string, 0, len(metricFamiliesByName)) for name, mf := range metricFamiliesByName { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go index 2744443ac2..c1b8fad36a 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go @@ -25,7 +25,8 @@ import ( // Labels represents a collection of label name -> value mappings. This type is // commonly used with the With(Labels) and GetMetricWith(Labels) methods of // metric vector Collectors, e.g.: -// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) +// +// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) // // The other use-case is the specification of constant label pairs in Opts or to // create a Desc. @@ -39,7 +40,7 @@ var errInconsistentCardinality = errors.New("inconsistent label cardinality") func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error { return fmt.Errorf( - "%s: %q has %d variable labels named %q but %d values %q were provided", + "%w: %q has %d variable labels named %q but %d values %q were provided", errInconsistentCardinality, fqName, len(labels), labels, len(labelValues), labelValues, @@ -49,7 +50,7 @@ func makeInconsistentCardinalityError(fqName string, labels, labelValues []strin func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { if len(labels) != expectedNumberOfValues { return fmt.Errorf( - "%s: expected %d label values but got %d in %#v", + "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(labels), labels, ) @@ -67,7 +68,7 @@ func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { func validateLabelValues(vals []string, expectedNumberOfValues int) error { if len(vals) != expectedNumberOfValues { return fmt.Errorf( - "%s: expected %d label values but got %d in %#v", + "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(vals), vals, ) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go index dc121910a5..b5119c5041 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -14,6 +14,9 @@ package prometheus import ( + "errors" + "math" + "sort" "strings" "time" @@ -115,22 +118,6 @@ func BuildFQName(namespace, subsystem, name string) string { return name } -// labelPairSorter implements sort.Interface. It is used to sort a slice of -// dto.LabelPair pointers. -type labelPairSorter []*dto.LabelPair - -func (s labelPairSorter) Len() int { - return len(s) -} - -func (s labelPairSorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s labelPairSorter) Less(i, j int) bool { - return s[i].GetName() < s[j].GetName() -} - type invalidMetric struct { desc *Desc err error @@ -174,3 +161,96 @@ func (m timestampedMetric) Write(pb *dto.Metric) error { func NewMetricWithTimestamp(t time.Time, m Metric) Metric { return timestampedMetric{Metric: m, t: t} } + +type withExemplarsMetric struct { + Metric + + exemplars []*dto.Exemplar +} + +func (m *withExemplarsMetric) Write(pb *dto.Metric) error { + if err := m.Metric.Write(pb); err != nil { + return err + } + + switch { + case pb.Counter != nil: + pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1] + case pb.Histogram != nil: + for _, e := range m.exemplars { + // pb.Histogram.Bucket are sorted by UpperBound. + i := sort.Search(len(pb.Histogram.Bucket), func(i int) bool { + return pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue() + }) + if i < len(pb.Histogram.Bucket) { + pb.Histogram.Bucket[i].Exemplar = e + } else { + // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365. + b := &dto.Bucket{ + CumulativeCount: proto.Uint64(pb.Histogram.GetSampleCount()), + UpperBound: proto.Float64(math.Inf(1)), + Exemplar: e, + } + pb.Histogram.Bucket = append(pb.Histogram.Bucket, b) + } + } + default: + // TODO(bwplotka): Implement Gauge? + return errors.New("cannot inject exemplar into Gauge, Summary or Untyped") + } + + return nil +} + +// Exemplar is easier to use, user-facing representation of *dto.Exemplar. +type Exemplar struct { + Value float64 + Labels Labels + // Optional. + // Default value (time.Time{}) indicates its empty, which should be + // understood as time.Now() time at the moment of creation of metric. + Timestamp time.Time +} + +// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given +// exemplars. Exemplars are validated. +// +// Only last applicable exemplar is injected from the list. +// For example for Counter it means last exemplar is injected. +// For Histogram, it means last applicable exemplar for each bucket is injected. +// +// NewMetricWithExemplars works best with MustNewConstMetric and +// MustNewConstHistogram, see example. +func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) { + if len(exemplars) == 0 { + return nil, errors.New("no exemplar was passed for NewMetricWithExemplars") + } + + var ( + now = time.Now() + exs = make([]*dto.Exemplar, len(exemplars)) + err error + ) + for i, e := range exemplars { + ts := e.Timestamp + if ts == (time.Time{}) { + ts = now + } + exs[i], err = newExemplar(e.Value, ts, e.Labels) + if err != nil { + return nil, err + } + } + + return &withExemplarsMetric{Metric: m, exemplars: exs}, nil +} + +// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where +// NewMetricWithExemplars would have returned an error. +func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric { + ret, err := NewMetricWithExemplars(m, exemplars...) + if err != nil { + panic(err) + } + return ret +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go new file mode 100644 index 0000000000..7c12b21087 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go @@ -0,0 +1,25 @@ +// Copyright 2018 The Prometheus 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. + +//go:build !js || wasm +// +build !js wasm + +package prometheus + +import "runtime" + +// getRuntimeNumThreads returns the number of open OS threads. +func getRuntimeNumThreads() float64 { + n, _ := runtime.ThreadCreateProfile(nil) + return float64(n) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go new file mode 100644 index 0000000000..7348df01df --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go @@ -0,0 +1,22 @@ +// Copyright 2018 The Prometheus 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. + +//go:build js && !wasm +// +build js,!wasm + +package prometheus + +// getRuntimeNumThreads returns the number of open OS threads. +func getRuntimeNumThreads() float64 { + return 1 +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go index 44128016fd..03773b21f7 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/observer.go @@ -58,7 +58,7 @@ type ObserverVec interface { // current time as timestamp, and the provided Labels. Empty Labels will lead to // a valid (label-less) exemplar. But if Labels is nil, the current exemplar is // left in place. ObserveWithExemplar panics if any of the provided labels are -// invalid or if the provided labels contain more than 64 runes in total. +// invalid or if the provided labels contain more than 128 runes in total. type ExemplarObserver interface { ObserveWithExemplar(value float64, exemplar Labels) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go index 5bfe0ff5bb..8548dd18ed 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go @@ -16,7 +16,6 @@ package prometheus import ( "errors" "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -104,8 +103,7 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector { } if opts.PidFn == nil { - pid := os.Getpid() - c.pidFn = func() (int, error) { return pid, nil } + c.pidFn = getPIDFn() } else { c.pidFn = opts.PidFn } @@ -152,13 +150,13 @@ func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) // It is meant to be used for the PidFn field in ProcessCollectorOpts. func NewPidFileFn(pidFilePath string) func() (int, error) { return func() (int, error) { - content, err := ioutil.ReadFile(pidFilePath) + content, err := os.ReadFile(pidFilePath) if err != nil { - return 0, fmt.Errorf("can't read pid file %q: %+v", pidFilePath, err) + return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err) } pid, err := strconv.Atoi(strings.TrimSpace(string(content))) if err != nil { - return 0, fmt.Errorf("can't parse pid file %q: %+v", pidFilePath, err) + return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err) } return pid, nil diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go new file mode 100644 index 0000000000..b1e363d6cf --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Prometheus 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. + +//go:build js +// +build js + +package prometheus + +func canCollectProcess() bool { + return false +} + +func (c *processCollector) processCollect(ch chan<- Metric) { + // noop on this platform + return +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go index 2dc3660da0..c0152cdb61 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !windows -// +build !windows +//go:build !windows && !js +// +build !windows,!js package prometheus diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go index e7c0d05464..9819917b83 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go @@ -76,16 +76,19 @@ func (r *responseWriterDelegator) Write(b []byte) (int, error) { return n, err } -type closeNotifierDelegator struct{ *responseWriterDelegator } -type flusherDelegator struct{ *responseWriterDelegator } -type hijackerDelegator struct{ *responseWriterDelegator } -type readerFromDelegator struct{ *responseWriterDelegator } -type pusherDelegator struct{ *responseWriterDelegator } +type ( + closeNotifierDelegator struct{ *responseWriterDelegator } + flusherDelegator struct{ *responseWriterDelegator } + hijackerDelegator struct{ *responseWriterDelegator } + readerFromDelegator struct{ *responseWriterDelegator } + pusherDelegator struct{ *responseWriterDelegator } +) func (d closeNotifierDelegator) CloseNotify() <-chan bool { //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. return d.ResponseWriter.(http.CloseNotifier).CloseNotify() } + func (d flusherDelegator) Flush() { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. @@ -94,9 +97,11 @@ func (d flusherDelegator) Flush() { } d.ResponseWriter.(http.Flusher).Flush() } + func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) { return d.ResponseWriter.(http.Hijacker).Hijack() } + func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. @@ -107,6 +112,7 @@ func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) { d.written += n return n, err } + func (d pusherDelegator) Push(target string, opts *http.PushOptions) error { return d.ResponseWriter.(http.Pusher).Push(target, opts) } @@ -261,7 +267,7 @@ func init() { http.Flusher }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } - pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23 + pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23 return struct { *responseWriterDelegator http.Pusher diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index d86d0cf4b0..a4cc9810b0 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -33,6 +33,7 @@ package promhttp import ( "compress/gzip" + "errors" "fmt" "io" "net/http" @@ -84,6 +85,13 @@ func Handler() http.Handler { // instrumentation. Use the InstrumentMetricHandler function to apply the same // kind of instrumentation as it is used by the Handler function. func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { + return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts) +} + +// HandlerForTransactional is like HandlerFor, but it uses transactional gather, which +// can safely change in-place returned *dto.MetricFamily before call to `Gather` and after +// call to `done` of that `Gather`. +func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler { var ( inFlightSem chan struct{} errCnt = prometheus.NewCounterVec( @@ -103,7 +111,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { errCnt.WithLabelValues("gathering") errCnt.WithLabelValues("encoding") if err := opts.Registry.Register(errCnt); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { errCnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) @@ -123,7 +132,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { return } } - mfs, err := reg.Gather() + mfs, done, err := reg.Gather() + defer done() if err != nil { if opts.ErrorLog != nil { opts.ErrorLog.Println("error gathering metrics:", err) @@ -242,7 +252,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht cnt.WithLabelValues("500") cnt.WithLabelValues("503") if err := reg.Register(cnt); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { cnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) @@ -254,7 +265,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht Help: "Current number of scrapes being served.", }) if err := reg.Register(gge); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { gge = are.ExistingCollector.(prometheus.Gauge) } else { panic(err) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go index 861b4d21ca..2108678162 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go @@ -38,11 +38,11 @@ func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc { - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { gauge.Inc() defer gauge.Dec() return next.RoundTrip(r) - }) + } } // InstrumentRoundTripperCounter is a middleware that wraps the provided @@ -59,22 +59,28 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp // If the wrapped RoundTripper panics or returns a non-nil error, the Counter // is not incremented. // +// Use with WithExemplarFromContext to instrument the exemplars on the counter of requests. +// // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { - rtOpts := &option{} + rtOpts := defaultOptions() for _, o := range opts { - o(rtOpts) + o.apply(rtOpts) } code, method := checkLabels(counter) - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { resp, err := next.RoundTrip(r) if err == nil { - counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc() + addWithExemplar( + counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), + 1, + rtOpts.getExemplarFn(r.Context()), + ) } return resp, err - }) + } } // InstrumentRoundTripperDuration is a middleware that wraps the provided @@ -94,24 +100,30 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou // If the wrapped RoundTripper panics or returns a non-nil error, no values are // reported. // +// Use with WithExemplarFromContext to instrument the exemplars on the duration histograms. +// // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { - rtOpts := &option{} + rtOpts := defaultOptions() for _, o := range opts { - o(rtOpts) + o.apply(rtOpts) } code, method := checkLabels(obs) - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { start := time.Now() resp, err := next.RoundTrip(r) if err == nil { - obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds()) + observeWithExemplar( + obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), + time.Since(start).Seconds(), + rtOpts.getExemplarFn(r.Context()), + ) } return resp, err - }) + } } // InstrumentTrace is used to offer flexibility in instrumenting the available @@ -149,7 +161,7 @@ type InstrumentTrace struct { // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc { - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { start := time.Now() trace := &httptrace.ClientTrace{ @@ -231,5 +243,5 @@ func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) Ro r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace)) return next.RoundTrip(r) - }) + } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go index a23f0edc6f..cca67a78a9 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go @@ -28,6 +28,26 @@ import ( // magicString is used for the hacky label test in checkLabels. Remove once fixed. const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" +// observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver], +// which falls back to [prometheus.Observer.Observe] if no labels are provided. +func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) { + if labels == nil { + obs.Observe(val) + return + } + obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) +} + +// addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar], +// which falls back to [prometheus.Counter.Add] if no labels are provided. +func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) { + if labels == nil { + obs.Add(val) + return + } + obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels) +} + // InstrumentHandlerInFlight is a middleware that wraps the provided // http.Handler. It sets the provided prometheus.Gauge to the number of // requests currently handled by the wrapped http.Handler. @@ -48,7 +68,7 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl // names are "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. -//`WithExtraMethods` can be used to add more methods to the set. The Observe +// `WithExtraMethods` can be used to add more methods to the set. The Observe // method of the Observer in the ObserverVec is called with the request duration // in seconds. Partitioning happens by HTTP status code and/or HTTP method if // the respective instance label names are present in the ObserverVec. For @@ -62,28 +82,37 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, nil) next.ServeHTTP(d, r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) - }) + observeWithExemplar( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() next.ServeHTTP(w, r) - obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) - }) + + observeWithExemplar( + obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerCounter is a middleware that wraps the provided http.Handler @@ -104,25 +133,34 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(counter) if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc() - }) + + addWithExemplar( + counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + 1, + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) - counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc() - }) + addWithExemplar( + counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + 1, + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided @@ -148,20 +186,24 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, func(status int) { - obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) + observeWithExemplar( + obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) }) next.ServeHTTP(d, r) - }) + } } // InstrumentHandlerRequestSize is a middleware that wraps the provided @@ -184,27 +226,34 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) - if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) size := computeApproximateRequestSize(r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size)) - }) + observeWithExemplar( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + float64(size), + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) size := computeApproximateRequestSize(r) - obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size)) - }) + observeWithExemplar( + obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + float64(size), + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerResponseSize is a middleware that wraps the provided @@ -227,9 +276,9 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) @@ -237,7 +286,11 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written())) + observeWithExemplar( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + float64(d.Written()), + hOpts.getExemplarFn(r.Context()), + ) }) } @@ -246,7 +299,7 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler // Collector does not have a Desc or has more than one Desc or its Desc is // invalid. It also panics if the Collector has any non-const, non-curried // labels that are not named "code" or "method". -func checkLabels(c prometheus.Collector) (code bool, method bool) { +func checkLabels(c prometheus.Collector) (code, method bool) { // TODO(beorn7): Remove this hacky way to check for instance labels // once Descriptors can have their dimensionality queried. var ( diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go index 35e41bd1e6..c590d912c9 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go @@ -13,19 +13,46 @@ package promhttp -// Option are used to configure a middleware or round tripper.. -type Option func(*option) +import ( + "context" -type option struct { - extraMethods []string + "github.com/prometheus/client_golang/prometheus" +) + +// Option are used to configure both handler (middleware) or round tripper. +type Option interface { + apply(*options) +} + +// options store options for both a handler or round tripper. +type options struct { + extraMethods []string + getExemplarFn func(requestCtx context.Context) prometheus.Labels +} + +func defaultOptions() *options { + return &options{getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }} } +type optionApplyFunc func(*options) + +func (o optionApplyFunc) apply(opt *options) { o(opt) } + // WithExtraMethods adds additional HTTP methods to the list of allowed methods. // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list. // // See the example for ExampleInstrumentHandlerWithExtraMethods for example usage. func WithExtraMethods(methods ...string) Option { - return func(o *option) { + return optionApplyFunc(func(o *options) { o.extraMethods = methods - } + }) +} + +// WithExemplarFromContext adds allows to put a hook to all counter and histogram metrics. +// If the hook function returns non-nil labels, exemplars will be added for that request, otherwise metric +// will get instrumented without exemplar. +func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { + return optionApplyFunc(func(o *options) { + o.getExemplarFn = getExemplarFn + }) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index 383a7f5941..09e34d307c 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -15,8 +15,8 @@ package prometheus import ( "bytes" + "errors" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -252,9 +252,12 @@ func (errs MultiError) MaybeUnwrap() error { } // Registry registers Prometheus collectors, collects their metrics, and gathers -// them into MetricFamilies for exposition. It implements both Registerer and -// Gatherer. The zero value is not usable. Create instances with NewRegistry or -// NewPedanticRegistry. +// them into MetricFamilies for exposition. It implements Registerer, Gatherer, +// and Collector. The zero value is not usable. Create instances with +// NewRegistry or NewPedanticRegistry. +// +// Registry implements Collector to allow it to be used for creating groups of +// metrics. See the Grouping example for how this can be done. type Registry struct { mtx sync.RWMutex collectorsByID map[uint64]Collector // ID is a hash of the descIDs. @@ -289,7 +292,7 @@ func (r *Registry) Register(c Collector) error { // Is the descriptor valid at all? if desc.err != nil { - return fmt.Errorf("descriptor %s is invalid: %s", desc, desc.err) + return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err) } // Is the descID unique? @@ -407,6 +410,14 @@ func (r *Registry) MustRegister(cs ...Collector) { // Gather implements Gatherer. func (r *Registry) Gather() ([]*dto.MetricFamily, error) { + r.mtx.RLock() + + if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 { + // Fast path. + r.mtx.RUnlock() + return nil, nil + } + var ( checkedMetricChan = make(chan Metric, capMetricChan) uncheckedMetricChan = make(chan Metric, capMetricChan) @@ -416,7 +427,6 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { registeredDescIDs map[uint64]struct{} // Only used for pedantic checks ) - r.mtx.RLock() goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors) metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName)) checkedCollectors := make(chan Collector, len(r.collectorsByID)) @@ -549,6 +559,31 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() } +// Describe implements Collector. +func (r *Registry) Describe(ch chan<- *Desc) { + r.mtx.RLock() + defer r.mtx.RUnlock() + + // Only report the checked Collectors; unchecked collectors don't report any + // Desc. + for _, c := range r.collectorsByID { + c.Describe(ch) + } +} + +// Collect implements Collector. +func (r *Registry) Collect(ch chan<- Metric) { + r.mtx.RLock() + defer r.mtx.RUnlock() + + for _, c := range r.collectorsByID { + c.Collect(ch) + } + for _, c := range r.uncheckedCollectors { + c.Collect(ch) + } +} + // WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the // Prometheus text format, and writes it to a temporary file. Upon success, the // temporary file is renamed to the provided filename. @@ -556,7 +591,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { // This is intended for use with the textfile collector of the node exporter. // Note that the node exporter expects the filename to be suffixed with ".prom". func WriteToTextfile(filename string, g Gatherer) error { - tmp, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)) + tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) if err != nil { return err } @@ -575,7 +610,7 @@ func WriteToTextfile(filename string, g Gatherer) error { return err } - if err := os.Chmod(tmp.Name(), 0644); err != nil { + if err := os.Chmod(tmp.Name(), 0o644); err != nil { return err } return os.Rename(tmp.Name(), filename) @@ -596,7 +631,7 @@ func processMetric( } dtoMetric := &dto.Metric{} if err := metric.Write(dtoMetric); err != nil { - return fmt.Errorf("error collecting metric %v: %s", desc, err) + return fmt.Errorf("error collecting metric %v: %w", desc, err) } metricFamily, ok := metricFamiliesByName[desc.fqName] if ok { // Existing name. @@ -718,12 +753,13 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { for i, g := range gs { mfs, err := g.Gather() if err != nil { - if multiErr, ok := err.(MultiError); ok { + multiErr := MultiError{} + if errors.As(err, &multiErr) { for _, err := range multiErr { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err)) + errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } else { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err)) + errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } for _, mf := range mfs { @@ -884,11 +920,11 @@ func checkMetricConsistency( h.Write(separatorByteSlice) // Make sure label pairs are sorted. We depend on it for the consistency // check. - if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) { + if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) { // We cannot sort dtoMetric.Label in place as it is immutable by contract. copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label)) copy(copiedLabels, dtoMetric.Label) - sort.Sort(labelPairSorter(copiedLabels)) + sort.Sort(internal.LabelPairSorter(copiedLabels)) dtoMetric.Label = copiedLabels } for _, lp := range dtoMetric.Label { @@ -935,7 +971,7 @@ func checkDescConsistency( metricFamily.GetName(), dtoMetric, desc, ) } - sort.Sort(labelPairSorter(lpsFromDesc)) + sort.Sort(internal.LabelPairSorter(lpsFromDesc)) for i, lpFromDesc := range lpsFromDesc { lpFromMetric := dtoMetric.Label[i] if lpFromDesc.GetName() != lpFromMetric.GetName() || @@ -948,3 +984,89 @@ func checkDescConsistency( } return nil } + +var _ TransactionalGatherer = &MultiTRegistry{} + +// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple +// transactional gatherers. +// +// It is caller responsibility to ensure two registries have mutually exclusive metric families, +// no deduplication will happen. +type MultiTRegistry struct { + tGatherers []TransactionalGatherer +} + +// NewMultiTRegistry creates MultiTRegistry. +func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry { + return &MultiTRegistry{ + tGatherers: tGatherers, + } +} + +// Gather implements TransactionalGatherer interface. +func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) { + errs := MultiError{} + + dFns := make([]func(), 0, len(r.tGatherers)) + // TODO(bwplotka): Implement concurrency for those? + for _, g := range r.tGatherers { + // TODO(bwplotka): Check for duplicates? + m, d, err := g.Gather() + errs.Append(err) + + mfs = append(mfs, m...) + dFns = append(dFns, d) + } + + // TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already. + sort.Slice(mfs, func(i, j int) bool { + return *mfs[i].Name < *mfs[j].Name + }) + return mfs, func() { + for _, d := range dFns { + d() + } + }, errs.MaybeUnwrap() +} + +// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory +// used by metric family is no longer used by a caller. This allows implementations with cache. +type TransactionalGatherer interface { + // Gather returns metrics in a lexicographically sorted slice + // of uniquely named MetricFamily protobufs. Gather ensures that the + // returned slice is valid and self-consistent so that it can be used + // for valid exposition. As an exception to the strict consistency + // requirements described for metric.Desc, Gather will tolerate + // different sets of label names for metrics of the same metric family. + // + // Even if an error occurs, Gather attempts to gather as many metrics as + // possible. Hence, if a non-nil error is returned, the returned + // MetricFamily slice could be nil (in case of a fatal error that + // prevented any meaningful metric collection) or contain a number of + // MetricFamily protobufs, some of which might be incomplete, and some + // might be missing altogether. The returned error (which might be a + // MultiError) explains the details. Note that this is mostly useful for + // debugging purposes. If the gathered protobufs are to be used for + // exposition in actual monitoring, it is almost always better to not + // expose an incomplete result and instead disregard the returned + // MetricFamily protobufs in case the returned error is non-nil. + // + // Important: done is expected to be triggered (even if the error occurs!) + // once caller does not need returned slice of dto.MetricFamily. + Gather() (_ []*dto.MetricFamily, done func(), err error) +} + +// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function. +func ToTransactionalGatherer(g Gatherer) TransactionalGatherer { + return &noTransactionGatherer{g: g} +} + +type noTransactionGatherer struct { + g Gatherer +} + +// Gather implements TransactionalGatherer interface. +func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { + mfs, err := g.g.Gather() + return mfs, func() {}, err +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go index c5fa8ed7c7..7bc448a893 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go @@ -603,7 +603,8 @@ func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like -// myVec.WithLabelValues("404", "GET").Observe(42.21) +// +// myVec.WithLabelValues("404", "GET").Observe(42.21) func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { s, err := v.GetMetricWithLabelValues(lvs...) if err != nil { @@ -614,7 +615,8 @@ func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) +// +// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) func (v *SummaryVec) With(labels Labels) Observer { s, err := v.GetMetricWith(labels) if err != nil { @@ -701,7 +703,8 @@ func (s *constSummary) Write(out *dto.Metric) error { // // quantiles maps ranks to quantile values. For example, a median latency of // 0.23s and a 99th percentile latency of 0.56s would be expressed as: -// map[float64]float64{0.5: 0.23, 0.99: 0.56} +// +// map[float64]float64{0.5: 0.23, 0.99: 0.56} // // NewConstSummary returns an error if the length of labelValues is not // consistent with the variable labels in Desc or if Desc is invalid. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/testutil/lint.go b/vendor/github.com/prometheus/client_golang/prometheus/testutil/lint.go index 7681877a89..8d2f05500b 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/testutil/lint.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/testutil/lint.go @@ -26,7 +26,7 @@ import ( func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.Problem, error) { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { - return nil, fmt.Errorf("registering collector failed: %s", err) + return nil, fmt.Errorf("registering collector failed: %w", err) } return GatherAndLint(reg, metricNames...) } @@ -37,7 +37,7 @@ func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.P func GatherAndLint(g prometheus.Gatherer, metricNames ...string) ([]promlint.Problem, error) { got, err := g.Gather() if err != nil { - return nil, fmt.Errorf("gathering metrics failed: %s", err) + return nil, fmt.Errorf("gathering metrics failed: %w", err) } if metricNames != nil { got = filterMetrics(got, metricNames) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go b/vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go index ec80617062..a20f159b78 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go @@ -15,6 +15,7 @@ package promlint import ( + "errors" "fmt" "io" "regexp" @@ -83,7 +84,7 @@ func (l *Linter) Lint() ([]Problem, error) { mf := &dto.MetricFamily{} for { if err := d.Decode(mf); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } @@ -283,7 +284,7 @@ func lintUnitAbbreviations(mf *dto.MetricFamily) []Problem { // metricUnits attempts to detect known unit types used as part of a metric name, // e.g. "foo_bytes_total" or "bar_baz_milligrams". -func metricUnits(m string) (unit string, base string, ok bool) { +func metricUnits(m string) (unit, base string, ok bool) { ss := strings.Split(m, "_") for unit, base := range units { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/testutil/testutil.go b/vendor/github.com/prometheus/client_golang/prometheus/testutil/testutil.go index 9af60ce1d2..91b83b5285 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/testutil/testutil.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/testutil/testutil.go @@ -41,10 +41,12 @@ import ( "bytes" "fmt" "io" + "net/http" + "reflect" - "github.com/prometheus/common/expfmt" - + "github.com/davecgh/go-spew/spew" dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" @@ -99,7 +101,9 @@ func ToFloat64(c prometheus.Collector) float64 { } pb := &dto.Metric{} - m.Write(pb) + if err := m.Write(pb); err != nil { + panic(fmt.Errorf("error happened while collecting metrics: %w", err)) + } if pb.Gauge != nil { return pb.Gauge.GetValue() } @@ -122,7 +126,7 @@ func ToFloat64(c prometheus.Collector) float64 { func CollectAndCount(c prometheus.Collector, metricNames ...string) int { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { - panic(fmt.Errorf("registering collector failed: %s", err)) + panic(fmt.Errorf("registering collector failed: %w", err)) } result, err := GatherAndCount(reg, metricNames...) if err != nil { @@ -138,7 +142,7 @@ func CollectAndCount(c prometheus.Collector, metricNames ...string) int { func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) { got, err := g.Gather() if err != nil { - return 0, fmt.Errorf("gathering metrics failed: %s", err) + return 0, fmt.Errorf("gathering metrics failed: %w", err) } if metricNames != nil { got = filterMetrics(got, metricNames) @@ -151,13 +155,41 @@ func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) { return result, nil } +// ScrapeAndCompare calls a remote exporter's endpoint which is expected to return some metrics in +// plain text format. Then it compares it with the results that the `expected` would return. +// If the `metricNames` is not empty it would filter the comparison only to the given metric names. +func ScrapeAndCompare(url string, expected io.Reader, metricNames ...string) error { + resp, err := http.Get(url) + if err != nil { + return fmt.Errorf("scraping metrics failed: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("the scraping target returned a status code other than 200: %d", + resp.StatusCode) + } + + scraped, err := convertReaderToMetricFamily(resp.Body) + if err != nil { + return err + } + + wanted, err := convertReaderToMetricFamily(expected) + if err != nil { + return err + } + + return compareMetricFamilies(scraped, wanted, metricNames...) +} + // CollectAndCompare registers the provided Collector with a newly created // pedantic Registry. It then calls GatherAndCompare with that Registry and with // the provided metricNames. func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames ...string) error { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { - return fmt.Errorf("registering collector failed: %s", err) + return fmt.Errorf("registering collector failed: %w", err) } return GatherAndCompare(reg, expected, metricNames...) } @@ -167,21 +199,48 @@ func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames . // exposition format. If any metricNames are provided, only metrics with those // names are compared. func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error { - got, err := g.Gather() + return TransactionalGatherAndCompare(prometheus.ToTransactionalGatherer(g), expected, metricNames...) +} + +// TransactionalGatherAndCompare gathers all metrics from the provided Gatherer and compares +// it to an expected output read from the provided Reader in the Prometheus text +// exposition format. If any metricNames are provided, only metrics with those +// names are compared. +func TransactionalGatherAndCompare(g prometheus.TransactionalGatherer, expected io.Reader, metricNames ...string) error { + got, done, err := g.Gather() + defer done() if err != nil { - return fmt.Errorf("gathering metrics failed: %s", err) + return fmt.Errorf("gathering metrics failed: %w", err) } - if metricNames != nil { - got = filterMetrics(got, metricNames) + + wanted, err := convertReaderToMetricFamily(expected) + if err != nil { + return err } + + return compareMetricFamilies(got, wanted, metricNames...) +} + +// convertReaderToMetricFamily would read from a io.Reader object and convert it to a slice of +// dto.MetricFamily. +func convertReaderToMetricFamily(reader io.Reader) ([]*dto.MetricFamily, error) { var tp expfmt.TextParser - wantRaw, err := tp.TextToMetricFamilies(expected) + notNormalized, err := tp.TextToMetricFamilies(reader) if err != nil { - return fmt.Errorf("parsing expected metrics failed: %s", err) + return nil, fmt.Errorf("converting reader to metric families failed: %w", err) } - want := internal.NormalizeMetricFamilies(wantRaw) - return compare(got, want) + return internal.NormalizeMetricFamilies(notNormalized), nil +} + +// compareMetricFamilies would compare 2 slices of metric families, and optionally filters both of +// them to the `metricNames` provided. +func compareMetricFamilies(got, expected []*dto.MetricFamily, metricNames ...string) error { + if metricNames != nil { + got = filterMetrics(got, metricNames) + } + + return compare(got, expected) } // compare encodes both provided slices of metric families into the text format, @@ -193,27 +252,80 @@ func compare(got, want []*dto.MetricFamily) error { enc := expfmt.NewEncoder(&gotBuf, expfmt.FmtText) for _, mf := range got { if err := enc.Encode(mf); err != nil { - return fmt.Errorf("encoding gathered metrics failed: %s", err) + return fmt.Errorf("encoding gathered metrics failed: %w", err) } } enc = expfmt.NewEncoder(&wantBuf, expfmt.FmtText) for _, mf := range want { if err := enc.Encode(mf); err != nil { - return fmt.Errorf("encoding expected metrics failed: %s", err) + return fmt.Errorf("encoding expected metrics failed: %w", err) } } + if diffErr := diff(wantBuf, gotBuf); diffErr != "" { + return fmt.Errorf(diffErr) + } + return nil +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice, array or string. Otherwise it returns an empty string. +func diff(expected, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } - if wantBuf.String() != gotBuf.String() { - return fmt.Errorf(` -metric output does not match expectation; want: + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + if et != at { + return "" + } -%s -got: + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { + return "" + } + + var e, a string + c := spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + DisableCapacities: true, + SortKeys: true, + } + if et != reflect.TypeOf("") { + e = c.Sdump(expected) + a = c.Sdump(actual) + } else { + e = reflect.ValueOf(expected).String() + a = reflect.ValueOf(actual).String() + } -%s`, wantBuf.String(), gotBuf.String()) + diff, _ := internal.GetUnifiedDiffString(internal.UnifiedDiff{ + A: internal.SplitLines(e), + B: internal.SplitLines(a), + FromFile: "metric output does not match expectation; want", + FromDate: "", + ToFile: "got:", + ToDate: "", + Context: 1, + }) + if diff == "" { + return "" } - return nil + + return "\n\nDiff:\n" + diff +} + +// typeAndKind returns the type and kind of the given interface{} +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() + + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + return t, k } func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go index 8d5f105233..f28a76f3a6 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/timer.go @@ -25,11 +25,12 @@ type Timer struct { // NewTimer creates a new Timer. The provided Observer is used to observe a // duration in seconds. Timer is usually used to time a function call in the // following way: -// func TimeMe() { -// timer := NewTimer(myHistogram) -// defer timer.ObserveDuration() -// // Do actual work. -// } +// +// func TimeMe() { +// timer := NewTimer(myHistogram) +// defer timer.ObserveDuration() +// // Do actual work. +// } func NewTimer(o Observer) *Timer { return &Timer{ begin: time.Now(), diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go index b4e0ae11cb..2d3abc1cbd 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/value.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go @@ -23,6 +23,8 @@ import ( "github.com/golang/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/prometheus/client_golang/prometheus/internal" + dto "github.com/prometheus/client_model/go" ) @@ -38,6 +40,23 @@ const ( UntypedValue ) +var ( + CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }() + GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }() + UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }() +) + +func (v ValueType) ToDTO() *dto.MetricType { + switch v { + case CounterValue: + return CounterMetricTypePtr + case GaugeValue: + return GaugeMetricTypePtr + default: + return UntypedMetricTypePtr + } +} + // valueFunc is a generic metric for simple values retrieved on collect time // from a function. It implements Metric and Collector. Its effective type is // determined by ValueType. This is a low-level building block used by the @@ -91,11 +110,15 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil { return nil, err } + + metric := &dto.Metric{} + if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric); err != nil { + return nil, err + } + return &constMetric{ - desc: desc, - valType: valueType, - val: value, - labelPairs: MakeLabelPairs(desc, labelValues), + desc: desc, + metric: metric, }, nil } @@ -110,10 +133,8 @@ func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelVal } type constMetric struct { - desc *Desc - valType ValueType - val float64 - labelPairs []*dto.LabelPair + desc *Desc + metric *dto.Metric } func (m *constMetric) Desc() *Desc { @@ -121,7 +142,11 @@ func (m *constMetric) Desc() *Desc { } func (m *constMetric) Write(out *dto.Metric) error { - return populateMetric(m.valType, m.val, m.labelPairs, nil, out) + out.Label = m.metric.Label + out.Counter = m.metric.Counter + out.Gauge = m.metric.Gauge + out.Untyped = m.metric.Untyped + return nil } func populateMetric( @@ -170,12 +195,12 @@ func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { }) } labelPairs = append(labelPairs, desc.constLabelPairs...) - sort.Sort(labelPairSorter(labelPairs)) + sort.Sort(internal.LabelPairSorter(labelPairs)) return labelPairs } // ExemplarMaxRunes is the max total number of runes allowed in exemplar labels. -const ExemplarMaxRunes = 64 +const ExemplarMaxRunes = 128 // newExemplar creates a new dto.Exemplar from the provided values. An error is // returned if any of the label names or values are invalid or if the total diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go index 4ababe6c98..7ae322590c 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -99,6 +99,16 @@ func (m *MetricVec) Delete(labels Labels) bool { return m.metricMap.deleteByHashWithLabels(h, labels, m.curry) } +// DeletePartialMatch deletes all metrics where the variable labels contain all of those +// passed in as labels. The order of the labels does not matter. +// It returns the number of metrics deleted. +// +// Note that curried labels will never be matched if deleting from the curried vector. +// To match curried labels with DeletePartialMatch, it must be called on the base vector. +func (m *MetricVec) DeletePartialMatch(labels Labels) int { + return m.metricMap.deleteByLabels(labels, m.curry) +} + // Without explicit forwarding of Describe, Collect, Reset, those methods won't // show up in GoDoc. @@ -381,6 +391,82 @@ func (m *metricMap) deleteByHashWithLabels( return true } +// deleteByLabels deletes a metric if the given labels are present in the metric. +func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int { + m.mtx.Lock() + defer m.mtx.Unlock() + + var numDeleted int + + for h, metrics := range m.metrics { + i := findMetricWithPartialLabels(m.desc, metrics, labels, curry) + if i >= len(metrics) { + // Didn't find matching labels in this metric slice. + continue + } + delete(m.metrics, h) + numDeleted++ + } + + return numDeleted +} + +// findMetricWithPartialLabel returns the index of the matching metric or +// len(metrics) if not found. +func findMetricWithPartialLabels( + desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, +) int { + for i, metric := range metrics { + if matchPartialLabels(desc, metric.values, labels, curry) { + return i + } + } + return len(metrics) +} + +// indexOf searches the given slice of strings for the target string and returns +// the index or len(items) as well as a boolean whether the search succeeded. +func indexOf(target string, items []string) (int, bool) { + for i, l := range items { + if l == target { + return i, true + } + } + return len(items), false +} + +// valueMatchesVariableOrCurriedValue determines if a value was previously curried, +// and returns whether it matches either the "base" value or the curried value accordingly. +// It also indicates whether the match is against a curried or uncurried value. +func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) { + for _, curriedValue := range curry { + if curriedValue.index == index { + // This label was curried. See if the curried value matches our target. + return curriedValue.value == targetValue, true + } + } + // This label was not curried. See if the current value matches our target label. + return values[index] == targetValue, false +} + +// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present. +func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { + for l, v := range labels { + // Check if the target label exists in our metrics and get the index. + varLabelIndex, validLabel := indexOf(l, desc.variableLabels) + if validLabel { + // Check the value of that label against the target value. + // We don't consider curried values in partial matches. + matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry) + if matches && !curried { + continue + } + } + return false + } + return true +} + // getOrCreateMetricWithLabelValues retrieves the metric by hash and label value // or creates it and returns the new one. // @@ -485,7 +571,7 @@ func findMetricWithLabels( return len(metrics) } -func matchLabelValues(values []string, lvs []string, curry []curriedLabelValue) bool { +func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool { if len(values) != len(lvs)+len(curry) { return false } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go index 74ee93280f..1498ee144c 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go @@ -21,6 +21,8 @@ import ( "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" + + "github.com/prometheus/client_golang/prometheus/internal" ) // WrapRegistererWith returns a Registerer wrapping the provided @@ -182,7 +184,7 @@ func (m *wrappingMetric) Write(out *dto.Metric) error { Value: proto.String(lv), }) } - sort.Sort(labelPairSorter(out.Label)) + sort.Sort(internal.LabelPairSorter(out.Label)) return nil } diff --git a/vendor/github.com/prometheus/client_model/go/metrics.pb.go b/vendor/github.com/prometheus/client_model/go/metrics.pb.go index 2f4930d9dd..35904ea198 100644 --- a/vendor/github.com/prometheus/client_model/go/metrics.pb.go +++ b/vendor/github.com/prometheus/client_model/go/metrics.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: metrics.proto +// source: io/prometheus/client/metrics.proto package io_prometheus_client @@ -24,11 +24,18 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type MetricType int32 const ( - MetricType_COUNTER MetricType = 0 - MetricType_GAUGE MetricType = 1 - MetricType_SUMMARY MetricType = 2 - MetricType_UNTYPED MetricType = 3 + // COUNTER must use the Metric field "counter". + MetricType_COUNTER MetricType = 0 + // GAUGE must use the Metric field "gauge". + MetricType_GAUGE MetricType = 1 + // SUMMARY must use the Metric field "summary". + MetricType_SUMMARY MetricType = 2 + // UNTYPED must use the Metric field "untyped". + MetricType_UNTYPED MetricType = 3 + // HISTOGRAM must use the Metric field "histogram". MetricType_HISTOGRAM MetricType = 4 + // GAUGE_HISTOGRAM must use the Metric field "histogram". + MetricType_GAUGE_HISTOGRAM MetricType = 5 ) var MetricType_name = map[int32]string{ @@ -37,14 +44,16 @@ var MetricType_name = map[int32]string{ 2: "SUMMARY", 3: "UNTYPED", 4: "HISTOGRAM", + 5: "GAUGE_HISTOGRAM", } var MetricType_value = map[string]int32{ - "COUNTER": 0, - "GAUGE": 1, - "SUMMARY": 2, - "UNTYPED": 3, - "HISTOGRAM": 4, + "COUNTER": 0, + "GAUGE": 1, + "SUMMARY": 2, + "UNTYPED": 3, + "HISTOGRAM": 4, + "GAUGE_HISTOGRAM": 5, } func (x MetricType) Enum() *MetricType { @@ -67,7 +76,7 @@ func (x *MetricType) UnmarshalJSON(data []byte) error { } func (MetricType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{0} + return fileDescriptor_d1e5ddb18987a258, []int{0} } type LabelPair struct { @@ -82,7 +91,7 @@ func (m *LabelPair) Reset() { *m = LabelPair{} } func (m *LabelPair) String() string { return proto.CompactTextString(m) } func (*LabelPair) ProtoMessage() {} func (*LabelPair) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{0} + return fileDescriptor_d1e5ddb18987a258, []int{0} } func (m *LabelPair) XXX_Unmarshal(b []byte) error { @@ -128,7 +137,7 @@ func (m *Gauge) Reset() { *m = Gauge{} } func (m *Gauge) String() string { return proto.CompactTextString(m) } func (*Gauge) ProtoMessage() {} func (*Gauge) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{1} + return fileDescriptor_d1e5ddb18987a258, []int{1} } func (m *Gauge) XXX_Unmarshal(b []byte) error { @@ -168,7 +177,7 @@ func (m *Counter) Reset() { *m = Counter{} } func (m *Counter) String() string { return proto.CompactTextString(m) } func (*Counter) ProtoMessage() {} func (*Counter) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{2} + return fileDescriptor_d1e5ddb18987a258, []int{2} } func (m *Counter) XXX_Unmarshal(b []byte) error { @@ -215,7 +224,7 @@ func (m *Quantile) Reset() { *m = Quantile{} } func (m *Quantile) String() string { return proto.CompactTextString(m) } func (*Quantile) ProtoMessage() {} func (*Quantile) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{3} + return fileDescriptor_d1e5ddb18987a258, []int{3} } func (m *Quantile) XXX_Unmarshal(b []byte) error { @@ -263,7 +272,7 @@ func (m *Summary) Reset() { *m = Summary{} } func (m *Summary) String() string { return proto.CompactTextString(m) } func (*Summary) ProtoMessage() {} func (*Summary) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{4} + return fileDescriptor_d1e5ddb18987a258, []int{4} } func (m *Summary) XXX_Unmarshal(b []byte) error { @@ -316,7 +325,7 @@ func (m *Untyped) Reset() { *m = Untyped{} } func (m *Untyped) String() string { return proto.CompactTextString(m) } func (*Untyped) ProtoMessage() {} func (*Untyped) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{5} + return fileDescriptor_d1e5ddb18987a258, []int{5} } func (m *Untyped) XXX_Unmarshal(b []byte) error { @@ -345,9 +354,34 @@ func (m *Untyped) GetValue() float64 { } type Histogram struct { - SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` - SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` - Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"` + SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` + SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"` + SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` + // Buckets for the conventional histogram. + Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"` + // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8. + // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and + // then each power of two is divided into 2^n logarithmic buckets. + // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n). + // In the future, more bucket schemas may be added using numbers < -4 or > 8. + Schema *int32 `protobuf:"zigzag32,5,opt,name=schema" json:"schema,omitempty"` + ZeroThreshold *float64 `protobuf:"fixed64,6,opt,name=zero_threshold,json=zeroThreshold" json:"zero_threshold,omitempty"` + ZeroCount *uint64 `protobuf:"varint,7,opt,name=zero_count,json=zeroCount" json:"zero_count,omitempty"` + ZeroCountFloat *float64 `protobuf:"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat" json:"zero_count_float,omitempty"` + // Negative buckets for the native histogram. + NegativeSpan []*BucketSpan `protobuf:"bytes,9,rep,name=negative_span,json=negativeSpan" json:"negative_span,omitempty"` + // Use either "negative_delta" or "negative_count", the former for + // regular histograms with integer counts, the latter for float + // histograms. + NegativeDelta []int64 `protobuf:"zigzag64,10,rep,name=negative_delta,json=negativeDelta" json:"negative_delta,omitempty"` + NegativeCount []float64 `protobuf:"fixed64,11,rep,name=negative_count,json=negativeCount" json:"negative_count,omitempty"` + // Positive buckets for the native histogram. + PositiveSpan []*BucketSpan `protobuf:"bytes,12,rep,name=positive_span,json=positiveSpan" json:"positive_span,omitempty"` + // Use either "positive_delta" or "positive_count", the former for + // regular histograms with integer counts, the latter for float + // histograms. + PositiveDelta []int64 `protobuf:"zigzag64,13,rep,name=positive_delta,json=positiveDelta" json:"positive_delta,omitempty"` + PositiveCount []float64 `protobuf:"fixed64,14,rep,name=positive_count,json=positiveCount" json:"positive_count,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -357,7 +391,7 @@ func (m *Histogram) Reset() { *m = Histogram{} } func (m *Histogram) String() string { return proto.CompactTextString(m) } func (*Histogram) ProtoMessage() {} func (*Histogram) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{6} + return fileDescriptor_d1e5ddb18987a258, []int{6} } func (m *Histogram) XXX_Unmarshal(b []byte) error { @@ -385,6 +419,13 @@ func (m *Histogram) GetSampleCount() uint64 { return 0 } +func (m *Histogram) GetSampleCountFloat() float64 { + if m != nil && m.SampleCountFloat != nil { + return *m.SampleCountFloat + } + return 0 +} + func (m *Histogram) GetSampleSum() float64 { if m != nil && m.SampleSum != nil { return *m.SampleSum @@ -399,8 +440,81 @@ func (m *Histogram) GetBucket() []*Bucket { return nil } +func (m *Histogram) GetSchema() int32 { + if m != nil && m.Schema != nil { + return *m.Schema + } + return 0 +} + +func (m *Histogram) GetZeroThreshold() float64 { + if m != nil && m.ZeroThreshold != nil { + return *m.ZeroThreshold + } + return 0 +} + +func (m *Histogram) GetZeroCount() uint64 { + if m != nil && m.ZeroCount != nil { + return *m.ZeroCount + } + return 0 +} + +func (m *Histogram) GetZeroCountFloat() float64 { + if m != nil && m.ZeroCountFloat != nil { + return *m.ZeroCountFloat + } + return 0 +} + +func (m *Histogram) GetNegativeSpan() []*BucketSpan { + if m != nil { + return m.NegativeSpan + } + return nil +} + +func (m *Histogram) GetNegativeDelta() []int64 { + if m != nil { + return m.NegativeDelta + } + return nil +} + +func (m *Histogram) GetNegativeCount() []float64 { + if m != nil { + return m.NegativeCount + } + return nil +} + +func (m *Histogram) GetPositiveSpan() []*BucketSpan { + if m != nil { + return m.PositiveSpan + } + return nil +} + +func (m *Histogram) GetPositiveDelta() []int64 { + if m != nil { + return m.PositiveDelta + } + return nil +} + +func (m *Histogram) GetPositiveCount() []float64 { + if m != nil { + return m.PositiveCount + } + return nil +} + +// A Bucket of a conventional histogram, each of which is treated as +// an individual counter-like time series by Prometheus. type Bucket struct { CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"` + CumulativeCountFloat *float64 `protobuf:"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat" json:"cumulative_count_float,omitempty"` UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"` Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -412,7 +526,7 @@ func (m *Bucket) Reset() { *m = Bucket{} } func (m *Bucket) String() string { return proto.CompactTextString(m) } func (*Bucket) ProtoMessage() {} func (*Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{7} + return fileDescriptor_d1e5ddb18987a258, []int{7} } func (m *Bucket) XXX_Unmarshal(b []byte) error { @@ -440,6 +554,13 @@ func (m *Bucket) GetCumulativeCount() uint64 { return 0 } +func (m *Bucket) GetCumulativeCountFloat() float64 { + if m != nil && m.CumulativeCountFloat != nil { + return *m.CumulativeCountFloat + } + return 0 +} + func (m *Bucket) GetUpperBound() float64 { if m != nil && m.UpperBound != nil { return *m.UpperBound @@ -454,6 +575,59 @@ func (m *Bucket) GetExemplar() *Exemplar { return nil } +// A BucketSpan defines a number of consecutive buckets in a native +// histogram with their offset. Logically, it would be more +// straightforward to include the bucket counts in the Span. However, +// the protobuf representation is more compact in the way the data is +// structured here (with all the buckets in a single array separate +// from the Spans). +type BucketSpan struct { + Offset *int32 `protobuf:"zigzag32,1,opt,name=offset" json:"offset,omitempty"` + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BucketSpan) Reset() { *m = BucketSpan{} } +func (m *BucketSpan) String() string { return proto.CompactTextString(m) } +func (*BucketSpan) ProtoMessage() {} +func (*BucketSpan) Descriptor() ([]byte, []int) { + return fileDescriptor_d1e5ddb18987a258, []int{8} +} + +func (m *BucketSpan) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BucketSpan.Unmarshal(m, b) +} +func (m *BucketSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BucketSpan.Marshal(b, m, deterministic) +} +func (m *BucketSpan) XXX_Merge(src proto.Message) { + xxx_messageInfo_BucketSpan.Merge(m, src) +} +func (m *BucketSpan) XXX_Size() int { + return xxx_messageInfo_BucketSpan.Size(m) +} +func (m *BucketSpan) XXX_DiscardUnknown() { + xxx_messageInfo_BucketSpan.DiscardUnknown(m) +} + +var xxx_messageInfo_BucketSpan proto.InternalMessageInfo + +func (m *BucketSpan) GetOffset() int32 { + if m != nil && m.Offset != nil { + return *m.Offset + } + return 0 +} + +func (m *BucketSpan) GetLength() uint32 { + if m != nil && m.Length != nil { + return *m.Length + } + return 0 +} + type Exemplar struct { Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` @@ -467,7 +641,7 @@ func (m *Exemplar) Reset() { *m = Exemplar{} } func (m *Exemplar) String() string { return proto.CompactTextString(m) } func (*Exemplar) ProtoMessage() {} func (*Exemplar) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{8} + return fileDescriptor_d1e5ddb18987a258, []int{9} } func (m *Exemplar) XXX_Unmarshal(b []byte) error { @@ -526,7 +700,7 @@ func (m *Metric) Reset() { *m = Metric{} } func (m *Metric) String() string { return proto.CompactTextString(m) } func (*Metric) ProtoMessage() {} func (*Metric) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{9} + return fileDescriptor_d1e5ddb18987a258, []int{10} } func (m *Metric) XXX_Unmarshal(b []byte) error { @@ -610,7 +784,7 @@ func (m *MetricFamily) Reset() { *m = MetricFamily{} } func (m *MetricFamily) String() string { return proto.CompactTextString(m) } func (*MetricFamily) ProtoMessage() {} func (*MetricFamily) Descriptor() ([]byte, []int) { - return fileDescriptor_6039342a2ba47b72, []int{10} + return fileDescriptor_d1e5ddb18987a258, []int{11} } func (m *MetricFamily) XXX_Unmarshal(b []byte) error { @@ -669,55 +843,72 @@ func init() { proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped") proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram") proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket") + proto.RegisterType((*BucketSpan)(nil), "io.prometheus.client.BucketSpan") proto.RegisterType((*Exemplar)(nil), "io.prometheus.client.Exemplar") proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric") proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily") } -func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) } - -var fileDescriptor_6039342a2ba47b72 = []byte{ - // 665 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0xfd, 0xdc, 0x38, 0x3f, 0xbe, 0x69, 0x3f, 0xa2, 0x51, 0x17, 0x56, 0xa1, 0x24, 0x78, 0x55, - 0x58, 0x38, 0xa2, 0x6a, 0x05, 0x2a, 0xb0, 0x68, 0x4b, 0x48, 0x91, 0x48, 0x5b, 0x26, 0xc9, 0xa2, - 0xb0, 0x88, 0x1c, 0x77, 0x70, 0x2c, 0x3c, 0xb1, 0xb1, 0x67, 0x2a, 0xb2, 0x66, 0xc1, 0x16, 0x5e, - 0x81, 0x17, 0x05, 0xcd, 0x8f, 0x6d, 0x2a, 0xb9, 0x95, 0x40, 0xec, 0x66, 0xee, 0x3d, 0xe7, 0xfa, - 0xcc, 0xf8, 0x9c, 0x81, 0x0d, 0x4a, 0x58, 0x1a, 0xfa, 0x99, 0x9b, 0xa4, 0x31, 0x8b, 0xd1, 0x66, - 0x18, 0x8b, 0x15, 0x25, 0x6c, 0x41, 0x78, 0xe6, 0xfa, 0x51, 0x48, 0x96, 0x6c, 0xab, 0x1b, 0xc4, - 0x71, 0x10, 0x91, 0xbe, 0xc4, 0xcc, 0xf9, 0x87, 0x3e, 0x0b, 0x29, 0xc9, 0x98, 0x47, 0x13, 0x45, - 0x73, 0xf6, 0xc1, 0x7a, 0xe3, 0xcd, 0x49, 0x74, 0xee, 0x85, 0x29, 0x42, 0x60, 0x2e, 0x3d, 0x4a, - 0x6c, 0xa3, 0x67, 0xec, 0x58, 0x58, 0xae, 0xd1, 0x26, 0xd4, 0xaf, 0xbc, 0x88, 0x13, 0x7b, 0x4d, - 0x16, 0xd5, 0xc6, 0xd9, 0x86, 0xfa, 0xd0, 0xe3, 0xc1, 0x6f, 0x6d, 0xc1, 0x31, 0xf2, 0xf6, 0x7b, - 0x68, 0x1e, 0xc7, 0x7c, 0xc9, 0x48, 0x5a, 0x0d, 0x40, 0x07, 0xd0, 0x22, 0x9f, 0x09, 0x4d, 0x22, - 0x2f, 0x95, 0x83, 0xdb, 0xbb, 0xf7, 0xdd, 0xaa, 0x03, 0xb8, 0x03, 0x8d, 0xc2, 0x05, 0xde, 0x79, - 0x0e, 0xad, 0xb7, 0xdc, 0x5b, 0xb2, 0x30, 0x22, 0x68, 0x0b, 0x5a, 0x9f, 0xf4, 0x5a, 0x7f, 0xa0, - 0xd8, 0x5f, 0x57, 0x5e, 0x48, 0xfb, 0x6a, 0x40, 0x73, 0xcc, 0x29, 0xf5, 0xd2, 0x15, 0x7a, 0x00, - 0xeb, 0x99, 0x47, 0x93, 0x88, 0xcc, 0x7c, 0xa1, 0x56, 0x4e, 0x30, 0x71, 0x5b, 0xd5, 0xe4, 0x01, - 0xd0, 0x36, 0x80, 0x86, 0x64, 0x9c, 0xea, 0x49, 0x96, 0xaa, 0x8c, 0x39, 0x15, 0xe7, 0x28, 0xbe, - 0x5f, 0xeb, 0xd5, 0x6e, 0x3e, 0x47, 0xae, 0xb8, 0xd4, 0xe7, 0x74, 0xa1, 0x39, 0x5d, 0xb2, 0x55, - 0x42, 0x2e, 0x6f, 0xb8, 0xc5, 0x2f, 0x06, 0x58, 0x27, 0x61, 0xc6, 0xe2, 0x20, 0xf5, 0xe8, 0x3f, - 0x10, 0xbb, 0x07, 0x8d, 0x39, 0xf7, 0x3f, 0x12, 0xa6, 0xa5, 0xde, 0xab, 0x96, 0x7a, 0x24, 0x31, - 0x58, 0x63, 0x9d, 0x6f, 0x06, 0x34, 0x54, 0x09, 0x3d, 0x84, 0x8e, 0xcf, 0x29, 0x8f, 0x3c, 0x16, - 0x5e, 0x5d, 0x97, 0x71, 0xa7, 0xac, 0x2b, 0x29, 0x5d, 0x68, 0xf3, 0x24, 0x21, 0xe9, 0x6c, 0x1e, - 0xf3, 0xe5, 0xa5, 0xd6, 0x02, 0xb2, 0x74, 0x24, 0x2a, 0xd7, 0x1c, 0x50, 0xfb, 0x43, 0x07, 0x7c, - 0x37, 0xa0, 0x95, 0x97, 0xd1, 0x3e, 0xd4, 0x23, 0xe1, 0x60, 0xdb, 0x90, 0x87, 0xea, 0x56, 0x4f, - 0x29, 0x4c, 0x8e, 0x15, 0xba, 0xda, 0x1d, 0xe8, 0x29, 0x58, 0x45, 0x42, 0xb4, 0xac, 0x2d, 0x57, - 0x65, 0xc8, 0xcd, 0x33, 0xe4, 0x4e, 0x72, 0x04, 0x2e, 0xc1, 0xce, 0xcf, 0x35, 0x68, 0x8c, 0x64, - 0x22, 0xff, 0x56, 0xd1, 0x63, 0xa8, 0x07, 0x22, 0x53, 0x3a, 0x10, 0x77, 0xab, 0x69, 0x32, 0x76, - 0x58, 0x21, 0xd1, 0x13, 0x68, 0xfa, 0x2a, 0x67, 0x5a, 0xec, 0x76, 0x35, 0x49, 0x87, 0x11, 0xe7, - 0x68, 0x41, 0xcc, 0x54, 0x08, 0x6c, 0xf3, 0x36, 0xa2, 0x4e, 0x0a, 0xce, 0xd1, 0x82, 0xc8, 0x95, - 0x69, 0xed, 0xfa, 0x6d, 0x44, 0xed, 0x6c, 0x9c, 0xa3, 0xd1, 0x0b, 0xb0, 0x16, 0xb9, 0x97, 0xed, - 0xa6, 0xa4, 0xde, 0x70, 0x31, 0x85, 0xe5, 0x71, 0xc9, 0x10, 0xee, 0x2f, 0xee, 0x7a, 0x46, 0x33, - 0xbb, 0xd1, 0x33, 0x76, 0x6a, 0xb8, 0x5d, 0xd4, 0x46, 0x99, 0xf3, 0xc3, 0x80, 0x75, 0xf5, 0x07, - 0x5e, 0x79, 0x34, 0x8c, 0x56, 0x95, 0xcf, 0x19, 0x02, 0x73, 0x41, 0xa2, 0x44, 0xbf, 0x66, 0x72, - 0x8d, 0xf6, 0xc0, 0x14, 0x1a, 0xe5, 0x15, 0xfe, 0xbf, 0xdb, 0xab, 0x56, 0xa5, 0x26, 0x4f, 0x56, - 0x09, 0xc1, 0x12, 0x2d, 0xd2, 0xa4, 0x5e, 0x60, 0xdb, 0xbc, 0x2d, 0x4d, 0x8a, 0x87, 0x35, 0xf6, - 0xd1, 0x08, 0xa0, 0x9c, 0x84, 0xda, 0xd0, 0x3c, 0x3e, 0x9b, 0x9e, 0x4e, 0x06, 0xb8, 0xf3, 0x1f, - 0xb2, 0xa0, 0x3e, 0x3c, 0x9c, 0x0e, 0x07, 0x1d, 0x43, 0xd4, 0xc7, 0xd3, 0xd1, 0xe8, 0x10, 0x5f, - 0x74, 0xd6, 0xc4, 0x66, 0x7a, 0x3a, 0xb9, 0x38, 0x1f, 0xbc, 0xec, 0xd4, 0xd0, 0x06, 0x58, 0x27, - 0xaf, 0xc7, 0x93, 0xb3, 0x21, 0x3e, 0x1c, 0x75, 0xcc, 0x23, 0x0c, 0x95, 0xef, 0xfe, 0xbb, 0x83, - 0x20, 0x64, 0x0b, 0x3e, 0x77, 0xfd, 0x98, 0xf6, 0xcb, 0x6e, 0x5f, 0x75, 0x67, 0x34, 0xbe, 0x24, - 0x51, 0x3f, 0x88, 0x9f, 0x85, 0xf1, 0xac, 0xec, 0xce, 0x54, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xd0, 0x84, 0x91, 0x73, 0x59, 0x06, 0x00, 0x00, +func init() { + proto.RegisterFile("io/prometheus/client/metrics.proto", fileDescriptor_d1e5ddb18987a258) +} + +var fileDescriptor_d1e5ddb18987a258 = []byte{ + // 896 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0xdb, 0x44, + 0x18, 0xc5, 0x9b, 0x5f, 0x7f, 0xd9, 0x6c, 0xd3, 0x61, 0x55, 0x59, 0x0b, 0xcb, 0x06, 0x4b, 0x48, + 0x0b, 0x42, 0x8e, 0x40, 0x5b, 0x81, 0x0a, 0x5c, 0xec, 0xb6, 0xe9, 0x16, 0x89, 0xb4, 0x65, 0x92, + 0x5c, 0x14, 0x2e, 0xac, 0x49, 0x32, 0xeb, 0x58, 0x78, 0x3c, 0xc6, 0x1e, 0x57, 0x2c, 0x2f, 0xc0, + 0x35, 0xaf, 0xc0, 0xc3, 0xf0, 0x22, 0x3c, 0x08, 0x68, 0xfe, 0xec, 0xdd, 0xe2, 0x94, 0xd2, 0x3b, + 0x7f, 0x67, 0xce, 0xf7, 0xcd, 0x39, 0xe3, 0xc9, 0x71, 0xc0, 0x8f, 0xf9, 0x24, 0xcb, 0x39, 0xa3, + 0x62, 0x4b, 0xcb, 0x62, 0xb2, 0x4e, 0x62, 0x9a, 0x8a, 0x09, 0xa3, 0x22, 0x8f, 0xd7, 0x45, 0x90, + 0xe5, 0x5c, 0x70, 0x74, 0x18, 0xf3, 0xa0, 0xe6, 0x04, 0x9a, 0x73, 0x74, 0x12, 0x71, 0x1e, 0x25, + 0x74, 0xa2, 0x38, 0xab, 0xf2, 0x6a, 0x22, 0x62, 0x46, 0x0b, 0x41, 0x58, 0xa6, 0xdb, 0xfc, 0xfb, + 0xe0, 0x7e, 0x47, 0x56, 0x34, 0x79, 0x4e, 0xe2, 0x1c, 0x21, 0x68, 0xa7, 0x84, 0x51, 0xcf, 0x19, + 0x3b, 0xa7, 0x2e, 0x56, 0xcf, 0xe8, 0x10, 0x3a, 0x2f, 0x49, 0x52, 0x52, 0x6f, 0x4f, 0x81, 0xba, + 0xf0, 0x8f, 0xa1, 0x73, 0x49, 0xca, 0xe8, 0xc6, 0xb2, 0xec, 0x71, 0xec, 0xf2, 0x8f, 0xd0, 0x7b, + 0xc8, 0xcb, 0x54, 0xd0, 0xbc, 0x99, 0x80, 0x1e, 0x40, 0x9f, 0xfe, 0x42, 0x59, 0x96, 0x90, 0x5c, + 0x0d, 0x1e, 0x7c, 0xfe, 0x41, 0xd0, 0x64, 0x20, 0x98, 0x1a, 0x16, 0xae, 0xf8, 0xfe, 0xd7, 0xd0, + 0xff, 0xbe, 0x24, 0xa9, 0x88, 0x13, 0x8a, 0x8e, 0xa0, 0xff, 0xb3, 0x79, 0x36, 0x1b, 0x54, 0xf5, + 0x6d, 0xe5, 0x95, 0xb4, 0xdf, 0x1c, 0xe8, 0xcd, 0x4b, 0xc6, 0x48, 0x7e, 0x8d, 0x3e, 0x84, 0xfd, + 0x82, 0xb0, 0x2c, 0xa1, 0xe1, 0x5a, 0xaa, 0x55, 0x13, 0xda, 0x78, 0xa0, 0x31, 0x65, 0x00, 0x1d, + 0x03, 0x18, 0x4a, 0x51, 0x32, 0x33, 0xc9, 0xd5, 0xc8, 0xbc, 0x64, 0xd2, 0x47, 0xb5, 0x7f, 0x6b, + 0xdc, 0xda, 0xed, 0xc3, 0x2a, 0xae, 0xf5, 0xf9, 0x27, 0xd0, 0x5b, 0xa6, 0xe2, 0x3a, 0xa3, 0x9b, + 0x1d, 0xa7, 0xf8, 0x57, 0x1b, 0xdc, 0x27, 0x71, 0x21, 0x78, 0x94, 0x13, 0xf6, 0x26, 0x62, 0x3f, + 0x05, 0x74, 0x93, 0x12, 0x5e, 0x25, 0x9c, 0x08, 0xaf, 0xad, 0x66, 0x8e, 0x6e, 0x10, 0x1f, 0x4b, + 0xfc, 0xbf, 0xac, 0x9d, 0x41, 0x77, 0x55, 0xae, 0x7f, 0xa2, 0xc2, 0x18, 0x7b, 0xbf, 0xd9, 0xd8, + 0x85, 0xe2, 0x60, 0xc3, 0x45, 0xf7, 0xa0, 0x5b, 0xac, 0xb7, 0x94, 0x11, 0xaf, 0x33, 0x76, 0x4e, + 0xef, 0x62, 0x53, 0xa1, 0x8f, 0xe0, 0xe0, 0x57, 0x9a, 0xf3, 0x50, 0x6c, 0x73, 0x5a, 0x6c, 0x79, + 0xb2, 0xf1, 0xba, 0x6a, 0xc3, 0xa1, 0x44, 0x17, 0x16, 0x94, 0x9a, 0x14, 0x4d, 0x5b, 0xec, 0x29, + 0x8b, 0xae, 0x44, 0xb4, 0xc1, 0x53, 0x18, 0xd5, 0xcb, 0xc6, 0x5e, 0x5f, 0xcd, 0x39, 0xa8, 0x48, + 0xda, 0xdc, 0x14, 0x86, 0x29, 0x8d, 0x88, 0x88, 0x5f, 0xd2, 0xb0, 0xc8, 0x48, 0xea, 0xb9, 0xca, + 0xc4, 0xf8, 0x75, 0x26, 0xe6, 0x19, 0x49, 0xf1, 0xbe, 0x6d, 0x93, 0x95, 0x94, 0x5d, 0x8d, 0xd9, + 0xd0, 0x44, 0x10, 0x0f, 0xc6, 0xad, 0x53, 0x84, 0xab, 0xe1, 0x8f, 0x24, 0x78, 0x8b, 0xa6, 0xa5, + 0x0f, 0xc6, 0x2d, 0xe9, 0xce, 0xa2, 0x5a, 0xfe, 0x14, 0x86, 0x19, 0x2f, 0xe2, 0x5a, 0xd4, 0xfe, + 0x9b, 0x8a, 0xb2, 0x6d, 0x56, 0x54, 0x35, 0x46, 0x8b, 0x1a, 0x6a, 0x51, 0x16, 0xad, 0x44, 0x55, + 0x34, 0x2d, 0xea, 0x40, 0x8b, 0xb2, 0xa8, 0x12, 0xe5, 0xff, 0xe9, 0x40, 0x57, 0x6f, 0x85, 0x3e, + 0x86, 0xd1, 0xba, 0x64, 0x65, 0x72, 0xd3, 0x88, 0xbe, 0x66, 0x77, 0x6a, 0x5c, 0x5b, 0x39, 0x83, + 0x7b, 0xaf, 0x52, 0x6f, 0x5d, 0xb7, 0xc3, 0x57, 0x1a, 0xf4, 0x5b, 0x39, 0x81, 0x41, 0x99, 0x65, + 0x34, 0x0f, 0x57, 0xbc, 0x4c, 0x37, 0xe6, 0xce, 0x81, 0x82, 0x2e, 0x24, 0x72, 0x2b, 0x17, 0x5a, + 0xff, 0x3b, 0x17, 0xa0, 0x3e, 0x32, 0x79, 0x11, 0xf9, 0xd5, 0x55, 0x41, 0xb5, 0x83, 0xbb, 0xd8, + 0x54, 0x12, 0x4f, 0x68, 0x1a, 0x89, 0xad, 0xda, 0x7d, 0x88, 0x4d, 0xe5, 0xff, 0xee, 0x40, 0xdf, + 0x0e, 0x45, 0xf7, 0xa1, 0x93, 0xc8, 0x54, 0xf4, 0x1c, 0xf5, 0x82, 0x4e, 0x9a, 0x35, 0x54, 0xc1, + 0x89, 0x35, 0xbb, 0x39, 0x71, 0xd0, 0x97, 0xe0, 0x56, 0xa9, 0x6b, 0x4c, 0x1d, 0x05, 0x3a, 0x97, + 0x03, 0x9b, 0xcb, 0xc1, 0xc2, 0x32, 0x70, 0x4d, 0xf6, 0xff, 0xde, 0x83, 0xee, 0x4c, 0xa5, 0xfc, + 0xdb, 0x2a, 0xfa, 0x0c, 0x3a, 0x91, 0xcc, 0x69, 0x13, 0xb2, 0xef, 0x35, 0xb7, 0xa9, 0x28, 0xc7, + 0x9a, 0x89, 0xbe, 0x80, 0xde, 0x5a, 0x67, 0xb7, 0x11, 0x7b, 0xdc, 0xdc, 0x64, 0x02, 0x1e, 0x5b, + 0xb6, 0x6c, 0x2c, 0x74, 0xb0, 0xaa, 0x3b, 0xb0, 0xb3, 0xd1, 0xa4, 0x2f, 0xb6, 0x6c, 0xd9, 0x58, + 0xea, 0x20, 0x54, 0xa1, 0xb1, 0xb3, 0xd1, 0xa4, 0x25, 0xb6, 0x6c, 0xf4, 0x0d, 0xb8, 0x5b, 0x9b, + 0x8f, 0x2a, 0x2c, 0x76, 0x1e, 0x4c, 0x15, 0xa3, 0xb8, 0xee, 0x90, 0x89, 0x5a, 0x9d, 0x75, 0xc8, + 0x0a, 0x95, 0x48, 0x2d, 0x3c, 0xa8, 0xb0, 0x59, 0xe1, 0xff, 0xe1, 0xc0, 0xbe, 0x7e, 0x03, 0x8f, + 0x09, 0x8b, 0x93, 0xeb, 0xc6, 0x4f, 0x24, 0x82, 0xf6, 0x96, 0x26, 0x99, 0xf9, 0x42, 0xaa, 0x67, + 0x74, 0x06, 0x6d, 0xa9, 0x51, 0x1d, 0xe1, 0xc1, 0xae, 0x5f, 0xb8, 0x9e, 0xbc, 0xb8, 0xce, 0x28, + 0x56, 0x6c, 0x99, 0xb9, 0xfa, 0xab, 0xee, 0xb5, 0x5f, 0x97, 0xb9, 0xba, 0x0f, 0x1b, 0xee, 0x27, + 0x2b, 0x80, 0x7a, 0x12, 0x1a, 0x40, 0xef, 0xe1, 0xb3, 0xe5, 0xd3, 0xc5, 0x14, 0x8f, 0xde, 0x41, + 0x2e, 0x74, 0x2e, 0xcf, 0x97, 0x97, 0xd3, 0x91, 0x23, 0xf1, 0xf9, 0x72, 0x36, 0x3b, 0xc7, 0x2f, + 0x46, 0x7b, 0xb2, 0x58, 0x3e, 0x5d, 0xbc, 0x78, 0x3e, 0x7d, 0x34, 0x6a, 0xa1, 0x21, 0xb8, 0x4f, + 0xbe, 0x9d, 0x2f, 0x9e, 0x5d, 0xe2, 0xf3, 0xd9, 0xa8, 0x8d, 0xde, 0x85, 0x3b, 0xaa, 0x27, 0xac, + 0xc1, 0xce, 0x05, 0x86, 0xc6, 0x3f, 0x18, 0x3f, 0x3c, 0x88, 0x62, 0xb1, 0x2d, 0x57, 0xc1, 0x9a, + 0xb3, 0x7f, 0xff, 0x45, 0x09, 0x19, 0xdf, 0xd0, 0x64, 0x12, 0xf1, 0xaf, 0x62, 0x1e, 0xd6, 0xab, + 0xa1, 0x5e, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x16, 0x77, 0x81, 0x98, 0xd7, 0x08, 0x00, 0x00, } diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index dc2eedeefc..f819e4f8b5 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -12,6 +12,7 @@ // limitations under the License. // Build only when actually fuzzing +//go:build gofuzz // +build gofuzz package expfmt diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go index 8a9313a3be..9d94ae9eff 100644 --- a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go @@ -22,7 +22,6 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/ptypes" "github.com/prometheus/common/model" dto "github.com/prometheus/client_model/go" @@ -473,10 +472,11 @@ func writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) { if err != nil { return written, err } - ts, err := ptypes.Timestamp((*e).Timestamp) + err = (*e).Timestamp.CheckValid() if err != nil { return written, err } + ts := (*e).Timestamp.AsTime() // TODO(beorn7): Format this directly from components of ts to // avoid overflow/underflow and precision issues of the float // conversion. diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index 7f67b16e42..c909b8aa8c 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -193,7 +193,7 @@ func ParseDuration(durationStr string) (Duration, error) { // Allow 0 without a unit. return 0, nil case "": - return 0, fmt.Errorf("empty duration string") + return 0, errors.New("empty duration string") } matches := durationRE.FindStringSubmatch(durationStr) if matches == nil { diff --git a/vendor/github.com/prometheus/procfs/.gitignore b/vendor/github.com/prometheus/procfs/.gitignore index 25e3659ab2..7cc33ae4a7 100644 --- a/vendor/github.com/prometheus/procfs/.gitignore +++ b/vendor/github.com/prometheus/procfs/.gitignore @@ -1 +1,2 @@ -/fixtures/ +/testdata/fixtures/ +/fixtures diff --git a/vendor/github.com/prometheus/procfs/.golangci.yml b/vendor/github.com/prometheus/procfs/.golangci.yml index 0aa09edacb..a197699a1e 100644 --- a/vendor/github.com/prometheus/procfs/.golangci.yml +++ b/vendor/github.com/prometheus/procfs/.golangci.yml @@ -1,4 +1,12 @@ --- linters: enable: - - golint + - godot + - revive + +linter-settings: + godot: + capital: true + exclude: + # Ignore "See: URL" + - 'See:' diff --git a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md b/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md index 9a1aff4127..d325872bdf 100644 --- a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md +++ b/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md @@ -1,3 +1,3 @@ -## Prometheus Community Code of Conduct +# Prometheus Community Code of Conduct -Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). +Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md index 943de7615e..853eb9d49b 100644 --- a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md +++ b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md @@ -97,7 +97,7 @@ Many of the files are changing continuously and the data being read can in some reads in the same file. Also, most of the files are relatively small (less than a few KBs), and system calls to the `stat` function will often return the wrong size. Therefore, for most files it's recommended to read the full file in a single operation using an internal utility function called `util.ReadFileNoStat`. -This function is similar to `ioutil.ReadFile`, but it avoids the system call to `stat` to get the current size of +This function is similar to `os.ReadFile`, but it avoids the system call to `stat` to get the current size of the file. Note that parsing the file's contents can still be performed one line at a time. This is done by first reading @@ -113,7 +113,7 @@ the full file, and then using a scanner on the `[]byte` or `string` containing t ``` The `/sys` filesystem contains many very small files which contain only a single numeric or text value. These files -can be read using an internal function called `util.SysReadFile` which is similar to `ioutil.ReadFile` but does +can be read using an internal function called `util.SysReadFile` which is similar to `os.ReadFile` but does not bother to check the size of the file before reading. ``` data, err := util.SysReadFile("/sys/class/power_supply/BAT0/capacity") diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile index fa2bd5b528..7edfe4d093 100644 --- a/vendor/github.com/prometheus/procfs/Makefile +++ b/vendor/github.com/prometheus/procfs/Makefile @@ -14,18 +14,18 @@ include Makefile.common %/.unpacked: %.ttar - @echo ">> extracting fixtures" + @echo ">> extracting fixtures $*" ./ttar -C $(dir $*) -x -f $*.ttar touch $@ -fixtures: fixtures/.unpacked +fixtures: testdata/fixtures/.unpacked update_fixtures: - rm -vf fixtures/.unpacked - ./ttar -c -f fixtures.ttar fixtures/ + rm -vf testdata/fixtures/.unpacked + ./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/ .PHONY: build build: .PHONY: test -test: fixtures/.unpacked common-test +test: testdata/fixtures/.unpacked common-test diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index a1b1ca40f4..e358db69c5 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -36,29 +36,6 @@ GO_VERSION ?= $(shell $(GO) version) GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') -GOVENDOR := -GO111MODULE := -ifeq (, $(PRE_GO_111)) - ifneq (,$(wildcard go.mod)) - # Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). - GO111MODULE := on - - ifneq (,$(wildcard vendor)) - # Always use the local vendor/ directory to satisfy the dependencies. - GOOPTS := $(GOOPTS) -mod=vendor - endif - endif -else - ifneq (,$(wildcard go.mod)) - ifneq (,$(wildcard vendor)) -$(warning This repository requires Go >= 1.11 because of Go modules) -$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') - endif - else - # This repository isn't using Go modules (yet). - GOVENDOR := $(FIRST_GOPATH)/bin/govendor - endif -endif PROMU := $(FIRST_GOPATH)/bin/promu pkgs = ./... @@ -78,17 +55,26 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.12.0 +PROMU_VERSION ?= 0.14.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz +SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.39.0 +GOLANGCI_LINT_VERSION ?= v1.49.0 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) - GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + # If we're in CI and there is an Actions file, that means the linter + # is being run in Actions, so we don't need to run it here. + ifneq (,$(SKIP_GOLANGCI_LINT)) + GOLANGCI_LINT := + else ifeq (,$(CIRCLE_JOB)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + endif endif endif @@ -144,32 +130,25 @@ common-check_license: .PHONY: common-deps common-deps: @echo ">> getting dependencies" -ifdef GO111MODULE - GO111MODULE=$(GO111MODULE) $(GO) mod download -else - $(GO) get $(GOOPTS) -t ./... -endif + $(GO) mod download .PHONY: update-go-deps update-go-deps: @echo ">> updating Go dependencies" @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ - $(GO) get $$m; \ + $(GO) get -d $$m; \ done - GO111MODULE=$(GO111MODULE) $(GO) mod tidy -ifneq (,$(wildcard vendor)) - GO111MODULE=$(GO111MODULE) $(GO) mod vendor -endif + $(GO) mod tidy .PHONY: common-test-short common-test-short: $(GOTEST_DIR) @echo ">> running short tests" - GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs) + $(GOTEST) -short $(GOOPTS) $(pkgs) .PHONY: common-test common-test: $(GOTEST_DIR) @echo ">> running all tests" - GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) + $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) $(GOTEST_DIR): @mkdir -p $@ @@ -177,25 +156,21 @@ $(GOTEST_DIR): .PHONY: common-format common-format: @echo ">> formatting code" - GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) + $(GO) fmt $(pkgs) .PHONY: common-vet common-vet: @echo ">> vetting code" - GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) + $(GO) vet $(GOOPTS) $(pkgs) .PHONY: common-lint common-lint: $(GOLANGCI_LINT) ifdef GOLANGCI_LINT @echo ">> running golangci-lint" -ifdef GO111MODULE # 'go list' needs to be executed before staticcheck to prepopulate the modules cache. # Otherwise staticcheck might fail randomly for some reason not yet explained. - GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null - GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) -else - $(GOLANGCI_LINT) run $(pkgs) -endif + $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null + $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) endif .PHONY: common-yamllint @@ -212,28 +187,15 @@ endif common-staticcheck: lint .PHONY: common-unused -common-unused: $(GOVENDOR) -ifdef GOVENDOR - @echo ">> running check for unused packages" - @$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' -else -ifdef GO111MODULE +common-unused: @echo ">> running check for unused/missing packages in go.mod" - GO111MODULE=$(GO111MODULE) $(GO) mod tidy -ifeq (,$(wildcard vendor)) + $(GO) mod tidy @git diff --exit-code -- go.sum go.mod -else - @echo ">> running check for unused packages in vendor/" - GO111MODULE=$(GO111MODULE) $(GO) mod vendor - @git diff --exit-code -- go.sum go.mod vendor/ -endif -endif -endif .PHONY: common-build common-build: promu @echo ">> building binaries" - GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) + $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) .PHONY: common-tarball common-tarball: promu @@ -289,12 +251,6 @@ $(GOLANGCI_LINT): | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) endif -ifdef GOVENDOR -.PHONY: $(GOVENDOR) -$(GOVENDOR): - GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor -endif - .PHONY: precheck precheck:: diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md index 67741f015a..fed02d85c7 100644 --- a/vendor/github.com/prometheus/procfs/SECURITY.md +++ b/vendor/github.com/prometheus/procfs/SECURITY.md @@ -3,4 +3,4 @@ The Prometheus security policy, including how to report vulnerabilities, can be found here: -https://prometheus.io/docs/operating/security/ + diff --git a/vendor/github.com/prometheus/procfs/arp.go b/vendor/github.com/prometheus/procfs/arp.go index 4e47e61720..68f36e888f 100644 --- a/vendor/github.com/prometheus/procfs/arp.go +++ b/vendor/github.com/prometheus/procfs/arp.go @@ -15,11 +15,28 @@ package procfs import ( "fmt" - "io/ioutil" "net" + "os" + "strconv" "strings" ) +// Learned from include/uapi/linux/if_arp.h. +const ( + // completed entry (ha valid). + ATFComplete = 0x02 + // permanent entry. + ATFPermanent = 0x04 + // Publish entry. + ATFPublish = 0x08 + // Has requested trailers. + ATFUseTrailers = 0x10 + // Obsoleted: Want to use a netmask (only for proxy entries). + ATFNetmask = 0x20 + // Don't answer this addresses. + ATFDontPublish = 0x40 +) + // ARPEntry contains a single row of the columnar data represented in // /proc/net/arp. type ARPEntry struct { @@ -29,12 +46,14 @@ type ARPEntry struct { HWAddr net.HardwareAddr // Name of the device Device string + // Flags + Flags byte } // GatherARPEntries retrieves all the ARP entries, parse the relevant columns, // and then return a slice of ARPEntry's. func (fs FS) GatherARPEntries() ([]ARPEntry, error) { - data, err := ioutil.ReadFile(fs.proc.Path("net/arp")) + data, err := os.ReadFile(fs.proc.Path("net/arp")) if err != nil { return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err) } @@ -72,14 +91,26 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) { } func parseARPEntry(columns []string) (ARPEntry, error) { + entry := ARPEntry{Device: columns[5]} ip := net.ParseIP(columns[0]) - mac := net.HardwareAddr(columns[3]) + entry.IPAddr = ip + + if mac, err := net.ParseMAC(columns[3]); err == nil { + entry.HWAddr = mac + } else { + return ARPEntry{}, err + } - entry := ARPEntry{ - IPAddr: ip, - HWAddr: mac, - Device: columns[5], + if flags, err := strconv.ParseUint(columns[2], 0, 8); err == nil { + entry.Flags = byte(flags) + } else { + return ARPEntry{}, err } return entry, nil } + +// IsComplete returns true if ARP entry is marked with complete flag. +func (entry *ARPEntry) IsComplete() bool { + return entry.Flags&ATFComplete != 0 +} diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go index 5623b24a16..06968ca2ed 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux // +build linux package procfs @@ -27,7 +28,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// CPUInfo contains general information about a system CPU found in /proc/cpuinfo +// CPUInfo contains general information about a system CPU found in /proc/cpuinfo. type CPUInfo struct { Processor uint VendorID string @@ -379,6 +380,42 @@ func parseCPUInfoMips(info []byte) ([]CPUInfo, error) { return cpuinfo, nil } +func parseCPUInfoLoong(info []byte) ([]CPUInfo, error) { + scanner := bufio.NewScanner(bytes.NewReader(info)) + // find the first "processor" line + firstLine := firstNonEmptyLine(scanner) + if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") { + return nil, errors.New("invalid cpuinfo file: " + firstLine) + } + field := strings.SplitN(firstLine, ": ", 2) + cpuinfo := []CPUInfo{} + systemType := field[1] + i := 0 + for scanner.Scan() { + line := scanner.Text() + if !strings.Contains(line, ":") { + continue + } + field := strings.SplitN(line, ": ", 2) + switch strings.TrimSpace(field[0]) { + case "processor": + v, err := strconv.ParseUint(field[1], 0, 32) + if err != nil { + return nil, err + } + i = int(v) + cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor + cpuinfo[i].Processor = uint(v) + cpuinfo[i].VendorID = systemType + case "CPU Family": + cpuinfo[i].CPUFamily = field[1] + case "Model Name": + cpuinfo[i].ModelName = field[1] + } + } + return cpuinfo, nil +} + func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) { scanner := bufio.NewScanner(bytes.NewReader(info)) @@ -469,7 +506,7 @@ func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode } // firstNonEmptyLine advances the scanner to the first non-empty line -// and returns the contents of that line +// and returns the contents of that line. func firstNonEmptyLine(scanner *bufio.Scanner) string { for scanner.Scan() { line := scanner.Text() diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go index 44b590ed38..64cfd534c1 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (arm || arm64) // +build linux // +build arm arm64 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go new file mode 100644 index 0000000000..d88442f0ed --- /dev/null +++ b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go @@ -0,0 +1,19 @@ +// Copyright 2022 The Prometheus 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. + +//go:build linux +// +build linux + +package procfs + +var parseCPUInfo = parseCPUInfoLoong diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go index 91e272573a..c11207f3ab 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (mips || mipsle || mips64 || mips64le) // +build linux // +build mips mipsle mips64 mips64le diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go index 95b5b4ec44..a6b2b3127c 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_others.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux -// +build !386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x +//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x +// +build linux,!386,!amd64,!arm,!arm64,!loong64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x package procfs diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go index 6068bd571c..003bc2ad4a 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (ppc64 || ppc64le) // +build linux // +build ppc64 ppc64le diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go index e83c2e207c..1c9b7313b6 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (riscv || riscv64) // +build linux // +build riscv riscv64 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go index 26814eebaa..fa3686bc00 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux // +build linux package procfs diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go index d5bedf97f3..a0ef55562e 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (386 || amd64) // +build linux // +build 386 amd64 diff --git a/vendor/github.com/prometheus/procfs/doc.go b/vendor/github.com/prometheus/procfs/doc.go index d31a82600f..f9d961e441 100644 --- a/vendor/github.com/prometheus/procfs/doc.go +++ b/vendor/github.com/prometheus/procfs/doc.go @@ -16,30 +16,29 @@ // // Example: // -// package main -// -// import ( -// "fmt" -// "log" -// -// "github.com/prometheus/procfs" -// ) -// -// func main() { -// p, err := procfs.Self() -// if err != nil { -// log.Fatalf("could not get process: %s", err) -// } -// -// stat, err := p.Stat() -// if err != nil { -// log.Fatalf("could not get process stat: %s", err) -// } -// -// fmt.Printf("command: %s\n", stat.Comm) -// fmt.Printf("cpu time: %fs\n", stat.CPUTime()) -// fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) -// fmt.Printf("rss: %dB\n", stat.ResidentMemory()) -// } -// +// package main +// +// import ( +// "fmt" +// "log" +// +// "github.com/prometheus/procfs" +// ) +// +// func main() { +// p, err := procfs.Self() +// if err != nil { +// log.Fatalf("could not get process: %s", err) +// } +// +// stat, err := p.Stat() +// if err != nil { +// log.Fatalf("could not get process stat: %s", err) +// } +// +// fmt.Printf("command: %s\n", stat.Comm) +// fmt.Printf("cpu time: %fs\n", stat.CPUTime()) +// fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) +// fmt.Printf("rss: %dB\n", stat.ResidentMemory()) +// } package procfs diff --git a/vendor/github.com/prometheus/procfs/fixtures.ttar b/vendor/github.com/prometheus/procfs/fixtures.ttar deleted file mode 100644 index 5e7eeef4a5..0000000000 --- a/vendor/github.com/prometheus/procfs/fixtures.ttar +++ /dev/null @@ -1,7673 +0,0 @@ -# Archive created by ttar -c -f fixtures.ttar fixtures/ -Directory: fixtures -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/cmdline -Lines: 1 -vimNULLBYTEtest.goNULLBYTE+10NULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/comm -Lines: 1 -vim -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/cwd -SymlinkTo: /usr/bin -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/environ -Lines: 1 -PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNULLBYTEHOSTNAME=cd24e11f73a5NULLBYTETERM=xtermNULLBYTEGOLANG_VERSION=1.12.5NULLBYTEGOPATH=/goNULLBYTEHOME=/rootNULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/exe -SymlinkTo: /usr/bin/vim -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/fd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/0 -SymlinkTo: ../../symlinktargets/abc -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/1 -SymlinkTo: ../../symlinktargets/def -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/10 -SymlinkTo: ../../symlinktargets/xyz -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/2 -SymlinkTo: ../../symlinktargets/ghi -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/3 -SymlinkTo: ../../symlinktargets/uvw -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/fdinfo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/0 -Lines: 6 -pos: 0 -flags: 02004000 -mnt_id: 13 -inotify wd:3 ino:1 sdev:34 mask:fce ignored_mask:0 fhandle-bytes:c fhandle-type:81 f_handle:000000000100000000000000 -inotify wd:2 ino:1300016 sdev:fd00002 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:16003001ed3f022a -inotify wd:1 ino:2e0001 sdev:fd00000 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01002e00138e7c65 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/1 -Lines: 4 -pos: 0 -flags: 02004002 -mnt_id: 13 -eventfd-count: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/10 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/2 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/3 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/io -Lines: 7 -rchar: 750339 -wchar: 818609 -syscr: 7405 -syscw: 5245 -read_bytes: 1024 -write_bytes: 2048 -cancelled_write_bytes: -1024 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/limits -Lines: 17 -Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 62898 62898 processes -Max open files 2048 4096 files -Max locked memory 18446744073708503040 18446744073708503040 bytes -Max address space 8589934592 unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 62898 62898 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/mountstats -Lines: 20 -device rootfs mounted on / with fstype rootfs -device sysfs mounted on /sys with fstype sysfs -device proc mounted on /proc with fstype proc -device /dev/sda1 mounted on / with fstype ext4 -device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1 - opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,clientaddr=192.168.1.5,local_lock=none - age: 13968 - caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 - nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured - sec: flavor=1,pseudoflavor=1 - events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 - bytes: 1207640230 0 0 0 1210214218 0 295483 0 - RPC iostats version: 1.0 p/v: 100003/4 (nfs) - xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 - per-op statistics - NULL: 0 0 0 0 0 0 0 0 - READ: 1298 1298 0 207680 1210292152 6 79386 79407 - WRITE: 0 0 0 0 0 0 0 0 - ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/net -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/net/dev -Lines: 4 -Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed - lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - eth0: 438 5 0 0 0 0 0 0 648 8 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/ns -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/ns/mnt -SymlinkTo: mnt:[4026531840] -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/ns/net -SymlinkTo: net:[4026531993] -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/root -SymlinkTo: / -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/schedstat -Lines: 1 -411605849 93680043 79 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/smaps -Lines: 252 -00400000-00cb1000 r-xp 00000000 fd:01 952273 /bin/alertmanager -Size: 8900 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 2952 kB -Pss: 2952 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 2952 kB -Private_Dirty: 0 kB -Referenced: 2864 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex mr mw me dw sd -00cb1000-016b0000 r--p 008b1000 fd:01 952273 /bin/alertmanager -Size: 10236 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 6152 kB -Pss: 6152 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 6152 kB -Private_Dirty: 0 kB -Referenced: 5308 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd mr mw me dw sd -016b0000-0171a000 rw-p 012b0000 fd:01 952273 /bin/alertmanager -Size: 424 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 176 kB -Pss: 176 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 84 kB -Private_Dirty: 92 kB -Referenced: 176 kB -Anonymous: 92 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 12 kB -SwapPss: 12 kB -Locked: 0 kB -VmFlags: rd wr mr mw me dw ac sd -0171a000-0173f000 rw-p 00000000 00:00 0 -Size: 148 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 76 kB -Pss: 76 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 76 kB -Referenced: 76 kB -Anonymous: 76 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -c000000000-c000400000 rw-p 00000000 00:00 0 -Size: 4096 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 2564 kB -Pss: 2564 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 20 kB -Private_Dirty: 2544 kB -Referenced: 2544 kB -Anonymous: 2564 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 1100 kB -SwapPss: 1100 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -c000400000-c001600000 rw-p 00000000 00:00 0 -Size: 18432 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 16024 kB -Pss: 16024 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 5864 kB -Private_Dirty: 10160 kB -Referenced: 11944 kB -Anonymous: 16024 kB -LazyFree: 5848 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 440 kB -SwapPss: 440 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd nh -c001600000-c004000000 rw-p 00000000 00:00 0 -Size: 43008 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -7f0ab95ca000-7f0abbb7b000 rw-p 00000000 00:00 0 -Size: 38596 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 1992 kB -Pss: 1992 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 476 kB -Private_Dirty: 1516 kB -Referenced: 1828 kB -Anonymous: 1992 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 384 kB -SwapPss: 384 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -7ffc07ecf000-7ffc07ef0000 rw-p 00000000 00:00 0 [stack] -Size: 132 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 8 kB -Pss: 8 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 8 kB -Referenced: 8 kB -Anonymous: 8 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 4 kB -SwapPss: 4 kB -Locked: 0 kB -VmFlags: rd wr mr mw me gd ac -7ffc07f9e000-7ffc07fa1000 r--p 00000000 00:00 0 [vvar] -Size: 12 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd mr pf io de dd sd -7ffc07fa1000-7ffc07fa3000 r-xp 00000000 00:00 0 [vdso] -Size: 8 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 4 kB -Pss: 0 kB -Shared_Clean: 4 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 4 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex mr mw me de sd -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] -Size: 4 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/smaps_rollup -Lines: 17 -00400000-ffffffffff601000 ---p 00000000 00:00 0 [rollup] -Rss: 29948 kB -Pss: 29944 kB -Shared_Clean: 4 kB -Shared_Dirty: 0 kB -Private_Clean: 15548 kB -Private_Dirty: 14396 kB -Referenced: 24752 kB -Anonymous: 20756 kB -LazyFree: 5848 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 1940 kB -SwapPss: 1940 kB -Locked: 0 kB -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/stat -Lines: 1 -26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/status -Lines: 53 - -Name: prometheus -Umask: 0022 -State: S (sleeping) -Tgid: 26231 -Ngid: 0 -Pid: 26231 -PPid: 1 -TracerPid: 0 -Uid: 1000 1000 1000 0 -Gid: 1001 1001 1001 0 -FDSize: 128 -Groups: -NStgid: 1 -NSpid: 1 -NSpgid: 1 -NSsid: 1 -VmPeak: 58472 kB -VmSize: 58440 kB -VmLck: 0 kB -VmPin: 0 kB -VmHWM: 8028 kB -VmRSS: 6716 kB -RssAnon: 2092 kB -RssFile: 4624 kB -RssShmem: 0 kB -VmData: 2580 kB -VmStk: 136 kB -VmExe: 948 kB -VmLib: 6816 kB -VmPTE: 128 kB -VmPMD: 12 kB -VmSwap: 660 kB -HugetlbPages: 0 kB -Threads: 1 -SigQ: 8/63965 -SigPnd: 0000000000000000 -ShdPnd: 0000000000000000 -SigBlk: 7be3c0fe28014a03 -SigIgn: 0000000000001000 -SigCgt: 00000001800004ec -CapInh: 0000000000000000 -CapPrm: 0000003fffffffff -CapEff: 0000003fffffffff -CapBnd: 0000003fffffffff -CapAmb: 0000000000000000 -Seccomp: 0 -Cpus_allowed: ff -Cpus_allowed_list: 0-7 -Mems_allowed: 00000000,00000001 -Mems_allowed_list: 0 -voluntary_ctxt_switches: 4742839 -nonvoluntary_ctxt_switches: 1727500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/wchan -Lines: 1 -poll_schedule_timeoutEOF -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26232 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/cmdline -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/comm -Lines: 1 -ata_sff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/cwd -SymlinkTo: /does/not/exist -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26232/fd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/0 -SymlinkTo: ../../symlinktargets/abc -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/1 -SymlinkTo: ../../symlinktargets/def -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/2 -SymlinkTo: ../../symlinktargets/ghi -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/3 -SymlinkTo: ../../symlinktargets/uvw -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/4 -SymlinkTo: ../../symlinktargets/xyz -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/limits -Lines: 17 -Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 29436 29436 processes -Max open files 1024 4096 files -Max locked memory 65536 65536 bytes -Max address space unlimited unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 29436 29436 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/maps -Lines: 9 -55680ae1e000-55680ae20000 r--p 00000000 fd:01 47316994 /bin/cat -55680ae29000-55680ae2a000 rwxs 0000a000 fd:01 47316994 /bin/cat -55680bed6000-55680bef7000 rw-p 00000000 00:00 0 [heap] -7fdf964fc000-7fdf973f2000 r--p 00000000 fd:01 17432624 /usr/lib/locale/locale-archive -7fdf973f2000-7fdf97417000 r--p 00000000 fd:01 60571062 /lib/x86_64-linux-gnu/libc-2.29.so -7ffe9215c000-7ffe9217f000 rw-p 00000000 00:00 0 [stack] -7ffe921da000-7ffe921dd000 r--p 00000000 00:00 0 [vvar] -7ffe921dd000-7ffe921de000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/root -SymlinkTo: /does/not/exist -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/stat -Lines: 1 -33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/wchan -Lines: 1 -0EOF -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26233 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26233/cmdline -Lines: 1 -com.github.uiautomatorNULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26233/schedstat -Lines: 8 - ____________________________________ -< this is a malformed schedstat file > - ------------------------------------ - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26234 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26234/maps -Lines: 4 -08048000-08089000 r-xp 00000000 03:01 104219 /bin/tcsh -08089000-0808c000 rw-p 00041000 03:01 104219 /bin/tcsh -0808c000-08146000 rwxp 00000000 00:00 0 -40000000-40015000 r-xp 00000000 03:01 61874 /lib/ld-2.3.2.so -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/584 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/584/stat -Lines: 2 -1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0 -#!/bin/cat /proc/self/stat -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/buddyinfo -Lines: 3 -Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3 -Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0 -Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/cmdline -Lines: 1 -BOOT_IMAGE=/vmlinuz-5.11.0-22-generic root=UUID=456a0345-450d-4f7b-b7c9-43e3241d99ad ro quiet splash vt.handoff=7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/cpuinfo -Lines: 216 -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 799.998 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 0 -cpu cores : 4 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.037 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 1 -cpu cores : 4 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.010 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 2 -cpu cores : 4 -apicid : 4 -initial apicid : 4 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.028 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 3 -cpu cores : 4 -apicid : 6 -initial apicid : 6 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 4 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 799.989 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 0 -cpu cores : 4 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 5 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.083 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 1 -cpu cores : 4 -apicid : 3 -initial apicid : 3 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 6 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.017 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 2 -cpu cores : 4 -apicid : 5 -initial apicid : 5 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 7 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.030 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 3 -cpu cores : 4 -apicid : 7 -initial apicid : 7 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/crypto -Lines: 972 -name : ccm(aes) -driver : ccm_base(ctr(aes-aesni),cbcmac(aes-aesni)) -module : ccm -priority : 300 -refcnt : 4 -selftest : passed -internal : no -type : aead -async : no -blocksize : 1 -ivsize : 16 -maxauthsize : 16 -geniv : - -name : cbcmac(aes) -driver : cbcmac(aes-aesni) -module : ccm -priority : 300 -refcnt : 7 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 16 - -name : ecdh -driver : ecdh-generic -module : ecdh_generic -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : kpp -async : yes - -name : ecb(arc4) -driver : ecb(arc4)-generic -module : arc4 -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 1 -max keysize : 256 -ivsize : 0 -chunksize : 1 -walksize : 1 - -name : arc4 -driver : arc4-generic -module : arc4 -priority : 0 -refcnt : 3 -selftest : passed -internal : no -type : cipher -blocksize : 1 -min keysize : 1 -max keysize : 256 - -name : crct10dif -driver : crct10dif-pclmul -module : crct10dif_pclmul -priority : 200 -refcnt : 2 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 2 - -name : crc32 -driver : crc32-pclmul -module : crc32_pclmul -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : __ghash -driver : cryptd(__ghash-pclmulqdqni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : ahash -async : yes -blocksize : 16 -digestsize : 16 - -name : ghash -driver : ghash-clmulni -module : ghash_clmulni_intel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : ahash -async : yes -blocksize : 16 -digestsize : 16 - -name : __ghash -driver : __ghash-pclmulqdqni -module : ghash_clmulni_intel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : shash -blocksize : 16 -digestsize : 16 - -name : crc32c -driver : crc32c-intel -module : crc32c_intel -priority : 200 -refcnt : 5 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : cbc(aes) -driver : cbc(aes-aesni) -module : kernel -priority : 300 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : ctr(aes) -driver : ctr(aes-aesni) -module : kernel -priority : 300 -refcnt : 5 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : pkcs1pad(rsa,sha256) -driver : pkcs1pad(rsa-generic,sha256) -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : akcipher - -name : __xts(aes) -driver : cryptd(__xts-aes-aesni) -module : kernel -priority : 451 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : xts(aes) -driver : xts-aes-aesni -module : kernel -priority : 401 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ctr(aes) -driver : cryptd(__ctr-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 1 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : ctr(aes) -driver : ctr-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __cbc(aes) -driver : cryptd(__cbc-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : cbc(aes) -driver : cbc-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ecb(aes) -driver : cryptd(__ecb-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : ecb(aes) -driver : ecb-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : __generic-gcm-aes-aesni -driver : cryptd(__driver-generic-gcm-aes-aesni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : yes -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : gcm(aes) -driver : generic-gcm-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : aead -async : yes -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : __generic-gcm-aes-aesni -driver : __driver-generic-gcm-aes-aesni -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : no -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : __gcm-aes-aesni -driver : cryptd(__driver-gcm-aes-aesni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : yes -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : rfc4106(gcm(aes)) -driver : rfc4106-gcm-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : aead -async : yes -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : __gcm-aes-aesni -driver : __driver-gcm-aes-aesni -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : no -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : __xts(aes) -driver : __xts-aes-aesni -module : kernel -priority : 401 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ctr(aes) -driver : __ctr-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __cbc(aes) -driver : __cbc-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ecb(aes) -driver : __ecb-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : __aes -driver : __aes-aesni -module : kernel -priority : 300 -refcnt : 1 -selftest : passed -internal : yes -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : aes -driver : aes-aesni -module : kernel -priority : 300 -refcnt : 8 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : hmac(sha1) -driver : hmac(sha1-generic) -module : kernel -priority : 100 -refcnt : 9 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 20 - -name : ghash -driver : ghash-generic -module : kernel -priority : 100 -refcnt : 3 -selftest : passed -internal : no -type : shash -blocksize : 16 -digestsize : 16 - -name : jitterentropy_rng -driver : jitterentropy_rng -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha256 -module : kernel -priority : 221 -refcnt : 2 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha512 -module : kernel -priority : 220 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha384 -module : kernel -priority : 219 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha1 -module : kernel -priority : 218 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha256 -module : kernel -priority : 217 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha512 -module : kernel -priority : 216 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha384 -module : kernel -priority : 215 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha1 -module : kernel -priority : 214 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes256 -module : kernel -priority : 213 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes192 -module : kernel -priority : 212 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes128 -module : kernel -priority : 211 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : hmac(sha256) -driver : hmac(sha256-generic) -module : kernel -priority : 100 -refcnt : 10 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 32 - -name : stdrng -driver : drbg_pr_hmac_sha256 -module : kernel -priority : 210 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha512 -module : kernel -priority : 209 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha384 -module : kernel -priority : 208 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha1 -module : kernel -priority : 207 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha256 -module : kernel -priority : 206 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha512 -module : kernel -priority : 205 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha384 -module : kernel -priority : 204 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha1 -module : kernel -priority : 203 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes256 -module : kernel -priority : 202 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes192 -module : kernel -priority : 201 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes128 -module : kernel -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : 842 -driver : 842-scomp -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : 842 -driver : 842-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : lzo-rle -driver : lzo-rle-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : lzo-rle -driver : lzo-rle-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : lzo -driver : lzo-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : lzo -driver : lzo-generic -module : kernel -priority : 0 -refcnt : 9 -selftest : passed -internal : no -type : compression - -name : crct10dif -driver : crct10dif-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 2 - -name : crc32c -driver : crc32c-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : zlib-deflate -driver : zlib-deflate-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : deflate -driver : deflate-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : deflate -driver : deflate-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : aes -driver : aes-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : sha224 -driver : sha224-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 28 - -name : sha256 -driver : sha256-generic -module : kernel -priority : 100 -refcnt : 11 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 32 - -name : sha1 -driver : sha1-generic -module : kernel -priority : 100 -refcnt : 11 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 20 - -name : md5 -driver : md5-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 16 - -name : ecb(cipher_null) -driver : ecb-cipher_null -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 0 -max keysize : 0 -ivsize : 0 -chunksize : 1 -walksize : 1 - -name : digest_null -driver : digest_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 0 - -name : compress_null -driver : compress_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : cipher_null -driver : cipher_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 1 -min keysize : 0 -max keysize : 0 - -name : rsa -driver : rsa-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : akcipher - -name : dh -driver : dh-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : kpp - -name : aes -driver : aes-asm -module : kernel -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -Mode: 444 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/diskstats -Lines: 52 - 1 0 ram0 0 0 0 0 0 0 0 0 0 0 0 - 1 1 ram1 0 0 0 0 0 0 0 0 0 0 0 - 1 2 ram2 0 0 0 0 0 0 0 0 0 0 0 - 1 3 ram3 0 0 0 0 0 0 0 0 0 0 0 - 1 4 ram4 0 0 0 0 0 0 0 0 0 0 0 - 1 5 ram5 0 0 0 0 0 0 0 0 0 0 0 - 1 6 ram6 0 0 0 0 0 0 0 0 0 0 0 - 1 7 ram7 0 0 0 0 0 0 0 0 0 0 0 - 1 8 ram8 0 0 0 0 0 0 0 0 0 0 0 - 1 9 ram9 0 0 0 0 0 0 0 0 0 0 0 - 1 10 ram10 0 0 0 0 0 0 0 0 0 0 0 - 1 11 ram11 0 0 0 0 0 0 0 0 0 0 0 - 1 12 ram12 0 0 0 0 0 0 0 0 0 0 0 - 1 13 ram13 0 0 0 0 0 0 0 0 0 0 0 - 1 14 ram14 0 0 0 0 0 0 0 0 0 0 0 - 1 15 ram15 0 0 0 0 0 0 0 0 0 0 0 - 7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 - 7 1 loop1 0 0 0 0 0 0 0 0 0 0 0 - 7 2 loop2 0 0 0 0 0 0 0 0 0 0 0 - 7 3 loop3 0 0 0 0 0 0 0 0 0 0 0 - 7 4 loop4 0 0 0 0 0 0 0 0 0 0 0 - 7 5 loop5 0 0 0 0 0 0 0 0 0 0 0 - 7 6 loop6 0 0 0 0 0 0 0 0 0 0 0 - 7 7 loop7 0 0 0 0 0 0 0 0 0 0 0 - 8 0 sda 25354637 34367663 1003346126 18492372 28444756 11134226 505697032 63877960 0 9653880 82621804 - 8 1 sda1 250 0 2000 36 0 0 0 0 0 36 36 - 8 2 sda2 246 0 1968 32 0 0 0 0 0 32 32 - 8 3 sda3 340 13 2818 52 11 8 152 8 0 56 60 - 8 4 sda4 25353629 34367650 1003337964 18492232 27448755 11134218 505696880 61593380 0 7576432 80332428 - 252 0 dm-0 59910002 0 1003337218 46229572 39231014 0 505696880 1158557800 0 11325968 1206301256 - 252 1 dm-1 388 0 3104 84 74 0 592 0 0 76 84 - 252 2 dm-2 11571 0 308350 6536 153522 0 5093416 122884 0 65400 129416 - 252 3 dm-3 3870 0 3870 104 0 0 0 0 0 16 104 - 252 4 dm-4 392 0 1034 28 38 0 137 16 0 24 44 - 252 5 dm-5 3729 0 84279 924 98918 0 1151688 104684 0 58848 105632 - 179 0 mmcblk0 192 3 1560 156 0 0 0 0 0 136 156 - 179 1 mmcblk0p1 17 3 160 24 0 0 0 0 0 24 24 - 179 2 mmcblk0p2 95 0 760 68 0 0 0 0 0 68 68 - 2 0 fd0 2 0 16 80 0 0 0 0 0 80 80 - 254 0 vda 1775784 15386 32670882 8655768 6038856 20711856 213637440 2069221364 0 41614592 2077872228 - 254 1 vda1 668 85 5984 956 207 4266 35784 32772 0 8808 33720 - 254 2 vda2 1774936 15266 32663262 8654692 5991028 20707590 213601656 2069152216 0 41607628 2077801992 - 11 0 sr0 0 0 0 0 0 0 0 0 0 0 0 - 259 0 nvme0n1 47114 4 4643973 21650 1078320 43950 39451633 1011053 0 222766 1032546 - 259 1 nvme0n1p1 1140 0 9370 16 1 0 1 0 0 16 16 - 259 2 nvme0n1p2 45914 4 4631243 21626 1036885 43950 39451632 919480 0 131580 940970 - 8 0 sdb 326552 841 9657779 84 41822 2895 1972905 5007 0 60730 67070 68851 0 1925173784 11130 - 8 1 sdb1 231 3 34466 4 24 23 106 0 0 64 64 0 0 0 0 - 8 2 sdb2 326310 838 9622281 67 40726 2872 1972799 4924 0 58250 64567 68851 0 1925173784 11130 - 8 0 sdc 14202 71 579164 21861 2995 1589 180500 40875 0 11628 55200 0 0 0 0 127 182 - 8 1 sdc1 1027 0 13795 5021 2 0 4096 3 0 690 4579 0 0 0 0 0 0 - 8 2 sdc2 13126 71 561749 16802 2830 1589 176404 40620 0 10931 50449 0 0 0 0 0 0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs/fscache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/fs/fscache/stats -Lines: 24 -FS-Cache statistics -Cookies: idx=3 dat=67877 spc=0 -Objects: alc=67473 nal=0 avl=67473 ded=388 -ChkAux : non=12 ok=33 upd=44 obs=55 -Pages : mrk=547164 unc=364577 -Acquire: n=67880 nul=98 noc=25 ok=67780 nbf=39 oom=26 -Lookups: n=67473 neg=67470 pos=58 crt=67473 tmo=85 -Invals : n=14 run=13 -Updates: n=7 nul=3 run=8 -Relinqs: n=394 nul=1 wcr=2 rtr=3 -AttrChg: n=6 ok=5 nbf=4 oom=3 run=2 -Allocs : n=20 ok=19 wt=18 nbf=17 int=16 -Allocs : ops=15 owt=14 abt=13 -Retrvls: n=151959 ok=82823 wt=23467 nod=69136 nbf=15 int=69 oom=43 -Retrvls: ops=151959 owt=42747 abt=44 -Stores : n=225565 ok=225565 agn=12 nbf=13 oom=14 -Stores : ops=69156 run=294721 pgs=225565 rxd=225565 olm=43 -VmScan : nos=364512 gon=2 bsy=43 can=12 wt=66 -Ops : pend=42753 run=221129 enq=628798 can=11 rej=88 -Ops : ini=377538 dfr=27 rel=377538 gc=37 -CacheOp: alo=1 luo=2 luc=3 gro=4 -CacheOp: inv=5 upo=6 dro=7 pto=8 atc=9 syn=10 -CacheOp: rap=11 ras=12 alp=13 als=14 wrp=15 ucp=16 dsp=17 -CacheEv: nsp=18 stl=19 rtr=20 cul=21EOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs/xfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/fs/xfs/stat -Lines: 23 -extent_alloc 92447 97589 92448 93751 -abt 0 0 0 0 -blk_map 1767055 188820 184891 92447 92448 2140766 0 -bmbt 0 0 0 0 -dir 185039 92447 92444 136422 -trans 706 944304 0 -ig 185045 58807 0 126238 0 33637 22 -log 2883 113448 9 17360 739 -push_ail 945014 0 134260 15483 0 3940 464 159985 0 40 -xstrat 92447 0 -rw 107739 94045 -attr 4 0 0 0 -icluster 8677 7849 135802 -vnodes 92601 0 0 0 92444 92444 92444 0 -buf 2666287 7122 2659202 3599 2 7085 0 10297 7085 -abtb2 184941 1277345 13257 13278 0 0 0 0 0 0 0 0 0 0 2746147 -abtc2 345295 2416764 172637 172658 0 0 0 0 0 0 0 0 0 0 21406023 -bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ibt2 343004 1358467 0 0 0 0 0 0 0 0 0 0 0 0 0 -fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -qm 0 0 0 0 0 0 0 0 -xpc 399724544 92823103 86219234 -debug 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/loadavg -Lines: 1 -0.02 0.04 0.05 1/497 11947 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/mdstat -Lines: 60 -Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] - -md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] sdd1[10](S) sdd2[11](S) - 5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU] - -md127 : active raid1 sdi2[0] sdj2[1] - 312319552 blocks [2/2] [UU] - -md0 : active raid1 sdi1[0] sdj1[1] - 248896 blocks [2/2] [UU] - -md4 : inactive raid1 sda3[0](F) sdb3[1](S) - 4883648 blocks [2/2] [UU] - -md6 : active raid1 sdb2[2](F) sdc[1](S) sda2[0] - 195310144 blocks [2/1] [U_] - [=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec - -md8 : active raid1 sdb1[1] sda1[0] sdc[2](S) sde[3](S) - 195310144 blocks [2/2] [UU] - [=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec - -md201 : active raid1 sda3[0] sdb3[1] - 1993728 blocks super 1.2 [2/2] [UU] - [=>...................] check = 5.7% (114176/1993728) finish=0.2min speed=114176K/sec - -md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1](F) - 7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU] - bitmap: 0/30 pages [0KB], 65536KB chunk - -md9 : active raid1 sdc2[2] sdd2[3] sdb2[1] sda2[0] sde[4](F) sdf[5](F) sdg[6](S) - 523968 blocks super 1.2 [4/4] [UUUU] - resync=DELAYED - -md10 : active raid0 sda1[0] sdb1[1] - 314159265 blocks 64k chunks - -md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1] sdc3[2](F) hda[4](S) ssdc2[3](S) - 4190208 blocks super 1.2 [2/2] [UU] - resync=PENDING - -md12 : active raid0 sdc2[0] sdd2[1] - 3886394368 blocks super 1.2 512k chunks - -md126 : active raid0 sdb[1] sdc[0] - 1855870976 blocks super external:/md127/0 128k chunks - -md219 : inactive sdb[2](S) sdc[1](S) sda[0](S) - 7932 blocks super external:imsm - -md00 : active raid0 xvdb[0] - 4186624 blocks super 1.2 256k chunks - -md120 : active linear sda1[1] sdb1[0] - 2095104 blocks super 1.2 0k rounding - -md101 : active (read-only) raid0 sdb[2] sdd[1] sdc[0] - 322560 blocks super 1.2 512k chunks - -unused devices: -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/meminfo -Lines: 42 -MemTotal: 15666184 kB -MemFree: 440324 kB -Buffers: 1020128 kB -Cached: 12007640 kB -SwapCached: 0 kB -Active: 6761276 kB -Inactive: 6532708 kB -Active(anon): 267256 kB -Inactive(anon): 268 kB -Active(file): 6494020 kB -Inactive(file): 6532440 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 768 kB -Writeback: 0 kB -AnonPages: 266216 kB -Mapped: 44204 kB -Shmem: 1308 kB -Slab: 1807264 kB -SReclaimable: 1738124 kB -SUnreclaim: 69140 kB -KernelStack: 1616 kB -PageTables: 5288 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 7833092 kB -Committed_AS: 530844 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 36596 kB -VmallocChunk: 34359637840 kB -HardwareCorrupted: 0 kB -AnonHugePages: 12288 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 91136 kB -DirectMap2M: 16039936 kB -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/arp -Lines: 2 -IP address HW type Flags HW address Mask Device -192.168.224.1 0x1 0x2 00:50:56:c0:00:08 * ens33 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/dev -Lines: 6 -Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed -vethf345468: 648 8 0 0 0 0 0 0 438 5 0 0 0 0 0 0 - lo: 1664039048 1566805 0 0 0 0 0 0 1664039048 1566805 0 0 0 0 0 0 -docker0: 2568 38 0 0 0 0 0 0 438 5 0 0 0 0 0 0 - eth0: 874354587 1036395 0 0 0 0 0 0 563352563 732147 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/ip_vs -Lines: 21 -IP Virtual Server version 1.2.1 (size=4096) -Prot LocalAddress:Port Scheduler Flags - -> RemoteAddress:Port Forward Weight ActiveConn InActConn -TCP C0A80016:0CEA wlc - -> C0A85216:0CEA Tunnel 100 248 2 - -> C0A85318:0CEA Tunnel 100 248 2 - -> C0A85315:0CEA Tunnel 100 248 1 -TCP C0A80039:0CEA wlc - -> C0A85416:0CEA Tunnel 0 0 0 - -> C0A85215:0CEA Tunnel 100 1499 0 - -> C0A83215:0CEA Tunnel 100 1498 0 -TCP C0A80037:0CEA wlc - -> C0A8321A:0CEA Tunnel 0 0 0 - -> C0A83120:0CEA Tunnel 100 0 0 -TCP [2620:0000:0000:0000:0000:0000:0000:0001]:0050 sh - -> [2620:0000:0000:0000:0000:0000:0000:0002]:0050 Route 1 0 0 - -> [2620:0000:0000:0000:0000:0000:0000:0003]:0050 Route 1 0 0 - -> [2620:0000:0000:0000:0000:0000:0000:0004]:0050 Route 1 1 1 -FWM 10001000 wlc - -> C0A8321A:0CEA Route 0 0 1 - -> C0A83215:0CEA Route 0 0 2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/ip_vs_stats -Lines: 6 - Total Incoming Outgoing Incoming Outgoing - Conns Packets Packets Bytes Bytes - 16AA370 E33656E5 0 51D8C8883AB3 0 - - Conns/s Pkts/s Pkts/s Bytes/s Bytes/s - 4 1FB3C 0 1282A8F 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/protocols -Lines: 14 -protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em -PACKET 1344 2 -1 NI 0 no kernel n n n n n n n n n n n n n n n n n n n -PINGv6 1112 0 -1 NI 0 yes kernel y y y n n y n n y y y y n y y y y y n -RAWv6 1112 1 -1 NI 0 yes kernel y y y n y y y n y y y y n y y y y n n -UDPLITEv6 1216 0 57 NI 0 yes kernel y y y n y y y n y y y y n n n y y y n -UDPv6 1216 10 57 NI 0 yes kernel y y y n y y y n y y y y n n n y y y n -TCPv6 2144 1937 1225378 no 320 yes kernel y y y y y y y y y y y y y n y y y y y -UNIX 1024 120 -1 NI 0 yes kernel n n n n n n n n n n n n n n n n n n n -UDP-Lite 1024 0 57 NI 0 yes kernel y y y n y y y n y y y y y n n y y y n -PING 904 0 -1 NI 0 yes kernel y y y n n y n n y y y y n y y y y y n -RAW 912 0 -1 NI 0 yes kernel y y y n y y y n y y y y n y y y y n n -UDP 1024 73 57 NI 0 yes kernel y y y n y y y n y y y y y n n y y y n -TCP 1984 93064 1225378 yes 320 yes kernel y y y y y y y y y y y y y n y y y y y -NETLINK 1040 16 -1 NI 0 no kernel n n n n n n n n n n n n n n n n n n n -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net/rpc -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/rpc/nfs -Lines: 5 -net 18628 0 18628 6 -rpc 4329785 0 4338291 -proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 -proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39 -proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/rpc/nfsd -Lines: 11 -rc 0 6 18622 -fh 0 0 0 0 0 -io 157286400 0 -th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 -ra 32 0 0 0 0 0 0 0 0 0 0 0 -net 18628 0 18628 6 -rpc 18628 0 0 0 0 -proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 -proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0 -proc4 2 2 10853 -proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/sockstat -Lines: 6 -sockets: used 1602 -TCP: inuse 35 orphan 0 tw 4 alloc 59 mem 22 -UDP: inuse 12 mem 62 -UDPLITE: inuse 0 -RAW: inuse 0 -FRAG: inuse 0 memory 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/sockstat6 -Lines: 5 -TCP6: inuse 17 -UDP6: inuse 9 -UDPLITE6: inuse 0 -RAW6: inuse 1 -FRAG6: inuse 0 memory 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/softnet_stat -Lines: 2 -00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/softnet_stat.broken -Lines: 1 -00015c73 00020e76 F0000769 00000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net/stat -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/stat/arp_cache -Lines: 3 -entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls -00000014 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 00000009 0000000a 0000000b 0000000c -00000014 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/stat/ndisc_cache -Lines: 3 -entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls -00000024 000000f0 000000f1 000000f2 000000f3 000000f4 000000f5 000000f6 000000f7 000000f8 000000f9 000000fa 000000fb -00000024 000000fc 000000fd 000000fe 000000ff 00000100 00000101 00000102 00000103 00000104 00000105 00000106 00000107 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/tcp -Lines: 4 - sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 0500000A:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 1: 00000000:0016 00000000:0000 0A 00000001:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 2: 00000000:0016 00000000:0000 0A 00000001:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/tcp6 -Lines: 3 - sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops - 1315: 00000000000000000000000000000000:14EB 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 981 0 21040 2 0000000013726323 0 - 6073: 000080FE00000000FFADE15609667CFE:C781 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 11337031 2 00000000b9256fdd 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp -Lines: 4 - sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 0500000A:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 1: 00000000:0016 00000000:0000 0A 00000001:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 2: 00000000:0016 00000000:0000 0A 00000001:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp6 -Lines: 3 - sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops - 1315: 00000000000000000000000000000000:14EB 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 981 0 21040 2 0000000013726323 0 - 6073: 000080FE00000000FFADE15609667CFE:C781 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 11337031 2 00000000b9256fdd 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp_broken -Lines: 2 - sl local_address rem_address st - 1: 00000000:0016 00000000:0000 0A -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/unix -Lines: 6 -Num RefCount Protocol Flags Type St Inode Path -0000000000000000: 00000002 00000000 00010000 0001 01 3442596 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 0000000a 00000000 00010000 0005 01 10061 /run/udev/control -0000000000000000: 00000007 00000000 00000000 0002 01 12392 /dev/log -0000000000000000: 00000003 00000000 00000000 0001 03 4787297 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 00000003 00000000 00000000 0001 03 5091797 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/unix_without_inode -Lines: 6 -Num RefCount Protocol Flags Type St Path -0000000000000000: 00000002 00000000 00010000 0001 01 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 0000000a 00000000 00010000 0005 01 /run/udev/control -0000000000000000: 00000007 00000000 00000000 0002 01 /dev/log -0000000000000000: 00000003 00000000 00000000 0001 03 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 00000003 00000000 00000000 0001 03 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/xfrm_stat -Lines: 28 -XfrmInError 1 -XfrmInBufferError 2 -XfrmInHdrError 4 -XfrmInNoStates 3 -XfrmInStateProtoError 40 -XfrmInStateModeError 100 -XfrmInStateSeqError 6000 -XfrmInStateExpired 4 -XfrmInStateMismatch 23451 -XfrmInStateInvalid 55555 -XfrmInTmplMismatch 51 -XfrmInNoPols 65432 -XfrmInPolBlock 100 -XfrmInPolError 10000 -XfrmOutError 1000000 -XfrmOutBundleGenError 43321 -XfrmOutBundleCheckError 555 -XfrmOutNoStates 869 -XfrmOutStateProtoError 4542 -XfrmOutStateModeError 4 -XfrmOutStateSeqError 543 -XfrmOutStateExpired 565 -XfrmOutPolBlock 43456 -XfrmOutPolDead 7656 -XfrmOutPolError 1454 -XfrmFwdHdrError 6654 -XfrmOutStateInvalid 28765 -XfrmAcquireError 24532 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/pressure -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/cpu -Lines: 1 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/io -Lines: 2 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -full avg10=0.20 avg60=3.00 avg300=4.95 total=25 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/memory -Lines: 2 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -full avg10=0.20 avg60=3.00 avg300=4.95 total=25 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/schedstat -Lines: 6 -version 15 -timestamp 15819019232 -cpu0 498494191 0 3533438552 2553969831 3853684107 2465731542 2045936778163039 343796328169361 4767485306 -domain0 00000000,00000003 212499247 210112015 1861015 1860405436 536440 369895 32599 210079416 25368550 24241256 384652 927363878 807233 6366 1647 24239609 2122447165 1886868564 121112060 2848625533 125678146 241025 1032026 1885836538 2545 12 2533 0 0 0 0 0 0 1387952561 21076581 0 -cpu1 518377256 0 4155211005 2778589869 10466382 2867629021 1904686152592476 364107263788241 5145567945 -domain0 00000000,00000003 217653037 215526982 1577949 1580427380 557469 393576 28538 215498444 28721913 27662819 371153 870843407 745912 5523 1639 27661180 2331056874 2107732788 111442342 652402556 123615235 196159 1045245 2106687543 2400 3 2397 0 0 0 0 0 0 1437804657 26220076 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/self -SymlinkTo: 26231 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/slabinfo -Lines: 302 -slabinfo - version: 2.1 -# name : tunables : slabdata -pid_3 375 532 576 28 4 : tunables 0 0 0 : slabdata 19 19 0 -pid_2 3 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -nvidia_p2p_page_cache 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -nvidia_pte_cache 9022 9152 368 22 2 : tunables 0 0 0 : slabdata 416 416 0 -nvidia_stack_cache 321 326 12624 2 8 : tunables 0 0 0 : slabdata 163 163 0 -kvm_async_pf 0 0 472 34 4 : tunables 0 0 0 : slabdata 0 0 0 -kvm_vcpu 0 0 15552 2 8 : tunables 0 0 0 : slabdata 0 0 0 -kvm_mmu_page_header 0 0 504 32 4 : tunables 0 0 0 : slabdata 0 0 0 -pte_list_desc 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -x86_emulator 0 0 3024 10 8 : tunables 0 0 0 : slabdata 0 0 0 -x86_fpu 0 0 4608 7 8 : tunables 0 0 0 : slabdata 0 0 0 -iwl_cmd_pool:0000:04:00.0 0 128 512 32 4 : tunables 0 0 0 : slabdata 4 4 0 -ext4_groupinfo_4k 3719 3740 480 34 4 : tunables 0 0 0 : slabdata 110 110 0 -bio-6 32 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -bio-5 16 48 1344 24 8 : tunables 0 0 0 : slabdata 2 2 0 -bio-4 17 92 1408 23 8 : tunables 0 0 0 : slabdata 4 4 0 -fat_inode_cache 0 0 1056 31 8 : tunables 0 0 0 : slabdata 0 0 0 -fat_cache 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ovl_aio_req 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -ovl_inode 0 0 1000 32 8 : tunables 0 0 0 : slabdata 0 0 0 -squashfs_inode_cache 0 0 1088 30 8 : tunables 0 0 0 : slabdata 0 0 0 -fuse_request 0 0 472 34 4 : tunables 0 0 0 : slabdata 0 0 0 -fuse_inode 0 0 1152 28 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_dqtrx 0 0 864 37 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_dquot 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_buf 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bui_item 0 0 544 30 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_cui_item 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_cud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_rui_item 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_rud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_icr 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_ili 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_inode 0 0 1344 24 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_efi_item 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_efd_item 0 0 776 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_buf_item 0 0 608 26 4 : tunables 0 0 0 : slabdata 0 0 0 -xf_trans 0 0 568 28 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_ifork 0 0 376 21 2 : tunables 0 0 0 : slabdata 0 0 0 -xfs_da_state 0 0 816 20 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_btree_cur 0 0 560 29 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bmap_free_item 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -xfs_log_ticket 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -nfs_direct_cache 0 0 560 29 4 : tunables 0 0 0 : slabdata 0 0 0 -nfs_commit_data 4 28 1152 28 8 : tunables 0 0 0 : slabdata 1 1 0 -nfs_write_data 32 50 1280 25 8 : tunables 0 0 0 : slabdata 2 2 0 -nfs_read_data 0 0 1280 25 8 : tunables 0 0 0 : slabdata 0 0 0 -nfs_inode_cache 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -nfs_page 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -rpc_inode_cache 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -rpc_buffers 8 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -rpc_tasks 8 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -fscache_cookie_jar 1 35 464 35 4 : tunables 0 0 0 : slabdata 1 1 0 -jfs_mp 32 35 464 35 4 : tunables 0 0 0 : slabdata 1 1 0 -jfs_ip 0 0 1592 20 8 : tunables 0 0 0 : slabdata 0 0 0 -reiser_inode_cache 0 0 1096 29 8 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_end_io_wq 0 0 464 35 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_prelim_ref 0 0 424 38 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_extent_op 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_data_ref 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_tree_ref 0 0 440 37 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_ref_head 0 0 480 34 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_inode_defrag 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_node 0 0 648 25 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_ordered_extent 0 0 752 21 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_extent_map 0 0 480 34 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_extent_state 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -bio-3 35 92 704 23 4 : tunables 0 0 0 : slabdata 4 4 0 -btrfs_extent_buffer 0 0 600 27 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_free_space_bitmap 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_free_space 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_path 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_trans_handle 0 0 440 37 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_inode 0 0 1496 21 8 : tunables 0 0 0 : slabdata 0 0 0 -ext4_inode_cache 84136 84755 1400 23 8 : tunables 0 0 0 : slabdata 3685 3685 0 -ext4_free_data 22 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_allocation_context 0 70 464 35 4 : tunables 0 0 0 : slabdata 2 2 0 -ext4_prealloc_space 24 74 440 37 4 : tunables 0 0 0 : slabdata 2 2 0 -ext4_system_zone 267 273 376 21 2 : tunables 0 0 0 : slabdata 13 13 0 -ext4_io_end_vec 0 88 368 22 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_io_end 0 80 400 20 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_bio_post_read_ctx 128 147 384 21 2 : tunables 0 0 0 : slabdata 7 7 0 -ext4_pending_reservation 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ext4_extent_status 79351 79422 376 21 2 : tunables 0 0 0 : slabdata 3782 3782 0 -jbd2_transaction_s 44 100 640 25 4 : tunables 0 0 0 : slabdata 4 4 0 -jbd2_inode 6785 6840 400 20 2 : tunables 0 0 0 : slabdata 342 342 0 -jbd2_journal_handle 0 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -jbd2_journal_head 824 1944 448 36 4 : tunables 0 0 0 : slabdata 54 54 0 -jbd2_revoke_table_s 4 23 352 23 2 : tunables 0 0 0 : slabdata 1 1 0 -jbd2_revoke_record_s 0 156 416 39 4 : tunables 0 0 0 : slabdata 4 4 0 -ext2_inode_cache 0 0 1144 28 8 : tunables 0 0 0 : slabdata 0 0 0 -mbcache 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_thin_new_mapping 0 152 424 38 4 : tunables 0 0 0 : slabdata 4 4 0 -dm_snap_pending_exception 0 0 464 35 4 : tunables 0 0 0 : slabdata 0 0 0 -dm_exception 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_dirty_log_flush_entry 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_bio_prison_cell_v2 0 0 432 37 4 : tunables 0 0 0 : slabdata 0 0 0 -dm_bio_prison_cell 0 148 432 37 4 : tunables 0 0 0 : slabdata 4 4 0 -kcopyd_job 0 8 3648 8 8 : tunables 0 0 0 : slabdata 1 1 0 -io 0 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -dm_uevent 0 0 3224 10 8 : tunables 0 0 0 : slabdata 0 0 0 -dax_cache 1 28 1152 28 8 : tunables 0 0 0 : slabdata 1 1 0 -aic94xx_ascb 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -aic94xx_dma_token 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -asd_sas_event 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -sas_task 0 0 704 23 4 : tunables 0 0 0 : slabdata 0 0 0 -qla2xxx_srbs 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0 -sd_ext_cdb 2 22 368 22 2 : tunables 0 0 0 : slabdata 1 1 0 -scsi_sense_cache 258 288 512 32 4 : tunables 0 0 0 : slabdata 9 9 0 -virtio_scsi_cmd 64 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -L2TP/IPv6 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -L2TP/IP 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -ip6-frags 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -fib6_nodes 5 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -ip6_dst_cache 4 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -ip6_mrt_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -PINGv6 0 0 1600 20 8 : tunables 0 0 0 : slabdata 0 0 0 -RAWv6 25 40 1600 20 8 : tunables 0 0 0 : slabdata 2 2 0 -UDPLITEv6 0 0 1728 18 8 : tunables 0 0 0 : slabdata 0 0 0 -UDPv6 3 54 1728 18 8 : tunables 0 0 0 : slabdata 3 3 0 -tw_sock_TCPv6 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -request_sock_TCPv6 0 0 632 25 4 : tunables 0 0 0 : slabdata 0 0 0 -TCPv6 0 33 2752 11 8 : tunables 0 0 0 : slabdata 3 3 0 -uhci_urb_priv 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -sgpool-128 2 14 4544 7 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-64 2 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -sgpool-32 2 44 1472 22 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-16 2 68 960 34 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-8 2 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -btree_node 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -bfq_io_cq 0 0 488 33 4 : tunables 0 0 0 : slabdata 0 0 0 -bfq_queue 0 0 848 38 8 : tunables 0 0 0 : slabdata 0 0 0 -mqueue_inode_cache 1 24 1344 24 8 : tunables 0 0 0 : slabdata 1 1 0 -isofs_inode_cache 0 0 968 33 8 : tunables 0 0 0 : slabdata 0 0 0 -io_kiocb 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -kioctx 0 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0 -aio_kiocb 0 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -userfaultfd_ctx_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -fanotify_path_event 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -fanotify_fid_event 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -fsnotify_mark 0 0 408 20 2 : tunables 0 0 0 : slabdata 0 0 0 -dnotify_mark 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -dnotify_struct 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dio 0 0 1088 30 8 : tunables 0 0 0 : slabdata 0 0 0 -bio-2 4 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -fasync_cache 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -audit_tree_mark 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -pid_namespace 30 34 480 34 4 : tunables 0 0 0 : slabdata 1 1 0 -posix_timers_cache 0 27 592 27 4 : tunables 0 0 0 : slabdata 1 1 0 -iommu_devinfo 24 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -iommu_domain 10 10 3264 10 8 : tunables 0 0 0 : slabdata 1 1 0 -iommu_iova 8682 8748 448 36 4 : tunables 0 0 0 : slabdata 243 243 0 -UNIX 529 814 1472 22 8 : tunables 0 0 0 : slabdata 37 37 0 -ip4-frags 0 0 536 30 4 : tunables 0 0 0 : slabdata 0 0 0 -ip_mrt_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -UDP-Lite 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -tcp_bind_bucket 7 128 512 32 4 : tunables 0 0 0 : slabdata 4 4 0 -inet_peer_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -xfrm_dst_cache 0 0 704 23 4 : tunables 0 0 0 : slabdata 0 0 0 -xfrm_state 0 0 1152 28 8 : tunables 0 0 0 : slabdata 0 0 0 -ip_fib_trie 7 21 384 21 2 : tunables 0 0 0 : slabdata 1 1 0 -ip_fib_alias 9 20 392 20 2 : tunables 0 0 0 : slabdata 1 1 0 -ip_dst_cache 27 84 576 28 4 : tunables 0 0 0 : slabdata 3 3 0 -PING 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -RAW 32 46 1408 23 8 : tunables 0 0 0 : slabdata 2 2 0 -UDP 11 168 1536 21 8 : tunables 0 0 0 : slabdata 8 8 0 -tw_sock_TCP 1 56 576 28 4 : tunables 0 0 0 : slabdata 2 2 0 -request_sock_TCP 0 25 632 25 4 : tunables 0 0 0 : slabdata 1 1 0 -TCP 10 60 2624 12 8 : tunables 0 0 0 : slabdata 5 5 0 -hugetlbfs_inode_cache 2 35 928 35 8 : tunables 0 0 0 : slabdata 1 1 0 -dquot 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -bio-1 32 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -eventpoll_pwq 409 600 408 20 2 : tunables 0 0 0 : slabdata 30 30 0 -eventpoll_epi 408 672 576 28 4 : tunables 0 0 0 : slabdata 24 24 0 -inotify_inode_mark 58 195 416 39 4 : tunables 0 0 0 : slabdata 5 5 0 -scsi_data_buffer 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -bio_crypt_ctx 128 147 376 21 2 : tunables 0 0 0 : slabdata 7 7 0 -request_queue 29 39 2408 13 8 : tunables 0 0 0 : slabdata 3 3 0 -blkdev_ioc 81 148 440 37 4 : tunables 0 0 0 : slabdata 4 4 0 -bio-0 125 200 640 25 4 : tunables 0 0 0 : slabdata 8 8 0 -biovec-max 166 196 4544 7 8 : tunables 0 0 0 : slabdata 28 28 0 -biovec-128 0 52 2496 13 8 : tunables 0 0 0 : slabdata 4 4 0 -biovec-64 0 88 1472 22 8 : tunables 0 0 0 : slabdata 4 4 0 -biovec-16 0 92 704 23 4 : tunables 0 0 0 : slabdata 4 4 0 -bio_integrity_payload 4 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -khugepaged_mm_slot 59 180 448 36 4 : tunables 0 0 0 : slabdata 5 5 0 -ksm_mm_slot 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -ksm_stable_node 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -ksm_rmap_item 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -user_namespace 2 37 864 37 8 : tunables 0 0 0 : slabdata 1 1 0 -uid_cache 5 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-256 1 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-128 1 22 1472 22 8 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-16 1 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-2 1 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0 -audit_buffer 0 22 360 22 2 : tunables 0 0 0 : slabdata 1 1 0 -sock_inode_cache 663 1170 1216 26 8 : tunables 0 0 0 : slabdata 45 45 0 -skbuff_ext_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -skbuff_fclone_cache 1 72 896 36 8 : tunables 0 0 0 : slabdata 2 2 0 -skbuff_head_cache 3 650 640 25 4 : tunables 0 0 0 : slabdata 26 26 0 -configfs_dir_cache 7 38 424 38 4 : tunables 0 0 0 : slabdata 1 1 0 -file_lock_cache 27 116 552 29 4 : tunables 0 0 0 : slabdata 4 4 0 -file_lock_ctx 106 120 392 20 2 : tunables 0 0 0 : slabdata 6 6 0 -fsnotify_mark_connector 52 66 368 22 2 : tunables 0 0 0 : slabdata 3 3 0 -net_namespace 1 6 5312 6 8 : tunables 0 0 0 : slabdata 1 1 0 -task_delay_info 784 1560 416 39 4 : tunables 0 0 0 : slabdata 40 40 0 -taskstats 45 92 688 23 4 : tunables 0 0 0 : slabdata 4 4 0 -proc_dir_entry 678 682 528 31 4 : tunables 0 0 0 : slabdata 22 22 0 -pde_opener 0 189 376 21 2 : tunables 0 0 0 : slabdata 9 9 0 -proc_inode_cache 7150 8250 992 33 8 : tunables 0 0 0 : slabdata 250 250 0 -seq_file 60 735 456 35 4 : tunables 0 0 0 : slabdata 21 21 0 -sigqueue 0 156 416 39 4 : tunables 0 0 0 : slabdata 4 4 0 -bdev_cache 36 78 1216 26 8 : tunables 0 0 0 : slabdata 3 3 0 -shmem_inode_cache 1599 2208 1016 32 8 : tunables 0 0 0 : slabdata 69 69 0 -kernfs_iattrs_cache 1251 1254 424 38 4 : tunables 0 0 0 : slabdata 33 33 0 -kernfs_node_cache 52898 52920 464 35 4 : tunables 0 0 0 : slabdata 1512 1512 0 -mnt_cache 42 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -filp 4314 6371 704 23 4 : tunables 0 0 0 : slabdata 277 277 0 -inode_cache 28695 29505 920 35 8 : tunables 0 0 0 : slabdata 843 843 0 -dentry 166069 169074 528 31 4 : tunables 0 0 0 : slabdata 5454 5454 0 -names_cache 0 35 4544 7 8 : tunables 0 0 0 : slabdata 5 5 0 -hashtab_node 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ebitmap_node 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -avtab_extended_perms 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avtab_node 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_data 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_decision_node 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_node 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_node 37 40 408 20 2 : tunables 0 0 0 : slabdata 2 2 0 -iint_cache 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -lsm_inode_cache 122284 122340 392 20 2 : tunables 0 0 0 : slabdata 6117 6117 0 -lsm_file_cache 4266 4485 352 23 2 : tunables 0 0 0 : slabdata 195 195 0 -key_jar 8 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -buffer_head 255622 257076 440 37 4 : tunables 0 0 0 : slabdata 6948 6948 0 -uts_namespace 0 0 776 21 4 : tunables 0 0 0 : slabdata 0 0 0 -nsproxy 31 40 408 20 2 : tunables 0 0 0 : slabdata 2 2 0 -vm_area_struct 39115 43214 528 31 4 : tunables 0 0 0 : slabdata 1394 1394 0 -mm_struct 96 529 1408 23 8 : tunables 0 0 0 : slabdata 23 23 0 -fs_cache 102 756 448 36 4 : tunables 0 0 0 : slabdata 21 21 0 -files_cache 102 588 1152 28 8 : tunables 0 0 0 : slabdata 21 21 0 -signal_cache 266 672 1536 21 8 : tunables 0 0 0 : slabdata 32 32 0 -sighand_cache 266 507 2496 13 8 : tunables 0 0 0 : slabdata 39 39 0 -task_struct 783 963 10240 3 8 : tunables 0 0 0 : slabdata 321 321 0 -cred_jar 364 952 576 28 4 : tunables 0 0 0 : slabdata 34 34 0 -anon_vma_chain 63907 67821 416 39 4 : tunables 0 0 0 : slabdata 1739 1739 0 -anon_vma 25891 28899 416 39 4 : tunables 0 0 0 : slabdata 741 741 0 -pid 408 992 512 32 4 : tunables 0 0 0 : slabdata 31 31 0 -Acpi-Operand 6682 6740 408 20 2 : tunables 0 0 0 : slabdata 337 337 0 -Acpi-ParseExt 0 39 416 39 4 : tunables 0 0 0 : slabdata 1 1 0 -Acpi-Parse 0 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -Acpi-State 0 78 416 39 4 : tunables 0 0 0 : slabdata 2 2 0 -Acpi-Namespace 3911 3948 384 21 2 : tunables 0 0 0 : slabdata 188 188 0 -trace_event_file 2638 2660 424 38 4 : tunables 0 0 0 : slabdata 70 70 0 -ftrace_event_field 6592 6594 384 21 2 : tunables 0 0 0 : slabdata 314 314 0 -pool_workqueue 41 64 1024 32 8 : tunables 0 0 0 : slabdata 2 2 0 -radix_tree_node 21638 24045 912 35 8 : tunables 0 0 0 : slabdata 687 687 0 -task_group 48 78 1216 26 8 : tunables 0 0 0 : slabdata 3 3 0 -vmap_area 4411 4680 400 20 2 : tunables 0 0 0 : slabdata 234 234 0 -dma-kmalloc-8k 0 0 24576 1 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-4k 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-2k 0 0 6144 5 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-1k 0 0 3072 10 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-512 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-256 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-128 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-64 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-32 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-16 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-8 0 0 344 23 2 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-192 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-96 0 0 432 37 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-8k 0 0 24576 1 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-4k 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-2k 0 0 6144 5 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-1k 0 0 3072 10 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-512 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-256 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-192 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-128 31 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -kmalloc-rcl-96 3371 3626 432 37 4 : tunables 0 0 0 : slabdata 98 98 0 -kmalloc-rcl-64 2080 2272 512 32 4 : tunables 0 0 0 : slabdata 71 71 0 -kmalloc-rcl-32 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-16 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-8 0 0 344 23 2 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-8k 133 140 24576 1 8 : tunables 0 0 0 : slabdata 140 140 0 -kmalloc-4k 403 444 12288 2 8 : tunables 0 0 0 : slabdata 222 222 0 -kmalloc-2k 2391 2585 6144 5 8 : tunables 0 0 0 : slabdata 517 517 0 -kmalloc-1k 2163 2420 3072 10 8 : tunables 0 0 0 : slabdata 242 242 0 -kmalloc-512 2972 3633 1536 21 8 : tunables 0 0 0 : slabdata 173 173 0 -kmalloc-256 1841 1856 1024 32 8 : tunables 0 0 0 : slabdata 58 58 0 -kmalloc-192 2165 2914 528 31 4 : tunables 0 0 0 : slabdata 94 94 0 -kmalloc-128 1137 1175 640 25 4 : tunables 0 0 0 : slabdata 47 47 0 -kmalloc-96 1925 2590 432 37 4 : tunables 0 0 0 : slabdata 70 70 0 -kmalloc-64 9433 10688 512 32 4 : tunables 0 0 0 : slabdata 334 334 0 -kmalloc-32 9098 10062 416 39 4 : tunables 0 0 0 : slabdata 258 258 0 -kmalloc-16 10914 10956 368 22 2 : tunables 0 0 0 : slabdata 498 498 0 -kmalloc-8 7576 7705 344 23 2 : tunables 0 0 0 : slabdata 335 335 0 -kmem_cache_node 904 928 512 32 4 : tunables 0 0 0 : slabdata 29 29 0 -kmem_cache 904 936 832 39 8 : tunables 0 0 0 : slabdata 24 24 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/stat -Lines: 16 -cpu 301854 612 111922 8979004 3552 2 3944 0 0 0 -cpu0 44490 19 21045 1087069 220 1 3410 0 0 0 -cpu1 47869 23 16474 1110787 591 0 46 0 0 0 -cpu2 46504 36 15916 1112321 441 0 326 0 0 0 -cpu3 47054 102 15683 1113230 533 0 60 0 0 0 -cpu4 28413 25 10776 1140321 217 0 8 0 0 0 -cpu5 29271 101 11586 1136270 672 0 30 0 0 0 -cpu6 29152 36 10276 1139721 319 0 29 0 0 0 -cpu7 29098 268 10164 1139282 555 0 31 0 0 0 -intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ctxt 38014093 -btime 1418183276 -processes 26442 -procs_running 2 -procs_blocked 1 -softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/swaps -Lines: 2 -Filename Type Size Used Priority -/dev/dm-2 partition 131068 176 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/symlinktargets -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/README -Lines: 2 -This directory contains some empty files that are the symlinks the files in the "fd" directory point to. -They are otherwise ignored by the tests -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/abc -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/def -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/ghi -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/uvw -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/xyz -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/kernel -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/kernel/random -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/entropy_avail -Lines: 1 -3943 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/poolsize -Lines: 1 -4096 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/urandom_min_reseed_secs -Lines: 1 -60 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/write_wakeup_threshold -Lines: 1 -3072 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/vm -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/admin_reserve_kbytes -Lines: 1 -8192 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/block_dump -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/compact_unevictable_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_background_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_background_ratio -Lines: 1 -10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_expire_centisecs -Lines: 1 -3000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_ratio -Lines: 1 -20 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_writeback_centisecs -Lines: 1 -500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirtytime_expire_seconds -Lines: 1 -43200 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/drop_caches -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/extfrag_threshold -Lines: 1 -500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/hugetlb_shm_group -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/laptop_mode -Lines: 1 -5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/legacy_va_layout -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/lowmem_reserve_ratio -Lines: 1 -256 256 32 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/max_map_count -Lines: 1 -65530 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/memory_failure_early_kill -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/memory_failure_recovery -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_free_kbytes -Lines: 1 -67584 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_slab_ratio -Lines: 1 -5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_unmapped_ratio -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/mmap_min_addr -Lines: 1 -65536 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_hugepages -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_hugepages_mempolicy -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_overcommit_hugepages -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/numa_stat -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/numa_zonelist_order -Lines: 1 -Node -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/oom_dump_tasks -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/oom_kill_allocating_task -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_kbytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_memory -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_ratio -Lines: 1 -50 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/page-cluster -Lines: 1 -3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/panic_on_oom -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/percpu_pagelist_fraction -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/stat_interval -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/swappiness -Lines: 1 -60 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/user_reserve_kbytes -Lines: 1 -131072 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/vfs_cache_pressure -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/watermark_boost_factor -Lines: 1 -15000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/watermark_scale_factor -Lines: 1 -10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/zone_reclaim_mode -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/zoneinfo -Lines: 262 -Node 0, zone DMA - per-node stats - nr_inactive_anon 230981 - nr_active_anon 547580 - nr_inactive_file 316904 - nr_active_file 346282 - nr_unevictable 115467 - nr_slab_reclaimable 131220 - nr_slab_unreclaimable 47320 - nr_isolated_anon 0 - nr_isolated_file 0 - workingset_nodes 11627 - workingset_refault 466886 - workingset_activate 276925 - workingset_restore 84055 - workingset_nodereclaim 487 - nr_anon_pages 795576 - nr_mapped 215483 - nr_file_pages 761874 - nr_dirty 908 - nr_writeback 0 - nr_writeback_temp 0 - nr_shmem 224925 - nr_shmem_hugepages 0 - nr_shmem_pmdmapped 0 - nr_anon_transparent_hugepages 0 - nr_unstable 0 - nr_vmscan_write 12950 - nr_vmscan_immediate_reclaim 3033 - nr_dirtied 8007423 - nr_written 7752121 - nr_kernel_misc_reclaimable 0 - pages free 3952 - min 33 - low 41 - high 49 - spanned 4095 - present 3975 - managed 3956 - protection: (0, 2877, 7826, 7826, 7826) - nr_free_pages 3952 - nr_zone_inactive_anon 0 - nr_zone_active_anon 0 - nr_zone_inactive_file 0 - nr_zone_active_file 0 - nr_zone_unevictable 0 - nr_zone_write_pending 0 - nr_mlock 0 - nr_page_table_pages 0 - nr_kernel_stack 0 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 1 - numa_miss 0 - numa_foreign 0 - numa_interleave 0 - numa_local 1 - numa_other 0 - pagesets - cpu: 0 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 1 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 2 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 3 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 4 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 5 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 6 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 7 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - node_unreclaimable: 0 - start_pfn: 1 -Node 0, zone DMA32 - pages free 204252 - min 19510 - low 21059 - high 22608 - spanned 1044480 - present 759231 - managed 742806 - protection: (0, 0, 4949, 4949, 4949) - nr_free_pages 204252 - nr_zone_inactive_anon 118558 - nr_zone_active_anon 106598 - nr_zone_inactive_file 75475 - nr_zone_active_file 70293 - nr_zone_unevictable 66195 - nr_zone_write_pending 64 - nr_mlock 4 - nr_page_table_pages 1756 - nr_kernel_stack 2208 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 113952967 - numa_miss 0 - numa_foreign 0 - numa_interleave 0 - numa_local 113952967 - numa_other 0 - pagesets - cpu: 0 - count: 345 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 1 - count: 356 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 2 - count: 325 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 3 - count: 346 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 4 - count: 321 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 5 - count: 316 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 6 - count: 373 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 7 - count: 339 - high: 378 - batch: 63 - vm stats threshold: 48 - node_unreclaimable: 0 - start_pfn: 4096 -Node 0, zone Normal - pages free 18553 - min 11176 - low 13842 - high 16508 - spanned 1308160 - present 1308160 - managed 1268711 - protection: (0, 0, 0, 0, 0) - nr_free_pages 18553 - nr_zone_inactive_anon 112423 - nr_zone_active_anon 440982 - nr_zone_inactive_file 241429 - nr_zone_active_file 275989 - nr_zone_unevictable 49272 - nr_zone_write_pending 844 - nr_mlock 154 - nr_page_table_pages 9750 - nr_kernel_stack 15136 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 162718019 - numa_miss 0 - numa_foreign 0 - numa_interleave 26812 - numa_local 162718019 - numa_other 0 - pagesets - cpu: 0 - count: 316 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 1 - count: 366 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 2 - count: 60 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 3 - count: 256 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 4 - count: 253 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 5 - count: 159 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 6 - count: 311 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 7 - count: 264 - high: 378 - batch: 63 - vm stats threshold: 56 - node_unreclaimable: 0 - start_pfn: 1048576 -Node 0, zone Movable - pages free 0 - min 0 - low 0 - high 0 - spanned 0 - present 0 - managed 0 - protection: (0, 0, 0, 0, 0) -Node 0, zone Device - pages free 0 - min 0 - low 0 - high 0 - spanned 0 - present 0 - managed 0 - protection: (0, 0, 0, 0, 0) -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/dm-0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/dm-0/stat -Lines: 1 -6447303 0 710266738 1529043 953216 0 31201176 4557464 0 796160 6088971 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda/queue -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/add_random -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/chunk_sectors -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/dax -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_granularity -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_max_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_max_hw_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_zeroes_data -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/fua -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/hw_sector_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_poll -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_poll_delay -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_timeout -Lines: 1 -30000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda/queue/iosched -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/back_seek_max -Lines: 1 -16384 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/back_seek_penalty -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_async -Lines: 1 -250 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_sync -Lines: 1 -125 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/low_latency -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/max_budget -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/slice_idle -Lines: 1 -8 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/slice_idle_us -Lines: 1 -8000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/strict_guarantees -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/timeout_sync -Lines: 1 -125 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iostats -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/logical_block_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_discard_segments -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_hw_sectors_kb -Lines: 1 -32767 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_integrity_segments -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_sectors_kb -Lines: 1 -1280 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_segment_size -Lines: 1 -65536 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_segments -Lines: 1 -168 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/minimum_io_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nomerges -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nr_requests -Lines: 1 -64 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nr_zones -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/optimal_io_size -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/physical_block_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/read_ahead_kb -Lines: 1 -128 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/rotational -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/rq_affinity -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/scheduler -Lines: 1 -mq-deadline kyber [bfq] none -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/wbt_lat_usec -Lines: 1 -75000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_cache -Lines: 1 -write back -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_same_max_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_zeroes_max_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/zoned -Lines: 1 -none -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/stat -Lines: 1 -9652963 396792 759304206 412943 8422549 6731723 286915323 13947418 0 5658367 19174573 1 2 3 12 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm/card0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm/card0/device -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_correctable -Lines: 9 -RxErr 0 -BadTLP 0 -BadDLLP 0 -Rollover 0 -Timeout 0 -NonFatalErr 0 -CorrIntErr 0 -HeaderOF 0 -TOTAL_ERR_COR 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_fatal -Lines: 19 -Undefined 0 -DLP 0 -SDES 0 -TLP 0 -FCP 0 -CmpltTO 0 -CmpltAbrt 0 -UnxCmplt 0 -RxOF 0 -MalfTLP 0 -ECRC 0 -UnsupReq 0 -ACSViol 0 -UncorrIntErr 0 -BlockedTLP 0 -AtomicOpBlocked 0 -TLPBlockedErr 0 -PoisonTLPBlocked 0 -TOTAL_ERR_FATAL 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_nonfatal -Lines: 19 -Undefined 0 -DLP 0 -SDES 0 -TLP 0 -FCP 0 -CmpltTO 0 -CmpltAbrt 0 -UnxCmplt 0 -RxOF 0 -MalfTLP 0 -ECRC 0 -UnsupReq 0 -ACSViol 0 -UncorrIntErr 0 -BlockedTLP 0 -AtomicOpBlocked 0 -TLPBlockedErr 0 -PoisonTLPBlocked 0 -TOTAL_ERR_NONFATAL 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/ari_enabled -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/boot_vga -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/broken_parity_status -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/class -Lines: 1 -0x030000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/consistent_dma_mask_bits -Lines: 1 -44 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/current_link_speed -Lines: 1 -8.0 GT/s PCIe -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/current_link_width -Lines: 1 -16 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/d3cold_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/device -Lines: 1 -0x687f -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/dma_mask_bits -Lines: 1 -44 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/driver_override -Lines: 1 -(null) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/gpu_busy_percent -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/irq -Lines: 1 -95 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/local_cpulist -Lines: 1 -0-15 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/local_cpus -Lines: 1 -0000ffff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/max_link_speed -Lines: 1 -8.0 GT/s PCIe -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/max_link_width -Lines: 1 -16 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_used -Lines: 1 -144560128 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_used -Lines: 1 -1490378752 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_used -Lines: 1 -1490378752 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_vendor -Lines: 1 -samsung -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/modalias -Lines: 1 -pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/msi_bus -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/numa_node -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pcie_bw -Lines: 1 -6641 815 256 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pcie_replay_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_dpm_force_performance_level -Lines: 1 -manual -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_dpm_state -Lines: 1 -performance -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_state -Lines: 1 -D0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_cur_state -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_dcefclk -Lines: 5 -0: 600Mhz * -1: 720Mhz -2: 800Mhz -3: 847Mhz -4: 900Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_mclk -Lines: 4 -0: 167Mhz * -1: 500Mhz -2: 800Mhz -3: 945Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_pcie -Lines: 2 -0: 8.0GT/s, x16 -1: 8.0GT/s, x16 * -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_sclk -Lines: 8 -0: 852Mhz * -1: 991Mhz -2: 1084Mhz -3: 1138Mhz -4: 1200Mhz -5: 1401Mhz -6: 1536Mhz -7: 1630Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_socclk -Lines: 8 -0: 600Mhz -1: 720Mhz * -2: 800Mhz -3: 847Mhz -4: 900Mhz -5: 960Mhz -6: 1028Mhz -7: 1107Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_features -Lines: 32 -Current ppfeatures: 0x0000000019a1ff4f -FEATURES BITMASK ENABLEMENT -DPM_PREFETCHER 0x0000000000000001 Y -GFXCLK_DPM 0x0000000000000002 Y -UCLK_DPM 0x0000000000000004 Y -SOCCLK_DPM 0x0000000000000008 Y -UVD_DPM 0x0000000000000010 N -VCE_DPM 0x0000000000000020 N -ULV 0x0000000000000040 Y -MP0CLK_DPM 0x0000000000000080 N -LINK_DPM 0x0000000000000100 Y -DCEFCLK_DPM 0x0000000000000200 Y -AVFS 0x0000000000000400 Y -GFXCLK_DS 0x0000000000000800 Y -SOCCLK_DS 0x0000000000001000 Y -LCLK_DS 0x0000000000002000 Y -PPT 0x0000000000004000 Y -TDC 0x0000000000008000 Y -THERMAL 0x0000000000010000 Y -GFX_PER_CU_CG 0x0000000000020000 N -RM 0x0000000000040000 N -DCEFCLK_DS 0x0000000000080000 N -ACDC 0x0000000000100000 N -VR0HOT 0x0000000000200000 Y -VR1HOT 0x0000000000400000 N -FW_CTF 0x0000000000800000 Y -LED_DISPLAY 0x0000000001000000 Y -FAN_CONTROL 0x0000000002000000 N -FAST_PPT 0x0000000004000000 N -DIDT 0x0000000008000000 Y -ACG 0x0000000010000000 Y -PCC_LIMIT 0x0000000020000000 N -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_force_state -Lines: 1 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_mclk_od -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_num_states -Lines: 3 -states: 2 -0 boot -1 performance -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_od_clk_voltage -Lines: 18 -OD_SCLK: -0: 852Mhz 800mV -1: 991Mhz 900mV -2: 1084Mhz 950mV -3: 1138Mhz 1000mV -4: 1200Mhz 1050mV -5: 1401Mhz 1100mV -6: 1536Mhz 1150mV -7: 1630Mhz 1200mV -OD_MCLK: -0: 167Mhz 800mV -1: 500Mhz 800mV -2: 800Mhz 950mV -3: 945Mhz 1100mV -OD_RANGE: -SCLK: 852MHz 2400MHz -MCLK: 167MHz 1500MHz -VDDC: 800mV 1200mV -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_power_profile_mode -Lines: 8 -NUM MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL - 0 BOOTUP_DEFAULT : 70 60 0 0 - 1 3D_FULL_SCREEN*: 70 60 1 3 - 2 POWER_SAVING : 90 60 0 0 - 3 VIDEO : 70 60 0 0 - 4 VR : 70 90 0 0 - 5 COMPUTE : 30 60 0 6 - 6 CUSTOM : 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_sclk_od -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/product_name -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/product_number -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/resource -Lines: 13 -0x0000007c00000000 0x0000007dffffffff 0x000000000014220c -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000007e00000000 0x0000007e0fffffff 0x000000000014220c -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x000000000000d000 0x000000000000d0ff 0x0000000000040101 -0x00000000fcd00000 0x00000000fcd7ffff 0x0000000000040200 -0x00000000fcd80000 0x00000000fcd9ffff 0x0000000000046200 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/revision -Lines: 1 -0xc1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/serial_number -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/subsystem_device -Lines: 1 -0x04c4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/subsystem_vendor -Lines: 1 -0x1043 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/thermal_throttling_logging -Lines: 1 -0000:09:00.0: thermal throttling logging enabled, with interval 60 seconds -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/uevent -Lines: 6 -DRIVER=amdgpu -PCI_CLASS=30000 -PCI_ID=1002:687F -PCI_SUBSYS_ID=1043:04C4 -PCI_SLOT_NAME=0000:09:00.0 -MODALIAS=pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/unique_id -Lines: 1 -0123456789abcdef -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/vbios_version -Lines: 1 -115-D050PIL-100 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/vendor -Lines: 1 -0x1002 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host/host0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/dev_loss_tmo -Lines: 1 -30 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/fabric_name -Lines: 1 -0x0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/node_name -Lines: 1 -0x2000e0071bce95f2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_id -Lines: 1 -0x000002 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_name -Lines: 1 -0x1000e0071bce95f2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_state -Lines: 1 -Online -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_type -Lines: 1 -Point-To-Point (direct nport connection) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/speed -Lines: 1 -16 Gbit -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host/host0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/dumped_frames -Lines: 1 -0xffffffffffffffff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/error_frames -Lines: 1 -0x0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/fcp_packet_aborts -Lines: 1 -0x13 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/invalid_crc_count -Lines: 1 -0x2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/invalid_tx_word_count -Lines: 1 -0x8 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/link_failure_count -Lines: 1 -0x9 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_signal_count -Lines: 1 -0x11 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_sync_count -Lines: 1 -0x10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/nos_count -Lines: 1 -0x12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/rx_frames -Lines: 1 -0x3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/rx_words -Lines: 1 -0x4 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/seconds_since_last_reset -Lines: 1 -0x7 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/tx_frames -Lines: 1 -0x5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/tx_words -Lines: 1 -0x6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/supported_classes -Lines: 1 -Class 3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/supported_speeds -Lines: 1 -4 Gbit, 8 Gbit, 16 Gbit -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/symbolic_name -Lines: 1 -Emulex SN1100E2P FV12.4.270.3 DV12.4.0.0. HN:gotest. OS:Linux -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/board_id -Lines: 1 -HPE 100Gb 1-port OP101 QSFP28 x16 PCIe Gen3 with Intel Omni-Path Adapter -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/fw_ver -Lines: 1 -1.27.0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/VL15_dropped -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_data -Lines: 1 -345091702026 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_packets -Lines: 1 -638036947 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_data -Lines: 1 -273558326543 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_packets -Lines: 1 -568318856 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_wait -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/rate -Lines: 1 -100 Gb/sec (4X EDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/board_id -Lines: 1 -SM_1141000001000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/fw_ver -Lines: 1 -2.31.5050 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/hca_type -Lines: 1 -MT4099 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/VL15_dropped -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_data -Lines: 1 -2221223609 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_packets -Lines: 1 -87169372 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_data -Lines: 1 -26509113295 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_packets -Lines: 1 -85734114 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_wait -Lines: 1 -3599 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/rate -Lines: 1 -40 Gb/sec (4X QDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/VL15_dropped -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_data -Lines: 1 -2460436784 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_packets -Lines: 1 -89332064 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_data -Lines: 1 -26540356890 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_packets -Lines: 1 -88622850 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_wait -Lines: 1 -3846 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/rate -Lines: 1 -40 Gb/sec (4X QDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/net -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/net/eth0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/addr_assign_type -Lines: 1 -3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/addr_len -Lines: 1 -6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/address -Lines: 1 -01:01:01:01:01:01 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/broadcast -Lines: 1 -ff:ff:ff:ff:ff:ff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_changes -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_down_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_up_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/dev_id -Lines: 1 -0x20 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/device -SymlinkTo: ../../../devices/pci0000:00/0000:00:1f.6/ -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/dormant -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/duplex -Lines: 1 -full -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/flags -Lines: 1 -0x1303 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/ifalias -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/ifindex -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/iflink -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/link_mode -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/mtu -Lines: 1 -1500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/name_assign_type -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/netdev_group -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/operstate -Lines: 1 -up -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_port_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_port_name -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_switch_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/speed -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/tx_queue_len -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/type -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/nvme -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/nvme/nvme0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/firmware_rev -Lines: 1 -1B2QEXP7 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/model -Lines: 1 -Samsung SSD 970 PRO 512GB -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/serial -Lines: 1 -S680HF8N190894I -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/state -Lines: 1 -live -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/power_supply/AC -SymlinkTo: ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/power_supply/BAT0 -SymlinkTo: ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_max_power_uw -Lines: 1 -95000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_time_window_us -Lines: 1 -999424 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_max_power_uw -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_name -Lines: 1 -short_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_time_window_us -Lines: 1 -2440 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/energy_uj -Lines: 1 -240422366267 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/name -Lines: 1 -package-0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_max_power_uw -Lines: 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_power_limit_uw -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_time_window_us -Lines: 1 -976 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/enabled -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/energy_uj -Lines: 1 -118821284256 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/name -Lines: 1 -core -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_max_power_uw -Lines: 1 -95000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_time_window_us -Lines: 1 -999424 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_max_power_uw -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_name -Lines: 1 -short_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_time_window_us -Lines: 1 -2440 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/energy_uj -Lines: 1 -240422366267 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/name -Lines: 1 -package-10 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/scsi_tape -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0 -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0a -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0l -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0m -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0 -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0a -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0l -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0m -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/cooling_device0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/cur_state -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/max_state -Lines: 1 -50 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/type -Lines: 1 -Processor -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/cooling_device1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/cur_state -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/max_state -Lines: 1 -27 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/type -Lines: 1 -intel_powerclamp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/thermal_zone0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/policy -Lines: 1 -step_wise -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/temp -Lines: 1 -49925 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/type -Lines: 1 -bcm2835_thermal -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/thermal_zone1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/mode -Lines: 1 -enabled -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/passive -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/policy -Lines: 1 -step_wise -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/temp -Lines: 1 --44000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/type -Lines: 1 -acpitz -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/device -SymlinkTo: ../../../ACPI0003:00 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/online -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/async -Lines: 1 -disabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/autosuspend_delay_ms -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/control -Lines: 1 -auto -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_active_kids -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_active_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_enabled -Lines: 1 -disabled -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_status -Lines: 1 -unsupported -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_suspended_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_usage -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup -Lines: 1 -enabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_abort_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_active -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_active_count -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_expire_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_last_time_ms -Lines: 1 -10598 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_max_time_ms -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_prevent_sleep_time_ms -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_total_time_ms -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/subsystem -SymlinkTo: ../../../../../../../../../class/power_supply -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/type -Lines: 1 -Mains -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/uevent -Lines: 2 -POWER_SUPPLY_NAME=AC -POWER_SUPPLY_ONLINE=0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/alarm -Lines: 1 -2369000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/capacity -Lines: 1 -98 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/capacity_level -Lines: 1 -Normal -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_start_threshold -Lines: 1 -95 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_stop_threshold -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/cycle_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/device -SymlinkTo: ../../../PNP0C0A:00 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full -Lines: 1 -50060000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full_design -Lines: 1 -47520000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_now -Lines: 1 -49450000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/manufacturer -Lines: 1 -LGC -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/model_name -Lines: 1 -LNV-45N1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/async -Lines: 1 -disabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/autosuspend_delay_ms -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/control -Lines: 1 -auto -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_active_kids -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_active_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_enabled -Lines: 1 -disabled -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_status -Lines: 1 -unsupported -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_suspended_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_usage -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power_now -Lines: 1 -4830000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/present -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/serial_number -Lines: 1 -38109 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/status -Lines: 1 -Discharging -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/subsystem -SymlinkTo: ../../../../../../../../../class/power_supply -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/technology -Lines: 1 -Li-ion -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/type -Lines: 1 -Battery -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/uevent -Lines: 16 -POWER_SUPPLY_NAME=BAT0 -POWER_SUPPLY_STATUS=Discharging -POWER_SUPPLY_PRESENT=1 -POWER_SUPPLY_TECHNOLOGY=Li-ion -POWER_SUPPLY_CYCLE_COUNT=0 -POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000 -POWER_SUPPLY_VOLTAGE_NOW=11750000 -POWER_SUPPLY_POWER_NOW=5064000 -POWER_SUPPLY_ENERGY_FULL_DESIGN=47520000 -POWER_SUPPLY_ENERGY_FULL=47390000 -POWER_SUPPLY_ENERGY_NOW=40730000 -POWER_SUPPLY_CAPACITY=85 -POWER_SUPPLY_CAPACITY_LEVEL=Normal -POWER_SUPPLY_MODEL_NAME=LNV-45N1 -POWER_SUPPLY_MANUFACTURER=LGC -POWER_SUPPLY_SERIAL_NUMBER=38109 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_min_design -Lines: 1 -10800000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_now -Lines: 1 -12229000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/dirty_data -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/io_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/metadata_written -Lines: 1 -512 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/priority_stats -Lines: 5 -Unused: 99% -Metadata: 0% -Average: 10473 -Sectors per Q: 64 -Quantiles: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/written -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:1f.6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/ari_enabled -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/broken_parity_status -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/class -Lines: 1 -0x020000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/consistent_dma_mask_bits -Lines: 1 -64 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/d3cold_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/device -Lines: 1 -0x15d7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/dma_mask_bits -Lines: 1 -64 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/driver_override -Lines: 1 -(null) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/irq -Lines: 1 -140 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/local_cpulist -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/local_cpus -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/modalias -Lines: 1 -pci:v00008086d000015D7sv000017AAsd0000225Abc02sc00i00 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/msi_bus -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/numa_node -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/resource -Lines: 13 -0x00000000ec200000 0x00000000ec21ffff 0x0000000000040200 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/revision -Lines: 1 -0x21 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/subsystem_device -Lines: 1 -0x225a -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/subsystem_vendor -Lines: 1 -0x17aa -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/uevent -Lines: 6 -DRIVER=e1000e -PCI_CLASS=20000 -PCI_ID=8086:15D7 -PCI_SUBSYS_ID=17AA:225A -PCI_SLOT_NAME=0000:00:1f.6 -MODALIAS=pci:v00008086d000015D7sv000017AAsd0000225Abc02sc00i00 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/vendor -Lines: 1 -0x8086 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd/0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/0/name -Lines: 1 -demo -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/0/pool -Lines: 1 -iscsi-images -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/1/name -Lines: 1 -wrong -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/1/pool -Lines: 1 -wrong-images -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/clocksource -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/clocksource/clocksource0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/clocksource/clocksource0/available_clocksource -Lines: 1 -tsc hpet acpi_pm -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/clocksource/clocksource0/current_clocksource -Lines: 1 -tsc -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/cpufreq -SymlinkTo: ../cpufreq/policy0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count -Lines: 1 -10084 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count -Lines: 1 -34818 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0/topology -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_siblings -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_siblings_list -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/physical_package_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/thread_siblings -Lines: 1 -11 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/thread_siblings_list -Lines: 1 -0,4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/cpufreq -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq -Lines: 1 -1200195 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq -Lines: 1 -3300000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq -Lines: 1 -1200000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_transition_latency -Lines: 1 -4294967295 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/related_cpus -Lines: 1 -1 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_governors -Lines: 1 -performance powersave -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_driver -Lines: 1 -intel_pstate -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor -Lines: 1 -powersave -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq -Lines: 1 -3300000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq -Lines: 1 -1200000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_setspeed -Lines: 1 - -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle/core_throttle_count -Lines: 1 -523 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle/package_throttle_count -Lines: 1 -34818 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/topology -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_id -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_siblings -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_siblings_list -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/physical_package_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/thread_siblings -Lines: 1 -22 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/thread_siblings_list -Lines: 1 -1,5 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq/policy0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/affected_cpus -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq -Lines: 1 -2400000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq -Lines: 1 -800000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_transition_latency -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/related_cpus -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors -Lines: 1 -performance powersave -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq -Lines: 1 -1219917 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_driver -Lines: 1 -intel_pstate -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_governor -Lines: 1 -powersave -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq -Lines: 1 -2400000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq -Lines: 1 -800000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -Lines: 1 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq/policy1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node1/vmstat -Lines: 6 -nr_free_pages 1 -nr_zone_inactive_anon 2 -nr_zone_active_anon 3 -nr_zone_inactive_file 4 -nr_zone_active_file 5 -nr_zone_unevictable 6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node2/vmstat -Lines: 6 -nr_free_pages 7 -nr_zone_inactive_anon 8 -nr_zone_active_anon 9 -nr_zone_inactive_file 10 -nr_zone_active_file 11 -nr_zone_unevictable 12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/average_key_size -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0 -Mode: 777 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/dirty_data -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/writeback_rate_debug -Lines: 7 -rate: 1.1M/sec -dirty: 20.4G -target: 20.4G -proportional: 427.5k -integral: 790.0k -change: 321.5k/sec -next io: 17ms -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/btree_cache_size -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0 -Mode: 777 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/io_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/metadata_written -Lines: 1 -512 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/priority_stats -Lines: 5 -Unused: 99% -Metadata: 0% -Average: 10473 -Sectors per Q: 64 -Quantiles: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/written -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache_available_percent -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/congested -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/active_journal_entries -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/btree_nodes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/btree_read_average_duration_us -Lines: 1 -1305 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/cache_read_races -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/root_usage_percent -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/tree_depth -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_used -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/disk_total -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/disk_used -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/flags -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0/total_bytes -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0/used_bytes -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/total_bytes -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/global_rsv_reserved -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/global_rsv_size -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_may_use -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_readonly -Lines: 1 -131072 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_used -Lines: 1 -933888 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/disk_total -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/disk_used -Lines: 1 -1867776 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/flags -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1/total_bytes -Lines: 1 -1073741824 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1/used_bytes -Lines: 1 -933888 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/total_bytes -Lines: 1 -1073741824 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/disk_total -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/disk_used -Lines: 1 -32768 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/flags -Lines: 1 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1/total_bytes -Lines: 1 -8388608 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1/used_bytes -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/total_bytes -Lines: 1 -8388608 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/clone_alignment -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop25 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop25/size -Lines: 1 -20971520 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop26 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop26/size -Lines: 1 -20971520 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/big_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/extended_iref -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/mixed_backref -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/skinny_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/label -Lines: 1 -fixture -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/metadata_uuid -Lines: 1 -0abb23a9-579b-43e6-ad30-227ef47fcb9d -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/nodesize -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/quota_override -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/sectorsize -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_used -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/disk_total -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/disk_used -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/flags -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5/total_bytes -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5/used_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/total_bytes -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/global_rsv_reserved -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/global_rsv_size -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_may_use -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_readonly -Lines: 1 -262144 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_used -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/disk_total -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/disk_used -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/flags -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6/total_bytes -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6/used_bytes -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/total_bytes -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/disk_total -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/disk_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/flags -Lines: 1 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6/total_bytes -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6/used_bytes -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/total_bytes -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/clone_alignment -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop22 -SymlinkTo: ../../../../devices/virtual/block/loop22 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop23 -SymlinkTo: ../../../../devices/virtual/block/loop23 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop24 -SymlinkTo: ../../../../devices/virtual/block/loop24 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop25 -SymlinkTo: ../../../../devices/virtual/block/loop25 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/big_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/extended_iref -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/mixed_backref -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/raid56 -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/skinny_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/label -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/metadata_uuid -Lines: 1 -7f07c59f-6136-449c-ab87-e1cf2328731b -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/nodesize -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/quota_override -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/sectorsize -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sda1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sda1/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/xfs/sda1/stats/stats -Lines: 1 -extent_alloc 1 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sdb1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sdb1/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/xfs/sdb1/stats/stats -Lines: 1 -extent_alloc 2 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/udev_path -Lines: 1 -/home/iscsi/file_back_1G -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/iblock_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/udev_path -Lines: 1 -/dev/rbd1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rbd_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/udev_path -Lines: 1 -/dev/rbd/iscsi-images/demo -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/udev_path -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/7f4a4eb56d -SymlinkTo: ../../../../../../target/core/rd_mcp_119/ramdisk_lio_1G -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -204950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -10325 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -40325 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/795b7c7026 -SymlinkTo: ../../../../../../target/core/iblock_0/block_lio_rbd1 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -104950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -20095 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -71235 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/fff5e16686 -SymlinkTo: ../../../../../../target/core/fileio_1/file_lio_1G -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -301950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -10195 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -30195 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/eba1edf893 -SymlinkTo: ../../../../../../target/core/rbd_0/iscsi-images-demo -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -1234 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -1504 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -4733 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/prometheus/procfs/internal/fs/fs.go b/vendor/github.com/prometheus/procfs/internal/fs/fs.go index 0040753b1c..3c18c7610e 100644 --- a/vendor/github.com/prometheus/procfs/internal/fs/fs.go +++ b/vendor/github.com/prometheus/procfs/internal/fs/fs.go @@ -26,7 +26,7 @@ const ( // DefaultSysMountPoint is the common mount point of the sys filesystem. DefaultSysMountPoint = "/sys" - // DefaultConfigfsMountPoint is the common mount point of the configfs + // DefaultConfigfsMountPoint is the common mount point of the configfs. DefaultConfigfsMountPoint = "/sys/kernel/config" ) diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go index 22cb07a6bb..b030951faf 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/parse.go +++ b/vendor/github.com/prometheus/procfs/internal/util/parse.go @@ -14,7 +14,7 @@ package util import ( - "io/ioutil" + "os" "strconv" "strings" ) @@ -66,7 +66,7 @@ func ParsePInt64s(ss []string) ([]*int64, error) { // ReadUintFromFile reads a file and attempts to parse a uint64 from it. func ReadUintFromFile(path string) (uint64, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } @@ -75,7 +75,7 @@ func ReadUintFromFile(path string) (uint64, error) { // ReadIntFromFile reads a file and attempts to parse a int64 from it. func ReadIntFromFile(path string) (int64, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } diff --git a/vendor/github.com/prometheus/procfs/internal/util/readfile.go b/vendor/github.com/prometheus/procfs/internal/util/readfile.go index 8051161b2a..71b7a70ebd 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/readfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/readfile.go @@ -15,17 +15,16 @@ package util import ( "io" - "io/ioutil" "os" ) -// ReadFileNoStat uses ioutil.ReadAll to read contents of entire file. -// This is similar to ioutil.ReadFile but without the call to os.Stat, because +// ReadFileNoStat uses io.ReadAll to read contents of entire file. +// This is similar to os.ReadFile but without the call to os.Stat, because // many files in /proc and /sys report incorrect file sizes (either 0 or 4096). -// Reads a max file size of 512kB. For files larger than this, a scanner +// Reads a max file size of 1024kB. For files larger than this, a scanner // should be used. func ReadFileNoStat(filename string) ([]byte, error) { - const maxBufferSize = 1024 * 512 + const maxBufferSize = 1024 * 1024 f, err := os.Open(filename) if err != nil { @@ -34,5 +33,5 @@ func ReadFileNoStat(filename string) ([]byte, error) { defer f.Close() reader := io.LimitReader(f, maxBufferSize) - return ioutil.ReadAll(reader) + return io.ReadAll(reader) } diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go index c07de0b6c9..1ab875ceec 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go @@ -11,7 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux,!appengine +//go:build (linux || darwin) && !appengine +// +build linux darwin +// +build !appengine package util @@ -21,7 +23,7 @@ import ( "syscall" ) -// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly. +// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly. // https://github.com/prometheus/node_exporter/pull/728/files // // Note that this function will not read files larger than 128 bytes. @@ -33,7 +35,7 @@ func SysReadFile(file string) (string, error) { defer f.Close() // On some machines, hwmon drivers are broken and return EAGAIN. This causes - // Go's ioutil.ReadFile implementation to poll forever. + // Go's os.ReadFile implementation to poll forever. // // Since we either want to read data or bail immediately, do the simplest // possible read using syscall directly. diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go index bd55b45377..1d86f5e63f 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go @@ -11,7 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux,appengine !linux +//go:build (linux && appengine) || (!linux && !darwin) +// +build linux,appengine !linux,!darwin package util diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go index 89e447746c..391c07957e 100644 --- a/vendor/github.com/prometheus/procfs/ipvs.go +++ b/vendor/github.com/prometheus/procfs/ipvs.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "strconv" @@ -84,7 +83,7 @@ func parseIPVSStats(r io.Reader) (IPVSStats, error) { stats IPVSStats ) - statContent, err := ioutil.ReadAll(r) + statContent, err := io.ReadAll(r) if err != nil { return IPVSStats{}, err } diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go index da3a941d60..db88566bdf 100644 --- a/vendor/github.com/prometheus/procfs/kernel_random.go +++ b/vendor/github.com/prometheus/procfs/kernel_random.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs diff --git a/vendor/github.com/prometheus/procfs/loadavg.go b/vendor/github.com/prometheus/procfs/loadavg.go index 0cce190ec2..0096cafbdf 100644 --- a/vendor/github.com/prometheus/procfs/loadavg.go +++ b/vendor/github.com/prometheus/procfs/loadavg.go @@ -21,7 +21,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// LoadAvg represents an entry in /proc/loadavg +// LoadAvg represents an entry in /proc/loadavg. type LoadAvg struct { Load1 float64 Load5 float64 diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go index f0b9e5f75a..a95c889cb9 100644 --- a/vendor/github.com/prometheus/procfs/mdstat.go +++ b/vendor/github.com/prometheus/procfs/mdstat.go @@ -15,7 +15,7 @@ package procfs import ( "fmt" - "io/ioutil" + "os" "regexp" "strconv" "strings" @@ -64,7 +64,7 @@ type MDStat struct { // structs containing the relevant info. More information available here: // https://raid.wiki.kernel.org/index.php/Mdstat func (fs FS) MDStat() ([]MDStat, error) { - data, err := ioutil.ReadFile(fs.proc.Path("mdstat")) + data, err := os.ReadFile(fs.proc.Path("mdstat")) if err != nil { return nil, err } @@ -166,8 +166,12 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { } func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { + statusFields := strings.Fields(statusLine) + if len(statusFields) < 1 { + return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q", statusLine) + } - sizeStr := strings.Fields(statusLine)[0] + sizeStr := statusFields[0] size, err = strconv.ParseInt(sizeStr, 10, 64) if err != nil { return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go index f7a828bb1d..0c482c18cc 100644 --- a/vendor/github.com/prometheus/procfs/mountstats.go +++ b/vendor/github.com/prometheus/procfs/mountstats.go @@ -284,7 +284,8 @@ func parseMountStats(r io.Reader) ([]*Mount, error) { } // parseMount parses an entry in /proc/[pid]/mountstats in the format: -// device [device] mounted on [mount] with fstype [type] +// +// device [device] mounted on [mount] with fstype [type] func parseMount(ss []string) (*Mount, error) { if len(ss) < deviceEntryLen { return nil, fmt.Errorf("invalid device entry: %v", ss) diff --git a/vendor/github.com/prometheus/procfs/net_conntrackstat.go b/vendor/github.com/prometheus/procfs/net_conntrackstat.go index 9964a3600b..8300daca05 100644 --- a/vendor/github.com/prometheus/procfs/net_conntrackstat.go +++ b/vendor/github.com/prometheus/procfs/net_conntrackstat.go @@ -25,7 +25,7 @@ import ( ) // A ConntrackStatEntry represents one line from net/stat/nf_conntrack -// and contains netfilter conntrack statistics at one CPU core +// and contains netfilter conntrack statistics at one CPU core. type ConntrackStatEntry struct { Entries uint64 Found uint64 @@ -38,12 +38,12 @@ type ConntrackStatEntry struct { SearchRestart uint64 } -// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores +// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores. func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) { return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack")) } -// Parses a slice of ConntrackStatEntries from the given filepath +// Parses a slice of ConntrackStatEntries from the given filepath. func readConntrackStat(path string) ([]ConntrackStatEntry, error) { // This file is small and can be read with one syscall. b, err := util.ReadFileNoStat(path) @@ -61,7 +61,7 @@ func readConntrackStat(path string) ([]ConntrackStatEntry, error) { return stat, nil } -// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries +// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries. func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { var entries []ConntrackStatEntry @@ -79,7 +79,7 @@ func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { return entries, nil } -// Parses a ConntrackStatEntry from given array of fields +// Parses a ConntrackStatEntry from given array of fields. func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { if len(fields) != 17 { return nil, fmt.Errorf("invalid conntrackstat entry, missing fields") @@ -143,7 +143,7 @@ func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { return entry, nil } -// Parses a uint64 from given hex in string +// Parses a uint64 from given hex in string. func parseConntrackStatField(field string) (uint64, error) { val, err := strconv.ParseUint(field, 16, 64) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go index 47a710befb..e66208aa05 100644 --- a/vendor/github.com/prometheus/procfs/net_dev.go +++ b/vendor/github.com/prometheus/procfs/net_dev.go @@ -87,17 +87,17 @@ func newNetDev(file string) (NetDev, error) { // parseLine parses a single line from the /proc/net/dev file. Header lines // must be filtered prior to calling this method. func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) { - parts := strings.SplitN(rawLine, ":", 2) - if len(parts) != 2 { + idx := strings.LastIndex(rawLine, ":") + if idx == -1 { return nil, errors.New("invalid net/dev line, missing colon") } - fields := strings.Fields(strings.TrimSpace(parts[1])) + fields := strings.Fields(strings.TrimSpace(rawLine[idx+1:])) var err error line := &NetDevLine{} // Interface Name - line.Name = strings.TrimSpace(parts[0]) + line.Name = strings.TrimSpace(rawLine[:idx]) if line.Name == "" { return nil, errors.New("invalid net/dev line, empty interface name") } diff --git a/vendor/github.com/prometheus/procfs/net_ip_socket.go b/vendor/github.com/prometheus/procfs/net_ip_socket.go index 8c9ee3de87..7fd57d7f46 100644 --- a/vendor/github.com/prometheus/procfs/net_ip_socket.go +++ b/vendor/github.com/prometheus/procfs/net_ip_socket.go @@ -34,7 +34,7 @@ const ( readLimit = 4294967296 // Byte -> 4 GiB ) -// this contains generic data structures for both udp and tcp sockets +// This contains generic data structures for both udp and tcp sockets. type ( // NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header. NetIPSocket []*netIPSocketLine diff --git a/vendor/github.com/prometheus/procfs/net_protocols.go b/vendor/github.com/prometheus/procfs/net_protocols.go index 8c6de3791b..374b6f73f8 100644 --- a/vendor/github.com/prometheus/procfs/net_protocols.go +++ b/vendor/github.com/prometheus/procfs/net_protocols.go @@ -23,7 +23,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// NetProtocolStats stores the contents from /proc/net/protocols +// NetProtocolStats stores the contents from /proc/net/protocols. type NetProtocolStats map[string]NetProtocolStatLine // NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We @@ -41,7 +41,7 @@ type NetProtocolStatLine struct { Capabilities NetProtocolCapabilities } -// NetProtocolCapabilities contains a list of capabilities for each protocol +// NetProtocolCapabilities contains a list of capabilities for each protocol. type NetProtocolCapabilities struct { Close bool // 8 Connect bool // 9 diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go index 46f12c61d3..06b7b8f216 100644 --- a/vendor/github.com/prometheus/procfs/net_softnet.go +++ b/vendor/github.com/prometheus/procfs/net_softnet.go @@ -27,17 +27,30 @@ import ( // For the proc file format details, // See: // * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343 -// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 -// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. +// * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 +// * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 +// * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 -// SoftnetStat contains a single row of data from /proc/net/softnet_stat +// SoftnetStat contains a single row of data from /proc/net/softnet_stat. type SoftnetStat struct { - // Number of processed packets + // Number of processed packets. Processed uint32 - // Number of dropped packets + // Number of dropped packets. Dropped uint32 - // Number of times processing packets ran out of quota + // Number of times processing packets ran out of quota. TimeSqueezed uint32 + // Number of collision occur while obtaining device lock while transmitting. + CPUCollision uint32 + // Number of times cpu woken up received_rps. + ReceivedRps uint32 + // number of times flow limit has been reached. + FlowLimitCount uint32 + // Softnet backlog status. + SoftnetBacklogLen uint32 + // CPU id owning this softnet_data. + Index uint32 + // softnet_data's Width. + Width int } var softNetProcFile = "net/softnet_stat" @@ -66,22 +79,57 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) { for s.Scan() { columns := strings.Fields(s.Text()) width := len(columns) + softnetStat := SoftnetStat{} if width < minColumns { return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns) } - // We only parse the first three columns at the moment. - us, err := parseHexUint32s(columns[0:3]) - if err != nil { - return nil, err + // Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347 + if width >= minColumns { + us, err := parseHexUint32s(columns[0:9]) + if err != nil { + return nil, err + } + + softnetStat.Processed = us[0] + softnetStat.Dropped = us[1] + softnetStat.TimeSqueezed = us[2] + softnetStat.CPUCollision = us[8] + } + + // Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 + if width >= 10 { + us, err := parseHexUint32s(columns[9:10]) + if err != nil { + return nil, err + } + + softnetStat.ReceivedRps = us[0] } - stats = append(stats, SoftnetStat{ - Processed: us[0], - Dropped: us[1], - TimeSqueezed: us[2], - }) + // Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 + if width >= 11 { + us, err := parseHexUint32s(columns[10:11]) + if err != nil { + return nil, err + } + + softnetStat.FlowLimitCount = us[0] + } + + // Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 + if width >= 13 { + us, err := parseHexUint32s(columns[11:13]) + if err != nil { + return nil, err + } + + softnetStat.SoftnetBacklogLen = us[0] + softnetStat.Index = us[1] + } + softnetStat.Width = width + stats = append(stats, softnetStat) } return stats, nil diff --git a/vendor/github.com/prometheus/procfs/net_xfrm.go b/vendor/github.com/prometheus/procfs/net_xfrm.go new file mode 100644 index 0000000000..f9d9d243db --- /dev/null +++ b/vendor/github.com/prometheus/procfs/net_xfrm.go @@ -0,0 +1,189 @@ +// Copyright 2017 Prometheus Team +// 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 procfs + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// XfrmStat models the contents of /proc/net/xfrm_stat. +type XfrmStat struct { + // All errors which are not matched by other + XfrmInError int + // No buffer is left + XfrmInBufferError int + // Header Error + XfrmInHdrError int + // No state found + // i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong + XfrmInNoStates int + // Transformation protocol specific error + // e.g. SA Key is wrong + XfrmInStateProtoError int + // Transformation mode specific error + XfrmInStateModeError int + // Sequence error + // e.g. sequence number is out of window + XfrmInStateSeqError int + // State is expired + XfrmInStateExpired int + // State has mismatch option + // e.g. UDP encapsulation type is mismatched + XfrmInStateMismatch int + // State is invalid + XfrmInStateInvalid int + // No matching template for states + // e.g. Inbound SAs are correct but SP rule is wrong + XfrmInTmplMismatch int + // No policy is found for states + // e.g. Inbound SAs are correct but no SP is found + XfrmInNoPols int + // Policy discards + XfrmInPolBlock int + // Policy error + XfrmInPolError int + // All errors which are not matched by others + XfrmOutError int + // Bundle generation error + XfrmOutBundleGenError int + // Bundle check error + XfrmOutBundleCheckError int + // No state was found + XfrmOutNoStates int + // Transformation protocol specific error + XfrmOutStateProtoError int + // Transportation mode specific error + XfrmOutStateModeError int + // Sequence error + // i.e sequence number overflow + XfrmOutStateSeqError int + // State is expired + XfrmOutStateExpired int + // Policy discads + XfrmOutPolBlock int + // Policy is dead + XfrmOutPolDead int + // Policy Error + XfrmOutPolError int + // Forward routing of a packet is not allowed + XfrmFwdHdrError int + // State is invalid, perhaps expired + XfrmOutStateInvalid int + // State hasn’t been fully acquired before use + XfrmAcquireError int +} + +// NewXfrmStat reads the xfrm_stat statistics. +func NewXfrmStat() (XfrmStat, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return XfrmStat{}, err + } + + return fs.NewXfrmStat() +} + +// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem. +func (fs FS) NewXfrmStat() (XfrmStat, error) { + file, err := os.Open(fs.proc.Path("net/xfrm_stat")) + if err != nil { + return XfrmStat{}, err + } + defer file.Close() + + var ( + x = XfrmStat{} + s = bufio.NewScanner(file) + ) + + for s.Scan() { + fields := strings.Fields(s.Text()) + + if len(fields) != 2 { + return XfrmStat{}, fmt.Errorf("couldn't parse %q line %q", file.Name(), s.Text()) + } + + name := fields[0] + value, err := strconv.Atoi(fields[1]) + if err != nil { + return XfrmStat{}, err + } + + switch name { + case "XfrmInError": + x.XfrmInError = value + case "XfrmInBufferError": + x.XfrmInBufferError = value + case "XfrmInHdrError": + x.XfrmInHdrError = value + case "XfrmInNoStates": + x.XfrmInNoStates = value + case "XfrmInStateProtoError": + x.XfrmInStateProtoError = value + case "XfrmInStateModeError": + x.XfrmInStateModeError = value + case "XfrmInStateSeqError": + x.XfrmInStateSeqError = value + case "XfrmInStateExpired": + x.XfrmInStateExpired = value + case "XfrmInStateInvalid": + x.XfrmInStateInvalid = value + case "XfrmInTmplMismatch": + x.XfrmInTmplMismatch = value + case "XfrmInNoPols": + x.XfrmInNoPols = value + case "XfrmInPolBlock": + x.XfrmInPolBlock = value + case "XfrmInPolError": + x.XfrmInPolError = value + case "XfrmOutError": + x.XfrmOutError = value + case "XfrmInStateMismatch": + x.XfrmInStateMismatch = value + case "XfrmOutBundleGenError": + x.XfrmOutBundleGenError = value + case "XfrmOutBundleCheckError": + x.XfrmOutBundleCheckError = value + case "XfrmOutNoStates": + x.XfrmOutNoStates = value + case "XfrmOutStateProtoError": + x.XfrmOutStateProtoError = value + case "XfrmOutStateModeError": + x.XfrmOutStateModeError = value + case "XfrmOutStateSeqError": + x.XfrmOutStateSeqError = value + case "XfrmOutStateExpired": + x.XfrmOutStateExpired = value + case "XfrmOutPolBlock": + x.XfrmOutPolBlock = value + case "XfrmOutPolDead": + x.XfrmOutPolDead = value + case "XfrmOutPolError": + x.XfrmOutPolError = value + case "XfrmFwdHdrError": + x.XfrmFwdHdrError = value + case "XfrmOutStateInvalid": + x.XfrmOutStateInvalid = value + case "XfrmAcquireError": + x.XfrmAcquireError = value + } + + } + + return x, s.Err() +} diff --git a/vendor/github.com/prometheus/procfs/netstat.go b/vendor/github.com/prometheus/procfs/netstat.go index 94d892f113..5cc40aef55 100644 --- a/vendor/github.com/prometheus/procfs/netstat.go +++ b/vendor/github.com/prometheus/procfs/netstat.go @@ -15,19 +15,20 @@ package procfs import ( "bufio" + "io" "os" "path/filepath" "strconv" "strings" ) -// NetStat contains statistics for all the counters from one file +// NetStat contains statistics for all the counters from one file. type NetStat struct { - Filename string Stats map[string][]uint64 + Filename string } -// NetStat retrieves stats from /proc/net/stat/ +// NetStat retrieves stats from `/proc/net/stat/`. func (fs FS) NetStat() ([]NetStat, error) { statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) if err != nil { @@ -42,27 +43,43 @@ func (fs FS) NetStat() ([]NetStat, error) { return nil, err } - netStatFile := NetStat{ - Filename: filepath.Base(filePath), - Stats: make(map[string][]uint64), + procNetstat, err := parseNetstat(file) + if err != nil { + return nil, err + } + procNetstat.Filename = filepath.Base(filePath) + + netStatsTotal = append(netStatsTotal, procNetstat) + } + return netStatsTotal, nil +} + +// parseNetstat parses the metrics from `/proc/net/stat/` file +// and returns a NetStat structure. +func parseNetstat(r io.Reader) (NetStat, error) { + var ( + scanner = bufio.NewScanner(r) + netStat = NetStat{ + Stats: make(map[string][]uint64), } - scanner := bufio.NewScanner(file) - scanner.Scan() - // First string is always a header for stats - var headers []string - headers = append(headers, strings.Fields(scanner.Text())...) + ) + + scanner.Scan() - // Other strings represent per-CPU counters - for scanner.Scan() { - for num, counter := range strings.Fields(scanner.Text()) { - value, err := strconv.ParseUint(counter, 16, 32) - if err != nil { - return nil, err - } - netStatFile.Stats[headers[num]] = append(netStatFile.Stats[headers[num]], value) + // First string is always a header for stats + var headers []string + headers = append(headers, strings.Fields(scanner.Text())...) + + // Other strings represent per-CPU counters + for scanner.Scan() { + for num, counter := range strings.Fields(scanner.Text()) { + value, err := strconv.ParseUint(counter, 16, 64) + if err != nil { + return NetStat{}, err } + netStat.Stats[headers[num]] = append(netStat.Stats[headers[num]], value) } - netStatsTotal = append(netStatsTotal, netStatFile) } - return netStatsTotal, nil + + return netStat, nil } diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index 28f696803f..c30223af72 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -16,7 +16,7 @@ package procfs import ( "bytes" "fmt" - "io/ioutil" + "io" "os" "strconv" "strings" @@ -82,7 +82,7 @@ func (fs FS) Self() (Proc, error) { // NewProc returns a process for the given pid. // -// Deprecated: use fs.Proc() instead +// Deprecated: Use fs.Proc() instead. func (fs FS) NewProc(pid int) (Proc, error) { return fs.Proc(pid) } @@ -142,7 +142,7 @@ func (p Proc) Wchan() (string, error) { } defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) if err != nil { return "", err } @@ -185,7 +185,7 @@ func (p Proc) Cwd() (string, error) { return wd, err } -// RootDir returns the absolute path to the process's root directory (as set by chroot) +// RootDir returns the absolute path to the process's root directory (as set by chroot). func (p Proc) RootDir() (string, error) { rdir, err := os.Readlink(p.path("root")) if os.IsNotExist(err) { @@ -311,7 +311,7 @@ func (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) { // Schedstat returns task scheduling information for the process. func (p Proc) Schedstat() (ProcSchedstat, error) { - contents, err := ioutil.ReadFile(p.path("schedstat")) + contents, err := os.ReadFile(p.path("schedstat")) if err != nil { return ProcSchedstat{}, err } diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index be45b79873..ea83a75ffc 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -23,7 +23,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the the placement of a PID inside a +// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the placement of a PID inside a // specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource // controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies // contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in @@ -45,7 +45,7 @@ type Cgroup struct { } // parseCgroupString parses each line of the /proc/[pid]/cgroup file -// Line format is hierarchyID:[controller1,controller2]:path +// Line format is hierarchyID:[controller1,controller2]:path. func parseCgroupString(cgroupStr string) (*Cgroup, error) { var err error @@ -69,7 +69,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) { return cgroup, nil } -// parseCgroups reads each line of the /proc/[pid]/cgroup file +// parseCgroups reads each line of the /proc/[pid]/cgroup file. func parseCgroups(data []byte) ([]Cgroup, error) { var cgroups []Cgroup scanner := bufio.NewScanner(bytes.NewReader(data)) @@ -88,7 +88,7 @@ func parseCgroups(data []byte) ([]Cgroup, error) { // Cgroups reads from /proc//cgroups and returns a []*Cgroup struct locating this PID in each process // control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes, -// so the len of the returned struct is equal to the number of active hierarchies on this system +// so the len of the returned struct is equal to the number of active hierarchies on this system. func (p Proc) Cgroups() ([]Cgroup, error) { data, err := util.ReadFileNoStat(p.path("cgroup")) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/proc_cgroups.go b/vendor/github.com/prometheus/procfs/proc_cgroups.go new file mode 100644 index 0000000000..24d4dce9cf --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_cgroups.go @@ -0,0 +1,98 @@ +// Copyright 2021 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "fmt" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// CgroupSummary models one line from /proc/cgroups. +// This file contains information about the controllers that are compiled into the kernel. +// +// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html +type CgroupSummary struct { + // The name of the controller. controller is also known as subsystem. + SubsysName string + // The unique ID of the cgroup hierarchy on which this controller is mounted. + Hierarchy int + // The number of control groups in this hierarchy using this controller. + Cgroups int + // This field contains the value 1 if this controller is enabled, or 0 if it has been disabled + Enabled int +} + +// parseCgroupSummary parses each line of the /proc/cgroup file +// Line format is `subsys_name hierarchy num_cgroups enabled`. +func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) { + var err error + + fields := strings.Fields(CgroupSummaryStr) + // require at least 4 fields + if len(fields) < 4 { + return nil, fmt.Errorf("at least 4 fields required, found %d fields in cgroup info string: %s", len(fields), CgroupSummaryStr) + } + + CgroupSummary := &CgroupSummary{ + SubsysName: fields[0], + } + CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1]) + if err != nil { + return nil, fmt.Errorf("failed to parse hierarchy ID") + } + CgroupSummary.Cgroups, err = strconv.Atoi(fields[2]) + if err != nil { + return nil, fmt.Errorf("failed to parse Cgroup Num") + } + CgroupSummary.Enabled, err = strconv.Atoi(fields[3]) + if err != nil { + return nil, fmt.Errorf("failed to parse Enabled") + } + return CgroupSummary, nil +} + +// parseCgroupSummary reads each line of the /proc/cgroup file. +func parseCgroupSummary(data []byte) ([]CgroupSummary, error) { + var CgroupSummarys []CgroupSummary + scanner := bufio.NewScanner(bytes.NewReader(data)) + for scanner.Scan() { + CgroupSummaryString := scanner.Text() + // ignore comment lines + if strings.HasPrefix(CgroupSummaryString, "#") { + continue + } + CgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString) + if err != nil { + return nil, err + } + CgroupSummarys = append(CgroupSummarys, *CgroupSummary) + } + + err := scanner.Err() + return CgroupSummarys, err +} + +// CgroupSummarys returns information about current /proc/cgroups. +func (fs FS) CgroupSummarys() ([]CgroupSummary, error) { + data, err := util.ReadFileNoStat(fs.proc.Path("cgroups")) + if err != nil { + return nil, err + } + return parseCgroupSummary(data) +} diff --git a/vendor/github.com/prometheus/procfs/proc_environ.go b/vendor/github.com/prometheus/procfs/proc_environ.go index 6134b3580c..57a89895d6 100644 --- a/vendor/github.com/prometheus/procfs/proc_environ.go +++ b/vendor/github.com/prometheus/procfs/proc_environ.go @@ -19,7 +19,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Environ reads process environments from /proc//environ +// Environ reads process environments from `/proc//environ`. func (p Proc) Environ() ([]string, error) { environments := make([]string, 0) diff --git a/vendor/github.com/prometheus/procfs/proc_fdinfo.go b/vendor/github.com/prometheus/procfs/proc_fdinfo.go index cf63227f06..1bbdd4a8e9 100644 --- a/vendor/github.com/prometheus/procfs/proc_fdinfo.go +++ b/vendor/github.com/prometheus/procfs/proc_fdinfo.go @@ -22,7 +22,6 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Regexp variables var ( rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) @@ -122,7 +121,7 @@ func (p ProcFDInfos) Len() int { return len(p) } func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD } -// InotifyWatchLen returns the total number of inotify watches +// InotifyWatchLen returns the total number of inotify watches. func (p ProcFDInfos) InotifyWatchLen() (int, error) { length := 0 for _, f := range p { diff --git a/vendor/github.com/prometheus/procfs/proc_interrupts.go b/vendor/github.com/prometheus/procfs/proc_interrupts.go new file mode 100644 index 0000000000..9df79c2379 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_interrupts.go @@ -0,0 +1,98 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// Interrupt represents a single interrupt line. +type Interrupt struct { + // Info is the type of interrupt. + Info string + // Devices is the name of the device that is located at that IRQ + Devices string + // Values is the number of interrupts per CPU. + Values []string +} + +// Interrupts models the content of /proc/interrupts. Key is the IRQ number. +// - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-interrupts +// - https://raspberrypi.stackexchange.com/questions/105802/explanation-of-proc-interrupts-output +type Interrupts map[string]Interrupt + +// Interrupts creates a new instance from a given Proc instance. +func (p Proc) Interrupts() (Interrupts, error) { + data, err := util.ReadFileNoStat(p.path("interrupts")) + if err != nil { + return nil, err + } + return parseInterrupts(bytes.NewReader(data)) +} + +func parseInterrupts(r io.Reader) (Interrupts, error) { + var ( + interrupts = Interrupts{} + scanner = bufio.NewScanner(r) + ) + + if !scanner.Scan() { + return nil, errors.New("interrupts empty") + } + cpuNum := len(strings.Fields(scanner.Text())) // one header per cpu + + for scanner.Scan() { + parts := strings.Fields(scanner.Text()) + if len(parts) == 0 { // skip empty lines + continue + } + if len(parts) < 2 { + return nil, fmt.Errorf("not enough fields in interrupts (expected at least 2 fields but got %d): %s", len(parts), parts) + } + intName := parts[0][:len(parts[0])-1] // remove trailing : + + if len(parts) == 2 { + interrupts[intName] = Interrupt{ + Info: "", + Devices: "", + Values: []string{ + parts[1], + }, + } + continue + } + + intr := Interrupt{ + Values: parts[1 : cpuNum+1], + } + + if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt + intr.Info = parts[cpuNum+1] + intr.Devices = strings.Join(parts[cpuNum+2:], " ") + } else { + intr.Info = strings.Join(parts[cpuNum+1:], " ") + } + interrupts[intName] = intr + } + + return interrupts, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go index dd20f198a3..7a1388185a 100644 --- a/vendor/github.com/prometheus/procfs/proc_limits.go +++ b/vendor/github.com/prometheus/procfs/proc_limits.go @@ -79,7 +79,7 @@ var ( // NewLimits returns the current soft limits of the process. // -// Deprecated: use p.Limits() instead +// Deprecated: Use p.Limits() instead. func (p Proc) NewLimits() (ProcLimits, error) { return p.Limits() } diff --git a/vendor/github.com/prometheus/procfs/proc_maps.go b/vendor/github.com/prometheus/procfs/proc_maps.go index 1d7772d516..f1bcbf32bb 100644 --- a/vendor/github.com/prometheus/procfs/proc_maps.go +++ b/vendor/github.com/prometheus/procfs/proc_maps.go @@ -11,7 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +// +build !js package procfs @@ -25,7 +27,7 @@ import ( "golang.org/x/sys/unix" ) -// ProcMapPermissions contains permission settings read from /proc/[pid]/maps +// ProcMapPermissions contains permission settings read from `/proc/[pid]/maps`. type ProcMapPermissions struct { // mapping has the [R]ead flag set Read bool @@ -39,8 +41,8 @@ type ProcMapPermissions struct { Private bool } -// ProcMap contains the process memory-mappings of the process, -// read from /proc/[pid]/maps +// ProcMap contains the process memory-mappings of the process +// read from `/proc/[pid]/maps`. type ProcMap struct { // The start address of current mapping. StartAddr uintptr @@ -79,7 +81,7 @@ func parseDevice(s string) (uint64, error) { return unix.Mkdev(uint32(major), uint32(minor)), nil } -// parseAddress just converts a hex-string to a uintptr +// parseAddress converts a hex-string to a uintptr. func parseAddress(s string) (uintptr, error) { a, err := strconv.ParseUint(s, 16, 0) if err != nil { @@ -89,7 +91,7 @@ func parseAddress(s string) (uintptr, error) { return uintptr(a), nil } -// parseAddresses parses the start-end address +// parseAddresses parses the start-end address. func parseAddresses(s string) (uintptr, uintptr, error) { toks := strings.Split(s, "-") if len(toks) < 2 { diff --git a/vendor/github.com/prometheus/procfs/proc_netstat.go b/vendor/github.com/prometheus/procfs/proc_netstat.go new file mode 100644 index 0000000000..6a43bb2459 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_netstat.go @@ -0,0 +1,443 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcNetstat models the content of /proc//net/netstat. +type ProcNetstat struct { + // The process ID. + PID int + TcpExt + IpExt +} + +type TcpExt struct { // nolint:revive + SyncookiesSent *float64 + SyncookiesRecv *float64 + SyncookiesFailed *float64 + EmbryonicRsts *float64 + PruneCalled *float64 + RcvPruned *float64 + OfoPruned *float64 + OutOfWindowIcmps *float64 + LockDroppedIcmps *float64 + ArpFilter *float64 + TW *float64 + TWRecycled *float64 + TWKilled *float64 + PAWSActive *float64 + PAWSEstab *float64 + DelayedACKs *float64 + DelayedACKLocked *float64 + DelayedACKLost *float64 + ListenOverflows *float64 + ListenDrops *float64 + TCPHPHits *float64 + TCPPureAcks *float64 + TCPHPAcks *float64 + TCPRenoRecovery *float64 + TCPSackRecovery *float64 + TCPSACKReneging *float64 + TCPSACKReorder *float64 + TCPRenoReorder *float64 + TCPTSReorder *float64 + TCPFullUndo *float64 + TCPPartialUndo *float64 + TCPDSACKUndo *float64 + TCPLossUndo *float64 + TCPLostRetransmit *float64 + TCPRenoFailures *float64 + TCPSackFailures *float64 + TCPLossFailures *float64 + TCPFastRetrans *float64 + TCPSlowStartRetrans *float64 + TCPTimeouts *float64 + TCPLossProbes *float64 + TCPLossProbeRecovery *float64 + TCPRenoRecoveryFail *float64 + TCPSackRecoveryFail *float64 + TCPRcvCollapsed *float64 + TCPDSACKOldSent *float64 + TCPDSACKOfoSent *float64 + TCPDSACKRecv *float64 + TCPDSACKOfoRecv *float64 + TCPAbortOnData *float64 + TCPAbortOnClose *float64 + TCPAbortOnMemory *float64 + TCPAbortOnTimeout *float64 + TCPAbortOnLinger *float64 + TCPAbortFailed *float64 + TCPMemoryPressures *float64 + TCPMemoryPressuresChrono *float64 + TCPSACKDiscard *float64 + TCPDSACKIgnoredOld *float64 + TCPDSACKIgnoredNoUndo *float64 + TCPSpuriousRTOs *float64 + TCPMD5NotFound *float64 + TCPMD5Unexpected *float64 + TCPMD5Failure *float64 + TCPSackShifted *float64 + TCPSackMerged *float64 + TCPSackShiftFallback *float64 + TCPBacklogDrop *float64 + PFMemallocDrop *float64 + TCPMinTTLDrop *float64 + TCPDeferAcceptDrop *float64 + IPReversePathFilter *float64 + TCPTimeWaitOverflow *float64 + TCPReqQFullDoCookies *float64 + TCPReqQFullDrop *float64 + TCPRetransFail *float64 + TCPRcvCoalesce *float64 + TCPRcvQDrop *float64 + TCPOFOQueue *float64 + TCPOFODrop *float64 + TCPOFOMerge *float64 + TCPChallengeACK *float64 + TCPSYNChallenge *float64 + TCPFastOpenActive *float64 + TCPFastOpenActiveFail *float64 + TCPFastOpenPassive *float64 + TCPFastOpenPassiveFail *float64 + TCPFastOpenListenOverflow *float64 + TCPFastOpenCookieReqd *float64 + TCPFastOpenBlackhole *float64 + TCPSpuriousRtxHostQueues *float64 + BusyPollRxPackets *float64 + TCPAutoCorking *float64 + TCPFromZeroWindowAdv *float64 + TCPToZeroWindowAdv *float64 + TCPWantZeroWindowAdv *float64 + TCPSynRetrans *float64 + TCPOrigDataSent *float64 + TCPHystartTrainDetect *float64 + TCPHystartTrainCwnd *float64 + TCPHystartDelayDetect *float64 + TCPHystartDelayCwnd *float64 + TCPACKSkippedSynRecv *float64 + TCPACKSkippedPAWS *float64 + TCPACKSkippedSeq *float64 + TCPACKSkippedFinWait2 *float64 + TCPACKSkippedTimeWait *float64 + TCPACKSkippedChallenge *float64 + TCPWinProbe *float64 + TCPKeepAlive *float64 + TCPMTUPFail *float64 + TCPMTUPSuccess *float64 + TCPWqueueTooBig *float64 +} + +type IpExt struct { // nolint:revive + InNoRoutes *float64 + InTruncatedPkts *float64 + InMcastPkts *float64 + OutMcastPkts *float64 + InBcastPkts *float64 + OutBcastPkts *float64 + InOctets *float64 + OutOctets *float64 + InMcastOctets *float64 + OutMcastOctets *float64 + InBcastOctets *float64 + OutBcastOctets *float64 + InCsumErrors *float64 + InNoECTPkts *float64 + InECT1Pkts *float64 + InECT0Pkts *float64 + InCEPkts *float64 + ReasmOverlaps *float64 +} + +func (p Proc) Netstat() (ProcNetstat, error) { + filename := p.path("net/netstat") + data, err := util.ReadFileNoStat(filename) + if err != nil { + return ProcNetstat{PID: p.PID}, err + } + procNetstat, err := parseProcNetstat(bytes.NewReader(data), filename) + procNetstat.PID = p.PID + return procNetstat, err +} + +// parseProcNetstat parses the metrics from proc//net/netstat file +// and returns a ProcNetstat structure. +func parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) { + var ( + scanner = bufio.NewScanner(r) + procNetstat = ProcNetstat{} + ) + + for scanner.Scan() { + nameParts := strings.Split(scanner.Text(), " ") + scanner.Scan() + valueParts := strings.Split(scanner.Text(), " ") + // Remove trailing :. + protocol := strings.TrimSuffix(nameParts[0], ":") + if len(nameParts) != len(valueParts) { + return procNetstat, fmt.Errorf("mismatch field count mismatch in %s: %s", + fileName, protocol) + } + for i := 1; i < len(nameParts); i++ { + value, err := strconv.ParseFloat(valueParts[i], 64) + if err != nil { + return procNetstat, err + } + key := nameParts[i] + + switch protocol { + case "TcpExt": + switch key { + case "SyncookiesSent": + procNetstat.TcpExt.SyncookiesSent = &value + case "SyncookiesRecv": + procNetstat.TcpExt.SyncookiesRecv = &value + case "SyncookiesFailed": + procNetstat.TcpExt.SyncookiesFailed = &value + case "EmbryonicRsts": + procNetstat.TcpExt.EmbryonicRsts = &value + case "PruneCalled": + procNetstat.TcpExt.PruneCalled = &value + case "RcvPruned": + procNetstat.TcpExt.RcvPruned = &value + case "OfoPruned": + procNetstat.TcpExt.OfoPruned = &value + case "OutOfWindowIcmps": + procNetstat.TcpExt.OutOfWindowIcmps = &value + case "LockDroppedIcmps": + procNetstat.TcpExt.LockDroppedIcmps = &value + case "ArpFilter": + procNetstat.TcpExt.ArpFilter = &value + case "TW": + procNetstat.TcpExt.TW = &value + case "TWRecycled": + procNetstat.TcpExt.TWRecycled = &value + case "TWKilled": + procNetstat.TcpExt.TWKilled = &value + case "PAWSActive": + procNetstat.TcpExt.PAWSActive = &value + case "PAWSEstab": + procNetstat.TcpExt.PAWSEstab = &value + case "DelayedACKs": + procNetstat.TcpExt.DelayedACKs = &value + case "DelayedACKLocked": + procNetstat.TcpExt.DelayedACKLocked = &value + case "DelayedACKLost": + procNetstat.TcpExt.DelayedACKLost = &value + case "ListenOverflows": + procNetstat.TcpExt.ListenOverflows = &value + case "ListenDrops": + procNetstat.TcpExt.ListenDrops = &value + case "TCPHPHits": + procNetstat.TcpExt.TCPHPHits = &value + case "TCPPureAcks": + procNetstat.TcpExt.TCPPureAcks = &value + case "TCPHPAcks": + procNetstat.TcpExt.TCPHPAcks = &value + case "TCPRenoRecovery": + procNetstat.TcpExt.TCPRenoRecovery = &value + case "TCPSackRecovery": + procNetstat.TcpExt.TCPSackRecovery = &value + case "TCPSACKReneging": + procNetstat.TcpExt.TCPSACKReneging = &value + case "TCPSACKReorder": + procNetstat.TcpExt.TCPSACKReorder = &value + case "TCPRenoReorder": + procNetstat.TcpExt.TCPRenoReorder = &value + case "TCPTSReorder": + procNetstat.TcpExt.TCPTSReorder = &value + case "TCPFullUndo": + procNetstat.TcpExt.TCPFullUndo = &value + case "TCPPartialUndo": + procNetstat.TcpExt.TCPPartialUndo = &value + case "TCPDSACKUndo": + procNetstat.TcpExt.TCPDSACKUndo = &value + case "TCPLossUndo": + procNetstat.TcpExt.TCPLossUndo = &value + case "TCPLostRetransmit": + procNetstat.TcpExt.TCPLostRetransmit = &value + case "TCPRenoFailures": + procNetstat.TcpExt.TCPRenoFailures = &value + case "TCPSackFailures": + procNetstat.TcpExt.TCPSackFailures = &value + case "TCPLossFailures": + procNetstat.TcpExt.TCPLossFailures = &value + case "TCPFastRetrans": + procNetstat.TcpExt.TCPFastRetrans = &value + case "TCPSlowStartRetrans": + procNetstat.TcpExt.TCPSlowStartRetrans = &value + case "TCPTimeouts": + procNetstat.TcpExt.TCPTimeouts = &value + case "TCPLossProbes": + procNetstat.TcpExt.TCPLossProbes = &value + case "TCPLossProbeRecovery": + procNetstat.TcpExt.TCPLossProbeRecovery = &value + case "TCPRenoRecoveryFail": + procNetstat.TcpExt.TCPRenoRecoveryFail = &value + case "TCPSackRecoveryFail": + procNetstat.TcpExt.TCPSackRecoveryFail = &value + case "TCPRcvCollapsed": + procNetstat.TcpExt.TCPRcvCollapsed = &value + case "TCPDSACKOldSent": + procNetstat.TcpExt.TCPDSACKOldSent = &value + case "TCPDSACKOfoSent": + procNetstat.TcpExt.TCPDSACKOfoSent = &value + case "TCPDSACKRecv": + procNetstat.TcpExt.TCPDSACKRecv = &value + case "TCPDSACKOfoRecv": + procNetstat.TcpExt.TCPDSACKOfoRecv = &value + case "TCPAbortOnData": + procNetstat.TcpExt.TCPAbortOnData = &value + case "TCPAbortOnClose": + procNetstat.TcpExt.TCPAbortOnClose = &value + case "TCPDeferAcceptDrop": + procNetstat.TcpExt.TCPDeferAcceptDrop = &value + case "IPReversePathFilter": + procNetstat.TcpExt.IPReversePathFilter = &value + case "TCPTimeWaitOverflow": + procNetstat.TcpExt.TCPTimeWaitOverflow = &value + case "TCPReqQFullDoCookies": + procNetstat.TcpExt.TCPReqQFullDoCookies = &value + case "TCPReqQFullDrop": + procNetstat.TcpExt.TCPReqQFullDrop = &value + case "TCPRetransFail": + procNetstat.TcpExt.TCPRetransFail = &value + case "TCPRcvCoalesce": + procNetstat.TcpExt.TCPRcvCoalesce = &value + case "TCPRcvQDrop": + procNetstat.TcpExt.TCPRcvQDrop = &value + case "TCPOFOQueue": + procNetstat.TcpExt.TCPOFOQueue = &value + case "TCPOFODrop": + procNetstat.TcpExt.TCPOFODrop = &value + case "TCPOFOMerge": + procNetstat.TcpExt.TCPOFOMerge = &value + case "TCPChallengeACK": + procNetstat.TcpExt.TCPChallengeACK = &value + case "TCPSYNChallenge": + procNetstat.TcpExt.TCPSYNChallenge = &value + case "TCPFastOpenActive": + procNetstat.TcpExt.TCPFastOpenActive = &value + case "TCPFastOpenActiveFail": + procNetstat.TcpExt.TCPFastOpenActiveFail = &value + case "TCPFastOpenPassive": + procNetstat.TcpExt.TCPFastOpenPassive = &value + case "TCPFastOpenPassiveFail": + procNetstat.TcpExt.TCPFastOpenPassiveFail = &value + case "TCPFastOpenListenOverflow": + procNetstat.TcpExt.TCPFastOpenListenOverflow = &value + case "TCPFastOpenCookieReqd": + procNetstat.TcpExt.TCPFastOpenCookieReqd = &value + case "TCPFastOpenBlackhole": + procNetstat.TcpExt.TCPFastOpenBlackhole = &value + case "TCPSpuriousRtxHostQueues": + procNetstat.TcpExt.TCPSpuriousRtxHostQueues = &value + case "BusyPollRxPackets": + procNetstat.TcpExt.BusyPollRxPackets = &value + case "TCPAutoCorking": + procNetstat.TcpExt.TCPAutoCorking = &value + case "TCPFromZeroWindowAdv": + procNetstat.TcpExt.TCPFromZeroWindowAdv = &value + case "TCPToZeroWindowAdv": + procNetstat.TcpExt.TCPToZeroWindowAdv = &value + case "TCPWantZeroWindowAdv": + procNetstat.TcpExt.TCPWantZeroWindowAdv = &value + case "TCPSynRetrans": + procNetstat.TcpExt.TCPSynRetrans = &value + case "TCPOrigDataSent": + procNetstat.TcpExt.TCPOrigDataSent = &value + case "TCPHystartTrainDetect": + procNetstat.TcpExt.TCPHystartTrainDetect = &value + case "TCPHystartTrainCwnd": + procNetstat.TcpExt.TCPHystartTrainCwnd = &value + case "TCPHystartDelayDetect": + procNetstat.TcpExt.TCPHystartDelayDetect = &value + case "TCPHystartDelayCwnd": + procNetstat.TcpExt.TCPHystartDelayCwnd = &value + case "TCPACKSkippedSynRecv": + procNetstat.TcpExt.TCPACKSkippedSynRecv = &value + case "TCPACKSkippedPAWS": + procNetstat.TcpExt.TCPACKSkippedPAWS = &value + case "TCPACKSkippedSeq": + procNetstat.TcpExt.TCPACKSkippedSeq = &value + case "TCPACKSkippedFinWait2": + procNetstat.TcpExt.TCPACKSkippedFinWait2 = &value + case "TCPACKSkippedTimeWait": + procNetstat.TcpExt.TCPACKSkippedTimeWait = &value + case "TCPACKSkippedChallenge": + procNetstat.TcpExt.TCPACKSkippedChallenge = &value + case "TCPWinProbe": + procNetstat.TcpExt.TCPWinProbe = &value + case "TCPKeepAlive": + procNetstat.TcpExt.TCPKeepAlive = &value + case "TCPMTUPFail": + procNetstat.TcpExt.TCPMTUPFail = &value + case "TCPMTUPSuccess": + procNetstat.TcpExt.TCPMTUPSuccess = &value + case "TCPWqueueTooBig": + procNetstat.TcpExt.TCPWqueueTooBig = &value + } + case "IpExt": + switch key { + case "InNoRoutes": + procNetstat.IpExt.InNoRoutes = &value + case "InTruncatedPkts": + procNetstat.IpExt.InTruncatedPkts = &value + case "InMcastPkts": + procNetstat.IpExt.InMcastPkts = &value + case "OutMcastPkts": + procNetstat.IpExt.OutMcastPkts = &value + case "InBcastPkts": + procNetstat.IpExt.InBcastPkts = &value + case "OutBcastPkts": + procNetstat.IpExt.OutBcastPkts = &value + case "InOctets": + procNetstat.IpExt.InOctets = &value + case "OutOctets": + procNetstat.IpExt.OutOctets = &value + case "InMcastOctets": + procNetstat.IpExt.InMcastOctets = &value + case "OutMcastOctets": + procNetstat.IpExt.OutMcastOctets = &value + case "InBcastOctets": + procNetstat.IpExt.InBcastOctets = &value + case "OutBcastOctets": + procNetstat.IpExt.OutBcastOctets = &value + case "InCsumErrors": + procNetstat.IpExt.InCsumErrors = &value + case "InNoECTPkts": + procNetstat.IpExt.InNoECTPkts = &value + case "InECT1Pkts": + procNetstat.IpExt.InECT1Pkts = &value + case "InECT0Pkts": + procNetstat.IpExt.InECT0Pkts = &value + case "InCEPkts": + procNetstat.IpExt.InCEPkts = &value + case "ReasmOverlaps": + procNetstat.IpExt.ReasmOverlaps = &value + } + } + } + } + return procNetstat, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_psi.go b/vendor/github.com/prometheus/procfs/proc_psi.go index dc6c14f0a4..a68fe15290 100644 --- a/vendor/github.com/prometheus/procfs/proc_psi.go +++ b/vendor/github.com/prometheus/procfs/proc_psi.go @@ -35,9 +35,10 @@ import ( const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d" -// PSILine is a single line of values as returned by /proc/pressure/* -// The Avg entries are averages over n seconds, as a percentage -// The Total line is in microseconds +// PSILine is a single line of values as returned by `/proc/pressure/*`. +// +// The Avg entries are averages over n seconds, as a percentage. +// The Total line is in microseconds. type PSILine struct { Avg10 float64 Avg60 float64 @@ -46,8 +47,9 @@ type PSILine struct { } // PSIStats represent pressure stall information from /proc/pressure/* -// Some indicates the share of time in which at least some tasks are stalled -// Full indicates the share of time in which all non-idle tasks are stalled simultaneously +// +// "Some" indicates the share of time in which at least some tasks are stalled. +// "Full" indicates the share of time in which all non-idle tasks are stalled simultaneously. type PSIStats struct { Some *PSILine Full *PSILine @@ -65,7 +67,7 @@ func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) { return parsePSIStats(resource, bytes.NewReader(data)) } -// parsePSIStats parses the specified file for pressure stall information +// parsePSIStats parses the specified file for pressure stall information. func parsePSIStats(resource string, r io.Reader) (PSIStats, error) { psiStats := PSIStats{} diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go index a576a720a4..0e97d99575 100644 --- a/vendor/github.com/prometheus/procfs/proc_smaps.go +++ b/vendor/github.com/prometheus/procfs/proc_smaps.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs @@ -28,30 +29,30 @@ import ( ) var ( - // match the header line before each mapped zone in /proc/pid/smaps + // match the header line before each mapped zone in `/proc/pid/smaps`. procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`) ) type ProcSMapsRollup struct { - // Amount of the mapping that is currently resident in RAM + // Amount of the mapping that is currently resident in RAM. Rss uint64 - // Process's proportional share of this mapping + // Process's proportional share of this mapping. Pss uint64 - // Size in bytes of clean shared pages + // Size in bytes of clean shared pages. SharedClean uint64 - // Size in bytes of dirty shared pages + // Size in bytes of dirty shared pages. SharedDirty uint64 - // Size in bytes of clean private pages + // Size in bytes of clean private pages. PrivateClean uint64 - // Size in bytes of dirty private pages + // Size in bytes of dirty private pages. PrivateDirty uint64 - // Amount of memory currently marked as referenced or accessed + // Amount of memory currently marked as referenced or accessed. Referenced uint64 - // Amount of memory that does not belong to any file + // Amount of memory that does not belong to any file. Anonymous uint64 - // Amount would-be-anonymous memory currently on swap + // Amount would-be-anonymous memory currently on swap. Swap uint64 - // Process's proportional memory on swap + // Process's proportional memory on swap. SwapPss uint64 } diff --git a/vendor/github.com/prometheus/procfs/proc_snmp.go b/vendor/github.com/prometheus/procfs/proc_snmp.go new file mode 100644 index 0000000000..6c46b71884 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_snmp.go @@ -0,0 +1,353 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcSnmp models the content of /proc//net/snmp. +type ProcSnmp struct { + // The process ID. + PID int + Ip + Icmp + IcmpMsg + Tcp + Udp + UdpLite +} + +type Ip struct { // nolint:revive + Forwarding *float64 + DefaultTTL *float64 + InReceives *float64 + InHdrErrors *float64 + InAddrErrors *float64 + ForwDatagrams *float64 + InUnknownProtos *float64 + InDiscards *float64 + InDelivers *float64 + OutRequests *float64 + OutDiscards *float64 + OutNoRoutes *float64 + ReasmTimeout *float64 + ReasmReqds *float64 + ReasmOKs *float64 + ReasmFails *float64 + FragOKs *float64 + FragFails *float64 + FragCreates *float64 +} + +type Icmp struct { // nolint:revive + InMsgs *float64 + InErrors *float64 + InCsumErrors *float64 + InDestUnreachs *float64 + InTimeExcds *float64 + InParmProbs *float64 + InSrcQuenchs *float64 + InRedirects *float64 + InEchos *float64 + InEchoReps *float64 + InTimestamps *float64 + InTimestampReps *float64 + InAddrMasks *float64 + InAddrMaskReps *float64 + OutMsgs *float64 + OutErrors *float64 + OutDestUnreachs *float64 + OutTimeExcds *float64 + OutParmProbs *float64 + OutSrcQuenchs *float64 + OutRedirects *float64 + OutEchos *float64 + OutEchoReps *float64 + OutTimestamps *float64 + OutTimestampReps *float64 + OutAddrMasks *float64 + OutAddrMaskReps *float64 +} + +type IcmpMsg struct { + InType3 *float64 + OutType3 *float64 +} + +type Tcp struct { // nolint:revive + RtoAlgorithm *float64 + RtoMin *float64 + RtoMax *float64 + MaxConn *float64 + ActiveOpens *float64 + PassiveOpens *float64 + AttemptFails *float64 + EstabResets *float64 + CurrEstab *float64 + InSegs *float64 + OutSegs *float64 + RetransSegs *float64 + InErrs *float64 + OutRsts *float64 + InCsumErrors *float64 +} + +type Udp struct { // nolint:revive + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 +} + +type UdpLite struct { // nolint:revive + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 +} + +func (p Proc) Snmp() (ProcSnmp, error) { + filename := p.path("net/snmp") + data, err := util.ReadFileNoStat(filename) + if err != nil { + return ProcSnmp{PID: p.PID}, err + } + procSnmp, err := parseSnmp(bytes.NewReader(data), filename) + procSnmp.PID = p.PID + return procSnmp, err +} + +// parseSnmp parses the metrics from proc//net/snmp file +// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}). +func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) { + var ( + scanner = bufio.NewScanner(r) + procSnmp = ProcSnmp{} + ) + + for scanner.Scan() { + nameParts := strings.Split(scanner.Text(), " ") + scanner.Scan() + valueParts := strings.Split(scanner.Text(), " ") + // Remove trailing :. + protocol := strings.TrimSuffix(nameParts[0], ":") + if len(nameParts) != len(valueParts) { + return procSnmp, fmt.Errorf("mismatch field count mismatch in %s: %s", + fileName, protocol) + } + for i := 1; i < len(nameParts); i++ { + value, err := strconv.ParseFloat(valueParts[i], 64) + if err != nil { + return procSnmp, err + } + key := nameParts[i] + + switch protocol { + case "Ip": + switch key { + case "Forwarding": + procSnmp.Ip.Forwarding = &value + case "DefaultTTL": + procSnmp.Ip.DefaultTTL = &value + case "InReceives": + procSnmp.Ip.InReceives = &value + case "InHdrErrors": + procSnmp.Ip.InHdrErrors = &value + case "InAddrErrors": + procSnmp.Ip.InAddrErrors = &value + case "ForwDatagrams": + procSnmp.Ip.ForwDatagrams = &value + case "InUnknownProtos": + procSnmp.Ip.InUnknownProtos = &value + case "InDiscards": + procSnmp.Ip.InDiscards = &value + case "InDelivers": + procSnmp.Ip.InDelivers = &value + case "OutRequests": + procSnmp.Ip.OutRequests = &value + case "OutDiscards": + procSnmp.Ip.OutDiscards = &value + case "OutNoRoutes": + procSnmp.Ip.OutNoRoutes = &value + case "ReasmTimeout": + procSnmp.Ip.ReasmTimeout = &value + case "ReasmReqds": + procSnmp.Ip.ReasmReqds = &value + case "ReasmOKs": + procSnmp.Ip.ReasmOKs = &value + case "ReasmFails": + procSnmp.Ip.ReasmFails = &value + case "FragOKs": + procSnmp.Ip.FragOKs = &value + case "FragFails": + procSnmp.Ip.FragFails = &value + case "FragCreates": + procSnmp.Ip.FragCreates = &value + } + case "Icmp": + switch key { + case "InMsgs": + procSnmp.Icmp.InMsgs = &value + case "InErrors": + procSnmp.Icmp.InErrors = &value + case "InCsumErrors": + procSnmp.Icmp.InCsumErrors = &value + case "InDestUnreachs": + procSnmp.Icmp.InDestUnreachs = &value + case "InTimeExcds": + procSnmp.Icmp.InTimeExcds = &value + case "InParmProbs": + procSnmp.Icmp.InParmProbs = &value + case "InSrcQuenchs": + procSnmp.Icmp.InSrcQuenchs = &value + case "InRedirects": + procSnmp.Icmp.InRedirects = &value + case "InEchos": + procSnmp.Icmp.InEchos = &value + case "InEchoReps": + procSnmp.Icmp.InEchoReps = &value + case "InTimestamps": + procSnmp.Icmp.InTimestamps = &value + case "InTimestampReps": + procSnmp.Icmp.InTimestampReps = &value + case "InAddrMasks": + procSnmp.Icmp.InAddrMasks = &value + case "InAddrMaskReps": + procSnmp.Icmp.InAddrMaskReps = &value + case "OutMsgs": + procSnmp.Icmp.OutMsgs = &value + case "OutErrors": + procSnmp.Icmp.OutErrors = &value + case "OutDestUnreachs": + procSnmp.Icmp.OutDestUnreachs = &value + case "OutTimeExcds": + procSnmp.Icmp.OutTimeExcds = &value + case "OutParmProbs": + procSnmp.Icmp.OutParmProbs = &value + case "OutSrcQuenchs": + procSnmp.Icmp.OutSrcQuenchs = &value + case "OutRedirects": + procSnmp.Icmp.OutRedirects = &value + case "OutEchos": + procSnmp.Icmp.OutEchos = &value + case "OutEchoReps": + procSnmp.Icmp.OutEchoReps = &value + case "OutTimestamps": + procSnmp.Icmp.OutTimestamps = &value + case "OutTimestampReps": + procSnmp.Icmp.OutTimestampReps = &value + case "OutAddrMasks": + procSnmp.Icmp.OutAddrMasks = &value + case "OutAddrMaskReps": + procSnmp.Icmp.OutAddrMaskReps = &value + } + case "IcmpMsg": + switch key { + case "InType3": + procSnmp.IcmpMsg.InType3 = &value + case "OutType3": + procSnmp.IcmpMsg.OutType3 = &value + } + case "Tcp": + switch key { + case "RtoAlgorithm": + procSnmp.Tcp.RtoAlgorithm = &value + case "RtoMin": + procSnmp.Tcp.RtoMin = &value + case "RtoMax": + procSnmp.Tcp.RtoMax = &value + case "MaxConn": + procSnmp.Tcp.MaxConn = &value + case "ActiveOpens": + procSnmp.Tcp.ActiveOpens = &value + case "PassiveOpens": + procSnmp.Tcp.PassiveOpens = &value + case "AttemptFails": + procSnmp.Tcp.AttemptFails = &value + case "EstabResets": + procSnmp.Tcp.EstabResets = &value + case "CurrEstab": + procSnmp.Tcp.CurrEstab = &value + case "InSegs": + procSnmp.Tcp.InSegs = &value + case "OutSegs": + procSnmp.Tcp.OutSegs = &value + case "RetransSegs": + procSnmp.Tcp.RetransSegs = &value + case "InErrs": + procSnmp.Tcp.InErrs = &value + case "OutRsts": + procSnmp.Tcp.OutRsts = &value + case "InCsumErrors": + procSnmp.Tcp.InCsumErrors = &value + } + case "Udp": + switch key { + case "InDatagrams": + procSnmp.Udp.InDatagrams = &value + case "NoPorts": + procSnmp.Udp.NoPorts = &value + case "InErrors": + procSnmp.Udp.InErrors = &value + case "OutDatagrams": + procSnmp.Udp.OutDatagrams = &value + case "RcvbufErrors": + procSnmp.Udp.RcvbufErrors = &value + case "SndbufErrors": + procSnmp.Udp.SndbufErrors = &value + case "InCsumErrors": + procSnmp.Udp.InCsumErrors = &value + case "IgnoredMulti": + procSnmp.Udp.IgnoredMulti = &value + } + case "UdpLite": + switch key { + case "InDatagrams": + procSnmp.UdpLite.InDatagrams = &value + case "NoPorts": + procSnmp.UdpLite.NoPorts = &value + case "InErrors": + procSnmp.UdpLite.InErrors = &value + case "OutDatagrams": + procSnmp.UdpLite.OutDatagrams = &value + case "RcvbufErrors": + procSnmp.UdpLite.RcvbufErrors = &value + case "SndbufErrors": + procSnmp.UdpLite.SndbufErrors = &value + case "InCsumErrors": + procSnmp.UdpLite.InCsumErrors = &value + case "IgnoredMulti": + procSnmp.UdpLite.IgnoredMulti = &value + } + } + } + } + return procSnmp, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_snmp6.go b/vendor/github.com/prometheus/procfs/proc_snmp6.go new file mode 100644 index 0000000000..3059cc6a13 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_snmp6.go @@ -0,0 +1,381 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "errors" + "io" + "os" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcSnmp6 models the content of /proc//net/snmp6. +type ProcSnmp6 struct { + // The process ID. + PID int + Ip6 + Icmp6 + Udp6 + UdpLite6 +} + +type Ip6 struct { // nolint:revive + InReceives *float64 + InHdrErrors *float64 + InTooBigErrors *float64 + InNoRoutes *float64 + InAddrErrors *float64 + InUnknownProtos *float64 + InTruncatedPkts *float64 + InDiscards *float64 + InDelivers *float64 + OutForwDatagrams *float64 + OutRequests *float64 + OutDiscards *float64 + OutNoRoutes *float64 + ReasmTimeout *float64 + ReasmReqds *float64 + ReasmOKs *float64 + ReasmFails *float64 + FragOKs *float64 + FragFails *float64 + FragCreates *float64 + InMcastPkts *float64 + OutMcastPkts *float64 + InOctets *float64 + OutOctets *float64 + InMcastOctets *float64 + OutMcastOctets *float64 + InBcastOctets *float64 + OutBcastOctets *float64 + InNoECTPkts *float64 + InECT1Pkts *float64 + InECT0Pkts *float64 + InCEPkts *float64 +} + +type Icmp6 struct { + InMsgs *float64 + InErrors *float64 + OutMsgs *float64 + OutErrors *float64 + InCsumErrors *float64 + InDestUnreachs *float64 + InPktTooBigs *float64 + InTimeExcds *float64 + InParmProblems *float64 + InEchos *float64 + InEchoReplies *float64 + InGroupMembQueries *float64 + InGroupMembResponses *float64 + InGroupMembReductions *float64 + InRouterSolicits *float64 + InRouterAdvertisements *float64 + InNeighborSolicits *float64 + InNeighborAdvertisements *float64 + InRedirects *float64 + InMLDv2Reports *float64 + OutDestUnreachs *float64 + OutPktTooBigs *float64 + OutTimeExcds *float64 + OutParmProblems *float64 + OutEchos *float64 + OutEchoReplies *float64 + OutGroupMembQueries *float64 + OutGroupMembResponses *float64 + OutGroupMembReductions *float64 + OutRouterSolicits *float64 + OutRouterAdvertisements *float64 + OutNeighborSolicits *float64 + OutNeighborAdvertisements *float64 + OutRedirects *float64 + OutMLDv2Reports *float64 + InType1 *float64 + InType134 *float64 + InType135 *float64 + InType136 *float64 + InType143 *float64 + OutType133 *float64 + OutType135 *float64 + OutType136 *float64 + OutType143 *float64 +} + +type Udp6 struct { // nolint:revive + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 +} + +type UdpLite6 struct { // nolint:revive + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 +} + +func (p Proc) Snmp6() (ProcSnmp6, error) { + filename := p.path("net/snmp6") + data, err := util.ReadFileNoStat(filename) + if err != nil { + // On systems with IPv6 disabled, this file won't exist. + // Do nothing. + if errors.Is(err, os.ErrNotExist) { + return ProcSnmp6{PID: p.PID}, nil + } + + return ProcSnmp6{PID: p.PID}, err + } + + procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data)) + procSnmp6.PID = p.PID + return procSnmp6, err +} + +// parseSnmp6 parses the metrics from proc//net/snmp6 file +// and returns a map contains those metrics. +func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { + var ( + scanner = bufio.NewScanner(r) + procSnmp6 = ProcSnmp6{} + ) + + for scanner.Scan() { + stat := strings.Fields(scanner.Text()) + if len(stat) < 2 { + continue + } + // Expect to have "6" in metric name, skip line otherwise + if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 { + protocol := stat[0][:sixIndex+1] + key := stat[0][sixIndex+1:] + value, err := strconv.ParseFloat(stat[1], 64) + if err != nil { + return procSnmp6, err + } + + switch protocol { + case "Ip6": + switch key { + case "InReceives": + procSnmp6.Ip6.InReceives = &value + case "InHdrErrors": + procSnmp6.Ip6.InHdrErrors = &value + case "InTooBigErrors": + procSnmp6.Ip6.InTooBigErrors = &value + case "InNoRoutes": + procSnmp6.Ip6.InNoRoutes = &value + case "InAddrErrors": + procSnmp6.Ip6.InAddrErrors = &value + case "InUnknownProtos": + procSnmp6.Ip6.InUnknownProtos = &value + case "InTruncatedPkts": + procSnmp6.Ip6.InTruncatedPkts = &value + case "InDiscards": + procSnmp6.Ip6.InDiscards = &value + case "InDelivers": + procSnmp6.Ip6.InDelivers = &value + case "OutForwDatagrams": + procSnmp6.Ip6.OutForwDatagrams = &value + case "OutRequests": + procSnmp6.Ip6.OutRequests = &value + case "OutDiscards": + procSnmp6.Ip6.OutDiscards = &value + case "OutNoRoutes": + procSnmp6.Ip6.OutNoRoutes = &value + case "ReasmTimeout": + procSnmp6.Ip6.ReasmTimeout = &value + case "ReasmReqds": + procSnmp6.Ip6.ReasmReqds = &value + case "ReasmOKs": + procSnmp6.Ip6.ReasmOKs = &value + case "ReasmFails": + procSnmp6.Ip6.ReasmFails = &value + case "FragOKs": + procSnmp6.Ip6.FragOKs = &value + case "FragFails": + procSnmp6.Ip6.FragFails = &value + case "FragCreates": + procSnmp6.Ip6.FragCreates = &value + case "InMcastPkts": + procSnmp6.Ip6.InMcastPkts = &value + case "OutMcastPkts": + procSnmp6.Ip6.OutMcastPkts = &value + case "InOctets": + procSnmp6.Ip6.InOctets = &value + case "OutOctets": + procSnmp6.Ip6.OutOctets = &value + case "InMcastOctets": + procSnmp6.Ip6.InMcastOctets = &value + case "OutMcastOctets": + procSnmp6.Ip6.OutMcastOctets = &value + case "InBcastOctets": + procSnmp6.Ip6.InBcastOctets = &value + case "OutBcastOctets": + procSnmp6.Ip6.OutBcastOctets = &value + case "InNoECTPkts": + procSnmp6.Ip6.InNoECTPkts = &value + case "InECT1Pkts": + procSnmp6.Ip6.InECT1Pkts = &value + case "InECT0Pkts": + procSnmp6.Ip6.InECT0Pkts = &value + case "InCEPkts": + procSnmp6.Ip6.InCEPkts = &value + + } + case "Icmp6": + switch key { + case "InMsgs": + procSnmp6.Icmp6.InMsgs = &value + case "InErrors": + procSnmp6.Icmp6.InErrors = &value + case "OutMsgs": + procSnmp6.Icmp6.OutMsgs = &value + case "OutErrors": + procSnmp6.Icmp6.OutErrors = &value + case "InCsumErrors": + procSnmp6.Icmp6.InCsumErrors = &value + case "InDestUnreachs": + procSnmp6.Icmp6.InDestUnreachs = &value + case "InPktTooBigs": + procSnmp6.Icmp6.InPktTooBigs = &value + case "InTimeExcds": + procSnmp6.Icmp6.InTimeExcds = &value + case "InParmProblems": + procSnmp6.Icmp6.InParmProblems = &value + case "InEchos": + procSnmp6.Icmp6.InEchos = &value + case "InEchoReplies": + procSnmp6.Icmp6.InEchoReplies = &value + case "InGroupMembQueries": + procSnmp6.Icmp6.InGroupMembQueries = &value + case "InGroupMembResponses": + procSnmp6.Icmp6.InGroupMembResponses = &value + case "InGroupMembReductions": + procSnmp6.Icmp6.InGroupMembReductions = &value + case "InRouterSolicits": + procSnmp6.Icmp6.InRouterSolicits = &value + case "InRouterAdvertisements": + procSnmp6.Icmp6.InRouterAdvertisements = &value + case "InNeighborSolicits": + procSnmp6.Icmp6.InNeighborSolicits = &value + case "InNeighborAdvertisements": + procSnmp6.Icmp6.InNeighborAdvertisements = &value + case "InRedirects": + procSnmp6.Icmp6.InRedirects = &value + case "InMLDv2Reports": + procSnmp6.Icmp6.InMLDv2Reports = &value + case "OutDestUnreachs": + procSnmp6.Icmp6.OutDestUnreachs = &value + case "OutPktTooBigs": + procSnmp6.Icmp6.OutPktTooBigs = &value + case "OutTimeExcds": + procSnmp6.Icmp6.OutTimeExcds = &value + case "OutParmProblems": + procSnmp6.Icmp6.OutParmProblems = &value + case "OutEchos": + procSnmp6.Icmp6.OutEchos = &value + case "OutEchoReplies": + procSnmp6.Icmp6.OutEchoReplies = &value + case "OutGroupMembQueries": + procSnmp6.Icmp6.OutGroupMembQueries = &value + case "OutGroupMembResponses": + procSnmp6.Icmp6.OutGroupMembResponses = &value + case "OutGroupMembReductions": + procSnmp6.Icmp6.OutGroupMembReductions = &value + case "OutRouterSolicits": + procSnmp6.Icmp6.OutRouterSolicits = &value + case "OutRouterAdvertisements": + procSnmp6.Icmp6.OutRouterAdvertisements = &value + case "OutNeighborSolicits": + procSnmp6.Icmp6.OutNeighborSolicits = &value + case "OutNeighborAdvertisements": + procSnmp6.Icmp6.OutNeighborAdvertisements = &value + case "OutRedirects": + procSnmp6.Icmp6.OutRedirects = &value + case "OutMLDv2Reports": + procSnmp6.Icmp6.OutMLDv2Reports = &value + case "InType1": + procSnmp6.Icmp6.InType1 = &value + case "InType134": + procSnmp6.Icmp6.InType134 = &value + case "InType135": + procSnmp6.Icmp6.InType135 = &value + case "InType136": + procSnmp6.Icmp6.InType136 = &value + case "InType143": + procSnmp6.Icmp6.InType143 = &value + case "OutType133": + procSnmp6.Icmp6.OutType133 = &value + case "OutType135": + procSnmp6.Icmp6.OutType135 = &value + case "OutType136": + procSnmp6.Icmp6.OutType136 = &value + case "OutType143": + procSnmp6.Icmp6.OutType143 = &value + } + case "Udp6": + switch key { + case "InDatagrams": + procSnmp6.Udp6.InDatagrams = &value + case "NoPorts": + procSnmp6.Udp6.NoPorts = &value + case "InErrors": + procSnmp6.Udp6.InErrors = &value + case "OutDatagrams": + procSnmp6.Udp6.OutDatagrams = &value + case "RcvbufErrors": + procSnmp6.Udp6.RcvbufErrors = &value + case "SndbufErrors": + procSnmp6.Udp6.SndbufErrors = &value + case "InCsumErrors": + procSnmp6.Udp6.InCsumErrors = &value + case "IgnoredMulti": + procSnmp6.Udp6.IgnoredMulti = &value + } + case "UdpLite6": + switch key { + case "InDatagrams": + procSnmp6.UdpLite6.InDatagrams = &value + case "NoPorts": + procSnmp6.UdpLite6.NoPorts = &value + case "InErrors": + procSnmp6.UdpLite6.InErrors = &value + case "OutDatagrams": + procSnmp6.UdpLite6.OutDatagrams = &value + case "RcvbufErrors": + procSnmp6.UdpLite6.RcvbufErrors = &value + case "SndbufErrors": + procSnmp6.UdpLite6.SndbufErrors = &value + case "InCsumErrors": + procSnmp6.UdpLite6.InCsumErrors = &value + } + } + } + } + return procSnmp6, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go index 8c7b6e80a3..b278eb2c2d 100644 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ b/vendor/github.com/prometheus/procfs/proc_stat.go @@ -81,10 +81,10 @@ type ProcStat struct { STime uint // Amount of time that this process's waited-for children have been // scheduled in user mode, measured in clock ticks. - CUTime uint + CUTime int // Amount of time that this process's waited-for children have been // scheduled in kernel mode, measured in clock ticks. - CSTime uint + CSTime int // For processes running a real-time scheduling policy, this is the negated // scheduling priority, minus one. Priority int @@ -102,6 +102,8 @@ type ProcStat struct { RSS int // Soft limit in bytes on the rss of the process. RSSLimit uint64 + // CPU number last executed on. + Processor uint // Real-time scheduling priority, a number in the range 1 to 99 for processes // scheduled under a real-time policy, or 0, for non-real-time processes. RTPriority uint @@ -115,7 +117,7 @@ type ProcStat struct { // NewStat returns the current status information of the process. // -// Deprecated: use p.Stat() instead +// Deprecated: Use p.Stat() instead. func (p Proc) NewStat() (ProcStat, error) { return p.Stat() } @@ -141,6 +143,11 @@ func (p Proc) Stat() (ProcStat, error) { } s.Comm = string(data[l+1 : r]) + + // Check the following resources for the details about the particular stat + // fields and their data types: + // * https://man7.org/linux/man-pages/man5/proc.5.html + // * https://man7.org/linux/man-pages/man3/scanf.3.html _, err = fmt.Fscan( bytes.NewBuffer(data[r+2:]), &s.State, @@ -179,7 +186,7 @@ func (p Proc) Stat() (ProcStat, error) { &ignoreUint64, &ignoreUint64, &ignoreInt64, - &ignoreInt64, + &s.Processor, &s.RTPriority, &s.Policy, &s.DelayAcctBlkIOTicks, diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go index 6edd8333b3..3d8c06439a 100644 --- a/vendor/github.com/prometheus/procfs/proc_status.go +++ b/vendor/github.com/prometheus/procfs/proc_status.go @@ -33,37 +33,37 @@ type ProcStatus struct { TGID int // Peak virtual memory size. - VmPeak uint64 // nolint:golint + VmPeak uint64 // nolint:revive // Virtual memory size. - VmSize uint64 // nolint:golint + VmSize uint64 // nolint:revive // Locked memory size. - VmLck uint64 // nolint:golint + VmLck uint64 // nolint:revive // Pinned memory size. - VmPin uint64 // nolint:golint + VmPin uint64 // nolint:revive // Peak resident set size. - VmHWM uint64 // nolint:golint + VmHWM uint64 // nolint:revive // Resident set size (sum of RssAnnon RssFile and RssShmem). - VmRSS uint64 // nolint:golint + VmRSS uint64 // nolint:revive // Size of resident anonymous memory. - RssAnon uint64 // nolint:golint + RssAnon uint64 // nolint:revive // Size of resident file mappings. - RssFile uint64 // nolint:golint + RssFile uint64 // nolint:revive // Size of resident shared memory. - RssShmem uint64 // nolint:golint + RssShmem uint64 // nolint:revive // Size of data segments. - VmData uint64 // nolint:golint + VmData uint64 // nolint:revive // Size of stack segments. - VmStk uint64 // nolint:golint + VmStk uint64 // nolint:revive // Size of text segments. - VmExe uint64 // nolint:golint + VmExe uint64 // nolint:revive // Shared library code size. - VmLib uint64 // nolint:golint + VmLib uint64 // nolint:revive // Page table entries size. - VmPTE uint64 // nolint:golint + VmPTE uint64 // nolint:revive // Size of second-level page tables. - VmPMD uint64 // nolint:golint + VmPMD uint64 // nolint:revive // Swapped-out virtual memory size by anonymous private. - VmSwap uint64 // nolint:golint + VmSwap uint64 // nolint:revive // Size of hugetlb memory portions HugetlbPages uint64 @@ -96,10 +96,10 @@ func (p Proc) NewStatus() (ProcStatus, error) { kv := strings.SplitN(line, ":", 2) // removes spaces - k := string(strings.TrimSpace(kv[0])) - v := string(strings.TrimSpace(kv[1])) + k := strings.TrimSpace(kv[0]) + v := strings.TrimSpace(kv[1]) // removes "kB" - v = string(bytes.Trim([]byte(v), " kB")) + v = strings.TrimSuffix(v, " kB") // value to int when possible // we can skip error check here, 'cause vKBytes is not used when value is a string diff --git a/vendor/github.com/prometheus/procfs/proc_sys.go b/vendor/github.com/prometheus/procfs/proc_sys.go new file mode 100644 index 0000000000..d46533ebf4 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_sys.go @@ -0,0 +1,51 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "fmt" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +func sysctlToPath(sysctl string) string { + return strings.Replace(sysctl, ".", "/", -1) +} + +func (fs FS) SysctlStrings(sysctl string) ([]string, error) { + value, err := util.SysReadFile(fs.proc.Path("sys", sysctlToPath(sysctl))) + if err != nil { + return nil, err + } + return strings.Fields(value), nil + +} + +func (fs FS) SysctlInts(sysctl string) ([]int, error) { + fields, err := fs.SysctlStrings(sysctl) + if err != nil { + return nil, err + } + + values := make([]int, len(fields)) + for i, f := range fields { + vp := util.NewValueParser(f) + values[i] = vp.Int() + if err := vp.Err(); err != nil { + return nil, fmt.Errorf("field %d in sysctl %s is not a valid int: %w", i, sysctl, err) + } + } + return values, nil +} diff --git a/vendor/github.com/prometheus/procfs/schedstat.go b/vendor/github.com/prometheus/procfs/schedstat.go index 28228164ef..5f7f32dc83 100644 --- a/vendor/github.com/prometheus/procfs/schedstat.go +++ b/vendor/github.com/prometheus/procfs/schedstat.go @@ -40,7 +40,7 @@ type Schedstat struct { CPUs []*SchedstatCPU } -// SchedstatCPU contains the values from one "cpu" line +// SchedstatCPU contains the values from one "cpu" line. type SchedstatCPU struct { CPUNum string @@ -49,14 +49,14 @@ type SchedstatCPU struct { RunTimeslices uint64 } -// ProcSchedstat contains the values from /proc//schedstat +// ProcSchedstat contains the values from `/proc//schedstat`. type ProcSchedstat struct { RunningNanoseconds uint64 WaitingNanoseconds uint64 RunTimeslices uint64 } -// Schedstat reads data from /proc/schedstat +// Schedstat reads data from `/proc/schedstat`. func (fs FS) Schedstat() (*Schedstat, error) { file, err := os.Open(fs.proc.Path("schedstat")) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/slab.go b/vendor/github.com/prometheus/procfs/slab.go index 7896fd7242..bc9aaf5c28 100644 --- a/vendor/github.com/prometheus/procfs/slab.go +++ b/vendor/github.com/prometheus/procfs/slab.go @@ -137,7 +137,7 @@ func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) { return s, nil } -// SlabInfo reads data from /proc/slabinfo +// SlabInfo reads data from `/proc/slabinfo`. func (fs FS) SlabInfo() (SlabInfo, error) { // TODO: Consider passing options to allow for parsing different // slabinfo versions. However, slabinfo 2.1 has been stable since diff --git a/vendor/github.com/prometheus/procfs/softirqs.go b/vendor/github.com/prometheus/procfs/softirqs.go new file mode 100644 index 0000000000..559129cbca --- /dev/null +++ b/vendor/github.com/prometheus/procfs/softirqs.go @@ -0,0 +1,160 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// Softirqs represents the softirq statistics. +type Softirqs struct { + Hi []uint64 + Timer []uint64 + NetTx []uint64 + NetRx []uint64 + Block []uint64 + IRQPoll []uint64 + Tasklet []uint64 + Sched []uint64 + HRTimer []uint64 + RCU []uint64 +} + +func (fs FS) Softirqs() (Softirqs, error) { + fileName := fs.proc.Path("softirqs") + data, err := util.ReadFileNoStat(fileName) + if err != nil { + return Softirqs{}, err + } + + reader := bytes.NewReader(data) + + return parseSoftirqs(reader) +} + +func parseSoftirqs(r io.Reader) (Softirqs, error) { + var ( + softirqs = Softirqs{} + scanner = bufio.NewScanner(r) + ) + + if !scanner.Scan() { + return Softirqs{}, fmt.Errorf("softirqs empty") + } + + for scanner.Scan() { + parts := strings.Fields(scanner.Text()) + var err error + + // require at least one cpu + if len(parts) < 2 { + continue + } + switch { + case parts[0] == "HI:": + perCPU := parts[1:] + softirqs.Hi = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (HI%d): %w", count, i, err) + } + } + case parts[0] == "TIMER:": + perCPU := parts[1:] + softirqs.Timer = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (TIMER%d): %w", count, i, err) + } + } + case parts[0] == "NET_TX:": + perCPU := parts[1:] + softirqs.NetTx = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_TX%d): %w", count, i, err) + } + } + case parts[0] == "NET_RX:": + perCPU := parts[1:] + softirqs.NetRx = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_RX%d): %w", count, i, err) + } + } + case parts[0] == "BLOCK:": + perCPU := parts[1:] + softirqs.Block = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (BLOCK%d): %w", count, i, err) + } + } + case parts[0] == "IRQ_POLL:": + perCPU := parts[1:] + softirqs.IRQPoll = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (IRQ_POLL%d): %w", count, i, err) + } + } + case parts[0] == "TASKLET:": + perCPU := parts[1:] + softirqs.Tasklet = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (TASKLET%d): %w", count, i, err) + } + } + case parts[0] == "SCHED:": + perCPU := parts[1:] + softirqs.Sched = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (SCHED%d): %w", count, i, err) + } + } + case parts[0] == "HRTIMER:": + perCPU := parts[1:] + softirqs.HRTimer = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (HRTIMER%d): %w", count, i, err) + } + } + case parts[0] == "RCU:": + perCPU := parts[1:] + softirqs.RCU = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (RCU%d): %w", count, i, err) + } + } + } + } + + if err := scanner.Err(); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse softirqs: %w", err) + } + + return softirqs, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go index 6d8727541e..586af48af9 100644 --- a/vendor/github.com/prometheus/procfs/stat.go +++ b/vendor/github.com/prometheus/procfs/stat.go @@ -41,7 +41,7 @@ type CPUStat struct { // SoftIRQStat represent the softirq statistics as exported in the procfs stat file. // A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html -// It is possible to get per-cpu stats by reading /proc/softirqs +// It is possible to get per-cpu stats by reading `/proc/softirqs`. type SoftIRQStat struct { Hi uint64 Timer uint64 @@ -62,7 +62,7 @@ type Stat struct { // Summed up cpu statistics. CPUTotal CPUStat // Per-CPU statistics. - CPU []CPUStat + CPU map[int64]CPUStat // Number of times interrupts were handled, which contains numbered and unnumbered IRQs. IRQTotal uint64 // Number of times a numbered IRQ was triggered. @@ -145,7 +145,7 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) { // NewStat returns information about current cpu/process statistics. // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt // -// Deprecated: use fs.Stat() instead +// Deprecated: Use fs.Stat() instead. func NewStat() (Stat, error) { fs, err := NewFS(fs.DefaultProcMountPoint) if err != nil { @@ -155,25 +155,38 @@ func NewStat() (Stat, error) { } // NewStat returns information about current cpu/process statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt +// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt // -// Deprecated: use fs.Stat() instead +// Deprecated: Use fs.Stat() instead. func (fs FS) NewStat() (Stat, error) { return fs.Stat() } // Stat returns information about current cpu/process statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt +// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt func (fs FS) Stat() (Stat, error) { fileName := fs.proc.Path("stat") data, err := util.ReadFileNoStat(fileName) if err != nil { return Stat{}, err } + procStat, err := parseStat(bytes.NewReader(data), fileName) + if err != nil { + return Stat{}, err + } + return procStat, nil +} - stat := Stat{} +// parseStat parses the metrics from /proc/[pid]/stat. +func parseStat(r io.Reader, fileName string) (Stat, error) { + var ( + scanner = bufio.NewScanner(r) + stat = Stat{ + CPU: make(map[int64]CPUStat), + } + err error + ) - scanner := bufio.NewScanner(bytes.NewReader(data)) for scanner.Scan() { line := scanner.Text() parts := strings.Fields(scanner.Text()) @@ -228,9 +241,6 @@ func (fs FS) Stat() (Stat, error) { if cpuID == -1 { stat.CPUTotal = cpuStat } else { - for int64(len(stat.CPU)) <= cpuID { - stat.CPU = append(stat.CPU, CPUStat{}) - } stat.CPU[cpuID] = cpuStat } } diff --git a/vendor/github.com/prometheus/procfs/thread.go b/vendor/github.com/prometheus/procfs/thread.go new file mode 100644 index 0000000000..f08bfc769d --- /dev/null +++ b/vendor/github.com/prometheus/procfs/thread.go @@ -0,0 +1,79 @@ +// Copyright 2022 The Prometheus 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 procfs + +import ( + "fmt" + "os" + "strconv" + + fsi "github.com/prometheus/procfs/internal/fs" +) + +// Provide access to /proc/PID/task/TID files, for thread specific values. Since +// such files have the same structure as /proc/PID/ ones, the data structures +// and the parsers for the latter may be reused. + +// AllThreads returns a list of all currently available threads under /proc/PID. +func AllThreads(pid int) (Procs, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return Procs{}, err + } + return fs.AllThreads(pid) +} + +// AllThreads returns a list of all currently available threads for PID. +func (fs FS) AllThreads(pid int) (Procs, error) { + taskPath := fs.proc.Path(strconv.Itoa(pid), "task") + d, err := os.Open(taskPath) + if err != nil { + return Procs{}, err + } + defer d.Close() + + names, err := d.Readdirnames(-1) + if err != nil { + return Procs{}, fmt.Errorf("could not read %q: %w", d.Name(), err) + } + + t := Procs{} + for _, n := range names { + tid, err := strconv.ParseInt(n, 10, 64) + if err != nil { + continue + } + t = append(t, Proc{PID: int(tid), fs: fsi.FS(taskPath)}) + } + + return t, nil +} + +// Thread returns a process for a given PID, TID. +func (fs FS) Thread(pid, tid int) (Proc, error) { + taskPath := fs.proc.Path(strconv.Itoa(pid), "task") + if _, err := os.Stat(taskPath); err != nil { + return Proc{}, err + } + return Proc{PID: tid, fs: fsi.FS(taskPath)}, nil +} + +// Thread returns a process for a given TID of Proc. +func (proc Proc) Thread(tid int) (Proc, error) { + tfs := fsi.FS(proc.path("task")) + if _, err := os.Stat(tfs.Path(strconv.Itoa(tid))); err != nil { + return Proc{}, err + } + return Proc{PID: tid, fs: tfs}, nil +} diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go index cb13891414..cdedcae996 100644 --- a/vendor/github.com/prometheus/procfs/vm.go +++ b/vendor/github.com/prometheus/procfs/vm.go @@ -11,13 +11,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -26,10 +26,12 @@ import ( ) // The VM interface is described at -// https://www.kernel.org/doc/Documentation/sysctl/vm.txt +// +// https://www.kernel.org/doc/Documentation/sysctl/vm.txt +// // Each setting is exposed as a single file. // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array -// and numa_zonelist_order (deprecated) which is a string +// and numa_zonelist_order (deprecated) which is a string. type VM struct { AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes BlockDump *int64 // /proc/sys/vm/block_dump @@ -87,7 +89,7 @@ func (fs FS) VM() (*VM, error) { return nil, fmt.Errorf("%s is not a directory", path) } - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/xfrm.go b/vendor/github.com/prometheus/procfs/xfrm.go deleted file mode 100644 index eed07c7d77..0000000000 --- a/vendor/github.com/prometheus/procfs/xfrm.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2017 Prometheus Team -// 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 procfs - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -// XfrmStat models the contents of /proc/net/xfrm_stat. -type XfrmStat struct { - // All errors which are not matched by other - XfrmInError int - // No buffer is left - XfrmInBufferError int - // Header Error - XfrmInHdrError int - // No state found - // i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong - XfrmInNoStates int - // Transformation protocol specific error - // e.g. SA Key is wrong - XfrmInStateProtoError int - // Transformation mode specific error - XfrmInStateModeError int - // Sequence error - // e.g. sequence number is out of window - XfrmInStateSeqError int - // State is expired - XfrmInStateExpired int - // State has mismatch option - // e.g. UDP encapsulation type is mismatched - XfrmInStateMismatch int - // State is invalid - XfrmInStateInvalid int - // No matching template for states - // e.g. Inbound SAs are correct but SP rule is wrong - XfrmInTmplMismatch int - // No policy is found for states - // e.g. Inbound SAs are correct but no SP is found - XfrmInNoPols int - // Policy discards - XfrmInPolBlock int - // Policy error - XfrmInPolError int - // All errors which are not matched by others - XfrmOutError int - // Bundle generation error - XfrmOutBundleGenError int - // Bundle check error - XfrmOutBundleCheckError int - // No state was found - XfrmOutNoStates int - // Transformation protocol specific error - XfrmOutStateProtoError int - // Transportation mode specific error - XfrmOutStateModeError int - // Sequence error - // i.e sequence number overflow - XfrmOutStateSeqError int - // State is expired - XfrmOutStateExpired int - // Policy discads - XfrmOutPolBlock int - // Policy is dead - XfrmOutPolDead int - // Policy Error - XfrmOutPolError int - XfrmFwdHdrError int - XfrmOutStateInvalid int - XfrmAcquireError int -} - -// NewXfrmStat reads the xfrm_stat statistics. -func NewXfrmStat() (XfrmStat, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return XfrmStat{}, err - } - - return fs.NewXfrmStat() -} - -// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem. -func (fs FS) NewXfrmStat() (XfrmStat, error) { - file, err := os.Open(fs.proc.Path("net/xfrm_stat")) - if err != nil { - return XfrmStat{}, err - } - defer file.Close() - - var ( - x = XfrmStat{} - s = bufio.NewScanner(file) - ) - - for s.Scan() { - fields := strings.Fields(s.Text()) - - if len(fields) != 2 { - return XfrmStat{}, fmt.Errorf("couldn't parse %q line %q", file.Name(), s.Text()) - } - - name := fields[0] - value, err := strconv.Atoi(fields[1]) - if err != nil { - return XfrmStat{}, err - } - - switch name { - case "XfrmInError": - x.XfrmInError = value - case "XfrmInBufferError": - x.XfrmInBufferError = value - case "XfrmInHdrError": - x.XfrmInHdrError = value - case "XfrmInNoStates": - x.XfrmInNoStates = value - case "XfrmInStateProtoError": - x.XfrmInStateProtoError = value - case "XfrmInStateModeError": - x.XfrmInStateModeError = value - case "XfrmInStateSeqError": - x.XfrmInStateSeqError = value - case "XfrmInStateExpired": - x.XfrmInStateExpired = value - case "XfrmInStateInvalid": - x.XfrmInStateInvalid = value - case "XfrmInTmplMismatch": - x.XfrmInTmplMismatch = value - case "XfrmInNoPols": - x.XfrmInNoPols = value - case "XfrmInPolBlock": - x.XfrmInPolBlock = value - case "XfrmInPolError": - x.XfrmInPolError = value - case "XfrmOutError": - x.XfrmOutError = value - case "XfrmInStateMismatch": - x.XfrmInStateMismatch = value - case "XfrmOutBundleGenError": - x.XfrmOutBundleGenError = value - case "XfrmOutBundleCheckError": - x.XfrmOutBundleCheckError = value - case "XfrmOutNoStates": - x.XfrmOutNoStates = value - case "XfrmOutStateProtoError": - x.XfrmOutStateProtoError = value - case "XfrmOutStateModeError": - x.XfrmOutStateModeError = value - case "XfrmOutStateSeqError": - x.XfrmOutStateSeqError = value - case "XfrmOutStateExpired": - x.XfrmOutStateExpired = value - case "XfrmOutPolBlock": - x.XfrmOutPolBlock = value - case "XfrmOutPolDead": - x.XfrmOutPolDead = value - case "XfrmOutPolError": - x.XfrmOutPolError = value - case "XfrmFwdHdrError": - x.XfrmFwdHdrError = value - case "XfrmOutStateInvalid": - x.XfrmOutStateInvalid = value - case "XfrmAcquireError": - x.XfrmAcquireError = value - } - - } - - return x, s.Err() -} diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go index 209e2ac987..c745a4c04f 100644 --- a/vendor/github.com/prometheus/procfs/zoneinfo.go +++ b/vendor/github.com/prometheus/procfs/zoneinfo.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs @@ -18,7 +19,7 @@ package procfs import ( "bytes" "fmt" - "io/ioutil" + "os" "regexp" "strings" @@ -72,7 +73,7 @@ var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`) // structs containing the relevant info. More information available here: // https://www.kernel.org/doc/Documentation/sysctl/vm.txt func (fs FS) Zoneinfo() ([]Zoneinfo, error) { - data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo")) + data, err := os.ReadFile(fs.proc.Path("zoneinfo")) if err != nil { return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err) } diff --git a/vendor/github.com/rubenv/sql-migrate/README.md b/vendor/github.com/rubenv/sql-migrate/README.md index c954aa8956..56585233b6 100644 --- a/vendor/github.com/rubenv/sql-migrate/README.md +++ b/vendor/github.com/rubenv/sql-migrate/README.md @@ -24,6 +24,10 @@ To install the library and command line program, use the following: ```bash go get -v github.com/rubenv/sql-migrate/... ``` +For Go version from 1.18, use: +```bash +go install github.com/rubenv/sql-migrate/...@latest +``` ## Usage diff --git a/vendor/github.com/russross/blackfriday/.gitignore b/vendor/github.com/russross/blackfriday/.gitignore deleted file mode 100644 index 75623dcccb..0000000000 --- a/vendor/github.com/russross/blackfriday/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.out -*.swp -*.8 -*.6 -_obj -_test* -markdown -tags diff --git a/vendor/github.com/russross/blackfriday/.travis.yml b/vendor/github.com/russross/blackfriday/.travis.yml deleted file mode 100644 index 2f3351d7ae..0000000000 --- a/vendor/github.com/russross/blackfriday/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -sudo: false -language: go -go: - - "1.9.x" - - "1.10.x" - - tip -matrix: - fast_finish: true - allow_failures: - - go: tip -install: - - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). -script: - - go get -t -v ./... - - diff -u <(echo -n) <(gofmt -d -s .) - - go tool vet . - - go test -v -race ./... diff --git a/vendor/github.com/russross/blackfriday/LICENSE.txt b/vendor/github.com/russross/blackfriday/LICENSE.txt deleted file mode 100644 index 2885af3602..0000000000 --- a/vendor/github.com/russross/blackfriday/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -Blackfriday is distributed under the Simplified BSD License: - -> Copyright © 2011 Russ Ross -> 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. -> -> 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/russross/blackfriday/README.md b/vendor/github.com/russross/blackfriday/README.md deleted file mode 100644 index 3c62e13753..0000000000 --- a/vendor/github.com/russross/blackfriday/README.md +++ /dev/null @@ -1,369 +0,0 @@ -Blackfriday -[![Build Status][BuildSVG]][BuildURL] -[![Godoc][GodocV2SVG]][GodocV2URL] -=========== - -Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It -is paranoid about its input (so you can safely feed it user-supplied -data), it is fast, it supports common extensions (tables, smart -punctuation substitutions, etc.), and it is safe for all utf-8 -(unicode) input. - -HTML output is currently supported, along with Smartypants -extensions. - -It started as a translation from C of [Sundown][3]. - - -Installation ------------- - -Blackfriday is compatible with any modern Go release. With Go and git installed: - - go get -u gopkg.in/russross/blackfriday.v2 - -will download, compile, and install the package into your `$GOPATH` directory -hierarchy. - - -Versions --------- - -Currently maintained and recommended version of Blackfriday is `v2`. It's being -developed on its own branch: https://github.com/russross/blackfriday/tree/v2 and the -documentation is available at -https://godoc.org/gopkg.in/russross/blackfriday.v2. - -It is `go get`-able via [gopkg.in][6] at `gopkg.in/russross/blackfriday.v2`, -but we highly recommend using package management tool like [dep][7] or -[Glide][8] and make use of semantic versioning. With package management you -should import `github.com/russross/blackfriday` and specify that you're using -version 2.0.0. - -Version 2 offers a number of improvements over v1: - -* Cleaned up API -* A separate call to [`Parse`][4], which produces an abstract syntax tree for - the document -* Latest bug fixes -* Flexibility to easily add your own rendering extensions - -Potential drawbacks: - -* Our benchmarks show v2 to be slightly slower than v1. Currently in the - ballpark of around 15%. -* API breakage. If you can't afford modifying your code to adhere to the new API - and don't care too much about the new features, v2 is probably not for you. -* Several bug fixes are trailing behind and still need to be forward-ported to - v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for - tracking. - -If you are still interested in the legacy `v1`, you can import it from -`github.com/russross/blackfriday`. Documentation for the legacy v1 can be found -here: https://godoc.org/github.com/russross/blackfriday - -### Known issue with `dep` - -There is a known problem with using Blackfriday v1 _transitively_ and `dep`. -Currently `dep` prioritizes semver versions over anything else, and picks the -latest one, plus it does not apply a `[[constraint]]` specifier to transitively -pulled in packages. So if you're using something that uses Blackfriday v1, but -that something does not use `dep` yet, you will get Blackfriday v2 pulled in and -your first dependency will fail to build. - -There are couple of fixes for it, documented here: -https://github.com/golang/dep/blob/master/docs/FAQ.md#how-do-i-constrain-a-transitive-dependencys-version - -Meanwhile, `dep` team is working on a more general solution to the constraints -on transitive dependencies problem: https://github.com/golang/dep/issues/1124. - - -Usage ------ - -### v1 - -For basic usage, it is as simple as getting your input into a byte -slice and calling: - - output := blackfriday.MarkdownBasic(input) - -This renders it with no extensions enabled. To get a more useful -feature set, use this instead: - - output := blackfriday.MarkdownCommon(input) - -### v2 - -For the most sensible markdown processing, it is as simple as getting your input -into a byte slice and calling: - -```go -output := blackfriday.Run(input) -``` - -Your input will be parsed and the output rendered with a set of most popular -extensions enabled. If you want the most basic feature set, corresponding with -the bare Markdown specification, use: - -```go -output := blackfriday.Run(input, blackfriday.WithNoExtensions()) -``` - -### Sanitize untrusted content - -Blackfriday itself does nothing to protect against malicious content. If you are -dealing with user-supplied markdown, we recommend running Blackfriday's output -through HTML sanitizer such as [Bluemonday][5]. - -Here's an example of simple usage of Blackfriday together with Bluemonday: - -```go -import ( - "github.com/microcosm-cc/bluemonday" - "gopkg.in/russross/blackfriday.v2" -) - -// ... -unsafe := blackfriday.Run(input) -html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) -``` - -### Custom options, v1 - -If you want to customize the set of options, first get a renderer -(currently only the HTML output engine), then use it to -call the more general `Markdown` function. For examples, see the -implementations of `MarkdownBasic` and `MarkdownCommon` in -`markdown.go`. - -### Custom options, v2 - -If you want to customize the set of options, use `blackfriday.WithExtensions`, -`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`. - -### `blackfriday-tool` - -You can also check out `blackfriday-tool` for a more complete example -of how to use it. Download and install it using: - - go get github.com/russross/blackfriday-tool - -This is a simple command-line tool that allows you to process a -markdown file using a standalone program. You can also browse the -source directly on github if you are just looking for some example -code: - -* - -Note that if you have not already done so, installing -`blackfriday-tool` will be sufficient to download and install -blackfriday in addition to the tool itself. The tool binary will be -installed in `$GOPATH/bin`. This is a statically-linked binary that -can be copied to wherever you need it without worrying about -dependencies and library versions. - -### Sanitized anchor names - -Blackfriday includes an algorithm for creating sanitized anchor names -corresponding to a given input text. This algorithm is used to create -anchors for headings when `EXTENSION_AUTO_HEADER_IDS` is enabled. The -algorithm has a specification, so that other packages can create -compatible anchor names and links to those anchors. - -The specification is located at https://godoc.org/github.com/russross/blackfriday#hdr-Sanitized_Anchor_Names. - -[`SanitizedAnchorName`](https://godoc.org/github.com/russross/blackfriday#SanitizedAnchorName) exposes this functionality, and can be used to -create compatible links to the anchor names generated by blackfriday. -This algorithm is also implemented in a small standalone package at -[`github.com/shurcooL/sanitized_anchor_name`](https://godoc.org/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients -that want a small package and don't need full functionality of blackfriday. - - -Features --------- - -All features of Sundown are supported, including: - -* **Compatibility**. The Markdown v1.0.3 test suite passes with - the `--tidy` option. Without `--tidy`, the differences are - mostly in whitespace and entity escaping, where blackfriday is - more consistent and cleaner. - -* **Common extensions**, including table support, fenced code - blocks, autolinks, strikethroughs, non-strict emphasis, etc. - -* **Safety**. Blackfriday is paranoid when parsing, making it safe - to feed untrusted user input without fear of bad things - happening. The test suite stress tests this and there are no - known inputs that make it crash. If you find one, please let me - know and send me the input that does it. - - NOTE: "safety" in this context means *runtime safety only*. In order to - protect yourself against JavaScript injection in untrusted content, see - [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content). - -* **Fast processing**. It is fast enough to render on-demand in - most web applications without having to cache the output. - -* **Thread safety**. You can run multiple parsers in different - goroutines without ill effect. There is no dependence on global - shared state. - -* **Minimal dependencies**. Blackfriday only depends on standard - library packages in Go. The source code is pretty - self-contained, so it is easy to add to any project, including - Google App Engine projects. - -* **Standards compliant**. Output successfully validates using the - W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional. - - -Extensions ----------- - -In addition to the standard markdown syntax, this package -implements the following extensions: - -* **Intra-word emphasis supression**. The `_` character is - commonly used inside words when discussing code, so having - markdown interpret it as an emphasis command is usually the - wrong thing. Blackfriday lets you treat all emphasis markers as - normal characters when they occur inside a word. - -* **Tables**. Tables can be created by drawing them in the input - using a simple syntax: - - ``` - Name | Age - --------|------ - Bob | 27 - Alice | 23 - ``` - -* **Fenced code blocks**. In addition to the normal 4-space - indentation to mark code blocks, you can explicitly mark them - and supply a language (to make syntax highlighting simple). Just - mark it like this: - - ``` go - func getTrue() bool { - return true - } - ``` - - You can use 3 or more backticks to mark the beginning of the - block, and the same number to mark the end of the block. - - To preserve classes of fenced code blocks while using the bluemonday - HTML sanitizer, use the following policy: - - ``` go - p := bluemonday.UGCPolicy() - p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code") - html := p.SanitizeBytes(unsafe) - ``` - -* **Definition lists**. A simple definition list is made of a single-line - term followed by a colon and the definition for that term. - - Cat - : Fluffy animal everyone likes - - Internet - : Vector of transmission for pictures of cats - - Terms must be separated from the previous definition by a blank line. - -* **Footnotes**. A marker in the text that will become a superscript number; - a footnote definition that will be placed in a list of footnotes at the - end of the document. A footnote looks like this: - - This is a footnote.[^1] - - [^1]: the footnote text. - -* **Autolinking**. Blackfriday can find URLs that have not been - explicitly marked as links and turn them into links. - -* **Strikethrough**. Use two tildes (`~~`) to mark text that - should be crossed out. - -* **Hard line breaks**. With this extension enabled (it is off by - default in the `MarkdownBasic` and `MarkdownCommon` convenience - functions), newlines in the input translate into line breaks in - the output. - -* **Smart quotes**. Smartypants-style punctuation substitution is - supported, turning normal double- and single-quote marks into - curly quotes, etc. - -* **LaTeX-style dash parsing** is an additional option, where `--` - is translated into `–`, and `---` is translated into - `—`. This differs from most smartypants processors, which - turn a single hyphen into an ndash and a double hyphen into an - mdash. - -* **Smart fractions**, where anything that looks like a fraction - is translated into suitable HTML (instead of just a few special - cases like most smartypant processors). For example, `4/5` - becomes `45`, which renders as - 45. - - -Other renderers ---------------- - -Blackfriday is structured to allow alternative rendering engines. Here -are a few of note: - -* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown): - provides a GitHub Flavored Markdown renderer with fenced code block - highlighting, clickable heading anchor links. - - It's not customizable, and its goal is to produce HTML output - equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode), - except the rendering is performed locally. - -* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt, - but for markdown. - -* [LaTeX output](https://bitbucket.org/ambrevar/blackfriday-latex): - renders output as LaTeX. - -* [bfchroma](https://github.com/Depado/bfchroma/): provides convenience - integration with the [Chroma](https://github.com/alecthomas/chroma) code - highlighting library. bfchroma is only compatible with v2 of Blackfriday and - provides a drop-in renderer ready to use with Blackfriday, as well as - options and means for further customization. - - -TODO ----- - -* More unit testing -* Improve Unicode support. It does not understand all Unicode - rules (about what constitutes a letter, a punctuation symbol, - etc.), so it may fail to detect word boundaries correctly in - some instances. It is safe on all UTF-8 input. - - -License -------- - -[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt) - - - [1]: https://daringfireball.net/projects/markdown/ "Markdown" - [2]: https://golang.org/ "Go Language" - [3]: https://github.com/vmg/sundown "Sundown" - [4]: https://godoc.org/gopkg.in/russross/blackfriday.v2#Parse "Parse func" - [5]: https://github.com/microcosm-cc/bluemonday "Bluemonday" - [6]: https://labix.org/gopkg.in "gopkg.in" - [7]: https://github.com/golang/dep/ "dep" - [8]: https://github.com/Masterminds/glide "Glide" - - [BuildSVG]: https://travis-ci.org/russross/blackfriday.svg?branch=master - [BuildURL]: https://travis-ci.org/russross/blackfriday - [GodocV2SVG]: https://godoc.org/gopkg.in/russross/blackfriday.v2?status.svg - [GodocV2URL]: https://godoc.org/gopkg.in/russross/blackfriday.v2 diff --git a/vendor/github.com/russross/blackfriday/block.go b/vendor/github.com/russross/blackfriday/block.go deleted file mode 100644 index 45c21a6c26..0000000000 --- a/vendor/github.com/russross/blackfriday/block.go +++ /dev/null @@ -1,1474 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// Functions to parse block-level elements. -// - -package blackfriday - -import ( - "bytes" - "strings" - "unicode" -) - -// Parse block-level data. -// Note: this function and many that it calls assume that -// the input buffer ends with a newline. -func (p *parser) block(out *bytes.Buffer, data []byte) { - if len(data) == 0 || data[len(data)-1] != '\n' { - panic("block input is missing terminating newline") - } - - // this is called recursively: enforce a maximum depth - if p.nesting >= p.maxNesting { - return - } - p.nesting++ - - // parse out one block-level construct at a time - for len(data) > 0 { - // prefixed header: - // - // # Header 1 - // ## Header 2 - // ... - // ###### Header 6 - if p.isPrefixHeader(data) { - data = data[p.prefixHeader(out, data):] - continue - } - - // block of preformatted HTML: - // - //

- // ... - //
- if data[0] == '<' { - if i := p.html(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // title block - // - // % stuff - // % more stuff - // % even more stuff - if p.flags&EXTENSION_TITLEBLOCK != 0 { - if data[0] == '%' { - if i := p.titleBlock(out, data, true); i > 0 { - data = data[i:] - continue - } - } - } - - // blank lines. note: returns the # of bytes to skip - if i := p.isEmpty(data); i > 0 { - data = data[i:] - continue - } - - // indented code block: - // - // func max(a, b int) int { - // if a > b { - // return a - // } - // return b - // } - if p.codePrefix(data) > 0 { - data = data[p.code(out, data):] - continue - } - - // fenced code block: - // - // ``` go info string here - // func fact(n int) int { - // if n <= 1 { - // return n - // } - // return n * fact(n-1) - // } - // ``` - if p.flags&EXTENSION_FENCED_CODE != 0 { - if i := p.fencedCodeBlock(out, data, true); i > 0 { - data = data[i:] - continue - } - } - - // horizontal rule: - // - // ------ - // or - // ****** - // or - // ______ - if p.isHRule(data) { - p.r.HRule(out) - var i int - for i = 0; data[i] != '\n'; i++ { - } - data = data[i:] - continue - } - - // block quote: - // - // > A big quote I found somewhere - // > on the web - if p.quotePrefix(data) > 0 { - data = data[p.quote(out, data):] - continue - } - - // table: - // - // Name | Age | Phone - // ------|-----|--------- - // Bob | 31 | 555-1234 - // Alice | 27 | 555-4321 - if p.flags&EXTENSION_TABLES != 0 { - if i := p.table(out, data); i > 0 { - data = data[i:] - continue - } - } - - // an itemized/unordered list: - // - // * Item 1 - // * Item 2 - // - // also works with + or - - if p.uliPrefix(data) > 0 { - data = data[p.list(out, data, 0):] - continue - } - - // a numbered/ordered list: - // - // 1. Item 1 - // 2. Item 2 - if p.oliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_ORDERED):] - continue - } - - // definition lists: - // - // Term 1 - // : Definition a - // : Definition b - // - // Term 2 - // : Definition c - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(data) > 0 { - data = data[p.list(out, data, LIST_TYPE_DEFINITION):] - continue - } - } - - // anything else must look like a normal paragraph - // note: this finds underlined headers, too - data = data[p.paragraph(out, data):] - } - - p.nesting-- -} - -func (p *parser) isPrefixHeader(data []byte) bool { - if data[0] != '#' { - return false - } - - if p.flags&EXTENSION_SPACE_HEADERS != 0 { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - if data[level] != ' ' { - return false - } - } - return true -} - -func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { - level := 0 - for level < 6 && data[level] == '#' { - level++ - } - i := skipChar(data, level, ' ') - end := skipUntilChar(data, i, '\n') - skip := end - id := "" - if p.flags&EXTENSION_HEADER_IDS != 0 { - j, k := 0, 0 - // find start/end of header id - for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ { - } - for k = j + 1; k < end && data[k] != '}'; k++ { - } - // extract header id iff found - if j < end && k < end { - id = string(data[j+2 : k]) - end = j - skip = k + 1 - for end > 0 && data[end-1] == ' ' { - end-- - } - } - } - for end > 0 && data[end-1] == '#' { - if isBackslashEscaped(data, end-1) { - break - } - end-- - } - for end > 0 && data[end-1] == ' ' { - end-- - } - if end > i { - if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = SanitizedAnchorName(string(data[i:end])) - } - work := func() bool { - p.inline(out, data[i:end]) - return true - } - p.r.Header(out, work, level, id) - } - return skip -} - -func (p *parser) isUnderlinedHeader(data []byte) int { - // test of level 1 header - if data[0] == '=' { - i := skipChar(data, 1, '=') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 1 - } else { - return 0 - } - } - - // test of level 2 header - if data[0] == '-' { - i := skipChar(data, 1, '-') - i = skipChar(data, i, ' ') - if data[i] == '\n' { - return 2 - } else { - return 0 - } - } - - return 0 -} - -func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '%' { - return 0 - } - splitData := bytes.Split(data, []byte("\n")) - var i int - for idx, b := range splitData { - if !bytes.HasPrefix(b, []byte("%")) { - i = idx // - 1 - break - } - } - - data = bytes.Join(splitData[0:i], []byte("\n")) - p.r.TitleBlock(out, data) - - return len(data) -} - -func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { - var i, j int - - // identify the opening tag - if data[0] != '<' { - return 0 - } - curtag, tagfound := p.htmlFindTag(data[1:]) - - // handle special cases - if !tagfound { - // check for an HTML comment - if size := p.htmlComment(out, data, doRender); size > 0 { - return size - } - - // check for an
tag - if size := p.htmlHr(out, data, doRender); size > 0 { - return size - } - - // check for HTML CDATA - if size := p.htmlCDATA(out, data, doRender); size > 0 { - return size - } - - // no special case recognized - return 0 - } - - // look for an unindented matching closing tag - // followed by a blank line - found := false - /* - closetag := []byte("\n") - j = len(curtag) + 1 - for !found { - // scan for a closing tag at the beginning of a line - if skip := bytes.Index(data[j:], closetag); skip >= 0 { - j += skip + len(closetag) - } else { - break - } - - // see if it is the only thing on the line - if skip := p.isEmpty(data[j:]); skip > 0 { - // see if it is followed by a blank line/eof - j += skip - if j >= len(data) { - found = true - i = j - } else { - if skip := p.isEmpty(data[j:]); skip > 0 { - j += skip - found = true - i = j - } - } - } - } - */ - - // if not found, try a second pass looking for indented match - // but not if tag is "ins" or "del" (following original Markdown.pl) - if !found && curtag != "ins" && curtag != "del" { - i = 1 - for i < len(data) { - i++ - for i < len(data) && !(data[i-1] == '<' && data[i] == '/') { - i++ - } - - if i+2+len(curtag) >= len(data) { - break - } - - j = p.htmlFindEnd(curtag, data[i-1:]) - - if j > 0 { - i += j - 1 - found = true - break - } - } - } - - if !found { - return 0 - } - - // the end of the block has been found - if doRender { - // trim newlines - end := i - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - - return i -} - -func (p *parser) renderHTMLBlock(out *bytes.Buffer, data []byte, start int, doRender bool) int { - // html block needs to end with a blank line - if i := p.isEmpty(data[start:]); i > 0 { - size := start + i - if doRender { - // trim trailing newlines - end := size - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - return size - } - return 0 -} - -// HTML comment, lax form -func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { - i := p.inlineHTMLComment(out, data) - return p.renderHTMLBlock(out, data, i, doRender) -} - -// HTML CDATA section -func (p *parser) htmlCDATA(out *bytes.Buffer, data []byte, doRender bool) int { - const cdataTag = "') { - i++ - } - i++ - // no end-of-comment marker - if i >= len(data) { - return 0 - } - return p.renderHTMLBlock(out, data, i, doRender) -} - -// HR, which is the only self-closing block tag considered -func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') { - return 0 - } - if data[3] != ' ' && data[3] != '/' && data[3] != '>' { - // not an
tag after all; at least not a valid one - return 0 - } - - i := 3 - for data[i] != '>' && data[i] != '\n' { - i++ - } - - if data[i] == '>' { - return p.renderHTMLBlock(out, data, i+1, doRender) - } - - return 0 -} - -func (p *parser) htmlFindTag(data []byte) (string, bool) { - i := 0 - for isalnum(data[i]) { - i++ - } - key := string(data[:i]) - if _, ok := blockTags[key]; ok { - return key, true - } - return "", false -} - -func (p *parser) htmlFindEnd(tag string, data []byte) int { - // assume data[0] == '<' && data[1] == '/' already tested - - // check if tag is a match - closetag := []byte("") - if !bytes.HasPrefix(data, closetag) { - return 0 - } - i := len(closetag) - - // check that the rest of the line is blank - skip := 0 - if skip = p.isEmpty(data[i:]); skip == 0 { - return 0 - } - i += skip - skip = 0 - - if i >= len(data) { - return i - } - - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - return i - } - if skip = p.isEmpty(data[i:]); skip == 0 { - // following line must be blank - return 0 - } - - return i + skip -} - -func (*parser) isEmpty(data []byte) int { - // it is okay to call isEmpty on an empty buffer - if len(data) == 0 { - return 0 - } - - var i int - for i = 0; i < len(data) && data[i] != '\n'; i++ { - if data[i] != ' ' && data[i] != '\t' { - return 0 - } - } - return i + 1 -} - -func (*parser) isHRule(data []byte) bool { - i := 0 - - // skip up to three spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // look at the hrule char - if data[i] != '*' && data[i] != '-' && data[i] != '_' { - return false - } - c := data[i] - - // the whole line must be the char or whitespace - n := 0 - for data[i] != '\n' { - switch { - case data[i] == c: - n++ - case data[i] != ' ': - return false - } - i++ - } - - return n >= 3 -} - -// isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data, -// and returns the end index if so, or 0 otherwise. It also returns the marker found. -// If syntax is not nil, it gets set to the syntax specified in the fence line. -// A final newline is mandatory to recognize the fence line, unless newlineOptional is true. -func isFenceLine(data []byte, info *string, oldmarker string, newlineOptional bool) (end int, marker string) { - i, size := 0, 0 - - // skip up to three spaces - for i < len(data) && i < 3 && data[i] == ' ' { - i++ - } - - // check for the marker characters: ~ or ` - if i >= len(data) { - return 0, "" - } - if data[i] != '~' && data[i] != '`' { - return 0, "" - } - - c := data[i] - - // the whole line must be the same char or whitespace - for i < len(data) && data[i] == c { - size++ - i++ - } - - // the marker char must occur at least 3 times - if size < 3 { - return 0, "" - } - marker = string(data[i-size : i]) - - // if this is the end marker, it must match the beginning marker - if oldmarker != "" && marker != oldmarker { - return 0, "" - } - - // TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here - // into one, always get the info string, and discard it if the caller doesn't care. - if info != nil { - infoLength := 0 - i = skipChar(data, i, ' ') - - if i >= len(data) { - if newlineOptional && i == len(data) { - return i, marker - } - return 0, "" - } - - infoStart := i - - if data[i] == '{' { - i++ - infoStart++ - - for i < len(data) && data[i] != '}' && data[i] != '\n' { - infoLength++ - i++ - } - - if i >= len(data) || data[i] != '}' { - return 0, "" - } - - // strip all whitespace at the beginning and the end - // of the {} block - for infoLength > 0 && isspace(data[infoStart]) { - infoStart++ - infoLength-- - } - - for infoLength > 0 && isspace(data[infoStart+infoLength-1]) { - infoLength-- - } - - i++ - } else { - for i < len(data) && !isverticalspace(data[i]) { - infoLength++ - i++ - } - } - - *info = strings.TrimSpace(string(data[infoStart : infoStart+infoLength])) - } - - i = skipChar(data, i, ' ') - if i >= len(data) || data[i] != '\n' { - if newlineOptional && i == len(data) { - return i, marker - } - return 0, "" - } - - return i + 1, marker // Take newline into account. -} - -// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning, -// or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects. -// If doRender is true, a final newline is mandatory to recognize the fenced code block. -func (p *parser) fencedCodeBlock(out *bytes.Buffer, data []byte, doRender bool) int { - var infoString string - beg, marker := isFenceLine(data, &infoString, "", false) - if beg == 0 || beg >= len(data) { - return 0 - } - - var work bytes.Buffer - - for { - // safe to assume beg < len(data) - - // check for the end of the code block - newlineOptional := !doRender - fenceEnd, _ := isFenceLine(data[beg:], nil, marker, newlineOptional) - if fenceEnd != 0 { - beg += fenceEnd - break - } - - // copy the current line - end := skipUntilChar(data, beg, '\n') + 1 - - // did we reach the end of the buffer without a closing marker? - if end >= len(data) { - return 0 - } - - // verbatim copy to the working buffer - if doRender { - work.Write(data[beg:end]) - } - beg = end - } - - if doRender { - p.r.BlockCode(out, work.Bytes(), infoString) - } - - return beg -} - -func (p *parser) table(out *bytes.Buffer, data []byte) int { - var header bytes.Buffer - i, columns := p.tableHeader(&header, data) - if i == 0 { - return 0 - } - - var body bytes.Buffer - - for i < len(data) { - pipes, rowStart := 0, i - for ; data[i] != '\n'; i++ { - if data[i] == '|' { - pipes++ - } - } - - if pipes == 0 { - i = rowStart - break - } - - // include the newline in data sent to tableRow - i++ - p.tableRow(&body, data[rowStart:i], columns, false) - } - - p.r.Table(out, header.Bytes(), body.Bytes(), columns) - - return i -} - -// check if the specified position is preceded by an odd number of backslashes -func isBackslashEscaped(data []byte, i int) bool { - backslashes := 0 - for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' { - backslashes++ - } - return backslashes&1 == 1 -} - -func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns []int) { - i := 0 - colCount := 1 - for i = 0; data[i] != '\n'; i++ { - if data[i] == '|' && !isBackslashEscaped(data, i) { - colCount++ - } - } - - // doesn't look like a table header - if colCount == 1 { - return - } - - // include the newline in the data sent to tableRow - header := data[:i+1] - - // column count ignores pipes at beginning or end of line - if data[0] == '|' { - colCount-- - } - if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) { - colCount-- - } - - columns = make([]int, colCount) - - // move on to the header underline - i++ - if i >= len(data) { - return - } - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - i = skipChar(data, i, ' ') - - // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3 - // and trailing | optional on last column - col := 0 - for data[i] != '\n' { - dashes := 0 - - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_LEFT - dashes++ - } - for data[i] == '-' { - i++ - dashes++ - } - if data[i] == ':' { - i++ - columns[col] |= TABLE_ALIGNMENT_RIGHT - dashes++ - } - for data[i] == ' ' { - i++ - } - - // end of column test is messy - switch { - case dashes < 3: - // not a valid column - return - - case data[i] == '|' && !isBackslashEscaped(data, i): - // marker found, now skip past trailing whitespace - col++ - i++ - for data[i] == ' ' { - i++ - } - - // trailing junk found after last column - if col >= colCount && data[i] != '\n' { - return - } - - case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount: - // something else found where marker was required - return - - case data[i] == '\n': - // marker is optional for the last column - col++ - - default: - // trailing junk found after last column - return - } - } - if col != colCount { - return - } - - p.tableRow(out, header, columns, true) - size = i + 1 - return -} - -func (p *parser) tableRow(out *bytes.Buffer, data []byte, columns []int, header bool) { - i, col := 0, 0 - var rowWork bytes.Buffer - - if data[i] == '|' && !isBackslashEscaped(data, i) { - i++ - } - - for col = 0; col < len(columns) && i < len(data); col++ { - for data[i] == ' ' { - i++ - } - - cellStart := i - - for (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' { - i++ - } - - cellEnd := i - - // skip the end-of-cell marker, possibly taking us past end of buffer - i++ - - for cellEnd > cellStart && data[cellEnd-1] == ' ' { - cellEnd-- - } - - var cellWork bytes.Buffer - p.inline(&cellWork, data[cellStart:cellEnd]) - - if header { - p.r.TableHeaderCell(&rowWork, cellWork.Bytes(), columns[col]) - } else { - p.r.TableCell(&rowWork, cellWork.Bytes(), columns[col]) - } - } - - // pad it out with empty columns to get the right number - for ; col < len(columns); col++ { - if header { - p.r.TableHeaderCell(&rowWork, nil, columns[col]) - } else { - p.r.TableCell(&rowWork, nil, columns[col]) - } - } - - // silently ignore rows with too many cells - - p.r.TableRow(out, rowWork.Bytes()) -} - -// returns blockquote prefix length -func (p *parser) quotePrefix(data []byte) int { - i := 0 - for i < 3 && data[i] == ' ' { - i++ - } - if data[i] == '>' { - if data[i+1] == ' ' { - return i + 2 - } - return i + 1 - } - return 0 -} - -// blockquote ends with at least one blank line -// followed by something without a blockquote prefix -func (p *parser) terminateBlockquote(data []byte, beg, end int) bool { - if p.isEmpty(data[beg:]) <= 0 { - return false - } - if end >= len(data) { - return true - } - return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0 -} - -// parse a blockquote fragment -func (p *parser) quote(out *bytes.Buffer, data []byte) int { - var raw bytes.Buffer - beg, end := 0, 0 - for beg < len(data) { - end = beg - // Step over whole lines, collecting them. While doing that, check for - // fenced code and if one's found, incorporate it altogether, - // irregardless of any contents inside it - for data[end] != '\n' { - if p.flags&EXTENSION_FENCED_CODE != 0 { - if i := p.fencedCodeBlock(out, data[end:], false); i > 0 { - // -1 to compensate for the extra end++ after the loop: - end += i - 1 - break - } - } - end++ - } - end++ - - if pre := p.quotePrefix(data[beg:]); pre > 0 { - // skip the prefix - beg += pre - } else if p.terminateBlockquote(data, beg, end) { - break - } - - // this line is part of the blockquote - raw.Write(data[beg:end]) - beg = end - } - - var cooked bytes.Buffer - p.block(&cooked, raw.Bytes()) - p.r.BlockQuote(out, cooked.Bytes()) - return end -} - -// returns prefix length for block code -func (p *parser) codePrefix(data []byte) int { - if data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' { - return 4 - } - return 0 -} - -func (p *parser) code(out *bytes.Buffer, data []byte) int { - var work bytes.Buffer - - i := 0 - for i < len(data) { - beg := i - for data[i] != '\n' { - i++ - } - i++ - - blankline := p.isEmpty(data[beg:i]) > 0 - if pre := p.codePrefix(data[beg:i]); pre > 0 { - beg += pre - } else if !blankline { - // non-empty, non-prefixed line breaks the pre - i = beg - break - } - - // verbatim copy to the working buffeu - if blankline { - work.WriteByte('\n') - } else { - work.Write(data[beg:i]) - } - } - - // trim all the \n off the end of work - workbytes := work.Bytes() - eol := len(workbytes) - for eol > 0 && workbytes[eol-1] == '\n' { - eol-- - } - if eol != len(workbytes) { - work.Truncate(eol) - } - - work.WriteByte('\n') - - p.r.BlockCode(out, work.Bytes(), "") - - return i -} - -// returns unordered list item prefix -func (p *parser) uliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // need a *, +, or - followed by a space - if (data[i] != '*' && data[i] != '+' && data[i] != '-') || - data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns ordered list item prefix -func (p *parser) oliPrefix(data []byte) int { - i := 0 - - // start with up to 3 spaces - for i < 3 && data[i] == ' ' { - i++ - } - - // count the digits - start := i - for data[i] >= '0' && data[i] <= '9' { - i++ - } - - // we need >= 1 digits followed by a dot and a space - if start == i || data[i] != '.' || data[i+1] != ' ' { - return 0 - } - return i + 2 -} - -// returns definition list item prefix -func (p *parser) dliPrefix(data []byte) int { - i := 0 - - // need a : followed by a spaces - if data[i] != ':' || data[i+1] != ' ' { - return 0 - } - for data[i] == ' ' { - i++ - } - return i + 2 -} - -// parse ordered or unordered list block -func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int { - i := 0 - flags |= LIST_ITEM_BEGINNING_OF_LIST - work := func() bool { - for i < len(data) { - skip := p.listItem(out, data[i:], &flags) - i += skip - - if skip == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { - break - } - flags &= ^LIST_ITEM_BEGINNING_OF_LIST - } - return true - } - - p.r.List(out, work, flags) - return i -} - -// Parse a single list item. -// Assumes initial prefix is already removed if this is a sublist. -func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int { - // keep track of the indentation of the first line - itemIndent := 0 - for itemIndent < 3 && data[itemIndent] == ' ' { - itemIndent++ - } - - i := p.uliPrefix(data) - if i == 0 { - i = p.oliPrefix(data) - } - if i == 0 { - i = p.dliPrefix(data) - // reset definition term flag - if i > 0 { - *flags &= ^LIST_TYPE_TERM - } - } - if i == 0 { - // if in defnition list, set term flag and continue - if *flags&LIST_TYPE_DEFINITION != 0 { - *flags |= LIST_TYPE_TERM - } else { - return 0 - } - } - - // skip leading whitespace on first line - for data[i] == ' ' { - i++ - } - - // find the end of the line - line := i - for i > 0 && data[i-1] != '\n' { - i++ - } - - // get working buffer - var raw bytes.Buffer - - // put the first line into the working buffer - raw.Write(data[line:i]) - line = i - - // process the following lines - containsBlankLine := false - sublist := 0 - codeBlockMarker := "" - -gatherlines: - for line < len(data) { - i++ - - // find the end of this line - for data[i-1] != '\n' { - i++ - } - - // if it is an empty line, guess that it is part of this item - // and move on to the next line - if p.isEmpty(data[line:i]) > 0 { - containsBlankLine = true - raw.Write(data[line:i]) - line = i - continue - } - - // calculate the indentation - indent := 0 - for indent < 4 && line+indent < i && data[line+indent] == ' ' { - indent++ - } - - chunk := data[line+indent : i] - - if p.flags&EXTENSION_FENCED_CODE != 0 { - // determine if in or out of codeblock - // if in codeblock, ignore normal list processing - _, marker := isFenceLine(chunk, nil, codeBlockMarker, false) - if marker != "" { - if codeBlockMarker == "" { - // start of codeblock - codeBlockMarker = marker - } else { - // end of codeblock. - *flags |= LIST_ITEM_CONTAINS_BLOCK - codeBlockMarker = "" - } - } - // we are in a codeblock, write line, and continue - if codeBlockMarker != "" || marker != "" { - raw.Write(data[line+indent : i]) - line = i - continue gatherlines - } - } - - // evaluate how this line fits in - switch { - // is this a nested list item? - case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || - p.oliPrefix(chunk) > 0 || - p.dliPrefix(chunk) > 0: - - if containsBlankLine { - // end the list if the type changed after a blank line - if indent <= itemIndent && - ((*flags&LIST_TYPE_ORDERED != 0 && p.uliPrefix(chunk) > 0) || - (*flags&LIST_TYPE_ORDERED == 0 && p.oliPrefix(chunk) > 0)) { - - *flags |= LIST_ITEM_END_OF_LIST - break gatherlines - } - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - // to be a nested list, it must be indented more - // if not, it is the next item in the same list - if indent <= itemIndent { - break gatherlines - } - - // is this the first item in the nested list? - if sublist == 0 { - sublist = raw.Len() - } - - // is this a nested prefix header? - case p.isPrefixHeader(chunk): - // if the header is not indented, it is not nested in the list - // and thus ends the list - if containsBlankLine && indent < 4 { - *flags |= LIST_ITEM_END_OF_LIST - break gatherlines - } - *flags |= LIST_ITEM_CONTAINS_BLOCK - - // anything following an empty line is only part - // of this item if it is indented 4 spaces - // (regardless of the indentation of the beginning of the item) - case containsBlankLine && indent < 4: - if *flags&LIST_TYPE_DEFINITION != 0 && i < len(data)-1 { - // is the next item still a part of this list? - next := i - for data[next] != '\n' { - next++ - } - for next < len(data)-1 && data[next] == '\n' { - next++ - } - if i < len(data)-1 && data[i] != ':' && data[next] != ':' { - *flags |= LIST_ITEM_END_OF_LIST - } - } else { - *flags |= LIST_ITEM_END_OF_LIST - } - break gatherlines - - // a blank line means this should be parsed as a block - case containsBlankLine: - *flags |= LIST_ITEM_CONTAINS_BLOCK - } - - containsBlankLine = false - - // add the line into the working buffer without prefix - raw.Write(data[line+indent : i]) - - line = i - } - - // If reached end of data, the Renderer.ListItem call we're going to make below - // is definitely the last in the list. - if line >= len(data) { - *flags |= LIST_ITEM_END_OF_LIST - } - - rawBytes := raw.Bytes() - - // render the contents of the list item - var cooked bytes.Buffer - if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 && *flags&LIST_TYPE_TERM == 0 { - // intermediate render of block item, except for definition term - if sublist > 0 { - p.block(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.block(&cooked, rawBytes) - } - } else { - // intermediate render of inline item - if sublist > 0 { - p.inline(&cooked, rawBytes[:sublist]) - p.block(&cooked, rawBytes[sublist:]) - } else { - p.inline(&cooked, rawBytes) - } - } - - // render the actual list item - cookedBytes := cooked.Bytes() - parsedEnd := len(cookedBytes) - - // strip trailing newlines - for parsedEnd > 0 && cookedBytes[parsedEnd-1] == '\n' { - parsedEnd-- - } - p.r.ListItem(out, cookedBytes[:parsedEnd], *flags) - - return line -} - -// render a single paragraph that has already been parsed out -func (p *parser) renderParagraph(out *bytes.Buffer, data []byte) { - if len(data) == 0 { - return - } - - // trim leading spaces - beg := 0 - for data[beg] == ' ' { - beg++ - } - - // trim trailing newline - end := len(data) - 1 - - // trim trailing spaces - for end > beg && data[end-1] == ' ' { - end-- - } - - work := func() bool { - p.inline(out, data[beg:end]) - return true - } - p.r.Paragraph(out, work) -} - -func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { - // prev: index of 1st char of previous line - // line: index of 1st char of current line - // i: index of cursor/end of current line - var prev, line, i int - - // keep going until we find something to mark the end of the paragraph - for i < len(data) { - // mark the beginning of the current line - prev = line - current := data[i:] - line = i - - // did we find a blank line marking the end of the paragraph? - if n := p.isEmpty(current); n > 0 { - // did this blank line followed by a definition list item? - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if i < len(data)-1 && data[i+1] == ':' { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - p.renderParagraph(out, data[:i]) - return i + n - } - - // an underline under some text marks a header, so our paragraph ended on prev line - if i > 0 { - if level := p.isUnderlinedHeader(current); level > 0 { - // render the paragraph - p.renderParagraph(out, data[:prev]) - - // ignore leading and trailing whitespace - eol := i - 1 - for prev < eol && data[prev] == ' ' { - prev++ - } - for eol > prev && data[eol-1] == ' ' { - eol-- - } - - // render the header - // this ugly double closure avoids forcing variables onto the heap - work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool { - return func() bool { - pp.inline(o, d) - return true - } - }(out, p, data[prev:eol]) - - id := "" - if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { - id = SanitizedAnchorName(string(data[prev:eol])) - } - - p.r.Header(out, work, level, id) - - // find the end of the underline - for data[i] != '\n' { - i++ - } - return i - } - } - - // if the next line starts a block of HTML, then the paragraph ends here - if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { - if data[i] == '<' && p.html(out, current, false) > 0 { - // rewind to before the HTML block - p.renderParagraph(out, data[:i]) - return i - } - } - - // if there's a prefixed header or a horizontal rule after this, paragraph is over - if p.isPrefixHeader(current) || p.isHRule(current) { - p.renderParagraph(out, data[:i]) - return i - } - - // if there's a fenced code block, paragraph is over - if p.flags&EXTENSION_FENCED_CODE != 0 { - if p.fencedCodeBlock(out, current, false) > 0 { - p.renderParagraph(out, data[:i]) - return i - } - } - - // if there's a definition list item, prev line is a definition term - if p.flags&EXTENSION_DEFINITION_LISTS != 0 { - if p.dliPrefix(current) != 0 { - return p.list(out, data[prev:], LIST_TYPE_DEFINITION) - } - } - - // if there's a list after this, paragraph is over - if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 { - if p.uliPrefix(current) != 0 || - p.oliPrefix(current) != 0 || - p.quotePrefix(current) != 0 || - p.codePrefix(current) != 0 { - p.renderParagraph(out, data[:i]) - return i - } - } - - // otherwise, scan to the beginning of the next line - for data[i] != '\n' { - i++ - } - i++ - } - - p.renderParagraph(out, data[:i]) - return i -} - -// SanitizedAnchorName returns a sanitized anchor name for the given text. -// -// It implements the algorithm specified in the package comment. -func SanitizedAnchorName(text string) string { - var anchorName []rune - futureDash := false - for _, r := range text { - switch { - case unicode.IsLetter(r) || unicode.IsNumber(r): - if futureDash && len(anchorName) > 0 { - anchorName = append(anchorName, '-') - } - futureDash = false - anchorName = append(anchorName, unicode.ToLower(r)) - default: - futureDash = true - } - } - return string(anchorName) -} diff --git a/vendor/github.com/russross/blackfriday/doc.go b/vendor/github.com/russross/blackfriday/doc.go deleted file mode 100644 index 9656c42a19..0000000000 --- a/vendor/github.com/russross/blackfriday/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Package blackfriday is a Markdown processor. -// -// It translates plain text with simple formatting rules into HTML or LaTeX. -// -// Sanitized Anchor Names -// -// Blackfriday includes an algorithm for creating sanitized anchor names -// corresponding to a given input text. This algorithm is used to create -// anchors for headings when EXTENSION_AUTO_HEADER_IDS is enabled. The -// algorithm is specified below, so that other packages can create -// compatible anchor names and links to those anchors. -// -// The algorithm iterates over the input text, interpreted as UTF-8, -// one Unicode code point (rune) at a time. All runes that are letters (category L) -// or numbers (category N) are considered valid characters. They are mapped to -// lower case, and included in the output. All other runes are considered -// invalid characters. Invalid characters that preceed the first valid character, -// as well as invalid character that follow the last valid character -// are dropped completely. All other sequences of invalid characters -// between two valid characters are replaced with a single dash character '-'. -// -// SanitizedAnchorName exposes this functionality, and can be used to -// create compatible links to the anchor names generated by blackfriday. -// This algorithm is also implemented in a small standalone package at -// github.com/shurcooL/sanitized_anchor_name. It can be useful for clients -// that want a small package and don't need full functionality of blackfriday. -package blackfriday - -// NOTE: Keep Sanitized Anchor Name algorithm in sync with package -// github.com/shurcooL/sanitized_anchor_name. -// Otherwise, users of sanitized_anchor_name will get anchor names -// that are incompatible with those generated by blackfriday. diff --git a/vendor/github.com/russross/blackfriday/html.go b/vendor/github.com/russross/blackfriday/html.go deleted file mode 100644 index e0a6c69c96..0000000000 --- a/vendor/github.com/russross/blackfriday/html.go +++ /dev/null @@ -1,938 +0,0 @@ -// -// Blackfriday Markdown Processor -// Available at http://github.com/russross/blackfriday -// -// Copyright © 2011 Russ Ross . -// Distributed under the Simplified BSD License. -// See README.md for details. -// - -// -// -// HTML rendering backend -// -// - -package blackfriday - -import ( - "bytes" - "fmt" - "regexp" - "strconv" - "strings" -) - -// Html renderer configuration options. -const ( - HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks - HTML_SKIP_STYLE // skip embedded