diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ce94ff9888..ebeaca4ce9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -2,8 +2,8 @@ FROM mcr.microsoft.com/devcontainers/go:1.21 RUN echo "Downloading prometheus..." \ - && curl -sSL -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/prometheus/prometheus/tags" -o /tmp/tags.json \ - && VERSION_LIST="$(jq -r '.[] | select(.name | contains("rc") | not) | .name | split("v") | .[1]' /tmp/tags.json | tr -d '"' | sort -rV)" \ + && curl -sSL -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/prometheus/prometheus/releases" -o /tmp/releases.json \ + && VERSION_LIST="$(jq -r '.[] | select(.tag_name | contains("rc") | not) | .tag_name | split("v") | .[1]' /tmp/releases.json | tr -d '"' | sort -rV)" \ && PROMETHEUS_LATEST_VERSION="$(echo "${VERSION_LIST}" | head -n 1)" \ && PROMETHEUS_FILE_NAME="prometheus-${PROMETHEUS_LATEST_VERSION}.linux-amd64" \ && curl -fsSLO "https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_LATEST_VERSION}/${PROMETHEUS_FILE_NAME}.tar.gz" \ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d751f8c96c..7e63cb7bc8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,21 +1,16 @@ +--- version: 2 updates: - package-ecosystem: "gomod" directory: "/" - vendor: false schedule: interval: "weekly" - labels: ["dependencies"] + open-pull-requests-limit: 20 - package-ecosystem: "docker" directory: "/" schedule: interval: "weekly" - labels: ["dependencies"] - - package-ecosystem: "github-actions" directory: "/" schedule: - interval: weekly - labels: - - "dependencies" - + interval: weekly diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 591bd8d49a..52e296ba15 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,16 +35,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/container-version.yaml b/.github/workflows/container-version.yaml index e4a443cd62..f9a3ba8cf9 100644 --- a/.github/workflows/container-version.yaml +++ b/.github/workflows/container-version.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run busybox updater run: | @@ -17,7 +17,7 @@ jobs: shell: bash - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 + uses: peter-evans/create-pull-request@v6 with: signoff: true token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index d43335efa9..8abf8f0dcc 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -15,21 +15,21 @@ jobs: GOBIN: /tmp/.bin steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: .mdoxcache key: ${{ runner.os }}-mdox-${{ hashFiles('docs/**/*.md', 'examples/**/*.md', 'mixin/**/*.md', '*.md') }} diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 3f7d3f698b..d9bff4e75f 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -16,14 +16,14 @@ jobs: GOBIN: /tmp/.bin steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | ~/.cache/go-build @@ -43,14 +43,14 @@ jobs: GOBIN: /tmp/.bin steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | ~/.cache/go-build @@ -115,14 +115,14 @@ jobs: GOBIN: /tmp/.bin steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Go. - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | ~/.cache/go-build diff --git a/.github/workflows/mixin.yaml b/.github/workflows/mixin.yaml index 378eae8666..12ec79b1fa 100644 --- a/.github/workflows/mixin.yaml +++ b/.github/workflows/mixin.yaml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x @@ -29,10 +29,10 @@ jobs: name: Linters (Static Analysis) for Jsonnet (mixin) steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: 1.21.x diff --git a/.github/workflows/react.yml b/.github/workflows/react.yml index cf20772f4b..df3dcebcae 100644 --- a/.github/workflows/react.yml +++ b/.github/workflows/react.yml @@ -15,14 +15,14 @@ jobs: name: React UI test on Node ${{ matrix.node }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install nodejs - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} diff --git a/.mdox.validate.yaml b/.mdox.validate.yaml index 94355e319e..9e67c44663 100644 --- a/.mdox.validate.yaml +++ b/.mdox.validate.yaml @@ -42,3 +42,6 @@ validators: type: 'ignore' - regex: 'twitter\.com' type: 'ignore' + # 500 when requested my mdox in GH actions. + - regex: 'outshift\.cisco\.com' + type: 'ignore' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9356b86078..e71ada3976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,38 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re ### Fixed +- [#7323](https://github.com/thanos-io/thanos/pull/7323) Sidecar: wait for prometheus on startup +- [#7326](https://github.com/thanos-io/thanos/pull/7326) Query: fixing exemplars proxy when querying stores with multiple tenants. +- [#7335](https://github.com/thanos-io/thanos/pull/7335) Dependency: Update minio-go to v7.0.70 which includes support for EKS Pod Identity. +- [#6948](https://github.com/thanos-io/thanos/pull/6948) Receive: fix goroutines leak during series requests to thanos store api. +- [#7392](https://github.com/thanos-io/thanos/pull/7392) Query: fix broken min, max for pre 0.34.1 sidecars + +### Added + +- [#7317](https://github.com/thanos-io/thanos/pull/7317) Tracing: allow specifying resource attributes for the OTLP configuration. +- [#7363](https://github.com/thanos-io/thanos/pull/7363) Query-frontend: set value of remote_user field in Slow Query Logs from HTTP header +- [#7335](https://github.com/thanos-io/thanos/pull/7335) Dependency: Update minio-go to v7.0.70 which includes support for EKS Pod Identity. +- [#7477](https://github.com/thanos-io/thanos/pull/7477) *: Bump objstore to `20240622095743-1afe5d4bc3cd` + +### Changed + +- [#7334](https://github.com/thanos-io/thanos/pull/7334) Compactor: do not vertically compact downsampled blocks. Such cases are now marked with `no-compact-mark.json`. Fixes panic `panic: unexpected seriesToChunkEncoder lack of iterations`. +- [#7382](https://github.com/thanos-io/thanos/pull/7382) *: Ensure objstore flag values are masked & disable debug/pprof/cmdline +- [#7393](https://github.com/thanos-io/thanos/pull/7393) *: *breaking :warning:* Using native histograms for grpc middleware metrics. Metrics `grpc_client_handling_seconds` and `grpc_server_handling_seconds` will now be native histograms, if you have enabled native histogram scraping you will need to update your PromQL expressions to use the new metric names. + +### Removed + +## [v0.35.1](https://github.com/thanos-io/thanos/tree/release-0.35) - 28.05.2024 + +### Fixed + +- [#7323](https://github.com/thanos-io/thanos/pull/7323) Sidecar: wait for prometheus on startup +- [#6948](https://github.com/thanos-io/thanos/pull/6948) Receive: fix goroutines leak during series requests to thanos store api. +- [#7382](https://github.com/thanos-io/thanos/pull/7382) *: Ensure objstore flag values are masked & disable debug/pprof/cmdline +- [#7392](https://github.com/thanos-io/thanos/pull/7392) Query: fix broken min, max for pre 0.34.1 sidecars +- [#7373](https://github.com/thanos-io/thanos/pull/7373) Receive: Fix stats for remote write +- [#7318](https://github.com/thanos-io/thanos/pull/7318) Compactor: Recover from panic to log block ID + ### Added ### Changed @@ -54,6 +86,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re - [#7271](https://github.com/thanos-io/thanos/pull/7271) Query: fixing dedup iterator when working on mixed sample types. - [#7289](https://github.com/thanos-io/thanos/pull/7289) Query Frontend: show warnings from downstream queries. - [#7308](https://github.com/thanos-io/thanos/pull/7308) Store: Batch TSDB Infos for blocks. +- [#7301](https://github.com/thanos-io/thanos/pull/7301) Store Gateway: fix index header reader `PostingsOffsets` returning wrong values. ### Added @@ -158,6 +191,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re - [#6753](https://github.com/thanos-io/thanos/pull/6753) mixin(Rule): *breaking :warning:* Fixed the mixin rules with duplicate names and updated the promtool version from v0.37.0 to v0.47.0 - [#6772](https://github.com/thanos-io/thanos/pull/6772) *: Bump prometheus to v0.47.2-0.20231006112807-a5a4eab679cc - [#6794](https://github.com/thanos-io/thanos/pull/6794) Receive: the exported HTTP metrics now uses the specified default tenant for requests where no tenants are found. +- [#6651](https://github.com/thanos-io/thanos/pull/6651) *: Update go_grpc_middleware to v2.0.0. Remove Tags Interceptor from Thanos. Tags interceptor is removed from v2.0.0 go-grpc-middleware and is not needed anymore. ### Removed diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 16d51e8552..8fb7be0cc3 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -13,7 +13,7 @@ | Matej Gera | matejgera@gmail.com | `@Matej Gera` | [@matej-g](https://github.com/matej-g) | Coralogix | | Filip Petkovski | filip.petkovsky@gmail.com | `@Filip Petkovski` | [@fpetkovski](https://github.com/fpetkovski) | Shopify | | Saswata Mukherjee | saswata.mukhe@gmail.com | `@saswatamcode` | [@saswatamcode](https://github.com/saswatamcode) | Red Hat | -| Michael Hoffmann | mhoffm@posteo.de | `@Michael Hoffmann` | [@MichaHoffmann](https://github.com/MichaHoffmann) | Aiven | +| Michael Hoffmann | mhoffm@posteo.de | `@Michael Hoffmann` | [@MichaHoffmann](https://github.com/MichaHoffmann) | Cloudflare | We are bunch of people from different companies with various interests and skills. We are from different parts of the world: Germany, Holland, Lithuania, US, UK and India. We have something in common though: We all share the love for OpenSource, Go, Prometheus, :coffee: and Observability topics. diff --git a/Makefile b/Makefile index bee70ee848..29e1d5cc87 100644 --- a/Makefile +++ b/Makefile @@ -404,6 +404,7 @@ NewHistorgram,NewHistogramVec,NewSummary,NewSummaryVec}=github.com/prometheus/cl NewCounterVec,NewCounterVec,NewGauge,NewGaugeVec,NewGaugeFunc,NewHistorgram,NewHistogramVec,NewSummary,NewSummaryVec},\ github.com/NYTimes/gziphandler.{GzipHandler}=github.com/klauspost/compress/gzhttp.{GzipHandler},\ sync/atomic=go.uber.org/atomic,github.com/cortexproject/cortex=github.com/thanos-io/thanos/internal/cortex,\ +github.com/prometheus/prometheus/promql/parser.{ParseExpr,ParseMetricSelector}=github.com/thanos-io/thanos/pkg/extpromql.{ParseExpr,ParseMetricSelector},\ io/ioutil.{Discard,NopCloser,ReadAll,ReadDir,ReadFile,TempDir,TempFile,Writefile}" $(shell go list ./... | grep -v "internal/cortex") @$(FAILLINT) -paths "fmt.{Print,Println,Sprint}" -ignore-tests ./... @echo ">> linting all of the Go files GOGC=${GOGC}" diff --git a/README.md b/README.md index f47c244121..fe97c79997 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![CI](https://github.com/thanos-io/thanos/workflows/CI/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3ACI) [![CI](https://circleci.com/gh/thanos-io/thanos.svg?style=svg)](https://circleci.com/gh/thanos-io/thanos) [![go](https://github.com/thanos-io/thanos/workflows/go/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3Ago) [![react](https://github.com/thanos-io/thanos/workflows/react/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3Areact) [![docs](https://github.com/thanos-io/thanos/workflows/docs/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3Adocs) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/thanos-io/thanos) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=109162639) -> đŸ“ĸ [ThanosCon](https://thanos.io/blog/2023-20-11-thanoscon/) is happening on 19th March as a co-located half-day on KubeCon EU in Paris. Join us there! 🤗 CFP is open until 3rd December! +> đŸ“ĸ [ThanosCon](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/thanoscon/) happened on 19th March 2024 as a co-located half-day on KubeCon EU in Paris. ## Overview diff --git a/VERSION b/VERSION index 731b95d7fc..19199bccac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.35.1 +0.36.1 diff --git a/cmd/thanos/compact.go b/cmd/thanos/compact.go index cdd3706069..cd34333ee5 100644 --- a/cmd/thanos/compact.go +++ b/cmd/thanos/compact.go @@ -369,13 +369,20 @@ func runCompact( conf.blockFilesConcurrency, conf.compactBlocksFetchConcurrency, ) + var planner compact.Planner + tsdbPlanner := compact.NewPlanner(logger, levels, noCompactMarkerFilter) - planner := compact.WithLargeTotalIndexSizeFilter( + largeIndexFilterPlanner := compact.WithLargeTotalIndexSizeFilter( tsdbPlanner, insBkt, int64(conf.maxBlockIndexSize), compactMetrics.blocksMarked.WithLabelValues(metadata.NoCompactMarkFilename, metadata.IndexSizeExceedingNoCompactReason), ) + if enableVerticalCompaction { + planner = compact.WithVerticalCompactionDownsampleFilter(largeIndexFilterPlanner, insBkt, compactMetrics.blocksMarked.WithLabelValues(metadata.NoCompactMarkFilename, metadata.DownsampleVerticalCompactionNoCompactReason)) + } else { + planner = largeIndexFilterPlanner + } blocksCleaner := compact.NewBlocksCleaner(logger, insBkt, ignoreDeletionMarkFilter, deleteDelay, compactMetrics.blocksCleaned, compactMetrics.blockCleanupFailures) compactor, err := compact.NewBucketCompactorWithCheckerAndCallback( logger, diff --git a/cmd/thanos/query.go b/cmd/thanos/query.go index 48b37872f0..2263a35dd6 100644 --- a/cmd/thanos/query.go +++ b/cmd/thanos/query.go @@ -17,7 +17,6 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" "github.com/oklog/run" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -268,7 +267,8 @@ func registerQuery(app *extkingpin.App) { return errors.Wrap(err, "error while parsing config for request logging") } - tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions(reqLogConfig) + grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(reqLogConfig) + if err != nil { return errors.Wrap(err, "error while parsing config for request logging") } @@ -310,7 +310,7 @@ func registerQuery(app *extkingpin.App) { tracer, httpLogOpts, grpcLogOpts, - tagOpts, + logFilterMethods, grpcServerConfig, *grpcCompression, *secure, @@ -395,7 +395,7 @@ func runQuery( tracer opentracing.Tracer, httpLogOpts []logging.Option, grpcLogOpts []grpc_logging.Option, - tagOpts []tags.Option, + logFilterMethods []string, grpcServerConfig grpcConfig, grpcCompression string, secure bool, @@ -831,7 +831,7 @@ func runQuery( defaultEngineType := querypb.EngineType(querypb.EngineType_value[defaultEngine]) grpcAPI := apiv1.NewGRPCAPI(time.Now, queryReplicaLabels, queryableCreator, engineFactory, defaultEngineType, lookbackDeltaCreator, instantDefaultMaxSourceResolution) storeServer := store.NewLimitedStoreServer(store.NewInstrumentedStoreServer(reg, proxy), reg, storeRateLimits) - s := grpcserver.New(logger, reg, tracer, grpcLogOpts, tagOpts, comp, grpcProbe, + s := grpcserver.New(logger, reg, tracer, grpcLogOpts, logFilterMethods, comp, grpcProbe, grpcserver.WithServer(apiv1.RegisterQueryServer(grpcAPI)), grpcserver.WithServer(store.RegisterStoreServer(storeServer, logger)), grpcserver.WithServer(rules.RegisterRulesServer(rulesProxy)), @@ -851,6 +851,7 @@ func runQuery( }, func(error) { statusProber.NotReady(err) s.Shutdown(err) + endpoints.Close() }) } @@ -949,7 +950,6 @@ func prepareEndpointSet( }) }, func(error) { cancel() - endpointSet.Close() }) } diff --git a/cmd/thanos/query_frontend.go b/cmd/thanos/query_frontend.go index fcaf983e48..2ae04a12a9 100644 --- a/cmd/thanos/query_frontend.go +++ b/cmd/thanos/query_frontend.go @@ -167,6 +167,8 @@ func registerQueryFrontend(app *extkingpin.App) { cmd.Flag("query-frontend.vertical-shards", "Number of shards to use when distributing shardable PromQL queries. For more details, you can refer to the Vertical query sharding proposal: https://thanos.io/tip/proposals-accepted/202205-vertical-query-sharding.md").IntVar(&cfg.NumShards) + cmd.Flag("query-frontend.slow-query-logs-user-header", "Set the value of the field remote_user in the slow query logs to the value of the given HTTP header. Falls back to reading the user from the basic auth header.").PlaceHolder("").Default("").StringVar(&cfg.CortexHandlerConfig.SlowQueryLogsUserHeader) + reqLogConfig := extkingpin.RegisterRequestLoggingFlags(cmd) cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { @@ -356,19 +358,19 @@ func runQueryFrontend( if !cfg.webDisableCORS { api.SetCORS(w) } - tracing.HTTPMiddleware( - tracer, - name, - logger, - ins.NewHandler( + middleware.RequestID( + tracing.HTTPMiddleware( + tracer, name, - gzhttp.GzipHandler( - middleware.RequestID( + logger, + ins.NewHandler( + name, + gzhttp.GzipHandler( logMiddleware.HTTPMiddleware(name, f), ), ), + // Cortex frontend middlewares require orgID. ), - // Cortex frontend middlewares require orgID. ).ServeHTTP(w, r.WithContext(user.InjectOrgID(r.Context(), orgId))) }) return hf diff --git a/cmd/thanos/receive.go b/cmd/thanos/receive.go index a945b8eac3..7df5ff778e 100644 --- a/cmd/thanos/receive.go +++ b/cmd/thanos/receive.go @@ -15,7 +15,6 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" "github.com/oklog/run" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -75,7 +74,8 @@ func registerReceive(app *extkingpin.App) { return errors.New("no external labels configured for receive, uniquely identifying external labels must be configured (ideally with `receive_` prefix); see https://thanos.io/tip/thanos/storage.md#external-labels for details.") } - tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions(conf.reqLogConfig) + grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(conf.reqLogConfig) + if err != nil { return errors.Wrap(err, "error while parsing config for request logging") } @@ -105,7 +105,8 @@ func registerReceive(app *extkingpin.App) { debugLogging, reg, tracer, - grpcLogOpts, tagOpts, + grpcLogOpts, + logFilterMethods, tsdbOpts, lset, component.Receive, @@ -123,7 +124,7 @@ func runReceive( reg *prometheus.Registry, tracer opentracing.Tracer, grpcLogOpts []grpc_logging.Option, - tagOpts []tags.Option, + logFilterMethods []string, tsdbOpts *tsdb.Options, lset labels.Labels, comp component.SourceStoreAPI, @@ -363,7 +364,7 @@ func runReceive( info.WithExemplarsInfoFunc(), ) - srv := grpcserver.New(logger, receive.NewUnRegisterer(reg), tracer, grpcLogOpts, tagOpts, comp, grpcProbe, + srv := grpcserver.New(logger, receive.NewUnRegisterer(reg), tracer, grpcLogOpts, logFilterMethods, comp, grpcProbe, grpcserver.WithServer(store.RegisterStoreServer(rw, logger)), grpcserver.WithServer(store.RegisterWritableStoreServer(rw)), grpcserver.WithServer(exemplars.RegisterExemplarsServer(exemplars.NewMultiTSDB(dbs.TSDBExemplars))), @@ -422,7 +423,13 @@ func runReceive( { ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { - return runutil.Repeat(2*time.Hour, ctx.Done(), func() error { + pruneInterval := 2 * time.Duration(tsdbOpts.MaxBlockDuration) * time.Millisecond + return runutil.Repeat(time.Minute, ctx.Done(), func() error { + currentTime := time.Now() + currentTotalMinutes := currentTime.Hour()*60 + currentTime.Minute() + if currentTotalMinutes%int(pruneInterval.Minutes()) != 0 { + return nil + } if err := dbs.Prune(ctx); err != nil { level.Error(logger).Log("err", err) } diff --git a/cmd/thanos/rule.go b/cmd/thanos/rule.go index c23d7d70e1..776894c0c2 100644 --- a/cmd/thanos/rule.go +++ b/cmd/thanos/rule.go @@ -21,7 +21,6 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" "github.com/oklog/run" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -59,6 +58,7 @@ import ( "github.com/thanos-io/thanos/pkg/extkingpin" "github.com/thanos-io/thanos/pkg/extprom" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/info" "github.com/thanos-io/thanos/pkg/info/infopb" "github.com/thanos-io/thanos/pkg/logging" @@ -233,7 +233,8 @@ func registerRule(app *extkingpin.App) { return errors.Wrap(err, "error while parsing config for request logging") } - tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions(reqLogConfig) + grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(reqLogConfig) + if err != nil { return errors.Wrap(err, "error while parsing config for request logging") } @@ -249,7 +250,7 @@ func registerRule(app *extkingpin.App) { getFlagsMap(cmd.Flags()), httpLogOpts, grpcLogOpts, - tagOpts, + logFilterMethods, tsdbOpts, agentOpts, ) @@ -313,7 +314,7 @@ func runRule( flagsMap map[string]string, httpLogOpts []logging.Option, grpcLogOpts []grpc_logging.Option, - tagOpts []tags.Option, + logFilterMethods []string, tsdbOpts *tsdb.Options, agentOpts *agent.Options, ) error { @@ -324,7 +325,7 @@ func runRule( if len(conf.queryConfigYAML) > 0 { queryCfg, err = clientconfig.LoadConfigs(conf.queryConfigYAML) if err != nil { - return err + return errors.Wrap(err, "query configuration") } } else { queryCfg, err = clientconfig.BuildConfigFromHTTPAddresses(conf.query.addrs) @@ -381,12 +382,12 @@ func runRule( cfg.HTTPConfig.HTTPClientConfig.ClientMetrics = queryClientMetrics c, err := clientconfig.NewHTTPClient(cfg.HTTPConfig.HTTPClientConfig, "query") if err != nil { - return err + return fmt.Errorf("failed to create HTTP query client: %w", err) } c.Transport = tracing.HTTPTripperware(logger, c.Transport) queryClient, err := clientconfig.NewClient(logger, cfg.HTTPConfig.EndpointsConfig, c, queryProvider.Clone()) if err != nil { - return err + return fmt.Errorf("failed to create query client: %w", err) } queryClients = append(queryClients, queryClient) promClients = append(promClients, promclient.NewClient(queryClient, logger, "thanos-rule")) @@ -762,7 +763,7 @@ func runRule( options = append(options, grpcserver.WithServer( info.RegisterInfoServer(info.NewInfoServer(component.Rule.String(), infoOptions...)), )) - s := grpcserver.New(logger, reg, tracer, grpcLogOpts, tagOpts, comp, grpcProbe, options...) + s := grpcserver.New(logger, reg, tracer, grpcLogOpts, logFilterMethods, comp, grpcProbe, options...) g.Add(func() error { statusProber.Ready() @@ -952,7 +953,7 @@ func queryFuncCreator( queryAPIClients := grpcEndpointSet.GetQueryAPIClients() for _, i := range rand.Perm(len(queryAPIClients)) { e := query.NewRemoteEngine(logger, queryAPIClients[i], query.Opts{}) - expr, err := parser.ParseExpr(qs) + expr, err := extpromql.ParseExpr(qs) if err != nil { level.Error(logger).Log("err", err, "query", qs) continue diff --git a/cmd/thanos/sidecar.go b/cmd/thanos/sidecar.go index 95ad4ba693..2d51063980 100644 --- a/cmd/thanos/sidecar.go +++ b/cmd/thanos/sidecar.go @@ -16,7 +16,6 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" "github.com/oklog/run" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -59,7 +58,9 @@ func registerSidecar(app *extkingpin.App) { conf := &sidecarConfig{} conf.registerFlag(cmd) cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { - tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions(conf.reqLogConfig) + + grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(conf.reqLogConfig) + if err != nil { return errors.Wrap(err, "error while parsing config for request logging") } @@ -101,7 +102,7 @@ func registerSidecar(app *extkingpin.App) { extprom.WrapRegistererWithPrefix("thanos_sidecar_", reg), &opts) - return runSidecar(g, logger, reg, tracer, rl, component.Sidecar, *conf, httpClient, grpcLogOpts, tagOpts) + return runSidecar(g, logger, reg, tracer, rl, component.Sidecar, *conf, httpClient, grpcLogOpts, logFilterMethods) }) } @@ -115,7 +116,7 @@ func runSidecar( conf sidecarConfig, httpClient *http.Client, grpcLogOpts []grpc_logging.Option, - tagOpts []tags.Option, + logFilterMethods []string, ) error { var m = &promMetadata{ @@ -134,10 +135,9 @@ func runSidecar( return errors.Wrap(err, "getting object store config") } - var uploads = true - if len(confContentYaml) == 0 { + var uploads = len(confContentYaml) != 0 + if !uploads { level.Info(logger).Log("msg", "no supported bucket was configured, uploads will be disabled") - uploads = false } grpcProbe := prober.NewGRPC() @@ -148,111 +148,119 @@ func runSidecar( prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) - srv := httpserver.New(logger, reg, comp, httpProbe, - httpserver.WithListen(conf.http.bindAddress), - httpserver.WithGracePeriod(time.Duration(conf.http.gracePeriod)), - httpserver.WithTLSConfig(conf.http.tlsConfig), - ) + // Setup the HTTP server. + { + srv := httpserver.New(logger, reg, comp, httpProbe, + httpserver.WithListen(conf.http.bindAddress), + httpserver.WithGracePeriod(time.Duration(conf.http.gracePeriod)), + httpserver.WithTLSConfig(conf.http.tlsConfig), + ) + + g.Add(func() error { + statusProber.Healthy() + return srv.ListenAndServe() + }, func(err error) { - g.Add(func() error { - statusProber.Healthy() + statusProber.NotReady(err) + defer statusProber.NotHealthy(err) - return srv.ListenAndServe() - }, func(err error) { - statusProber.NotReady(err) - defer statusProber.NotHealthy(err) + srv.Shutdown(err) + }) + } - srv.Shutdown(err) - }) + // Once we have loaded external labels from prometheus we can use this to signal the servers + // that they can start now. + readyToStartGRPC := make(chan struct{}) - // Setup all the concurrent groups. + // Setup Prometheus Heartbeats. { promUp := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_sidecar_prometheus_up", Help: "Boolean indicator whether the sidecar can reach its Prometheus peer.", }) - ctx := context.Background() - // Only check Prometheus's flags when upload is enabled. - if uploads { - // Check prometheus's flags to ensure same sidecar flags. - // We retry infinitely until we validated prometheus flags + ctx, cancel := context.WithCancel(context.Background()) + g.Add(func() error { + // Only check Prometheus's flags when upload is enabled. + if uploads { + // Check prometheus's flags to ensure same sidecar flags. + // We retry infinitely until we validated prometheus flags + err := runutil.Retry(conf.prometheus.getConfigInterval, ctx.Done(), func() error { + iterCtx, iterCancel := context.WithTimeout(context.Background(), conf.prometheus.getConfigTimeout) + defer iterCancel() + + if err := validatePrometheus(iterCtx, m.client, logger, conf.shipper.ignoreBlockSize, m); err != nil { + level.Warn(logger).Log( + "msg", "failed to validate prometheus flags. Is Prometheus running? Retrying", + "err", err, + ) + return err + } + + level.Info(logger).Log( + "msg", "successfully validated prometheus flags", + ) + return nil + }) + if err != nil { + return errors.Wrap(err, "failed to validate prometheus flags") + } + } + + // We retry infinitely until we reach and fetch BuildVersion from our Prometheus. err := runutil.Retry(conf.prometheus.getConfigInterval, ctx.Done(), func() error { iterCtx, iterCancel := context.WithTimeout(context.Background(), conf.prometheus.getConfigTimeout) defer iterCancel() - if err := validatePrometheus(iterCtx, m.client, logger, conf.shipper.ignoreBlockSize, m); err != nil { + if err := m.BuildVersion(iterCtx); err != nil { level.Warn(logger).Log( - "msg", "failed to validate prometheus flags. Is Prometheus running? Retrying", + "msg", "failed to fetch prometheus version. Is Prometheus running? Retrying", "err", err, ) return err } level.Info(logger).Log( - "msg", "successfully validated prometheus flags", + "msg", "successfully loaded prometheus version", ) return nil }) if err != nil { - return errors.Wrap(err, "failed to validate prometheus flags") - } - } - - // We retry infinitely until we reach and fetch BuildVersion from our Prometheus. - err := runutil.Retry(conf.prometheus.getConfigInterval, ctx.Done(), func() error { - iterCtx, iterCancel := context.WithTimeout(context.Background(), conf.prometheus.getConfigTimeout) - defer iterCancel() - - if err := m.BuildVersion(iterCtx); err != nil { - level.Warn(logger).Log( - "msg", "failed to fetch prometheus version. Is Prometheus running? Retrying", - "err", err, - ) - return err + return errors.Wrap(err, "failed to get prometheus version") } - level.Info(logger).Log( - "msg", "successfully loaded prometheus version", - ) - return nil - }) - if err != nil { - return errors.Wrap(err, "failed to get prometheus version") - } + // Blocking query of external labels before joining as a Source Peer into gossip. + // We retry infinitely until we reach and fetch labels from our Prometheus. + err = runutil.Retry(conf.prometheus.getConfigInterval, ctx.Done(), func() error { + iterCtx, iterCancel := context.WithTimeout(context.Background(), conf.prometheus.getConfigTimeout) + defer iterCancel() - // Blocking query of external labels before joining as a Source Peer into gossip. - // We retry infinitely until we reach and fetch labels from our Prometheus. - err = runutil.Retry(conf.prometheus.getConfigInterval, ctx.Done(), func() error { - iterCtx, iterCancel := context.WithTimeout(context.Background(), conf.prometheus.getConfigTimeout) - defer iterCancel() + if err := m.UpdateLabels(iterCtx); err != nil { + level.Warn(logger).Log( + "msg", "failed to fetch initial external labels. Is Prometheus running? Retrying", + "err", err, + ) + return err + } - if err := m.UpdateLabels(iterCtx); err != nil { - level.Warn(logger).Log( - "msg", "failed to fetch initial external labels. Is Prometheus running? Retrying", - "err", err, + level.Info(logger).Log( + "msg", "successfully loaded prometheus external labels", + "external_labels", m.Labels().String(), ) - return err + return nil + }) + if err != nil { + return errors.Wrap(err, "initial external labels query") } - level.Info(logger).Log( - "msg", "successfully loaded prometheus external labels", - "external_labels", m.Labels().String(), - ) - return nil - }) - if err != nil { - return errors.Wrap(err, "initial external labels query") - } + if len(m.Labels()) == 0 { + return errors.New("no external labels configured on Prometheus server, uniquely identifying external labels must be configured; see https://thanos.io/tip/thanos/storage.md#external-labels for details.") + } + promUp.Set(1) + statusProber.Ready() - if len(m.Labels()) == 0 { - return errors.New("no external labels configured on Prometheus server, uniquely identifying external labels must be configured; see https://thanos.io/tip/thanos/storage.md#external-labels for details.") - } - promUp.Set(1) - statusProber.Ready() + close(readyToStartGRPC) - ctx, cancel := context.WithCancel(context.Background()) - g.Add(func() error { // Periodically query the Prometheus config. We use this as a heartbeat as well as for updating // the external labels we apply. return runutil.Repeat(conf.prometheus.getConfigInterval, ctx.Done(), func() error { @@ -274,6 +282,8 @@ func runSidecar( cancel() }) } + + // Setup the Reloader. { ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { @@ -282,6 +292,8 @@ func runSidecar( cancel() }) } + + // Setup the gRPC server. { c := promclient.NewWithTracingClient(logger, httpClient, clientconfig.ThanosUserAgent) @@ -323,7 +335,7 @@ func runSidecar( ) storeServer := store.NewLimitedStoreServer(store.NewInstrumentedStoreServer(reg, promStore), reg, conf.storeRateLimits) - s := grpcserver.New(logger, reg, tracer, grpcLogOpts, tagOpts, comp, grpcProbe, + s := grpcserver.New(logger, reg, tracer, grpcLogOpts, logFilterMethods, comp, grpcProbe, grpcserver.WithServer(store.RegisterStoreServer(storeServer, logger)), grpcserver.WithServer(rules.RegisterRulesServer(rules.NewPrometheus(conf.prometheus.url, c, m.Labels))), grpcserver.WithServer(targets.RegisterTargetsServer(targets.NewPrometheus(conf.prometheus.url, c, m.Labels))), @@ -335,15 +347,23 @@ func runSidecar( grpcserver.WithMaxConnAge(conf.grpc.maxConnectionAge), grpcserver.WithTLSConfig(tlsCfg), ) + + ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { + select { + case <-ctx.Done(): + return ctx.Err() + case <-readyToStartGRPC: + } + statusProber.Ready() return s.ListenAndServe() }, func(err error) { + cancel() statusProber.NotReady(err) s.Shutdown(err) }) } - if uploads { // The background shipper continuously scans the data directory and uploads // new blocks to Google Cloud Storage or an S3-compatible storage service. diff --git a/cmd/thanos/store.go b/cmd/thanos/store.go index 6c752ce15d..d626fe55d8 100644 --- a/cmd/thanos/store.go +++ b/cmd/thanos/store.go @@ -15,7 +15,6 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" grpclogging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" "github.com/oklog/run" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -45,6 +44,7 @@ import ( "github.com/thanos-io/thanos/pkg/runutil" grpcserver "github.com/thanos-io/thanos/pkg/server/grpc" httpserver "github.com/thanos-io/thanos/pkg/server/http" + "github.com/thanos-io/thanos/pkg/server/http/middleware" "github.com/thanos-io/thanos/pkg/store" storecache "github.com/thanos-io/thanos/pkg/store/cache" "github.com/thanos-io/thanos/pkg/store/labelpb" @@ -240,7 +240,8 @@ func registerStore(app *extkingpin.App) { return errors.Wrap(err, "error while parsing config for request logging") } - tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions(conf.reqLogConfig) + grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(conf.reqLogConfig) + if err != nil { return errors.Wrap(err, "error while parsing config for request logging") } @@ -253,7 +254,7 @@ func registerStore(app *extkingpin.App) { tracer, httpLogOpts, grpcLogOpts, - tagOpts, + logFilterMethods, *conf, getFlagsMap(cmd.Flags()), ) @@ -268,7 +269,7 @@ func runStore( tracer opentracing.Tracer, httpLogOpts []logging.Option, grpcLogOpts []grpclogging.Option, - tagOpts []tags.Option, + logFilterMethods []string, conf storeConfig, flagsMap map[string]string, ) error { @@ -394,6 +395,13 @@ func runStore( options := []store.BucketStoreOption{ store.WithLogger(logger), + store.WithRequestLoggerFunc(func(ctx context.Context, logger log.Logger) log.Logger { + reqID, ok := middleware.RequestIDFromContext(ctx) + if ok { + return log.With(logger, "request-id", reqID) + } + return logger + }), store.WithRegistry(reg), store.WithIndexCache(indexCache), store.WithQueryGate(queriesGate), @@ -514,7 +522,7 @@ func runStore( } storeServer := store.NewInstrumentedStoreServer(reg, bs) - s := grpcserver.New(logger, reg, tracer, grpcLogOpts, tagOpts, conf.component, grpcProbe, + s := grpcserver.New(logger, reg, tracer, grpcLogOpts, logFilterMethods, conf.component, grpcProbe, grpcserver.WithServer(store.RegisterStoreServer(storeServer, logger)), grpcserver.WithServer(info.RegisterInfoServer(infoSrv)), grpcserver.WithListen(conf.grpcConfig.bindAddress), diff --git a/docs/components/query-frontend.md b/docs/components/query-frontend.md index ab418040bd..4d680f70ca 100644 --- a/docs/components/query-frontend.md +++ b/docs/components/query-frontend.md @@ -157,6 +157,8 @@ Other cache configuration parameters, you can refer to [redis-index-cache](store Query Frontend supports `--query-frontend.log-queries-longer-than` flag to log queries running longer than some duration. +The field `remote_user` can be read from an HTTP header, like `X-Grafana-User`, by setting `--query-frontend.slow-query-logs-user-header`. + ## Naming Naming is hard :) Please check [here](https://github.com/thanos-io/thanos/pull/2434#discussion_r408300683) to see why we chose `query-frontend` as the name. @@ -297,6 +299,11 @@ Flags: the request, the first matching arg specified will take precedence. If no headers match 'anonymous' will be used. + --query-frontend.slow-query-logs-user-header= + Set the value of the field remote_user in the + slow query logs to the value of the given HTTP + header. Falls back to reading the user from the + basic auth header. --query-frontend.vertical-shards=QUERY-FRONTEND.VERTICAL-SHARDS Number of shards to use when distributing shardable PromQL queries. diff --git a/docs/release-process.md b/docs/release-process.md index 6aff7b50a0..7fba14d509 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -23,6 +23,8 @@ Release shepherd responsibilities: | Release | Time of first RC | Shepherd (GitHub handle) | |---------|------------------|-------------------------------| +| v0.36.0 | 2024.06.26 | `@MichaHoffmann` | +| v0.35.0 | 2024.04.09 | `@saswatamcode` | | v0.34.0 | 2024.01.14 | `@MichaHoffmann` | | v0.33.0 | 2023.10.24 | `@MichaHoffmann` | | v0.32.0 | 2023.08.23 | `@saswatamcode` | diff --git a/docs/storage.md b/docs/storage.md index 288959f52c..14b311230e 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -66,6 +66,7 @@ config: bucket: "" endpoint: "" region: "" + disable_dualstack: false aws_sdk_auth: false access_key: "" insecure: false @@ -94,6 +95,7 @@ config: list_objects_version: "" bucket_lookup_type: auto send_content_md5: true + disable_multipart: false part_size: 67108864 sse_config: type: "" @@ -377,6 +379,7 @@ config: storage_account: "" storage_account_key: "" storage_connection_string: "" + storage_create_container: false container: "" endpoint: "" user_assigned_id: "" diff --git a/docs/tracing.md b/docs/tracing.md index e87a1fa0f3..3e052fe84a 100644 --- a/docs/tracing.md +++ b/docs/tracing.md @@ -79,6 +79,7 @@ type: OTLP config: client_type: "" service_name: "" + resource_attributes: {} reconnection_period: 0s compression: "" insecure: false diff --git a/go.mod b/go.mod index 078e2f1e48..2ad9f6b0f6 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,15 @@ module github.com/thanos-io/thanos go 1.21 require ( - cloud.google.com/go/storage v1.36.0 // indirect - cloud.google.com/go/trace v1.10.5 + cloud.google.com/go/storage v1.40.0 // indirect + cloud.google.com/go/trace v1.10.7 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.8.3 github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 github.com/alicebob/miniredis/v2 v2.22.0 github.com/blang/semver/v4 v4.0.0 github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b github.com/cespare/xxhash v1.1.0 - github.com/cespare/xxhash/v2 v2.2.0 + github.com/cespare/xxhash/v2 v2.3.0 github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 github.com/chromedp/chromedp v0.9.2 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -20,11 +20,11 @@ require ( github.com/efficientgo/tools/extkingpin v0.0.0-20220817170617-6c25e3b627dd github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb github.com/fatih/structtag v1.2.0 - github.com/felixge/fgprof v0.9.2 + github.com/felixge/fgprof v0.9.4 github.com/fortytw2/leaktest v1.3.0 github.com/fsnotify/fsnotify v1.7.0 github.com/go-kit/log v0.2.1 - github.com/go-openapi/strfmt v0.22.2 + github.com/go-openapi/strfmt v0.23.0 github.com/gogo/protobuf v1.3.2 github.com/gogo/status v1.1.1 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da @@ -32,64 +32,62 @@ require ( github.com/golang/snappy v0.0.4 github.com/googleapis/gax-go v2.0.2+incompatible github.com/gorilla/mux v1.8.0 // indirect - github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect - github.com/grpc-ecosystem/go-grpc-middleware/providers/kit/v2 v2.0.0-20201002093600-73cf2ae9d891 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201207153454-9f6bf00c00a7 - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/jpillora/backoff v1.0.0 github.com/json-iterator/go v1.1.12 - github.com/klauspost/compress v1.17.7 + github.com/klauspost/compress v1.17.9 github.com/leanovate/gopter v0.2.9 github.com/lightstep/lightstep-tracer-go v0.25.0 github.com/lovoo/gcloud-opentracing v0.3.0 - github.com/miekg/dns v1.1.58 - github.com/minio/minio-go/v7 v7.0.61 // indirect + github.com/miekg/dns v1.1.59 + github.com/minio/minio-go/v7 v7.0.72 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/oklog/run v1.1.0 github.com/oklog/ulid v1.3.1 github.com/olekukonko/tablewriter v0.0.5 github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e // indirect github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect - github.com/opentracing/basictracer-go v1.0.0 + github.com/opentracing/basictracer-go v1.1.0 github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/alertmanager v0.27.0 - github.com/prometheus/client_golang v1.19.0 - github.com/prometheus/client_model v0.6.0 - github.com/prometheus/common v0.49.1-0.20240306132007-4199f18c3e92 + github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_model v0.6.1 + github.com/prometheus/common v0.54.1-0.20240615204547-04635d2962f9 github.com/prometheus/exporter-toolkit v0.11.0 // Prometheus maps version 2.x.y to tags v0.x.y. - github.com/prometheus/prometheus v0.51.1-0.20240325140356-78c0fd2f4d75 + github.com/prometheus/prometheus v0.52.2-0.20240614130246-4c1e71fa0b3d github.com/sony/gobreaker v0.5.0 github.com/stretchr/testify v1.9.0 - github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3 - github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508 + github.com/thanos-io/objstore v0.0.0-20240622095743-1afe5d4bc3cd + github.com/thanos-io/promql-engine v0.0.0-20240515161521-93aa311933cf github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/vimeo/galaxycache v0.0.0-20210323154928-b7e5d71c067a github.com/weaveworks/common v0.0.0-20230728070032-dd9e68f319d5 - go.elastic.co/apm v1.11.0 - go.elastic.co/apm/module/apmot v1.11.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 + go.elastic.co/apm v1.15.0 + go.elastic.co/apm/module/apmot v1.15.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/bridge/opentracing v1.21.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 - go.opentelemetry.io/otel/sdk v1.24.0 - go.opentelemetry.io/otel/trace v1.24.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 + go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/trace v1.27.0 go.uber.org/atomic v1.11.0 go.uber.org/automaxprocs v1.5.3 go.uber.org/goleak v1.3.0 - golang.org/x/crypto v0.21.0 - golang.org/x/net v0.22.0 - golang.org/x/sync v0.6.0 - golang.org/x/text v0.14.0 + golang.org/x/crypto v0.24.0 + golang.org/x/net v0.26.0 + golang.org/x/sync v0.7.0 + golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 - google.golang.org/api v0.168.0 // indirect - google.golang.org/genproto v0.0.0-20240205150955-31a09d347014 // indirect - google.golang.org/grpc v1.62.1 + google.golang.org/api v0.183.0 // indirect + google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/grpc v1.64.0 google.golang.org/grpc/examples v0.0.0-20211119005141-f45e61797429 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/yaml.v2 v2.4.0 @@ -102,24 +100,24 @@ require ( ) require ( - cloud.google.com/go v0.112.0 // indirect - cloud.google.com/go/compute v1.23.4 // indirect - cloud.google.com/go/iam v1.1.6 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect + cloud.google.com/go v0.114.0 // indirect + cloud.google.com/go/iam v1.1.8 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.6.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.7.0 go.opentelemetry.io/otel/exporters/jaeger v1.16.0 ) require ( github.com/cortexproject/promqlsmith v0.0.0-20240326071418-c2a9ca1e89f5 + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 github.com/hashicorp/golang-lru v0.6.0 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/mitchellh/go-ps v1.0.0 - github.com/onsi/gomega v1.29.0 + github.com/onsi/gomega v1.33.1 github.com/prometheus-community/prom-label-proxy v0.8.1-0.20240127162815-c1195f9aabc0 go.opentelemetry.io/contrib/propagators/autoprop v0.38.0 go4.org/intern v0.0.0-20230525184215-6c62f75575cb @@ -127,16 +125,21 @@ require ( ) require ( + cloud.google.com/go/auth v0.5.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect + github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect github.com/cilium/ebpf v0.11.0 // indirect github.com/containerd/cgroups/v3 v3.0.3 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/elastic/go-licenser v0.3.1 // indirect github.com/go-openapi/runtime v0.27.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect - github.com/golang-jwt/jwt/v5 v5.2.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.3+incompatible // indirect + github.com/jcchavezs/porto v0.1.0 // indirect github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo v1.16.5 // indirect @@ -144,14 +147,14 @@ require ( github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/sercand/kuberesolver/v4 v4.0.0 // indirect github.com/zhangyunhao116/umap v0.0.0-20221211160557-cb7705fafa39 // indirect - go.opentelemetry.io/collector/featuregate v1.3.0 // indirect - go.opentelemetry.io/collector/pdata v1.3.0 // indirect - go.opentelemetry.io/collector/semconv v0.96.0 // indirect + go.opentelemetry.io/collector/pdata v1.8.0 // indirect + go.opentelemetry.io/collector/semconv v0.101.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/propagators/ot v1.13.0 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240304161311-37d4d3c04a78 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect k8s.io/apimachinery v0.29.3 // indirect k8s.io/client-go v0.29.3 // indirect k8s.io/klog/v2 v2.120.1 // indirect @@ -159,16 +162,16 @@ require ( ) require ( - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.32.3 // indirect - github.com/KimMachineGun/automemlimit v0.5.0 + github.com/KimMachineGun/automemlimit v0.6.1 github.com/OneOfOne/xxhash v1.2.6 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.50.32 // indirect + github.com/aws/aws-sdk-go v1.53.16 // indirect github.com/aws/aws-sdk-go-v2 v1.16.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.15.1 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.11.0 // indirect @@ -182,7 +185,7 @@ require ( github.com/aws/smithy-go v1.11.1 // indirect github.com/baidubce/bce-sdk-go v0.9.111 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/chromedp/sysutil v1.0.0 // indirect github.com/clbanning/mxj v1.8.4 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -191,13 +194,12 @@ require ( github.com/elastic/go-sysinfo v1.8.1 // indirect github.com/elastic/go-windows v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-kit/kit v0.12.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.22.2 // indirect - github.com/go-openapi/errors v0.21.1 // indirect + github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/loads v0.21.5 // indirect @@ -211,16 +213,16 @@ require ( github.com/gogo/googleapis v1.4.0 // indirect github.com/google/go-cmp v0.6.0 github.com/google/go-querystring v1.1.0 // indirect - github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect + github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect github.com/google/uuid v1.6.0 github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.4 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect @@ -236,7 +238,7 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/redis/rueidis v1.0.14-go1.18 github.com/rivo/uniseg v0.2.0 // indirect github.com/rs/xid v1.5.0 // indirect @@ -251,23 +253,22 @@ require ( github.com/weaveworks/promrus v1.2.0 // indirect github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - go.elastic.co/apm/module/apmhttp v1.11.0 // indirect + go.elastic.co/apm/module/apmhttp v1.15.0 // indirect go.elastic.co/fastjson v1.1.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/propagators/aws v1.13.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.13.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.13.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.16.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/tools v0.22.0 // indirect gonum.org/v1/gonum v0.12.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.34.2 gopkg.in/ini.v1 v1.67.0 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect ) @@ -277,10 +278,13 @@ replace ( // Required by Cortex https://github.com/cortexproject/cortex/pull/3051. github.com/bradfitz/gomemcache => github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab + // Pin kuberesolver/v5 to support new grpc version. Need to upgrade kuberesolver version on weaveworks/common. + github.com/sercand/kuberesolver/v4 => github.com/sercand/kuberesolver/v5 v5.1.1 + github.com/vimeo/galaxycache => github.com/thanos-community/galaxycache v0.0.0-20211122094458-3a32041a1f1e - // Override due to https://github.com/weaveworks/common/issues/239 - google.golang.org/grpc => google.golang.org/grpc v1.57.2 + // Pinning grpc due https://github.com/grpc/grpc-go/issues/7314 + google.golang.org/grpc => google.golang.org/grpc v1.63.2 // Overriding to use latest commit. gopkg.in/alecthomas/kingpin.v2 => github.com/alecthomas/kingpin v1.3.8-0.20210301060133-17f40c25f497 diff --git a/go.sum b/go.sum index f867ce239f..17dca14a16 100644 --- a/go.sum +++ b/go.sum @@ -35,35 +35,89 @@ cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRY cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= +cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM= +cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.114.0 h1:OIPFAdfrFDFO2ve2U7r/H5SwSbBzEdrBdE7xkgwc+kY= +cloud.google.com/go v0.114.0/go.mod h1:ZV9La5YYxctro1HTPug5lXH/GefROyW8PPD4T8n9J8E= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= +cloud.google.com/go/accessapproval v1.7.2/go.mod h1:/gShiq9/kK/h8T/eEn1BTzalDvk0mZxJlhfw0p+Xuc0= +cloud.google.com/go/accessapproval v1.7.3/go.mod h1:4l8+pwIxGTNqSf4T3ds8nLO94NQf0W/KnMNuQ9PbnP8= +cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= +cloud.google.com/go/accessapproval v1.7.5/go.mod h1:g88i1ok5dvQ9XJsxpUInWWvUBrIZhyPDPbk4T01OoJ0= cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= +cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= +cloud.google.com/go/accesscontextmanager v1.8.2/go.mod h1:E6/SCRM30elQJ2PKtFMs2YhfJpZSNcJyejhuzoId4Zk= +cloud.google.com/go/accesscontextmanager v1.8.3/go.mod h1:4i/JkF2JiFbhLnnpnfoTX5vRXfhf9ukhU1ANOTALTOQ= +cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= +cloud.google.com/go/accesscontextmanager v1.8.5/go.mod h1:TInEhcZ7V9jptGNqN3EzZ5XMhT6ijWxTGjzyETwmL0Q= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.50.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= +cloud.google.com/go/aiplatform v1.51.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= +cloud.google.com/go/aiplatform v1.51.1/go.mod h1:kY3nIMAVQOK2XDqDPHaOuD9e+FdMA6OOpfBjsvaFSOo= +cloud.google.com/go/aiplatform v1.51.2/go.mod h1:hCqVYB3mY45w99TmetEoe8eCQEwZEp9WHxeZdcv9phw= +cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.54.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.57.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.58.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.58.2/go.mod h1:c3kCiVmb6UC1dHAjZjcpDj6ZS0bHQ2slL88ZjC2LtlA= +cloud.google.com/go/aiplatform v1.60.0/go.mod h1:eTlGuHOahHprZw3Hio5VKmtThIOak5/qy6pzdsqcQnM= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/analytics v0.21.4/go.mod h1:zZgNCxLCy8b2rKKVfC1YkC2vTrpfZmeRCySM3aUbskA= +cloud.google.com/go/analytics v0.21.5/go.mod h1:BQtOBHWTlJ96axpPPnw5CvGJ6i3Ve/qX2fTxR8qWyr8= +cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/analytics v0.22.0/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/analytics v0.23.0/go.mod h1:YPd7Bvik3WS95KBok2gPXDqQPHy08TsCQG6CdUCb+u0= cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= +cloud.google.com/go/apigateway v1.6.2/go.mod h1:CwMC90nnZElorCW63P2pAYm25AtQrHfuOkbRSHj0bT8= +cloud.google.com/go/apigateway v1.6.3/go.mod h1:k68PXWpEs6BVDTtnLQAyG606Q3mz8pshItwPXjgv44Y= +cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= +cloud.google.com/go/apigateway v1.6.5/go.mod h1:6wCwvYRckRQogyDDltpANi3zsCDl6kWi0b4Je+w2UiI= cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= +cloud.google.com/go/apigeeconnect v1.6.2/go.mod h1:s6O0CgXT9RgAxlq3DLXvG8riw8PYYbU/v25jqP3Dy18= +cloud.google.com/go/apigeeconnect v1.6.3/go.mod h1:peG0HFQ0si2bN15M6QSjEW/W7Gy3NYkWGz7pFz13cbo= +cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= +cloud.google.com/go/apigeeconnect v1.6.5/go.mod h1:MEKm3AiT7s11PqTfKE3KZluZA9O91FNysvd3E6SJ6Ow= cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= +cloud.google.com/go/apigeeregistry v0.7.2/go.mod h1:9CA2B2+TGsPKtfi3F7/1ncCCsL62NXBRfM6iPoGSM+8= +cloud.google.com/go/apigeeregistry v0.8.1/go.mod h1:MW4ig1N4JZQsXmBSwH4rwpgDonocz7FPBSw6XPGHmYw= +cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= +cloud.google.com/go/apigeeregistry v0.8.3/go.mod h1:aInOWnqF4yMQx8kTjDqHNXjZGh/mxeNlAf52YqtASUs= cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= @@ -72,10 +126,20 @@ cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodC cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= +cloud.google.com/go/appengine v1.8.2/go.mod h1:WMeJV9oZ51pvclqFN2PqHoGnys7rK0rz6s3Mp6yMvDo= +cloud.google.com/go/appengine v1.8.3/go.mod h1:2oUPZ1LVZ5EXi+AF1ihNAF+S8JrzQ3till5m9VQkrsk= +cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= +cloud.google.com/go/appengine v1.8.5/go.mod h1:uHBgNoGLTS5di7BvU25NFDuKa82v0qQLjyMJLuPQrVo= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= +cloud.google.com/go/area120 v0.8.2/go.mod h1:a5qfo+x77SRLXnCynFWPUZhnZGeSgvQ+Y0v1kSItkh4= +cloud.google.com/go/area120 v0.8.3/go.mod h1:5zj6pMzVTH+SVHljdSKC35sriR/CVvQZzG/Icdyriw0= +cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= +cloud.google.com/go/area120 v0.8.5/go.mod h1:BcoFCbDLZjsfe4EkCnEq1LKvHSK0Ew/zk5UFu6GMyA0= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= @@ -84,6 +148,12 @@ cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1 cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= +cloud.google.com/go/artifactregistry v1.14.2/go.mod h1:Xk+QbsKEb0ElmyeMfdHAey41B+qBq3q5R5f5xD4XT3U= +cloud.google.com/go/artifactregistry v1.14.3/go.mod h1:A2/E9GXnsyXl7GUvQ/2CjHA+mVRoWAXC0brg2os+kNI= +cloud.google.com/go/artifactregistry v1.14.4/go.mod h1:SJJcZTMv6ce0LDMUnihCN7WSrI+kBSFV0KIKo8S8aYU= +cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= +cloud.google.com/go/artifactregistry v1.14.7/go.mod h1:0AUKhzWQzfmeTvT4SjfI4zjot72EMfrkvL9g9aRjnnM= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= @@ -92,27 +162,70 @@ cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAt cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= +cloud.google.com/go/asset v1.15.0/go.mod h1:tpKafV6mEut3+vN9ScGvCHXHj7FALFVta+okxFECHcg= +cloud.google.com/go/asset v1.15.1/go.mod h1:yX/amTvFWRpp5rcFq6XbCxzKT8RJUam1UoboE179jU4= +cloud.google.com/go/asset v1.15.2/go.mod h1:B6H5tclkXvXz7PD22qCA2TDxSVQfasa3iDlM89O2NXs= +cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/asset v1.16.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/asset v1.17.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/asset v1.17.1/go.mod h1:byvDw36UME5AzGNK7o4JnOnINkwOZ1yRrGrKIahHrng= +cloud.google.com/go/asset v1.17.2/go.mod h1:SVbzde67ehddSoKf5uebOD1sYw8Ab/jD/9EIeWg99q4= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= +cloud.google.com/go/assuredworkloads v1.11.2/go.mod h1:O1dfr+oZJMlE6mw0Bp0P1KZSlj5SghMBvTpZqIcUAW4= +cloud.google.com/go/assuredworkloads v1.11.3/go.mod h1:vEjfTKYyRUaIeA0bsGJceFV2JKpVRgyG2op3jfa59Zs= +cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= +cloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk= +cloud.google.com/go/auth v0.5.1 h1:0QNO7VThG54LUzKiQxv8C6x1YX7lUrzlAa1nVLF8CIw= +cloud.google.com/go/auth v0.5.1/go.mod h1:vbZT8GjzDf3AVqCcQmqeeM32U9HBFc32vVVAbwDsa6s= +cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= +cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= +cloud.google.com/go/automl v1.13.2/go.mod h1:gNY/fUmDEN40sP8amAX3MaXkxcqPIn7F1UIIPZpy4Mg= +cloud.google.com/go/automl v1.13.3/go.mod h1:Y8KwvyAZFOsMAPqUCfNu1AyclbC6ivCUF/MTwORymyY= +cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= +cloud.google.com/go/automl v1.13.5/go.mod h1:MDw3vLem3yh+SvmSgeYUmUKqyls6NzSumDm9OJ3xJ1Y= cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= +cloud.google.com/go/baremetalsolution v1.2.0/go.mod h1:68wi9AwPYkEWIUT4SvSGS9UJwKzNpshjHsH4lzk8iOw= +cloud.google.com/go/baremetalsolution v1.2.1/go.mod h1:3qKpKIw12RPXStwQXcbhfxVj1dqQGEvcmA+SX/mUR88= +cloud.google.com/go/baremetalsolution v1.2.2/go.mod h1:O5V6Uu1vzVelYahKfwEWRMaS3AbCkeYHy3145s1FkhM= +cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= +cloud.google.com/go/baremetalsolution v1.2.4/go.mod h1:BHCmxgpevw9IEryE99HbYEfxXkAEA3hkMJbYYsHtIuY= cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= +cloud.google.com/go/batch v1.4.1/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= +cloud.google.com/go/batch v1.5.0/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= +cloud.google.com/go/batch v1.5.1/go.mod h1:RpBuIYLkQu8+CWDk3dFD/t/jOCGuUpkpX+Y0n1Xccs8= +cloud.google.com/go/batch v1.6.1/go.mod h1:urdpD13zPe6YOK+6iZs/8/x2VBRofvblLpx0t57vM98= +cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/batch v1.7.0/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/batch v1.8.0/go.mod h1:k8V7f6VE2Suc0zUM4WtoibNrA6D3dqBpB+++e3vSGYc= cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/beyondcorp v1.0.1/go.mod h1:zl/rWWAFVeV+kx+X2Javly7o1EIQThU4WlkynffL/lk= +cloud.google.com/go/beyondcorp v1.0.2/go.mod h1:m8cpG7caD+5su+1eZr+TSvF6r21NdLJk4f9u4SP2Ntc= +cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= +cloud.google.com/go/beyondcorp v1.0.4/go.mod h1:Gx8/Rk2MxrvWfn4WIhHIG1NV7IBfg14pTKv1+EArVcc= 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= @@ -126,38 +239,92 @@ cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/Zur cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/bigquery v1.55.0/go.mod h1:9Y5I3PN9kQWuid6183JFhOGOW3GcirA5LpsKCUn+2ec= +cloud.google.com/go/bigquery v1.56.0/go.mod h1:KDcsploXTEY7XT3fDQzMUZlpQLHzE4itubHrnmhUrZA= +cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= +cloud.google.com/go/bigquery v1.58.0/go.mod h1:0eh4mWNY0KrBTjUzLjoYImapGORq9gEPT7MWjCy9lik= +cloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= +cloud.google.com/go/billing v1.17.0/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= +cloud.google.com/go/billing v1.17.1/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= +cloud.google.com/go/billing v1.17.2/go.mod h1:u/AdV/3wr3xoRBk5xvUzYMS1IawOAPwQMuHgHMdljDg= +cloud.google.com/go/billing v1.17.3/go.mod h1:z83AkoZ7mZwBGT3yTnt6rSGI1OOsHSIi6a5M3mJ8NaU= +cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/billing v1.18.0/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/billing v1.18.2/go.mod h1:PPIwVsOOQ7xzbADCwNe8nvK776QpfrOAUkvKjCUcpSE= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= +cloud.google.com/go/binaryauthorization v1.7.0/go.mod h1:Zn+S6QqTMn6odcMU1zDZCJxPjU2tZPV1oDl45lWY154= +cloud.google.com/go/binaryauthorization v1.7.1/go.mod h1:GTAyfRWYgcbsP3NJogpV3yeunbUIjx2T9xVeYovtURE= +cloud.google.com/go/binaryauthorization v1.7.2/go.mod h1:kFK5fQtxEp97m92ziy+hbu+uKocka1qRRL8MVJIgjv0= +cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/binaryauthorization v1.8.0/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/binaryauthorization v1.8.1/go.mod h1:1HVRyBerREA/nhI7yLang4Zn7vfNVA3okoAR9qYQJAQ= cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= +cloud.google.com/go/certificatemanager v1.7.2/go.mod h1:15SYTDQMd00kdoW0+XY5d9e+JbOPjp24AvF48D8BbcQ= +cloud.google.com/go/certificatemanager v1.7.3/go.mod h1:T/sZYuC30PTag0TLo28VedIRIj1KPGcOQzjWAptHa00= +cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= +cloud.google.com/go/certificatemanager v1.7.5/go.mod h1:uX+v7kWqy0Y3NG/ZhNvffh0kuqkKZIXdvlZRO7z0VtM= cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= +cloud.google.com/go/channel v1.17.0/go.mod h1:RpbhJsGi/lXWAUM1eF4IbQGbsfVlg2o8Iiy2/YLfVT0= +cloud.google.com/go/channel v1.17.1/go.mod h1:xqfzcOZAcP4b/hUDH0GkGg1Sd5to6di1HOJn/pi5uBQ= +cloud.google.com/go/channel v1.17.2/go.mod h1:aT2LhnftnyfQceFql5I/mP8mIbiiJS4lWqgXA815zMk= +cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/channel v1.17.4/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/channel v1.17.5/go.mod h1:FlpaOSINDAXgEext0KMaBq/vwpLMkkPAw9b2mApQeHc= cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.14.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.14.1/go.mod h1:K7wGc/3zfvmYWOWwYTgF/d/UVJhS4pu+HAy7PL7mCsU= +cloud.google.com/go/cloudbuild v1.14.2/go.mod h1:Bn6RO0mBYk8Vlrt+8NLrru7WXlQ9/RDWz2uo5KG1/sg= +cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/cloudbuild v1.15.0/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/cloudbuild v1.15.1/go.mod h1:gIofXZSu+XD2Uy+qkOrGKEx45zd7s28u/k8f99qKals= cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= +cloud.google.com/go/clouddms v1.7.0/go.mod h1:MW1dC6SOtI/tPNCciTsXtsGNEM0i0OccykPvv3hiYeM= +cloud.google.com/go/clouddms v1.7.1/go.mod h1:o4SR8U95+P7gZ/TX+YbJxehOCsM+fe6/brlrFquiszk= +cloud.google.com/go/clouddms v1.7.2/go.mod h1:Rk32TmWmHo64XqDvW7jgkFQet1tUKNVzs7oajtJT3jU= +cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= +cloud.google.com/go/clouddms v1.7.4/go.mod h1:RdrVqoFG9RWI5AvZ81SxJ/xvxPdtcRhFotwdE79DieY= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/cloudtasks v1.12.2/go.mod h1:A7nYkjNlW2gUoROg1kvJrQGhJP/38UaWwsnuBDOBVUk= +cloud.google.com/go/cloudtasks v1.12.3/go.mod h1:GPVXhIOSGEaR+3xT4Fp72ScI+HjHffSS4B8+BaBB5Ys= +cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= +cloud.google.com/go/cloudtasks v1.12.6/go.mod h1:b7c7fe4+TJsFZfDyzO51F7cjq7HLUlRi/KZQLQjDsaY= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= @@ -171,26 +338,57 @@ cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARy cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= -cloud.google.com/go/compute v1.23.4 h1:EBT9Nw4q3zyE7G45Wvv3MzolIrCJEuHys5muLY0wvAw= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute v1.23.4/go.mod h1:/EJMj55asU6kAFnuZET8zqgwgJ9FvXWXOkkfQZa4ioI= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/contactcenterinsights v1.11.0/go.mod h1:hutBdImE4XNZ1NV4vbPJKSFOnQruhC5Lj9bZqWMTKiU= +cloud.google.com/go/contactcenterinsights v1.11.1/go.mod h1:FeNP3Kg8iteKM80lMwSk3zZZKVxr+PGnAId6soKuXwE= +cloud.google.com/go/contactcenterinsights v1.11.2/go.mod h1:A9PIR5ov5cRcd28KlDbmmXE8Aay+Gccer2h4wzkYFso= +cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.12.0/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.12.1/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.13.0/go.mod h1:ieq5d5EtHsu8vhe2y3amtZ+BE+AQwX5qAy7cpo0POsI= cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/container v1.26.0/go.mod h1:YJCmRet6+6jnYYRS000T6k0D0xUXQgBSaJ7VwI8FBj4= +cloud.google.com/go/container v1.26.1/go.mod h1:5smONjPRUxeEpDG7bMKWfDL4sauswqEtnBK1/KKpR04= +cloud.google.com/go/container v1.26.2/go.mod h1:YlO84xCt5xupVbLaMY4s3XNE79MUJ+49VmkInr6HvF4= +cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.28.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.29.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.30.1/go.mod h1:vkbfX0EnAKL/vgVECs5BZn24e1cJROzgszJirRKQ4Bg= +cloud.google.com/go/container v1.31.0/go.mod h1:7yABn5s3Iv3lmw7oMmyGbeV6tQj86njcTijkkGuvdZA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= +cloud.google.com/go/containeranalysis v0.11.0/go.mod h1:4n2e99ZwpGxpNcz+YsFT1dfOHPQFGcAC8FN2M2/ne/U= +cloud.google.com/go/containeranalysis v0.11.1/go.mod h1:rYlUOM7nem1OJMKwE1SadufX0JP3wnXj844EtZAwWLY= +cloud.google.com/go/containeranalysis v0.11.2/go.mod h1:xibioGBC1MD2j4reTyV1xY1/MvKaz+fyM9ENWhmIeP8= +cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= +cloud.google.com/go/containeranalysis v0.11.4/go.mod h1:cVZT7rXYBS9NG1rhQbWL9pWbXCKHWJPYraE8/FTSYPE= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= @@ -199,44 +397,118 @@ cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOX cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= +cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.17.1/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= +cloud.google.com/go/datacatalog v1.18.0/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= +cloud.google.com/go/datacatalog v1.18.1/go.mod h1:TzAWaz+ON1tkNr4MOcak8EBHX7wIRX/gZKM+yTVsv+A= +cloud.google.com/go/datacatalog v1.18.2/go.mod h1:SPVgWW2WEMuWHA+fHodYjmxPiMqcOiWfhc9OD5msigk= +cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/datacatalog v1.19.0/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/datacatalog v1.19.2/go.mod h1:2YbODwmhpLM4lOFe3PuEhHK9EyTzQJ5AXgIy7EDKTEE= +cloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= +cloud.google.com/go/dataflow v0.9.2/go.mod h1:vBfdBZ/ejlTaYIGB3zB4T08UshH70vbtZeMD+urnUSo= +cloud.google.com/go/dataflow v0.9.3/go.mod h1:HI4kMVjcHGTs3jTHW/kv3501YW+eloiJSLxkJa/vqFE= +cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= +cloud.google.com/go/dataflow v0.9.5/go.mod h1:udl6oi8pfUHnL0z6UN9Lf9chGqzDMVqcYTcZ1aPnCZQ= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= +cloud.google.com/go/dataform v0.8.2/go.mod h1:X9RIqDs6NbGPLR80tnYoPNiO1w0wenKTb8PxxlhTMKM= +cloud.google.com/go/dataform v0.8.3/go.mod h1:8nI/tvv5Fso0drO3pEjtowz58lodx8MVkdV2q0aPlqg= +cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= +cloud.google.com/go/dataform v0.9.2/go.mod h1:S8cQUwPNWXo7m/g3DhWHsLBoufRNn9EgFrMgne2j7cI= cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= +cloud.google.com/go/datafusion v1.7.2/go.mod h1:62K2NEC6DRlpNmI43WHMWf9Vg/YvN6QVi8EVwifElI0= +cloud.google.com/go/datafusion v1.7.3/go.mod h1:eoLt1uFXKGBq48jy9LZ+Is8EAVLnmn50lNncLzwYokE= +cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= +cloud.google.com/go/datafusion v1.7.5/go.mod h1:bYH53Oa5UiqahfbNK9YuYKteeD4RbQSNMx7JF7peGHc= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= +cloud.google.com/go/datalabeling v0.8.2/go.mod h1:cyDvGHuJWu9U/cLDA7d8sb9a0tWLEletStu2sTmg3BE= +cloud.google.com/go/datalabeling v0.8.3/go.mod h1:tvPhpGyS/V7lqjmb3V0TaDdGvhzgR1JoW7G2bpi2UTI= +cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= +cloud.google.com/go/datalabeling v0.8.5/go.mod h1:IABB2lxQnkdUbMnQaOl2prCOfms20mcPxDBm36lps+s= cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.10.1/go.mod h1:1MzmBv8FvjYfc7vDdxhnLFNskikkB+3vl475/XdCDhs= +cloud.google.com/go/dataplex v1.10.2/go.mod h1:xdC8URdTrCrZMW6keY779ZT1cTOfV8KEPNsw+LTRT1Y= +cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.11.2/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.13.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.14.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.14.1/go.mod h1:bWxQAbg6Smg+sca2+Ex7s8D9a5qU6xfXtwmq4BVReps= +cloud.google.com/go/dataplex v1.14.2/go.mod h1:0oGOSFlEKef1cQeAHXy4GZPB/Ife0fz/PxBf+ZymA2U= cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= +cloud.google.com/go/dataproc/v2 v2.2.0/go.mod h1:lZR7AQtwZPvmINx5J87DSOOpTfof9LVZju6/Qo4lmcY= +cloud.google.com/go/dataproc/v2 v2.2.1/go.mod h1:QdAJLaBjh+l4PVlVZcmrmhGccosY/omC1qwfQ61Zv/o= +cloud.google.com/go/dataproc/v2 v2.2.2/go.mod h1:aocQywVmQVF4i8CL740rNI/ZRpsaaC1Wh2++BJ7HEJ4= +cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataproc/v2 v2.3.0/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataproc/v2 v2.4.0/go.mod h1:3B1Ht2aRB8VZIteGxQS/iNSJGzt9+CA0WGnDVMEm7Z4= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= +cloud.google.com/go/dataqna v0.8.2/go.mod h1:KNEqgx8TTmUipnQsScOoDpq/VlXVptUqVMZnt30WAPs= +cloud.google.com/go/dataqna v0.8.3/go.mod h1:wXNBW2uvc9e7Gl5k8adyAMnLush1KVV6lZUhB+rqNu4= +cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= +cloud.google.com/go/dataqna v0.8.5/go.mod h1:vgihg1mz6n7pb5q2YJF7KlXve6tCglInd6XO0JGOlWM= 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/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= +cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/datastream v1.10.1/go.mod h1:7ngSYwnw95YFyTd5tOGBxHlOZiL+OtpjheqU7t2/s/c= +cloud.google.com/go/datastream v1.10.2/go.mod h1:W42TFgKAs/om6x/CdXX5E4oiAsKlH+e8MTGy81zdYt0= +cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= +cloud.google.com/go/datastream v1.10.4/go.mod h1:7kRxPdxZxhPg3MFeCSulmAJnil8NJGGvSNdn4p1sRZo= cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/deploy v1.13.1/go.mod h1:8jeadyLkH9qu9xgO3hVWw8jVr29N1mnW42gRJT8GY6g= +cloud.google.com/go/deploy v1.14.1/go.mod h1:N8S0b+aIHSEeSr5ORVoC0+/mOPUysVt8ae4QkZYolAw= +cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.15.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.16.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.17.0/go.mod h1:XBr42U5jIr64t92gcpOXxNrqL2PStQCXHuKK5GRUuYo= +cloud.google.com/go/deploy v1.17.1/go.mod h1:SXQyfsXrk0fBmgBHRzBjQbZhMfKZ3hMQBw5ym7MN/50= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= @@ -245,35 +517,94 @@ cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFM cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.43.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= +cloud.google.com/go/dialogflow v1.44.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= +cloud.google.com/go/dialogflow v1.44.1/go.mod h1:n/h+/N2ouKOO+rbe/ZnI186xImpqvCVj2DdsWS/0EAk= +cloud.google.com/go/dialogflow v1.44.2/go.mod h1:QzFYndeJhpVPElnFkUXxdlptx0wPnBWLCBT9BvtC3/c= +cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.47.0/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.48.0/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.48.1/go.mod h1:C1sjs2/g9cEwjCltkKeYp3FFpz8BOzNondEaAlCpt+A= +cloud.google.com/go/dialogflow v1.48.2/go.mod h1:7A2oDf6JJ1/+hdpnFRfb/RjJUOh2X3rhIa5P8wQSEX4= +cloud.google.com/go/dialogflow v1.49.0/go.mod h1:dhVrXKETtdPlpPhE7+2/k4Z8FRNUp6kMV3EW3oz/fe0= cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= +cloud.google.com/go/dlp v1.10.2/go.mod h1:ZbdKIhcnyhILgccwVDzkwqybthh7+MplGC3kZVZsIOQ= +cloud.google.com/go/dlp v1.10.3/go.mod h1:iUaTc/ln8I+QT6Ai5vmuwfw8fqTk2kaz0FvCwhLCom0= +cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= +cloud.google.com/go/dlp v1.11.2/go.mod h1:9Czi+8Y/FegpWzgSfkRlyz+jwW6Te9Rv26P3UfU/h/w= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.1/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= +cloud.google.com/go/documentai v1.23.0/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= +cloud.google.com/go/documentai v1.23.2/go.mod h1:Q/wcRT+qnuXOpjAkvOV4A+IeQl04q2/ReT7SSbytLSo= +cloud.google.com/go/documentai v1.23.4/go.mod h1:4MYAaEMnADPN1LPN5xboDR5QVB6AgsaxgFdJhitlE2Y= +cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/documentai v1.23.6/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/documentai v1.23.7/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/documentai v1.23.8/go.mod h1:Vd/y5PosxCpUHmwC+v9arZyeMfTqBR9VIwOwIqQYYfA= +cloud.google.com/go/documentai v1.25.0/go.mod h1:ftLnzw5VcXkLItp6pw1mFic91tMRyfv6hHEY5br4KzY= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= +cloud.google.com/go/domains v0.9.2/go.mod h1:3YvXGYzZG1Temjbk7EyGCuGGiXHJwVNmwIf+E/cUp5I= +cloud.google.com/go/domains v0.9.3/go.mod h1:29k66YNDLDY9LCFKpGFeh6Nj9r62ZKm5EsUJxAl84KU= +cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= +cloud.google.com/go/domains v0.9.5/go.mod h1:dBzlxgepazdFhvG7u23XMhmMKBjrkoUNaw0A8AQB55Y= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= +cloud.google.com/go/edgecontainer v1.1.2/go.mod h1:wQRjIzqxEs9e9wrtle4hQPSR1Y51kqN75dgF7UllZZ4= +cloud.google.com/go/edgecontainer v1.1.3/go.mod h1:Ll2DtIABzEfaxaVSbwj3QHFaOOovlDFiWVDu349jSsA= +cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= +cloud.google.com/go/edgecontainer v1.1.5/go.mod h1:rgcjrba3DEDEQAidT4yuzaKWTbkTI5zAMu3yy6ZWS0M= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= +cloud.google.com/go/essentialcontacts v1.6.3/go.mod h1:yiPCD7f2TkP82oJEFXFTou8Jl8L6LBRPeBEkTaO0Ggo= +cloud.google.com/go/essentialcontacts v1.6.4/go.mod h1:iju5Vy3d9tJUg0PYMd1nHhjV7xoCXaOAVabrwLaPBEM= +cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= +cloud.google.com/go/essentialcontacts v1.6.6/go.mod h1:XbqHJGaiH0v2UvtuucfOzFXN+rpL/aU5BCZLn4DYl1Q= cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/eventarc v1.13.1/go.mod h1:EqBxmGHFrruIara4FUQ3RHlgfCn7yo1HYsu2Hpt/C3Y= +cloud.google.com/go/eventarc v1.13.2/go.mod h1:X9A80ShVu19fb4e5sc/OLV7mpFUKZMwfJFeeWhcIObM= +cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= +cloud.google.com/go/eventarc v1.13.4/go.mod h1:zV5sFVoAa9orc/52Q+OuYUG9xL2IIZTbbuTHC6JSY8s= cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= +cloud.google.com/go/filestore v1.7.2/go.mod h1:TYOlyJs25f/omgj+vY7/tIG/E7BX369triSPzE4LdgE= +cloud.google.com/go/filestore v1.7.3/go.mod h1:Qp8WaEERR3cSkxToxFPHh/b8AACkSut+4qlCjAmKTV0= +cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/filestore v1.8.1/go.mod h1:MbN9KcaM47DRTIuLfQhJEsjaocVebNtNQhSLhKCF5GM= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= +cloud.google.com/go/firestore v1.12.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= +cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= +cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= @@ -281,28 +612,64 @@ cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5Uwt cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= +cloud.google.com/go/functions v1.15.2/go.mod h1:CHAjtcR6OU4XF2HuiVeriEdELNcnvRZSk1Q8RMqy4lE= +cloud.google.com/go/functions v1.15.3/go.mod h1:r/AMHwBheapkkySEhiZYLDBwVJCdlRwsm4ieJu35/Ug= +cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= +cloud.google.com/go/functions v1.16.0/go.mod h1:nbNpfAG7SG7Duw/o1iZ6ohvL7mc6MapWQVpqtM29n8k= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkebackup v1.3.1/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkebackup v1.3.2/go.mod h1:OMZbXzEJloyXMC7gqdSB+EOEQ1AKcpGYvO3s1ec5ixk= +cloud.google.com/go/gkebackup v1.3.3/go.mod h1:eMk7/wVV5P22KBakhQnJxWSVftL1p4VBFLpv0kIft7I= +cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= +cloud.google.com/go/gkebackup v1.3.5/go.mod h1:KJ77KkNN7Wm1LdMopOelV6OodM01pMuK2/5Zt1t4Tvc= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= +cloud.google.com/go/gkeconnect v0.8.2/go.mod h1:6nAVhwchBJYgQCXD2pHBFQNiJNyAd/wyxljpaa6ZPrY= +cloud.google.com/go/gkeconnect v0.8.3/go.mod h1:i9GDTrfzBSUZGCe98qSu1B8YB8qfapT57PenIb820Jo= +cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= +cloud.google.com/go/gkeconnect v0.8.5/go.mod h1:LC/rS7+CuJ5fgIbXv8tCD/mdfnlAadTaUufgOkmijuk= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= +cloud.google.com/go/gkehub v0.14.2/go.mod h1:iyjYH23XzAxSdhrbmfoQdePnlMj2EWcvnR+tHdBQsCY= +cloud.google.com/go/gkehub v0.14.3/go.mod h1:jAl6WafkHHW18qgq7kqcrXYzN08hXeK/Va3utN8VKg8= +cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= +cloud.google.com/go/gkehub v0.14.5/go.mod h1:6bzqxM+a+vEH/h8W8ec4OJl4r36laxTs3A/fMNHJ0wA= cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/gkemulticloud v1.0.1/go.mod h1:AcrGoin6VLKT/fwZEYuqvVominLriQBCKmbjtnbMjG8= +cloud.google.com/go/gkemulticloud v1.0.2/go.mod h1:+ee5VXxKb3H1l4LZAcgWB/rvI16VTNTrInWxDjAGsGo= +cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/gkemulticloud v1.1.0/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/gkemulticloud v1.1.1/go.mod h1:C+a4vcHlWeEIf45IB5FFR5XGjTeYhF83+AYIpTy4i2Q= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= +cloud.google.com/go/grafeas v0.3.4/go.mod h1:A5m316hcG+AulafjAbPKXBO/+I5itU4LOdKO2R/uDIc= cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= +cloud.google.com/go/gsuiteaddons v1.6.2/go.mod h1:K65m9XSgs8hTF3X9nNTPi8IQueljSdYo9F+Mi+s4MyU= +cloud.google.com/go/gsuiteaddons v1.6.3/go.mod h1:sCFJkZoMrLZT3JTb8uJqgKPNshH2tfXeCwTFRebTq48= +cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= +cloud.google.com/go/gsuiteaddons v1.6.5/go.mod h1:Lo4P2IvO8uZ9W+RaC6s1JVxo42vgy+TX5a6hfBZ0ubs= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= @@ -312,20 +679,44 @@ cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGE cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= +cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= +cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= +cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= +cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY= +cloud.google.com/go/iap v1.9.1/go.mod h1:SIAkY7cGMLohLSdBR25BuIxO+I4fXJiL06IBL7cy/5Q= +cloud.google.com/go/iap v1.9.2/go.mod h1:GwDTOs047PPSnwRD0Us5FKf4WDRcVvHg1q9WVkKBhdI= +cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= +cloud.google.com/go/iap v1.9.4/go.mod h1:vO4mSq0xNf/Pu6E5paORLASBwEmphXEjgCFg7aeNu1w= cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= +cloud.google.com/go/ids v1.4.2/go.mod h1:3vw8DX6YddRu9BncxuzMyWn0g8+ooUjI2gslJ7FH3vk= +cloud.google.com/go/ids v1.4.3/go.mod h1:9CXPqI3GedjmkjbMWCUhMZ2P2N7TUMzAkVXYEH2orYU= +cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= +cloud.google.com/go/ids v1.4.5/go.mod h1:p0ZnyzjMWxww6d2DvMGnFwCsSxDJM666Iir1bK1UuBo= cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= +cloud.google.com/go/iot v1.7.2/go.mod h1:q+0P5zr1wRFpw7/MOgDXrG/HVA+l+cSwdObffkrpnSg= +cloud.google.com/go/iot v1.7.3/go.mod h1:t8itFchkol4VgNbHnIq9lXoOOtHNR3uAACQMYbN9N4I= +cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= +cloud.google.com/go/iot v1.7.5/go.mod h1:nq3/sqTz3HGaWJi1xNiX7F41ThOzpud67vwk0YsSsqs= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= @@ -333,93 +724,232 @@ cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4 cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM= +cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= +cloud.google.com/go/kms v1.15.3/go.mod h1:AJdXqHxS2GlPyduM99s9iGqi2nwbviBbhV/hdmt4iOQ= +cloud.google.com/go/kms v1.15.4/go.mod h1:L3Sdj6QTHK8dfwK5D1JLsAyELsNMnd3tAIwGS4ltKpc= +cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= +cloud.google.com/go/kms v1.15.6/go.mod h1:yF75jttnIdHfGBoE51AKsD/Yqf+/jICzB9v1s1acsms= +cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= +cloud.google.com/go/language v1.11.0/go.mod h1:uDx+pFDdAKTY8ehpWbiXyQdz8tDSYLJbQcXsCkjYyvQ= +cloud.google.com/go/language v1.11.1/go.mod h1:Xyid9MG9WOX3utvDbpX7j3tXDmmDooMyMDqgUVpH17U= +cloud.google.com/go/language v1.12.1/go.mod h1:zQhalE2QlQIxbKIZt54IASBzmZpN/aDASea5zl1l+J4= +cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= +cloud.google.com/go/language v1.12.3/go.mod h1:evFX9wECX6mksEva8RbRnr/4wi/vKGYnAJrTRXU8+f8= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= +cloud.google.com/go/lifesciences v0.9.2/go.mod h1:QHEOO4tDzcSAzeJg7s2qwnLM2ji8IRpQl4p6m5Z9yTA= +cloud.google.com/go/lifesciences v0.9.3/go.mod h1:gNGBOJV80IWZdkd+xz4GQj4mbqaz737SCLHn2aRhQKM= +cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= +cloud.google.com/go/lifesciences v0.9.5/go.mod h1:OdBm0n7C0Osh5yZB7j9BXyrMnTRGBJIZonUMxo5CzPw= cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= +cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE= cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= +cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= +cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= +cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= +cloud.google.com/go/longrunning v0.5.3/go.mod h1:y/0ga59EYu58J6SHmmQOvekvND2qODbu8ywBBW7EK7Y= +cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= +cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= +cloud.google.com/go/managedidentities v1.6.2/go.mod h1:5c2VG66eCa0WIq6IylRk3TBW83l161zkFvCj28X7jn8= +cloud.google.com/go/managedidentities v1.6.3/go.mod h1:tewiat9WLyFN0Fi7q1fDD5+0N4VUoL0SCX0OTCthZq4= +cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= +cloud.google.com/go/managedidentities v1.6.5/go.mod h1:fkFI2PwwyRQbjLxlm5bQ8SjtObFMW3ChBGNqaMcgZjI= cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/maps v1.3.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= +cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= +cloud.google.com/go/maps v1.4.1/go.mod h1:BxSa0BnW1g2U2gNdbq5zikLlHUuHW0GFWh7sgML2kIY= +cloud.google.com/go/maps v1.5.1/go.mod h1:NPMZw1LJwQZYCfz4y+EIw+SI+24A4bpdFJqdKVr0lt4= +cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/maps v1.6.2/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/maps v1.6.3/go.mod h1:VGAn809ADswi1ASofL5lveOHPnE6Rk/SFTTBx1yuOLw= +cloud.google.com/go/maps v1.6.4/go.mod h1:rhjqRy8NWmDJ53saCfsXQ0LKwBHfi6OSh5wkq6BaMhI= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= +cloud.google.com/go/mediatranslation v0.8.2/go.mod h1:c9pUaDRLkgHRx3irYE5ZC8tfXGrMYwNZdmDqKMSfFp8= +cloud.google.com/go/mediatranslation v0.8.3/go.mod h1:F9OnXTy336rteOEywtY7FOqCk+J43o2RF638hkOQl4Y= +cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= +cloud.google.com/go/mediatranslation v0.8.5/go.mod h1:y7kTHYIPCIfgyLbKncgqouXJtLsU+26hZhHEEy80fSs= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= +cloud.google.com/go/memcache v1.10.2/go.mod h1:f9ZzJHLBrmd4BkguIAa/l/Vle6uTHzHokdnzSWOdQ6A= +cloud.google.com/go/memcache v1.10.3/go.mod h1:6z89A41MT2DVAW0P4iIRdu5cmRTsbsFn4cyiIx8gbwo= +cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= +cloud.google.com/go/memcache v1.10.5/go.mod h1:/FcblbNd0FdMsx4natdj+2GWzTq+cjZvMa1I+9QsuMA= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/metastore v1.13.0/go.mod h1:URDhpG6XLeh5K+Glq0NOt74OfrPKTwS62gEPZzb5SOk= +cloud.google.com/go/metastore v1.13.1/go.mod h1:IbF62JLxuZmhItCppcIfzBBfUFq0DIB9HPDoLgWrVOU= +cloud.google.com/go/metastore v1.13.2/go.mod h1:KS59dD+unBji/kFebVp8XU/quNSyo8b6N6tPGspKszA= +cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= +cloud.google.com/go/metastore v1.13.4/go.mod h1:FMv9bvPInEfX9Ac1cVcRXp8EBBQnBcqH6gz3KvJ9BAE= cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/monitoring v1.17.1 h1:xqcNr+JXmFMCPXnent/i1r0De6zrcqzgcMy5X1xa5vg= +cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= +cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY= +cloud.google.com/go/monitoring v1.16.1/go.mod h1:6HsxddR+3y9j+o/cMJH6q/KJ/CBTvM/38L/1m7bTRJ4= +cloud.google.com/go/monitoring v1.16.2/go.mod h1:B44KGwi4ZCF8Rk/5n+FWeispDXoKSk9oss2QNlXJBgc= +cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= +cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= cloud.google.com/go/monitoring v1.17.1/go.mod h1:SJzPMakCF0GHOuKEH/r4hxVKF04zl+cRPQyc3d/fqII= +cloud.google.com/go/monitoring v1.18.0/go.mod h1:c92vVBCeq/OB4Ioyo+NbN2U7tlg5ZH41PZcdvfc+Lcg= +cloud.google.com/go/monitoring v1.19.0 h1:NCXf8hfQi+Kmr56QJezXRZ6GPb80ZI7El1XztyUuLQI= +cloud.google.com/go/monitoring v1.19.0/go.mod h1:25IeMR5cQ5BoZ8j1eogHE5VPJLlReQ7zFp5OiLgiGZw= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= +cloud.google.com/go/networkconnectivity v1.13.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= +cloud.google.com/go/networkconnectivity v1.14.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= +cloud.google.com/go/networkconnectivity v1.14.1/go.mod h1:LyGPXR742uQcDxZ/wv4EI0Vu5N6NKJ77ZYVnDe69Zug= +cloud.google.com/go/networkconnectivity v1.14.2/go.mod h1:5UFlwIisZylSkGG1AdwK/WZUaoz12PKu6wODwIbFzJo= +cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= +cloud.google.com/go/networkconnectivity v1.14.4/go.mod h1:PU12q++/IMnDJAB+3r+tJtuCXCfwfN+C6Niyj6ji1Po= cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= +cloud.google.com/go/networkmanagement v1.9.0/go.mod h1:UTUaEU9YwbCAhhz3jEOHr+2/K/MrBk2XxOLS89LQzFw= +cloud.google.com/go/networkmanagement v1.9.1/go.mod h1:CCSYgrQQvW73EJawO2QamemYcOb57LvrDdDU51F0mcI= +cloud.google.com/go/networkmanagement v1.9.2/go.mod h1:iDGvGzAoYRghhp4j2Cji7sF899GnfGQcQRQwgVOWnDw= +cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= +cloud.google.com/go/networkmanagement v1.9.4/go.mod h1:daWJAl0KTFytFL7ar33I6R/oNBH8eEOX/rBNHrC/8TA= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= +cloud.google.com/go/networksecurity v0.9.2/go.mod h1:jG0SeAttWzPMUILEHDUvFYdQTl8L/E/KC8iZDj85lEI= +cloud.google.com/go/networksecurity v0.9.3/go.mod h1:l+C0ynM6P+KV9YjOnx+kk5IZqMSLccdBqW6GUoF4p/0= +cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= +cloud.google.com/go/networksecurity v0.9.5/go.mod h1:KNkjH/RsylSGyyZ8wXpue8xpCEK+bTtvof8SBfIhMG8= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= +cloud.google.com/go/notebooks v1.10.0/go.mod h1:SOPYMZnttHxqot0SGSFSkRrwE29eqnKPBJFqgWmiK2k= +cloud.google.com/go/notebooks v1.10.1/go.mod h1:5PdJc2SgAybE76kFQCWrTfJolCOUQXF97e+gteUUA6A= +cloud.google.com/go/notebooks v1.11.1/go.mod h1:V2Zkv8wX9kDCGRJqYoI+bQAaoVeE5kSiz4yYHd2yJwQ= +cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= +cloud.google.com/go/notebooks v1.11.3/go.mod h1:0wQyI2dQC3AZyQqWnRsp+yA+kY4gC7ZIVP4Qg3AQcgo= cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= +cloud.google.com/go/optimization v1.5.0/go.mod h1:evo1OvTxeBRBu6ydPlrIRizKY/LJKo/drDMMRKqGEUU= +cloud.google.com/go/optimization v1.5.1/go.mod h1:NC0gnUD5MWVAF7XLdoYVPmYYVth93Q6BUzqAq3ZwtV8= +cloud.google.com/go/optimization v1.6.1/go.mod h1:hH2RYPTTM9e9zOiTaYPTiGPcGdNZVnBSBxjIAJzUkqo= +cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= +cloud.google.com/go/optimization v1.6.3/go.mod h1:8ve3svp3W6NFcAEFr4SfJxrldzhUl4VMUJmhrqVKtYA= cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= +cloud.google.com/go/orchestration v1.8.2/go.mod h1:T1cP+6WyTmh6LSZzeUhvGf0uZVmJyTx7t8z7Vg87+A0= +cloud.google.com/go/orchestration v1.8.3/go.mod h1:xhgWAYqlbYjlz2ftbFghdyqENYW+JXuhBx9KsjMoGHs= +cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= +cloud.google.com/go/orchestration v1.8.5/go.mod h1:C1J7HesE96Ba8/hZ71ISTV2UAat0bwN+pi85ky38Yq8= cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= +cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= +cloud.google.com/go/orgpolicy v1.11.2/go.mod h1:biRDpNwfyytYnmCRWZWxrKF22Nkz9eNVj9zyaBdpm1o= +cloud.google.com/go/orgpolicy v1.11.3/go.mod h1:oKAtJ/gkMjum5icv2aujkP4CxROxPXsBbYGCDbPO8MM= +cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/orgpolicy v1.12.0/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/orgpolicy v1.12.1/go.mod h1:aibX78RDl5pcK3jA8ysDQCFkVxLj3aOQqrbBaUL2V5I= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= +cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= +cloud.google.com/go/osconfig v1.12.2/go.mod h1:eh9GPaMZpI6mEJEuhEjUJmaxvQ3gav+fFEJon1Y8Iw0= +cloud.google.com/go/osconfig v1.12.3/go.mod h1:L/fPS8LL6bEYUi1au832WtMnPeQNT94Zo3FwwV1/xGM= +cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= +cloud.google.com/go/osconfig v1.12.5/go.mod h1:D9QFdxzfjgw3h/+ZaAb5NypM8bhOMqBzgmbhzWViiW8= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= +cloud.google.com/go/oslogin v1.11.0/go.mod h1:8GMTJs4X2nOAUVJiPGqIWVcDaF0eniEto3xlOxaboXE= +cloud.google.com/go/oslogin v1.11.1/go.mod h1:OhD2icArCVNUxKqtK0mcSmKL7lgr0LVlQz+v9s1ujTg= +cloud.google.com/go/oslogin v1.12.1/go.mod h1:VfwTeFJGbnakxAY236eN8fsnglLiVXndlbcNomY4iZU= +cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= +cloud.google.com/go/oslogin v1.13.0/go.mod h1:xPJqLwpTZ90LSE5IL1/svko+6c5avZLluiyylMb/sRA= +cloud.google.com/go/oslogin v1.13.1/go.mod h1:vS8Sr/jR7QvPWpCjNqy6LYZr5Zs1e8ZGW/KPn9gmhws= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= +cloud.google.com/go/phishingprotection v0.8.2/go.mod h1:LhJ91uyVHEYKSKcMGhOa14zMMWfbEdxG032oT6ECbC8= +cloud.google.com/go/phishingprotection v0.8.3/go.mod h1:3B01yO7T2Ra/TMojifn8EoGd4G9jts/6cIO0DgDY9J8= +cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= +cloud.google.com/go/phishingprotection v0.8.5/go.mod h1:g1smd68F7mF1hgQPuYn3z8HDbNre8L6Z0b7XMYFmX7I= cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= +cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= +cloud.google.com/go/policytroubleshooter v1.9.0/go.mod h1:+E2Lga7TycpeSTj2FsH4oXxTnrbHJGRlKhVZBLGgU64= +cloud.google.com/go/policytroubleshooter v1.9.1/go.mod h1:MYI8i0bCrL8cW+VHN1PoiBTyNZTstCg2WUw2eVC4c4U= +cloud.google.com/go/policytroubleshooter v1.10.1/go.mod h1:5C0rhT3TDZVxAu8813bwmTvd57Phbl8mr9F4ipOsxEs= +cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= +cloud.google.com/go/policytroubleshooter v1.10.3/go.mod h1:+ZqG3agHT7WPb4EBIRqUv4OyIwRTZvsVDHZ8GlZaoxk= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= +cloud.google.com/go/privatecatalog v0.9.2/go.mod h1:RMA4ATa8IXfzvjrhhK8J6H4wwcztab+oZph3c6WmtFc= +cloud.google.com/go/privatecatalog v0.9.3/go.mod h1:K5pn2GrVmOPjXz3T26mzwXLcKivfIJ9R5N79AFCF9UE= +cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= +cloud.google.com/go/privatecatalog v0.9.5/go.mod h1:fVWeBOVe7uj2n3kWRGlUQqR/pOd450J9yZoOECcQqJk= 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= @@ -428,9 +958,14 @@ cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcd cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.34.0/go.mod h1:alj4l4rBg+N3YTFDDC+/YyFTs6JAjam2QfYsddcAW4c= +cloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE= cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= @@ -439,46 +974,104 @@ cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.0/go.mod h1:QuE8EdU9dEnesG8/kG3XuJyNsjEqMlMzg3v3scCJ46c= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.1/go.mod h1:JZYZJOeZjgSSTGP4uz7NlQ4/d1w5hGmksVgM0lbEij0= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.2/go.mod h1:kpaDBOpkwD4G0GVMzG1W6Doy1tFFC97XAV3xy+Rd/pw= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.4/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.9.0/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.9.2/go.mod h1:trwwGkfhCmp05Ll5MSJPXY7yvnO0p4v3orGANAFHAuU= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= +cloud.google.com/go/recommendationengine v0.8.2/go.mod h1:QIybYHPK58qir9CV2ix/re/M//Ty10OxjnnhWdaKS1Y= +cloud.google.com/go/recommendationengine v0.8.3/go.mod h1:m3b0RZV02BnODE9FeSvGv1qibFo8g0OnmB/RMwYy4V8= +cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= +cloud.google.com/go/recommendationengine v0.8.5/go.mod h1:A38rIXHGFvoPvmy6pZLozr0g59NRNREz4cx7F58HAsQ= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= +cloud.google.com/go/recommender v1.11.0/go.mod h1:kPiRQhPyTJ9kyXPCG6u/dlPLbYfFlkwHNRwdzPVAoII= +cloud.google.com/go/recommender v1.11.1/go.mod h1:sGwFFAyI57v2Hc5LbIj+lTwXipGu9NW015rkaEM5B18= +cloud.google.com/go/recommender v1.11.2/go.mod h1:AeoJuzOvFR/emIcXdVFkspVXVTYpliRCmKNYDnyBv6Y= +cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/recommender v1.12.0/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/recommender v1.12.1/go.mod h1:gf95SInWNND5aPas3yjwl0I572dtudMhMIG4ni8nr+0= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= +cloud.google.com/go/redis v1.13.2/go.mod h1:0Hg7pCMXS9uz02q+LoEVl5dNHUkIQv+C/3L76fandSA= +cloud.google.com/go/redis v1.13.3/go.mod h1:vbUpCKUAZSYzFcWKmICnYgRAhTFg9r+djWqFxDYXi4U= +cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= +cloud.google.com/go/redis v1.14.2/go.mod h1:g0Lu7RRRz46ENdFKQ2EcQZBAJ2PtJHJLuiiRuEXwyQw= cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= +cloud.google.com/go/resourcemanager v1.9.2/go.mod h1:OujkBg1UZg5lX2yIyMo5Vz9O5hf7XQOSV7WxqxxMtQE= +cloud.google.com/go/resourcemanager v1.9.3/go.mod h1:IqrY+g0ZgLsihcfcmqSe+RKp1hzjXwG904B92AwBz6U= +cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= +cloud.google.com/go/resourcemanager v1.9.5/go.mod h1:hep6KjelHA+ToEjOfO3garMKi/CLYwTqeAw7YiEI9x8= cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= +cloud.google.com/go/resourcesettings v1.6.2/go.mod h1:mJIEDd9MobzunWMeniaMp6tzg4I2GvD3TTmPkc8vBXk= +cloud.google.com/go/resourcesettings v1.6.3/go.mod h1:pno5D+7oDYkMWZ5BpPsb4SO0ewg3IXcmmrUZaMJrFic= +cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= +cloud.google.com/go/resourcesettings v1.6.5/go.mod h1:WBOIWZraXZOGAgoR4ukNj0o0HiSMO62H9RpFi9WjP9I= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= +cloud.google.com/go/retail v1.14.2/go.mod h1:W7rrNRChAEChX336QF7bnMxbsjugcOCPU44i5kbLiL8= +cloud.google.com/go/retail v1.14.3/go.mod h1:Omz2akDHeSlfCq8ArPKiBxlnRpKEBjUH386JYFLUvXo= +cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= +cloud.google.com/go/retail v1.15.1/go.mod h1:In9nSBOYhLbDGa87QvWlnE1XA14xBN2FpQRiRsUs9wU= +cloud.google.com/go/retail v1.16.0/go.mod h1:LW7tllVveZo4ReWt68VnldZFWJRzsh9np+01J9dYWzE= cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= +cloud.google.com/go/run v1.3.0/go.mod h1:S/osX/4jIPZGg+ssuqh6GNgg7syixKe3YnprwehzHKU= +cloud.google.com/go/run v1.3.1/go.mod h1:cymddtZOzdwLIAsmS6s+Asl4JoXIDm/K1cpZTxV4Q5s= +cloud.google.com/go/run v1.3.2/go.mod h1:SIhmqArbjdU/D9M6JoHaAqnAMKLFtXaVdNeq04NjnVE= +cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= +cloud.google.com/go/run v1.3.4/go.mod h1:FGieuZvQ3tj1e9GnzXqrMABSuir38AJg5xhiYq+SF3o= cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= +cloud.google.com/go/scheduler v1.10.2/go.mod h1:O3jX6HRH5eKCA3FutMw375XHZJudNIKVonSCHv7ropY= +cloud.google.com/go/scheduler v1.10.3/go.mod h1:8ANskEM33+sIbpJ+R4xRfw/jzOG+ZFE8WVLy7/yGvbc= +cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/scheduler v1.10.5/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/scheduler v1.10.6/go.mod h1:pe2pNCtJ+R01E06XCDOJs1XvAMbv28ZsQEbqknxGOuE= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= +cloud.google.com/go/secretmanager v1.11.2/go.mod h1:MQm4t3deoSub7+WNwiC4/tRYgDBHJgJPvswqQVB1Vss= +cloud.google.com/go/secretmanager v1.11.3/go.mod h1:0bA2o6FabmShrEy328i67aV+65XoUFFSmVeLBn/51jI= +cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= +cloud.google.com/go/secretmanager v1.11.5/go.mod h1:eAGv+DaCHkeVyQi0BeXgAHOU0RdrMeZIASKc+S7VqH4= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= @@ -486,12 +1079,23 @@ cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= +cloud.google.com/go/security v1.15.2/go.mod h1:2GVE/v1oixIRHDaClVbHuPcZwAqFM28mXuAKCfMgYIg= +cloud.google.com/go/security v1.15.3/go.mod h1:gQ/7Q2JYUZZgOzqKtw9McShH+MjNvtDpL40J1cT+vBs= +cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= +cloud.google.com/go/security v1.15.5/go.mod h1:KS6X2eG3ynWjqcIX976fuToN5juVkF6Ra6c7MPnldtc= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= +cloud.google.com/go/securitycenter v1.23.1/go.mod h1:w2HV3Mv/yKhbXKwOCu2i8bCuLtNP1IMHuiYQn4HJq5s= +cloud.google.com/go/securitycenter v1.24.1/go.mod h1:3h9IdjjHhVMXdQnmqzVnM7b0wMn/1O/U20eWVpMpZjI= +cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/securitycenter v1.24.3/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/securitycenter v1.24.4/go.mod h1:PSccin+o1EMYKcFQzz9HMMnZ2r9+7jbc+LvPjXhpwcU= cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= @@ -503,6 +1107,12 @@ cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPj cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicedirectory v1.11.1/go.mod h1:tJywXimEWzNzw9FvtNjsQxxJ3/41jseeILgwU/QLrGI= +cloud.google.com/go/servicedirectory v1.11.2/go.mod h1:KD9hCLhncWRV5jJphwIpugKwM5bn1x0GyVVD4NO8mGg= +cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= +cloud.google.com/go/servicedirectory v1.11.4/go.mod h1:Bz2T9t+/Ehg6x+Y7Ycq5xiShYLD96NfEsWNHyitj1qM= cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= @@ -514,15 +1124,37 @@ cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DR cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= +cloud.google.com/go/shell v1.7.2/go.mod h1:KqRPKwBV0UyLickMn0+BY1qIyE98kKyI216sH/TuHmc= +cloud.google.com/go/shell v1.7.3/go.mod h1:cTTEz/JdaBsQAeTQ3B6HHldZudFoYBOqjteev07FbIc= +cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= +cloud.google.com/go/shell v1.7.5/go.mod h1:hL2++7F47/IfpfTO53KYf1EC+F56k3ThfNEXd4zcuiE= cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= +cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= +cloud.google.com/go/spanner v1.50.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= +cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= +cloud.google.com/go/spanner v1.53.0/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws= +cloud.google.com/go/spanner v1.53.1/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws= +cloud.google.com/go/spanner v1.54.0/go.mod h1:wZvSQVBgngF0Gq86fKup6KIYmN2be7uOKjtK97X+bQU= +cloud.google.com/go/spanner v1.55.0/go.mod h1:HXEznMUVhC+PC+HDyo9YFG2Ajj5BQDkcbqB9Z2Ffxi0= +cloud.google.com/go/spanner v1.56.0/go.mod h1:DndqtUKQAt3VLuV2Le+9Y3WTnq5cNKrnLb/Piqcj+h0= +cloud.google.com/go/spanner v1.57.0/go.mod h1:aXQ5QDdhPRIqVhYmnkAdwPYvj/DRN0FguclhEWw+jOo= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/speech v1.19.1/go.mod h1:WcuaWz/3hOlzPFOVo9DUsblMIHwxP589y6ZMtaG+iAA= +cloud.google.com/go/speech v1.19.2/go.mod h1:2OYFfj+Ch5LWjsaSINuCZsre/789zlcCI3SY4oAi2oI= +cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= +cloud.google.com/go/speech v1.21.0/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= +cloud.google.com/go/speech v1.21.1/go.mod h1:E5GHZXYQlkqWQwY5xRSLHw2ci5NMQNG52FfMU1aZrIA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -534,45 +1166,93 @@ cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeL cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k= +cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw= +cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g= cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= +cloud.google.com/go/storagetransfer v1.10.1/go.mod h1:rS7Sy0BtPviWYTTJVWCSV4QrbBitgPeuK4/FKa4IdLs= +cloud.google.com/go/storagetransfer v1.10.2/go.mod h1:meIhYQup5rg9juQJdyppnA/WLQCOguxtk1pr3/vBWzA= +cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= +cloud.google.com/go/storagetransfer v1.10.4/go.mod h1:vef30rZKu5HSEf/x1tK3WfWrL0XVoUQN/EPDRGPzjZs= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= +cloud.google.com/go/talent v1.6.3/go.mod h1:xoDO97Qd4AK43rGjJvyBHMskiEf3KulgYzcH6YWOVoo= +cloud.google.com/go/talent v1.6.4/go.mod h1:QsWvi5eKeh6gG2DlBkpMaFYZYrYUnIpo34f6/V5QykY= +cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= +cloud.google.com/go/talent v1.6.6/go.mod h1:y/WQDKrhVz12WagoarpAIyKKMeKGKHWPoReZ0g8tseQ= cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= +cloud.google.com/go/texttospeech v1.7.2/go.mod h1:VYPT6aTOEl3herQjFHYErTlSZJ4vB00Q2ZTmuVgluD4= +cloud.google.com/go/texttospeech v1.7.3/go.mod h1:Av/zpkcgWfXlDLRYob17lqMstGZ3GqlvJXqKMp2u8so= +cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= +cloud.google.com/go/texttospeech v1.7.5/go.mod h1:tzpCuNWPwrNJnEa4Pu5taALuZL4QRRLcb+K9pbhXT6M= cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= +cloud.google.com/go/tpu v1.6.2/go.mod h1:NXh3NDwt71TsPZdtGWgAG5ThDfGd32X1mJ2cMaRlVgU= +cloud.google.com/go/tpu v1.6.3/go.mod h1:lxiueqfVMlSToZY1151IaZqp89ELPSrk+3HIQ5HRkbY= +cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= +cloud.google.com/go/tpu v1.6.5/go.mod h1:P9DFOEBIBhuEcZhXi+wPoVy/cji+0ICFi4TtTkMHSSs= cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/trace v1.10.5 h1:0pr4lIKJ5XZFYD9GtxXEWr0KkVeigc3wlGpZco0X1oA= +cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= +cloud.google.com/go/trace v1.10.2/go.mod h1:NPXemMi6MToRFcSxRl2uDnu/qAlAQ3oULUphcHGh1vA= +cloud.google.com/go/trace v1.10.3/go.mod h1:Ke1bgfc73RV3wUFml+uQp7EsDw4dGaETLxB7Iq/r4CY= +cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= cloud.google.com/go/trace v1.10.5/go.mod h1:9hjCV1nGBCtXbAE4YK7OqJ8pmPYSxPA0I67JwRd5s3M= +cloud.google.com/go/trace v1.10.7 h1:gK8z2BIJQ3KIYGddw9RJLne5Fx0FEXkrEQzPaeEYVvk= +cloud.google.com/go/trace v1.10.7/go.mod h1:qk3eiKmZX0ar2dzIJN/3QhY2PIFh1eqcIdaN5uEjQPM= cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.9.0/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.9.1/go.mod h1:TWIgDZknq2+JD4iRcojgeDtqGEp154HN/uL6hMvylS8= +cloud.google.com/go/translate v1.9.2/go.mod h1:E3Tc6rUTsQkVrXW6avbUhKJSr7ZE3j7zNmqzXKHqRrY= +cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/translate v1.10.0/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/translate v1.10.1/go.mod h1:adGZcQNom/3ogU65N9UXHOnnSvjPwA/jKQUMnsYXOyk= cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/video v1.20.0/go.mod h1:U3G3FTnsvAGqglq9LxgqzOiBc/Nt8zis8S+850N2DUM= +cloud.google.com/go/video v1.20.1/go.mod h1:3gJS+iDprnj8SY6pe0SwLeC5BUW80NjhwX7INWEuWGU= +cloud.google.com/go/video v1.20.2/go.mod h1:lrixr5JeKNThsgfM9gqtwb6Okuqzfo4VrY2xynaViTA= +cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= +cloud.google.com/go/video v1.20.4/go.mod h1:LyUVjyW+Bwj7dh3UJnUGZfyqjEto9DnrvTe1f/+QrW0= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= +cloud.google.com/go/videointelligence v1.11.2/go.mod h1:ocfIGYtIVmIcWk1DsSGOoDiXca4vaZQII1C85qtoplc= +cloud.google.com/go/videointelligence v1.11.3/go.mod h1:tf0NUaGTjU1iS2KEkGWvO5hRHeCkFK3nPo0/cOZhZAo= +cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= +cloud.google.com/go/videointelligence v1.11.5/go.mod h1:/PkeQjpRponmOerPeJxNPuxvi12HlW7Em0lJO14FC3I= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= @@ -580,52 +1260,90 @@ cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= +cloud.google.com/go/vision/v2 v2.7.3/go.mod h1:V0IcLCY7W+hpMKXK1JYE0LV5llEqVmj+UJChjvA1WsM= +cloud.google.com/go/vision/v2 v2.7.4/go.mod h1:ynDKnsDN/0RtqkKxQZ2iatv3Dm9O+HfRb5djl7l4Vvw= +cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= +cloud.google.com/go/vision/v2 v2.7.6/go.mod h1:ZkvWTVNPBU3YZYzgF9Y1jwEbD1NBOCyJn0KFdQfE6Bw= +cloud.google.com/go/vision/v2 v2.8.0/go.mod h1:ocqDiA2j97pvgogdyhoxiQp2ZkDCyr0HWpicywGGRhU= cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= +cloud.google.com/go/vmmigration v1.7.2/go.mod h1:iA2hVj22sm2LLYXGPT1pB63mXHhrH1m/ruux9TwWLd8= +cloud.google.com/go/vmmigration v1.7.3/go.mod h1:ZCQC7cENwmSWlwyTrZcWivchn78YnFniEQYRWQ65tBo= +cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= +cloud.google.com/go/vmmigration v1.7.5/go.mod h1:pkvO6huVnVWzkFioxSghZxIGcsstDvYiVCxQ9ZH3eYI= cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vmwareengine v1.0.1/go.mod h1:aT3Xsm5sNx0QShk1Jc1B8OddrxAScYLwzVoaiXfdzzk= +cloud.google.com/go/vmwareengine v1.0.2/go.mod h1:xMSNjIk8/itYrz1JA8nV3Ajg4L4n3N+ugP8JKzk3OaA= +cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= +cloud.google.com/go/vmwareengine v1.1.1/go.mod h1:nMpdsIVkUrSaX8UvmnBhzVzG7PPvNYc5BszcvIVudYs= cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= +cloud.google.com/go/vpcaccess v1.7.2/go.mod h1:mmg/MnRHv+3e8FJUjeSibVFvQF1cCy2MsFaFqxeY1HU= +cloud.google.com/go/vpcaccess v1.7.3/go.mod h1:YX4skyfW3NC8vI3Fk+EegJnlYFatA+dXK4o236EUCUc= +cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= +cloud.google.com/go/vpcaccess v1.7.5/go.mod h1:slc5ZRvvjP78c2dnL7m4l4R9GwL3wDLcpIWz6P/ziig= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= +cloud.google.com/go/webrisk v1.9.2/go.mod h1:pY9kfDgAqxUpDBOrG4w8deLfhvJmejKB0qd/5uQIPBc= +cloud.google.com/go/webrisk v1.9.3/go.mod h1:RUYXe9X/wBDXhVilss7EDLW9ZNa06aowPuinUOPCXH8= +cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= +cloud.google.com/go/webrisk v1.9.5/go.mod h1:aako0Fzep1Q714cPEM5E+mtYX8/jsfegAuS8aivxy3U= cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= +cloud.google.com/go/websecurityscanner v1.6.2/go.mod h1:7YgjuU5tun7Eg2kpKgGnDuEOXWIrh8x8lWrJT4zfmas= +cloud.google.com/go/websecurityscanner v1.6.3/go.mod h1:x9XANObUFR+83Cya3g/B9M/yoHVqzxPnFtgF8yYGAXw= +cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= +cloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/Ijvuoa3FCyS1zBa1rAVQ= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= +cloud.google.com/go/workflows v1.12.0/go.mod h1:PYhSk2b6DhZ508tj8HXKaBh+OFe+xdl0dHF/tJdzPQM= +cloud.google.com/go/workflows v1.12.1/go.mod h1:5A95OhD/edtOhQd/O741NSfIMezNTbCwLM1P1tBRGHM= +cloud.google.com/go/workflows v1.12.2/go.mod h1:+OmBIgNqYJPVggnMo9nqmizW0qEXHhmnAzK/CnBqsHc= +cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= +cloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0 h1:MxA59PGoCFb+vCwRQi3PhQEwHj4+r2dhuv9HG+vM7iM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0/go.mod h1:uYt4CfhkJA9o0FN7jfE5minm/i4nUE4MjGUJkzB6Zs8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.6.0 h1:sUFnFjzDUie80h24I7mrKtwCKgLY9L8h5Tp2x9+TWqk= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.6.0/go.mod h1:52JbnQTp15qg5mRkMBHwp0j0ZFwHJ42Sx3zVV5RE9p0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0 h1:IfFdxTUDiV58iZqPKgyWiz4X4fCxZeQ1pTQPImLYXpY= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0/go.mod h1:SUZc9YRRHfx2+FAQKNDGrssXehqLpxmwRv2mC/5ntj4= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= 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/Code-Hex/go-generics-cache v1.3.1 h1:i8rLwyhoyhaerr7JpjtYjJZUcCbWOdiYO3fZXLiEC4g= -github.com/Code-Hex/go-generics-cache v1.3.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= +github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU= +github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.8.3 h1:i84ZOPT35YCJROyuf97VP/VEdYhQce/8NTLOWq5tqJw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.8.3/go.mod h1:3+qm+VCJbVmQ9uscVz+8h1rRkJEy9ZNFGgpT1XB9mPg= @@ -634,26 +1352,27 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/KimMachineGun/automemlimit v0.5.0 h1:BeOe+BbJc8L5chL3OwzVYjVzyvPALdd5wxVVOWuUZmQ= -github.com/KimMachineGun/automemlimit v0.5.0/go.mod h1:di3GCKiu9Y+1fs92erCbUvKzPkNyViN3mA0vti/ykEQ= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8= +github.com/KimMachineGun/automemlimit v0.6.1/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/kingpin v1.3.8-0.20210301060133-17f40c25f497 h1:aDITxVUQ/3KBhpVWX57Vo9ntGTxoRw1F0T6/x/tRzNU= github.com/alecthomas/kingpin v1.3.8-0.20210301060133-17f40c25f497/go.mod h1:b6br6/pDFSfMkBgC96TbpOji05q5pa+v5rIlS0Y6XtI= +github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y= +github.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -671,29 +1390,26 @@ github.com/alicebob/miniredis/v2 v2.22.0/go.mod h1:XNqvJdQJv5mSuVMc0ynneafpnL/zv github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= +github.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw= +github.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= -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/apache/thrift v0.17.0/go.mod h1:OLxhMRJxomX+1I/KUw03qoV3mMz16BwaKI+d4fPBx7Q= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.50.32 h1:POt81DvegnpQKM4DMDLlHz1CO6OBnEoQ1gRhYFd7QRY= -github.com/aws/aws-sdk-go v1.50.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc= +github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.16.0 h1:cBAYjiiexRAg9v2z9vb6IdxAa7ef4KCtjW7w7e3GxGo= github.com/aws/aws-sdk-go-v2 v1.16.0/go.mod h1:lJYcuZZEHWNIb6ugJjbQY1fykdoobWbOS7kJYb4APoI= github.com/aws/aws-sdk-go-v2/config v1.15.1 h1:hTIZFepYESYyowQUBo47lu69WSxsYqGUILY9Nu8+7pY= @@ -726,15 +1442,14 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= +github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -742,8 +1457,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -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/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 h1:aPflPkRFkVwbW6dmcVqfgwp1i+UWGFH6VgR1Jim5Ygc= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw= @@ -751,13 +1467,18 @@ github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmt github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -765,54 +1486,44 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipamEh2BpGYxScCH1TOF1LL1cXc= +github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cortexproject/promqlsmith v0.0.0-20240326071418-c2a9ca1e89f5 h1:UfuB6no2X1BcKxICY63lzgY+XaPMQ/Wv4woP3p0L+mg= github.com/cortexproject/promqlsmith v0.0.0-20240326071418-c2a9ca1e89f5/go.mod h1:fcysbw4fOsOipXKeXPXWSh7tXrUQSUr5V4duojv0oCM= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -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/cucumber/godog v0.8.1 h1:lVb+X41I4YDreE+ibZ50bdXmySxgRviYFgKY6Aw4XE8= -github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/digitalocean/godo v1.109.0 h1:4W97RJLJSUQ3veRZDNbp1Ol3Rbn6Lmt9bKGvfqYI5SU= -github.com/digitalocean/godo v1.109.0/go.mod h1:R6EmmWI8CT1+fCtjWY9UCB+L5uufuZH13wk3YhxycCs= +github.com/digitalocean/godo v1.117.0 h1:WVlTe09melDYTd7VCVyvHcNWbgB+uI1O115+5LOtdSw= +github.com/digitalocean/godo v1.117.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ= -github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= +github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 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-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/efficientgo/core v1.0.0-rc.2 h1:7j62qHLnrZqO3V3UA0AqOGd5d5aXV3AX6m/NZBHp78I= @@ -821,6 +1532,8 @@ github.com/efficientgo/e2e v0.14.1-0.20230710114240-c316eb95ae5b h1:8VX23BNufsa4 github.com/efficientgo/e2e v0.14.1-0.20230710114240-c316eb95ae5b/go.mod h1:plsKU0YHE9uX+7utvr7SiDtVBSHJyEfHRO4UnUgDmts= github.com/efficientgo/tools/extkingpin v0.0.0-20220817170617-6c25e3b627dd h1:VaYzzXeUbC5fVheskcKVNOyJMEYD+HgrJNzIAg/mRIM= github.com/efficientgo/tools/extkingpin v0.0.0-20220817170617-6c25e3b627dd/go.mod h1:ZV0utlglOczUWv3ih2AbqPSoLoFzdplUYxwV62eZi6Q= +github.com/elastic/go-licenser v0.3.1 h1:RmRukU/JUmts+rpexAw0Fvt2ly7VVu6mw8z4HrEzObU= +github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-sysinfo v1.8.1 h1:4Yhj+HdV6WjbCRgGdZpPJ8lZQlXZLKDAeIkmQ/VRvi4= github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM= @@ -831,24 +1544,31 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/felixge/fgprof v0.9.2 h1:tAMHtWMyl6E0BimjVbFt7fieU6FpjttsZN7j0wT5blc= -github.com/felixge/fgprof v0.9.2/go.mod h1:+VNi+ZXtHIQ6wIw6bUT8nXQRefQflWECoFyRealT5sg= +github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88= +github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -856,15 +1576,15 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/ github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fullstorydev/emulators/storage v0.0.0-20240401123056-edc69752f474 h1:TufioMBjkJ6/Oqmlye/ReuxHFS35HyLmypj/BNy/8GY= +github.com/fullstorydev/emulators/storage v0.0.0-20240401123056-edc69752f474/go.mod h1:PQwxF4UU8wuL+srGxr3BOhIW5zXqgucwVlO/nPZLsxw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= @@ -876,9 +1596,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= 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-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -892,6 +1609,8 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -901,8 +1620,8 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= -github.com/go-openapi/errors v0.21.1 h1:rVisxQPdETctjlYntm0Ek4dKf68nAQocCloCT50vWuI= -github.com/go-openapi/errors v0.21.1/go.mod h1:LyiY9bgc7AVVh6wtVvMYEyoj3KJYNoRw92mmvnMWgj8= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= @@ -913,21 +1632,25 @@ github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqv github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU= github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= -github.com/go-openapi/strfmt v0.22.2 h1:DPYOrm6gexCfZZfXUaXFS4+Jw6HAaIIG0SZ5630f8yw= -github.com/go-openapi/strfmt v0.22.2/go.mod h1:HB/b7TCm91rno75Dembc1dFW/0FPLk5CEXsoF9ReNc4= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw= github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSaEpHTJHtN5cbE= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= -github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +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-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= +github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -937,6 +1660,11 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE= +github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= @@ -946,8 +1674,6 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/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.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -955,13 +1681,13 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 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/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= 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= @@ -995,13 +1721,15 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1021,6 +1749,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -1032,8 +1762,9 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi 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/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= 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= @@ -1049,16 +1780,22 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= -github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g= +github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -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.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= @@ -1066,6 +1803,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww= @@ -1081,104 +1820,82 @@ github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqE github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= +github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI= -github.com/gophercloud/gophercloud v1.8.0 h1:TM3Jawprb2NrdOnvcHhWJalmKmAmOGgfZElM/3oBYCk= -github.com/gophercloud/gophercloud v1.8.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= -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/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gophercloud/gophercloud v1.12.0 h1:Jrz16vPAL93l80q16fp8NplrTCp93y7rZh2P3Q4Yq7g= +github.com/gophercloud/gophercloud v1.12.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 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 v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware/providers/kit/v2 v2.0.0-20201002093600-73cf2ae9d891 h1:RhOqTAECcPnehv3hKlYy1fAnpQ7rnZu58l3mpq6gT1k= -github.com/grpc-ecosystem/go-grpc-middleware/providers/kit/v2 v2.0.0-20201002093600-73cf2ae9d891/go.mod h1:516cTXxZzi4NBUBbKcwmO4Eqbb6GHAEd3o4N+GYyCBY= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-20200501113911-9a95f0fdbfea/go.mod h1:GugMBs30ZSAkckqXEAIEGyYdDH6EgqowG8ppA3Zt+AY= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201207153454-9f6bf00c00a7 h1:guQyUpELu4I0wKgdsRBZDA5blfGiUleuppRSVy9Qbi0= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201207153454-9f6bf00c00a7/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= -github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/api v1.29.1 h1:UEwOjYJrd3lG1x5w7HxDRMGiAUPrb3f103EoeKuuEcc= +github.com/hashicorp/consul/api v1.29.1/go.mod h1:lumfRkY/coLuqMICkI7Fh3ylMG31mQSRZyef2c5YvJI= github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/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-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -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.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -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/nomad/api v0.0.0-20240306004928-3e7191ccb702 h1:fI1LXuBaS1d9z1kmb++Og6YD8uMRwadXorCwE+xgOFA= -github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702/go.mod h1:z71gkJdrkAt/Rl6C7Q79VE7AwJ5lUF+M+fzFTyIHYB0= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/nomad/api v0.0.0-20240604134157-e73d8bb1140d h1:KHq+mAzWSkumj4PDoXc5VZbycPGcmYu8tohgVLQ6SIc= +github.com/hashicorp/nomad/api v0.0.0-20240604134157-e73d8bb1140d/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hetznercloud/hcloud-go/v2 v2.6.0 h1:RJOA2hHZ7rD1pScA4O1NF6qhkHyUdbbxjHgFNot8928= -github.com/hetznercloud/hcloud-go/v2 v2.6.0/go.mod h1:4J1cSE57+g0WS93IiHLV7ubTHItcp+awzeBp5bM9mfA= +github.com/hetznercloud/hcloud-go/v2 v2.9.0 h1:s0N6R7Zoi2DPfMtUF5o9VeUBzTtHVY6MIkHOQnfu/AY= +github.com/hetznercloud/hcloud-go/v2 v2.9.0/go.mod h1:qtW/TuU7Bs16ibXl/ktJarWqU2LwHr7eGlwoilHxtgg= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.3+incompatible h1:tKTaPHNVwikS3I1rdyf1INNvgJXWSf/+TzqsiGbrgnQ= github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.3+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= 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/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/jcchavezs/porto v0.1.0 h1:Xmxxn25zQMmgE7/yHYmh19KcItG81hIwfbEEFnd6w/Q= +github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -1187,14 +1904,11 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1202,25 +1916,26 @@ 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 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -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/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1242,14 +1957,13 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= -github.com/linode/linodego v1.30.0 h1:6HJli+LX7NGu+Sne2G+ux790EkVOWOV/SR4mK3jcs6k= -github.com/linode/linodego v1.30.0/go.mod h1:/46h/XpmWi//oSA92GX2p3FIxb8HbX7grslPPQalR2o= +github.com/linode/linodego v1.35.0 h1:rIhUeCHBLEDlkoRnOTwzSGzljQ3ksXwLxacmXnrV+Do= +github.com/linode/linodego v1.35.0/go.mod h1:JxuhOEAMfSxun6RU5/MgTKH2GGTmFrhKRj3wL1NFin0= github.com/lovoo/gcloud-opentracing v0.3.0 h1:nAeKG70rIsog0TelcEtt6KU0Y1s5qXtsDLnHp0urPLU= github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -1257,51 +1971,52 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2 github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQovz3p+BiQ81Jy845xSMu2CWKuXsXuUM= github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.61 h1:87c+x8J3jxQ5VUGimV9oHdpjsAvy3fhneEBKuoKEVUI= -github.com/minio/minio-go/v7 v7.0.61/go.mod h1:BTu8FcrEw+HidY0zd/0eny43QnVNkXRPXrLXFuQBHXg= +github.com/minio/minio-go/v7 v7.0.72 h1:ZSbxs2BfJensLyHdVOgHv+pfmvxYraaUy07ER04dWnA= +github.com/minio/minio-go/v7 v7.0.72/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -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 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -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.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= 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= @@ -1316,25 +2031,16 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m 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 h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.53 h1:luHjjTNtekIEvHg5KdAFIBaH7bWfNkefwFnpDffSIks= github.com/ncw/swift v1.0.53/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/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= 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.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1342,14 +2048,13 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.4.3/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.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -1359,38 +2064,28 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/ github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w= github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= -github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= +github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/oracle/oci-go-sdk/v65 v65.41.1 h1:+lbosOyNiib3TGJDvLq1HwEAuFqkOjPJDIkyxM15WdQ= github.com/oracle/oci-go-sdk/v65 v65.41.1/go.mod h1:MXMLMzHnnd9wlpgadPkdlkZ9YrwQmCOmbX5kjVEJodw= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/ovh/go-ovh v1.4.3 h1:Gs3V823zwTFpzgGLZNI6ILS4rmxZgJwJCz54Er9LwD0= -github.com/ovh/go-ovh v1.4.3/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI= +github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1398,13 +2093,11 @@ 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/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= @@ -1414,89 +2107,80 @@ github.com/prometheus-community/prom-label-proxy v0.8.1-0.20240127162815-c1195f9 github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I= github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE= 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= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= 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/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= 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.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= 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.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.49.1-0.20240306132007-4199f18c3e92 h1:nuwTDY/15McImfuXcUD6AA3alpUNEXfWws8K/8SXr68= -github.com/prometheus/common v0.49.1-0.20240306132007-4199f18c3e92/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.54.1-0.20240615204547-04635d2962f9 h1:WTZ/GBRTImL1HgRTEnJJcM2FuII7PXX1idCIEUJ8/r8= +github.com/prometheus/common v0.54.1-0.20240615204547-04635d2962f9/go.mod h1:1Yn/UzXoahbVLk1sn6wsGiSiemz3XQejcaz9FIA1r+I= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.8.2/go.mod h1:00shzmJL7KxcsabLWcONwpyNEuWhREOnFqZW7vadFS0= github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= 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= github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= 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/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/prometheus v0.51.1-0.20240325140356-78c0fd2f4d75 h1:kIGJHrZqxmiSIidDXlmHISDNtr4dSTqIC6vjxbYsH1I= -github.com/prometheus/prometheus v0.51.1-0.20240325140356-78c0fd2f4d75/go.mod h1:FguQG8pCICrSpHA2pwizwV5FxGNTUBSZED/wMoZwVfY= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/prometheus v0.52.2-0.20240614130246-4c1e71fa0b3d h1:FFA2droSZiHghpHgKHefUCZLJnJQo+ZrKkBkcgZ0xp4= +github.com/prometheus/prometheus v0.52.2-0.20240614130246-4c1e71fa0b3d/go.mod h1:5AuUoK+n3jJUhhlc7C2DKdhI+dUx93eJvTYpvE0A3jE= github.com/redis/rueidis v1.0.14-go1.18 h1:dGir5z8w8X1ex7JWO/Zx2FMBrZgQ8Yjm+lw9fPLSNGw= github.com/redis/rueidis v1.0.14-go1.18/go.mod h1:HGekzV3HbmzFmRK6j0xic8Z9119+ECoGMjeN1TV1NYU= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 h1:/8rfZAdFfafRXOgz+ZpMZZWZ5pYggCY9t7e/BvjaBHM= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sercand/kuberesolver/v4 v4.0.0 h1:frL7laPDG/lFm5n98ODmWnn+cvPpzlkf3LhzuPhcHP4= -github.com/sercand/kuberesolver/v4 v4.0.0/go.mod h1:F4RGyuRmMAjeXHKL+w4P7AwUnPceEAPAhxUgXZjKgvM= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27 h1:yGAraK1uUjlhSXgNMIy8o/J4LFNcy7yeipBqt9N9mVg= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= +github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ= github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/simonpasquier/klog-gokit/v3 v3.0.0 h1:J0QrVhAULISHWN05PeXX/xMqJBjnpl2fAuO8uHdQGsA= github.com/simonpasquier/klog-gokit/v3 v3.0.0/go.mod h1:+WRhGy707Lp2Q4r727m9Oc7FxazOHgW76FIyCr23nus= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1504,11 +2188,7 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -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/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1517,13 +2197,10 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= 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/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1539,19 +2216,22 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= github.com/tencentyun/cos-go-sdk-v5 v0.7.40 h1:W6vDGKCHe4wBACI1d2UgE6+50sJFhRWU4O8IB2ozzxM= github.com/tencentyun/cos-go-sdk-v5 v0.7.40/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw= github.com/thanos-community/galaxycache v0.0.0-20211122094458-3a32041a1f1e h1:f1Zsv7OAU9iQhZwigp50Yl38W10g/vd5NC8Rdk1Jzng= github.com/thanos-community/galaxycache v0.0.0-20211122094458-3a32041a1f1e/go.mod h1:jXcofnrSln/cLI6/dhlBxPQZEEQHVPCcFaH75M+nSzM= -github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3 h1:Q0BjHI7FMe5KkKVXBFYto5VNASxiA/+AEhHup/IT7N0= -github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3/go.mod h1:ptMYNPgbyAR7a2Ab2t7zHA2/0be2ePyawVR7lp7fZtg= -github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508 h1:4X0ThYb7/wTTKS73wT13ixw0lj5OJ87g45RWIZhPZDA= -github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508/go.mod h1:FEPnabuTql1bDA4OUM41mwcZOJ20R436k8vq+xtGEG0= +github.com/thanos-io/objstore v0.0.0-20240622095743-1afe5d4bc3cd h1:YBDmfk3k/eOYLfP4SR/vZdXi5/65pqWPmR9Do2WjkRM= +github.com/thanos-io/objstore v0.0.0-20240622095743-1afe5d4bc3cd/go.mod h1:3ukSkG4rIRUGkKM4oIz+BSuUx2e3RlQVVv3Cc3W+Tv4= +github.com/thanos-io/promql-engine v0.0.0-20240515161521-93aa311933cf h1:R6of9adrCWXhETBstsFzNqrZou5UqeY3fh3k5yv5POY= +github.com/thanos-io/promql-engine v0.0.0-20240515161521-93aa311933cf/go.mod h1:FEPnabuTql1bDA4OUM41mwcZOJ20R436k8vq+xtGEG0= github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab h1:7ZR3hmisBWw77ZpO1/o86g+JV3VKlk3d48jopJxzTjU= github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab/go.mod h1:eheTFp954zcWZXCU8d0AT76ftsQOTo4DTqkN/h3k1MY= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= @@ -1560,22 +2240,19 @@ github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYa github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/weaveworks/common v0.0.0-20230728070032-dd9e68f319d5 h1:nORobjToZAvi54wcuUXLq+XG2Rsr0XEizy5aHBHvqWQ= github.com/weaveworks/common v0.0.0-20230728070032-dd9e68f319d5/go.mod h1:rgbeLfJUtEr+G74cwFPR1k/4N0kDeaeSv/qhUNE4hm8= github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= 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= @@ -1591,20 +2268,17 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zhangyunhao116/umap v0.0.0-20221211160557-cb7705fafa39 h1:D3ltj0b2c2FgUacKrB1pWGgwrUyCESY9W8XYYQ5sqY8= github.com/zhangyunhao116/umap v0.0.0-20221211160557-cb7705fafa39/go.mod h1:r86X1CnsDRrOeLtJlqRWdELPWpkcf933GTlojQlifQw= -go.elastic.co/apm v1.11.0 h1:uJyt6nCW9880sZhfl1tB//Jy/5TadNoAd8edRUtgb3w= -go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= -go.elastic.co/apm/module/apmhttp v1.11.0 h1:k/MjK0y2aLOXumoM8jcWXqxvIFlMS4U8Bn9cMUPdVX0= -go.elastic.co/apm/module/apmhttp v1.11.0/go.mod h1:5JFMIxdeS4vJy+D1PPPjINuX6hZ3AHalZXoOgyqZAkk= -go.elastic.co/apm/module/apmot v1.11.0 h1:Qmol6ztDJgvGK/B2cRdcPRNw4qE7kRv1d0vo9ptZfIo= -go.elastic.co/apm/module/apmot v1.11.0/go.mod h1:Qnbt3w1DvUd/5QugAF1AJ3mR4AG86EcJFBnAGW77EmU= +go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= +go.elastic.co/apm v1.15.0 h1:uPk2g/whK7c7XiZyz/YCUnAUBNPiyNeE3ARX3G6Gx7Q= +go.elastic.co/apm v1.15.0/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY= +go.elastic.co/apm/module/apmhttp v1.15.0 h1:Le/DhI0Cqpr9wG/NIGOkbz7+rOMqJrfE4MRG6q/+leU= +go.elastic.co/apm/module/apmhttp v1.15.0/go.mod h1:NruY6Jq8ALLzWUVUQ7t4wIzn+onKoiP5woJJdTV7GMg= +go.elastic.co/apm/module/apmot v1.15.0 h1:yqarZ4HCIb6dLAzEVSWdppAuRhfrCfm2Z6UL+ubai2A= +go.elastic.co/apm/module/apmot v1.15.0/go.mod h1:BjFz2KOlnjXdnSo0p6nhDDaIEYYX8c6uVHwvkZiLqtQ= go.elastic.co/fastjson v1.1.0 h1:3MrGBWWVIxe/xvsbpghtkFoPciPhOCmjsR/HfwEeQR4= go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 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= @@ -1614,16 +2288,18 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector/featuregate v1.3.0 h1:nrFSx+zfjdisjE9oCx25Aep3nJ9RaUjeE1qFL6eovoU= -go.opentelemetry.io/collector/featuregate v1.3.0/go.mod h1:mm8+xyQfgDmqhyegZRNIQmoKsNnDTwWKFLsdMoXAb7A= -go.opentelemetry.io/collector/pdata v1.3.0 h1:JRYN7tVHYFwmtQhIYbxWeiKSa2L1nCohyAs8sYqKFZo= -go.opentelemetry.io/collector/pdata v1.3.0/go.mod h1:t7W0Undtes53HODPdSujPLTnfSR5fzT+WpL+RTaaayo= -go.opentelemetry.io/collector/semconv v0.96.0 h1:DrZy8BpzJDnN2zFxXRj6BhfGYxNlqpFHBqyuS9fVHRY= -go.opentelemetry.io/collector/semconv v0.96.0/go.mod h1:zOm/U3pgMIWcvrcnPbR9Xx2HinoXj46ERMK8PUV9wrs= +go.opentelemetry.io/collector/pdata v1.8.0 h1:d/QQgZxB4Y+d3mqLVh2ozvzujUhloD3P/fk7X+In764= +go.opentelemetry.io/collector/pdata v1.8.0/go.mod h1:/W7clu0wFC4WSRp94Ucn6Vm36Wkrt+tmtlDb1aiNZCY= +go.opentelemetry.io/collector/semconv v0.101.0 h1:tOe9iTe9dDCnvz/bqgfNRr4w80kXG8505tQJ5h5v08Q= +go.opentelemetry.io/collector/semconv v0.101.0/go.mod h1:8ElcRZ8Cdw5JnvhTOQOdYizkJaQ10Z2fS+R6djOnj6A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/contrib/propagators/autoprop v0.38.0 h1:WZwiLCwOL0XW/6TVT7LTtdRDveoHZ6q3wL+0iYsBcdE= go.opentelemetry.io/contrib/propagators/autoprop v0.38.0/go.mod h1:JBebP2d0HiffbfelbIEoBOCl4790g7Z8lD1scUd3Vd8= go.opentelemetry.io/contrib/propagators/aws v1.13.0 h1:9qOAQhTeJGiaYNfCCnRmL12XZGIaxclqS5yfkSXpn8o= @@ -1636,31 +2312,41 @@ go.opentelemetry.io/contrib/propagators/ot v1.13.0 h1:tHWNd0WRS6w9keZoZg9aF3zYoh go.opentelemetry.io/contrib/propagators/ot v1.13.0/go.mod h1:R6Op9T6LxNaMRVlGD0wVwz40LSsAq296CXiEydKLQBU= go.opentelemetry.io/contrib/samplers/jaegerremote v0.7.0 h1:E+RlfFhGZ5Tk0wO1oOJYC0Il4Q7SjE8ZMl8x/VTK9Pk= go.opentelemetry.io/contrib/samplers/jaegerremote v0.7.0/go.mod h1:cuBMmL+iGJ4UpZi6dykQlIUxqKSMkp5eu1C1UjUJYFI= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/bridge/opentracing v1.21.0 h1:7AfuSFhyvBmt/0YskcdxDyTdHPjQfrHcZQo6Zu5srF4= go.opentelemetry.io/otel/bridge/opentracing v1.21.0/go.mod h1:giUOMajCV30LvlPHnzRDNBvDV3/NmrGVrqCp/1suDok= go.opentelemetry.io/otel/exporters/jaeger v1.16.0 h1:YhxxmXZ011C0aDZKoNw+juVWAmEfv/0W2XBOv9aHTaA= go.opentelemetry.io/otel/exporters/jaeger v1.16.0/go.mod h1:grYbBo/5afWlPpdPZYhyn78Bk04hnvxn2+hvxQhKIQM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= -go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -1668,32 +2354,39 @@ go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go4.org/intern v0.0.0-20230525184215-6c62f75575cb h1:ae7kzL5Cfdmcecbh22ll7lYP3iuUdnfnhiPcSaDgH/8= go4.org/intern v0.0.0-20230525184215-6c62f75575cb/go.mod h1:Ycrt6raEcnF5FTsLiLKkhBTO6DPX3RCUCUVnks3gFJU= go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 h1:WJhcL4p+YeDxmZWg141nRm7XC8IDmhz7lk5GpadO1Sg= go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= 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-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-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-20210421170649-83a5a9bb288b/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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1709,6 +2402,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= @@ -1734,6 +2429,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -1749,19 +2445,20 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= -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-20190125091013-d26f9f9a57f3/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= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1772,7 +2469,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1781,6 +2477,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 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= @@ -1816,6 +2513,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -1823,9 +2521,18 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 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= @@ -1853,8 +2560,14 @@ golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -1871,15 +2584,16 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/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= @@ -1891,7 +2605,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w 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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1899,7 +2612,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/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-20191220142924-d4481acd189f/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= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1957,7 +2669,9 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/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-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/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-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1965,11 +2679,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1977,18 +2693,37 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= 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= @@ -2005,9 +2740,12 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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= @@ -2016,7 +2754,6 @@ golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2025,7 +2762,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -2037,7 +2773,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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= @@ -2045,7 +2780,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2083,11 +2817,17 @@ 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.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= 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= @@ -2108,7 +2848,6 @@ gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6d gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 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= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -2166,19 +2905,29 @@ google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/api v0.168.0 h1:MBRe+Ki4mMN93jhDDbpuRLjRddooArz4FeSObvUMmjY= -google.golang.org/api v0.168.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= +google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= +google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= +google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= +google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g= +google.golang.org/api v0.160.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= +google.golang.org/api v0.183.0 h1:PNMeRDwo1pJdgNcFQ9GstuLe/noWKIc89pRWRLMvLwE= +google.golang.org/api v0.183.0/go.mod h1:q43adC5/pHoSZTx5h2mSmdF7NcyfW9JuDyIOJAgS9ZQ= 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= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -2311,20 +3060,102 @@ google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVix google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto v0.0.0-20240205150955-31a09d347014 h1:g/4bk7P6TPMkAUbUhquq98xey1slwvuVJPosdBqYJlU= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= +google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= +google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= +google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto v0.0.0-20240528184218-531527333157 h1:u7WMYrIrVvs0TF5yaKwKNbcJyySYf+HAIFXxWltJOXE= +google.golang.org/genproto v0.0.0-20240528184218-531527333157/go.mod h1:ubQlAQnzejB8uZzszhrTCU2Fyp6Vi7ZE5nn0c3W8+qQ= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= +google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= +google.golang.org/genproto/googleapis/api v0.0.0-20240122161410-6c6643bf1457/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= +google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= +google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= +google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:PVreiBMirk8ypES6aw9d4p6iiBNSIfZEBqr3UGoAi2E= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231212172506-995d672761c0/go.mod h1:guYXGPwC6jwxgWKW5Y405fKWOFNwlvUlUnzyp9i0uqo= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:ZSvZ8l+AWJwXw91DoTjWjaVLpWU6o0eZ4YLYpH8aLeQ= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:SCz6T5xjNXM4QFPRwxHcfChp7V+9DcXR3ay2TkHR8Tg= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240304161311-37d4d3c04a78 h1:Xs9lu+tLXxLIfuci70nG4cpwaRC+mRQPUL7LoIeDJC4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= -google.golang.org/grpc v1.57.2 h1:uw37EN34aMFFXB2QPW7Tq6tdTbind1GpRxw5aOX3a5k= -google.golang.org/grpc v1.57.2/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920183334-c177e329c48b/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231211222908-989df2bf70f3/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240122161410-6c6643bf1457/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014/go.mod h1:SaPjaZGWb0lPqs6Ittu0spdfrOArqji4ZdeP5IC/9N4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:YUWgXUFRPfoYK1IHMuxH5K6nPEXSCzIMljnQ59lLRCk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= 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-20211119005141-f45e61797429 h1:vh/88xB6bVCYsvXtGnKcQGJLMt2fPUFwdSJrVfS2km8= google.golang.org/grpc/examples v0.0.0-20211119005141-f45e61797429/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU= @@ -2345,26 +3176,25 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= 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.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -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= @@ -2377,6 +3207,7 @@ 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= 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= @@ -2393,21 +3224,29 @@ k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= +modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= @@ -2417,20 +3256,38 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= +modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= +modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.21.2/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= +modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= +modernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0= +modernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= @@ -2439,7 +3296,5 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/cortex/chunk/cache/redis_cache.go b/internal/cortex/chunk/cache/redis_cache.go index 2fd30b7e80..e9caf727d4 100644 --- a/internal/cortex/chunk/cache/redis_cache.go +++ b/internal/cortex/chunk/cache/redis_cache.go @@ -70,7 +70,7 @@ func (c *RedisCache) Fetch(ctx context.Context, keys []string) (found []string, items, err = c.redis.MGet(ctx, keys) if err != nil { log.Error(err) - level.Error(c.logger).Log("msg", "failed to get from redis", "name", c.name, "err", err) + level.Debug(c.logger).Log("msg", "failed to get from redis", "name", c.name, "err", err) return err } diff --git a/internal/cortex/frontend/transport/handler.go b/internal/cortex/frontend/transport/handler.go index d9acbbdbcd..fc3d099eb9 100644 --- a/internal/cortex/frontend/transport/handler.go +++ b/internal/cortex/frontend/transport/handler.go @@ -48,6 +48,7 @@ type HandlerConfig struct { QueryStatsEnabled bool `yaml:"query_stats_enabled"` LogFailedQueries bool `yaml:"log_failed_queries"` FailedQueryCacheCapacity int `yaml:"failed_query_cache_capacity"` + SlowQueryLogsUserHeader string `yaml:"slow_query_logs_user_header"` } // Handler accepts queries and forwards them to RoundTripper. It can log slow queries, @@ -261,7 +262,13 @@ func (f *Handler) reportSlowQuery(r *http.Request, responseHeaders http.Header, thanosTraceID = traceID } - remoteUser, _, _ := r.BasicAuth() + var remoteUser string + // Prefer reading remote user from header. Fall back to the value of basic authentication. + if f.cfg.SlowQueryLogsUserHeader != "" { + remoteUser = r.Header.Get(f.cfg.SlowQueryLogsUserHeader) + } else { + remoteUser, _, _ = r.BasicAuth() + } logMessage := append([]interface{}{ "msg", "slow query detected", diff --git a/internal/cortex/frontend/transport/utils/utils.go b/internal/cortex/frontend/transport/utils/utils.go index 08d4764ea8..88c0cc7520 100644 --- a/internal/cortex/frontend/transport/utils/utils.go +++ b/internal/cortex/frontend/transport/utils/utils.go @@ -105,7 +105,7 @@ func (f *FailedQueryCache) addCacheEntry(queryExpressionNormalized string, query func queryHitCache(queryExpressionNormalized string, queryExpressionRangeLength int, lruCache *lru.Cache, cachedHits prometheus.Counter) (bool, string) { if value, ok := lruCache.Get(queryExpressionNormalized); ok && value.(int) <= queryExpressionRangeLength { cachedQueryRangeSeconds := value.(int) - message := createLogMessage("Retrieved query from cache", queryExpressionNormalized, cachedQueryRangeSeconds, queryExpressionRangeLength, nil) + message := createLogMessage("Blocked a query from failed query cache", queryExpressionNormalized, cachedQueryRangeSeconds, queryExpressionRangeLength, nil) cachedHits.Inc() return true, message } diff --git a/internal/cortex/frontend/transport/utils/utils_test.go b/internal/cortex/frontend/transport/utils/utils_test.go index c21252083b..46e44ae8e4 100644 --- a/internal/cortex/frontend/transport/utils/utils_test.go +++ b/internal/cortex/frontend/transport/utils/utils_test.go @@ -226,7 +226,7 @@ func TestQueryHitCache(t *testing.T) { "query": {"test_query"}, }, expectedResult: true, - expectedMessage: "Retrieved query from cache, cached_query: test_query, cached_range_seconds: 100, query_range_seconds: 100", + expectedMessage: "Blocked a query from failed query cache, cached_query: test_query, cached_range_seconds: 100, query_range_seconds: 100", }, { name: "Cache miss", @@ -258,7 +258,7 @@ func TestQueryHitCache(t *testing.T) { "query": {" \n\ttes \tt \n query \t\n "}, }, expectedResult: true, - expectedMessage: "Retrieved query from cache, cached_query: tes t query , cached_range_seconds: 100, query_range_seconds: 100", + expectedMessage: "Blocked a query from failed query cache, cached_query: tes t query , cached_range_seconds: 100, query_range_seconds: 100", }, { diff --git a/internal/cortex/querier/queryrange/results_cache.go b/internal/cortex/querier/queryrange/results_cache.go index 553e0aa214..28cc388134 100644 --- a/internal/cortex/querier/queryrange/results_cache.go +++ b/internal/cortex/querier/queryrange/results_cache.go @@ -7,6 +7,7 @@ import ( "context" "flag" "fmt" + "github.com/thanos-io/thanos/pkg/extpromql" "net/http" "sort" "strings" @@ -326,7 +327,7 @@ func (s resultsCache) isAtModifierCachable(r Request, maxCacheTime int64) bool { if !strings.Contains(query, "@") { return true } - expr, err := parser.ParseExpr(query) + expr, err := extpromql.ParseExpr(query) if err != nil { // We are being pessimistic in such cases. level.Warn(s.logger).Log("msg", "failed to parse query, considering @ modifier as not cachable", "query", query, "err", err) @@ -371,7 +372,7 @@ func (s resultsCache) isOffsetCachable(r Request) bool { if !strings.Contains(query, "offset") { return true } - expr, err := parser.ParseExpr(query) + expr, err := extpromql.ParseExpr(query) if err != nil { level.Warn(s.logger).Log("msg", "failed to parse query, considering offset as not cachable", "query", query, "err", err) return false diff --git a/internal/cortex/querier/queryrange/split_by_interval.go b/internal/cortex/querier/queryrange/split_by_interval.go index 039306e880..2ae53f7c50 100644 --- a/internal/cortex/querier/queryrange/split_by_interval.go +++ b/internal/cortex/querier/queryrange/split_by_interval.go @@ -5,6 +5,7 @@ package queryrange import ( "context" + "github.com/thanos-io/thanos/pkg/extpromql" "net/http" "time" @@ -97,7 +98,7 @@ func splitQuery(r Request, interval time.Duration) ([]Request, error) { // For example given the start of the query is 10.00, `http_requests_total[1h] @ start()` query will be replaced with `http_requests_total[1h] @ 10.00` // If the modifier is already a constant, it will be returned as is. func EvaluateAtModifierFunction(query string, start, end int64) (string, error) { - expr, err := parser.ParseExpr(query) + expr, err := extpromql.ParseExpr(query) if err != nil { return "", httpgrpc.Errorf(http.StatusBadRequest, `{"status": "error", "error": "%s"}`, err) } diff --git a/internal/cortex/querier/queryrange/split_by_interval_test.go b/internal/cortex/querier/queryrange/split_by_interval_test.go index bd0e96b35d..68b67d95dc 100644 --- a/internal/cortex/querier/queryrange/split_by_interval_test.go +++ b/internal/cortex/querier/queryrange/split_by_interval_test.go @@ -5,6 +5,7 @@ package queryrange import ( "context" + "github.com/thanos-io/thanos/pkg/extpromql" io "io" "net/http" "net/http/httptest" @@ -13,7 +14,6 @@ import ( "testing" "time" - "github.com/prometheus/prometheus/promql/parser" "github.com/stretchr/testify/require" "github.com/weaveworks/common/httpgrpc" "github.com/weaveworks/common/middleware" @@ -332,6 +332,11 @@ func Test_evaluateAtModifier(t *testing.T) { in: "topk(5, rate(http_requests_total[1h] @ start()))", expected: "topk(5, rate(http_requests_total[1h] @ 1546300.800))", }, + { + // extended functions + in: "topk(5, xrate(http_requests_total[1h] @ start()))", + expected: "topk(5, xrate(http_requests_total[1h] @ 1546300.800))", + }, { in: "topk(5, rate(http_requests_total[1h] @ 0))", expected: "topk(5, rate(http_requests_total[1h] @ 0.000))", @@ -390,7 +395,7 @@ func Test_evaluateAtModifier(t *testing.T) { require.Equal(t, tt.expectedErrorCode, int(httpResp.Code)) } else { require.NoError(t, err) - expectedExpr, err := parser.ParseExpr(tt.expected) + expectedExpr, err := extpromql.ParseExpr(tt.expected) require.NoError(t, err) require.Equal(t, expectedExpr.String(), out) } diff --git a/pkg/api/api.go b/pkg/api/api.go index d9dc5f4700..13b690cbe0 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -20,7 +20,6 @@ package api import ( - "encoding/json" "fmt" "net/http" "os" @@ -29,6 +28,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" + jsoniter "github.com/json-iterator/go" "github.com/klauspost/compress/gzhttp" "github.com/opentracing/opentracing-go" "github.com/prometheus/common/route" @@ -66,6 +66,11 @@ var corsHeaders = map[string]string{ "Access-Control-Expose-Headers": "Date", } +var ( + // Let suse the same json codec used by upstream prometheus. + json = jsoniter.ConfigCompatibleWithStandardLibrary +) + // ThanosVersion contains build information about Thanos. type ThanosVersion struct { Version string `json:"version"` @@ -221,10 +226,10 @@ func GetInstr( } }) - return tracing.HTTPMiddleware(tracer, name, logger, - ins.NewHandler(name, - gzhttp.GzipHandler( - middleware.RequestID( + return middleware.RequestID( + tracing.HTTPMiddleware(tracer, name, logger, + ins.NewHandler(name, + gzhttp.GzipHandler( logMiddleware.HTTPMiddleware(name, hf), ), ), diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 88c9a30772..fc9dd4bf2f 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -17,7 +17,6 @@ package api import ( - "encoding/json" "io" "net/http" "net/http/httptest" @@ -28,12 +27,48 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/common/route" + "github.com/prometheus/prometheus/promql" + "github.com/prometheus/prometheus/promql/parser" + promApiV1 "github.com/prometheus/prometheus/web/api/v1" "github.com/efficientgo/core/testutil" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" "github.com/thanos-io/thanos/pkg/logging" ) +func TestMarshallMatrixNull(t *testing.T) { + var m promql.Matrix + result := response{ + Status: StatusSuccess, + Data: promApiV1.QueryData{ + ResultType: parser.ValueTypeMatrix, + Result: m, // null + }, + } + + b1, err := json.Marshal(result) + if err != nil { + t.Fatalf("Error marshaling response body: %s", err) + } + + exp := response{ + Status: StatusSuccess, + Data: promApiV1.QueryData{ + ResultType: parser.ValueTypeMatrix, + Result: promql.Matrix{}, + }, + } + + b2, err := json.Marshal(exp) + if err != nil { + t.Fatalf("Error marshaling response body: %s", err) + } + + if !reflect.DeepEqual(b1, b2) { + t.Fatalf("Expected response \n%v\n but got \n%v\n", string(b1), string(b2)) + } +} + func TestRespondSuccess(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { Respond(w, "test", nil) diff --git a/pkg/api/blocks/v1_test.go b/pkg/api/blocks/v1_test.go index 0899c3e5bb..49e7ef0681 100644 --- a/pkg/api/blocks/v1_test.go +++ b/pkg/api/blocks/v1_test.go @@ -99,12 +99,12 @@ func TestMarkBlockEndpoint(t *testing.T) { // create block b1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, - {{Name: "b", Value: "1"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "val1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), + labels.FromStrings("b", "1"), + }, 100, 0, 1000, labels.FromStrings("ext1", "val1"), 124, metadata.NoneFunc) testutil.Ok(t, err) // upload block diff --git a/pkg/api/query/grpc.go b/pkg/api/query/grpc.go index e471001db2..093457dd06 100644 --- a/pkg/api/query/grpc.go +++ b/pkg/api/query/grpc.go @@ -9,6 +9,7 @@ import ( "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/storage" + "github.com/thanos-io/promql-engine/engine" "github.com/thanos-io/promql-engine/logicalplan" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -18,6 +19,7 @@ import ( "github.com/thanos-io/thanos/pkg/query" "github.com/thanos-io/thanos/pkg/store/labelpb" "github.com/thanos-io/thanos/pkg/store/storepb/prompb" + "github.com/thanos-io/thanos/pkg/tracing" ) type GRPCAPI struct { @@ -92,13 +94,20 @@ func (g *GRPCAPI) Query(request *querypb.QueryRequest, server querypb.Query_Quer query.NoopSeriesStatsReporter, ) - qry, err := g.getQueryForEngine(ctx, request, queryable, maxResolution) - if err != nil { + var qry promql.Query + if err := tracing.DoInSpanWithErr(ctx, "instant_query_create", func(ctx context.Context) error { + var err error + qry, err = g.getQueryForEngine(ctx, request, queryable, maxResolution) + return err + }); err != nil { return err } defer qry.Close() - result := qry.Exec(ctx) + var result *promql.Result + tracing.DoInSpan(ctx, "range_query_exec", func(ctx context.Context) { + result = qry.Exec(ctx) + }) if result.Err != nil { return status.Error(codes.Aborted, result.Err.Error()) } @@ -129,7 +138,9 @@ func (g *GRPCAPI) Query(request *querypb.QueryRequest, server querypb.Query_Quer return err } } - return nil + } + if err := server.Send(querypb.NewQueryStatsResponse(extractQueryStats(qry))); err != nil { + return err } return nil @@ -203,13 +214,20 @@ func (g *GRPCAPI) QueryRange(request *querypb.QueryRangeRequest, srv querypb.Que query.NoopSeriesStatsReporter, ) - qry, err := g.getRangeQueryForEngine(ctx, request, queryable) - if err != nil { + var qry promql.Query + if err := tracing.DoInSpanWithErr(ctx, "range_query_create", func(ctx context.Context) error { + var err error + qry, err = g.getRangeQueryForEngine(ctx, request, queryable) + return err + }); err != nil { return err } defer qry.Close() - result := qry.Exec(ctx) + var result *promql.Result + tracing.DoInSpan(ctx, "range_query_exec", func(ctx context.Context) { + result = qry.Exec(ctx) + }) if result.Err != nil { return status.Error(codes.Aborted, result.Err.Error()) } @@ -245,17 +263,35 @@ func (g *GRPCAPI) QueryRange(request *querypb.QueryRangeRequest, srv querypb.Que return err } } - return nil case promql.Scalar: series := &prompb.TimeSeries{ Samples: []prompb.Sample{{Value: value.V, Timestamp: value.T}}, } - return srv.Send(querypb.NewQueryRangeResponse(series)) + if err := srv.Send(querypb.NewQueryRangeResponse(series)); err != nil { + return err + } + } + if err := srv.Send(querypb.NewQueryRangeStatsResponse(extractQueryStats(qry))); err != nil { + return err } return nil } +func extractQueryStats(qry promql.Query) *querypb.QueryStats { + stats := &querypb.QueryStats{ + SamplesTotal: 0, + PeakSamples: 0, + } + if explQry, ok := qry.(engine.ExplainableQuery); ok { + analyze := explQry.Analyze() + stats.SamplesTotal = analyze.TotalSamples() + stats.PeakSamples = analyze.PeakSamples() + } + + return stats +} + func (g *GRPCAPI) getRangeQueryForEngine( ctx context.Context, request *querypb.QueryRangeRequest, diff --git a/pkg/api/query/grpc_test.go b/pkg/api/query/grpc_test.go index 4885126c46..f1be2a5489 100644 --- a/pkg/api/query/grpc_test.go +++ b/pkg/api/query/grpc_test.go @@ -13,7 +13,6 @@ import ( "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/promql" - "github.com/prometheus/prometheus/promql/parser" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/util/annotations" "github.com/thanos-io/promql-engine/logicalplan" @@ -21,6 +20,7 @@ import ( "github.com/thanos-io/thanos/pkg/api/query/querypb" "github.com/thanos-io/thanos/pkg/component" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/query" "github.com/thanos-io/thanos/pkg/store" ) @@ -36,7 +36,7 @@ func TestGRPCQueryAPIWithQueryPlan(t *testing.T) { } api := NewGRPCAPI(time.Now, nil, queryableCreator, engineFactory, querypb.EngineType_thanos, lookbackDeltaFunc, 0) - expr, err := parser.ParseExpr("metric") + expr, err := extpromql.ParseExpr("metric") testutil.Ok(t, err) lplan := logicalplan.NewFromAST(expr, &equery.Options{}, logicalplan.PlanOptions{}) testutil.Ok(t, err) @@ -117,7 +117,9 @@ func TestGRPCQueryAPIErrorHandling(t *testing.T) { if len(test.engine.warns) > 0 { testutil.Ok(t, err) for i, resp := range srv.responses { - testutil.Equals(t, test.engine.warns.AsErrors()[i].Error(), resp.GetWarnings()) + if resp.GetWarnings() != "" { + testutil.Equals(t, test.engine.warns.AsErrors()[i].Error(), resp.GetWarnings()) + } } } }) @@ -136,7 +138,9 @@ func TestGRPCQueryAPIErrorHandling(t *testing.T) { if len(test.engine.warns) > 0 { testutil.Ok(t, err) for i, resp := range srv.responses { - testutil.Equals(t, test.engine.warns.AsErrors()[i].Error(), resp.GetWarnings()) + if resp.GetWarnings() != "" { + testutil.Equals(t, test.engine.warns.AsErrors()[i].Error(), resp.GetWarnings()) + } } } }) diff --git a/pkg/api/query/querypb/query.pb.go b/pkg/api/query/querypb/query.pb.go index ca70d93e5e..ebeec71d80 100644 --- a/pkg/api/query/querypb/query.pb.go +++ b/pkg/api/query/querypb/query.pb.go @@ -58,6 +58,44 @@ func (EngineType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_4b2aba43925d729f, []int{0} } +type QueryStats struct { + SamplesTotal int64 `protobuf:"varint,1,opt,name=samples_total,json=samplesTotal,proto3" json:"samples_total,omitempty"` + PeakSamples int64 `protobuf:"varint,2,opt,name=peak_samples,json=peakSamples,proto3" json:"peak_samples,omitempty"` +} + +func (m *QueryStats) Reset() { *m = QueryStats{} } +func (m *QueryStats) String() string { return proto.CompactTextString(m) } +func (*QueryStats) ProtoMessage() {} +func (*QueryStats) Descriptor() ([]byte, []int) { + return fileDescriptor_4b2aba43925d729f, []int{0} +} +func (m *QueryStats) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryStats.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryStats.Merge(m, src) +} +func (m *QueryStats) XXX_Size() int { + return m.Size() +} +func (m *QueryStats) XXX_DiscardUnknown() { + xxx_messageInfo_QueryStats.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryStats proto.InternalMessageInfo + type QueryRequest struct { Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` QueryPlan *QueryPlan `protobuf:"bytes,14,opt,name=queryPlan,proto3" json:"queryPlan,omitempty"` @@ -78,7 +116,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} } func (m *QueryRequest) String() string { return proto.CompactTextString(m) } func (*QueryRequest) ProtoMessage() {} func (*QueryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{0} + return fileDescriptor_4b2aba43925d729f, []int{1} } func (m *QueryRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -115,7 +153,7 @@ func (m *StoreMatchers) Reset() { *m = StoreMatchers{} } func (m *StoreMatchers) String() string { return proto.CompactTextString(m) } func (*StoreMatchers) ProtoMessage() {} func (*StoreMatchers) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{1} + return fileDescriptor_4b2aba43925d729f, []int{2} } func (m *StoreMatchers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -148,6 +186,7 @@ type QueryResponse struct { // Types that are valid to be assigned to Result: // *QueryResponse_Warnings // *QueryResponse_Timeseries + // *QueryResponse_Stats Result isQueryResponse_Result `protobuf_oneof:"result"` } @@ -155,7 +194,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} } func (m *QueryResponse) String() string { return proto.CompactTextString(m) } func (*QueryResponse) ProtoMessage() {} func (*QueryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{2} + return fileDescriptor_4b2aba43925d729f, []int{3} } func (m *QueryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -196,9 +235,13 @@ type QueryResponse_Warnings struct { type QueryResponse_Timeseries struct { Timeseries *prompb.TimeSeries `protobuf:"bytes,2,opt,name=timeseries,proto3,oneof" json:"timeseries,omitempty"` } +type QueryResponse_Stats struct { + Stats *QueryStats `protobuf:"bytes,3,opt,name=stats,proto3,oneof" json:"stats,omitempty"` +} func (*QueryResponse_Warnings) isQueryResponse_Result() {} func (*QueryResponse_Timeseries) isQueryResponse_Result() {} +func (*QueryResponse_Stats) isQueryResponse_Result() {} func (m *QueryResponse) GetResult() isQueryResponse_Result { if m != nil { @@ -221,11 +264,19 @@ func (m *QueryResponse) GetTimeseries() *prompb.TimeSeries { return nil } +func (m *QueryResponse) GetStats() *QueryStats { + if x, ok := m.GetResult().(*QueryResponse_Stats); ok { + return x.Stats + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*QueryResponse) XXX_OneofWrappers() []interface{} { return []interface{}{ (*QueryResponse_Warnings)(nil), (*QueryResponse_Timeseries)(nil), + (*QueryResponse_Stats)(nil), } } @@ -239,7 +290,7 @@ func (m *QueryPlan) Reset() { *m = QueryPlan{} } func (m *QueryPlan) String() string { return proto.CompactTextString(m) } func (*QueryPlan) ProtoMessage() {} func (*QueryPlan) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{3} + return fileDescriptor_4b2aba43925d729f, []int{4} } func (m *QueryPlan) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -323,7 +374,7 @@ func (m *QueryRangeRequest) Reset() { *m = QueryRangeRequest{} } func (m *QueryRangeRequest) String() string { return proto.CompactTextString(m) } func (*QueryRangeRequest) ProtoMessage() {} func (*QueryRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{4} + return fileDescriptor_4b2aba43925d729f, []int{5} } func (m *QueryRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -356,6 +407,7 @@ type QueryRangeResponse struct { // Types that are valid to be assigned to Result: // *QueryRangeResponse_Warnings // *QueryRangeResponse_Timeseries + // *QueryRangeResponse_Stats Result isQueryRangeResponse_Result `protobuf_oneof:"result"` } @@ -363,7 +415,7 @@ func (m *QueryRangeResponse) Reset() { *m = QueryRangeResponse{} } func (m *QueryRangeResponse) String() string { return proto.CompactTextString(m) } func (*QueryRangeResponse) ProtoMessage() {} func (*QueryRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4b2aba43925d729f, []int{5} + return fileDescriptor_4b2aba43925d729f, []int{6} } func (m *QueryRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -404,9 +456,13 @@ type QueryRangeResponse_Warnings struct { type QueryRangeResponse_Timeseries struct { Timeseries *prompb.TimeSeries `protobuf:"bytes,2,opt,name=timeseries,proto3,oneof" json:"timeseries,omitempty"` } +type QueryRangeResponse_Stats struct { + Stats *QueryStats `protobuf:"bytes,3,opt,name=stats,proto3,oneof" json:"stats,omitempty"` +} func (*QueryRangeResponse_Warnings) isQueryRangeResponse_Result() {} func (*QueryRangeResponse_Timeseries) isQueryRangeResponse_Result() {} +func (*QueryRangeResponse_Stats) isQueryRangeResponse_Result() {} func (m *QueryRangeResponse) GetResult() isQueryRangeResponse_Result { if m != nil { @@ -429,16 +485,25 @@ func (m *QueryRangeResponse) GetTimeseries() *prompb.TimeSeries { return nil } +func (m *QueryRangeResponse) GetStats() *QueryStats { + if x, ok := m.GetResult().(*QueryRangeResponse_Stats); ok { + return x.Stats + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*QueryRangeResponse) XXX_OneofWrappers() []interface{} { return []interface{}{ (*QueryRangeResponse_Warnings)(nil), (*QueryRangeResponse_Timeseries)(nil), + (*QueryRangeResponse_Stats)(nil), } } func init() { proto.RegisterEnum("thanos.EngineType", EngineType_name, EngineType_value) + proto.RegisterType((*QueryStats)(nil), "thanos.QueryStats") proto.RegisterType((*QueryRequest)(nil), "thanos.QueryRequest") proto.RegisterType((*StoreMatchers)(nil), "thanos.StoreMatchers") proto.RegisterType((*QueryResponse)(nil), "thanos.QueryResponse") @@ -450,56 +515,60 @@ func init() { func init() { proto.RegisterFile("api/query/querypb/query.proto", fileDescriptor_4b2aba43925d729f) } var fileDescriptor_4b2aba43925d729f = []byte{ - // 784 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x6f, 0xe3, 0x44, - 0x1c, 0xb5, 0x37, 0xff, 0x7f, 0x4e, 0x52, 0xef, 0x28, 0x05, 0x6f, 0x00, 0x63, 0x22, 0xad, 0x30, - 0x2b, 0x48, 0x56, 0x61, 0xe1, 0x86, 0x04, 0x61, 0x57, 0x2a, 0x68, 0x91, 0xb6, 0x6e, 0x4f, 0x5c, - 0xa2, 0x49, 0x3c, 0x4d, 0x4c, 0x9c, 0x19, 0xd7, 0x33, 0x2e, 0x8d, 0xb8, 0x73, 0xe6, 0xe3, 0xf0, - 0x11, 0x7a, 0xac, 0xc4, 0x85, 0x13, 0x82, 0xf6, 0x8b, 0x20, 0x8f, 0xff, 0xc4, 0xae, 0x2a, 0x48, - 0x54, 0x69, 0x2f, 0xce, 0xcc, 0x7b, 0x6f, 0xc6, 0xbf, 0x79, 0xfe, 0xbd, 0x0c, 0x7c, 0x80, 0x03, - 0x6f, 0x74, 0x1e, 0x91, 0x70, 0x93, 0x3c, 0x83, 0x59, 0xf2, 0x3b, 0x0c, 0x42, 0x26, 0x18, 0xaa, - 0x8b, 0x25, 0xa6, 0x8c, 0xf7, 0x7b, 0x0b, 0xb6, 0x60, 0x12, 0x1a, 0xc5, 0xa3, 0x84, 0xed, 0x3f, - 0xe1, 0x82, 0x85, 0x64, 0x24, 0x9f, 0xc1, 0x6c, 0x24, 0x36, 0x01, 0xe1, 0x29, 0xf5, 0x6e, 0x99, - 0x0a, 0x83, 0x79, 0x4a, 0x58, 0x65, 0x22, 0x08, 0xd9, 0xba, 0xbc, 0x74, 0xf0, 0x47, 0x15, 0xda, - 0xc7, 0x71, 0x0d, 0x0e, 0x39, 0x8f, 0x08, 0x17, 0xa8, 0x07, 0x35, 0x59, 0x93, 0xa1, 0x5a, 0xaa, - 0xdd, 0x72, 0x92, 0x09, 0x1a, 0x41, 0x4b, 0x0e, 0xde, 0xf8, 0x98, 0x1a, 0x5d, 0x4b, 0xb5, 0xb5, - 0xf1, 0xe3, 0x61, 0x52, 0xee, 0x30, 0x27, 0x9c, 0xad, 0x06, 0x7d, 0x04, 0x6d, 0xe1, 0xad, 0xc9, - 0x94, 0x93, 0x39, 0xa3, 0x2e, 0x37, 0x1e, 0x59, 0xaa, 0x5d, 0x71, 0xb4, 0x18, 0x3b, 0x49, 0x20, - 0xf4, 0x31, 0x1c, 0xc4, 0x53, 0x16, 0x89, 0x5c, 0x55, 0x91, 0xaa, 0x6e, 0x0a, 0x67, 0xc2, 0x17, - 0xf0, 0xce, 0x1a, 0x5f, 0x4e, 0x43, 0xc2, 0x99, 0x1f, 0x09, 0x8f, 0xd1, 0x5c, 0x5f, 0x95, 0xfa, - 0xde, 0x1a, 0x5f, 0x3a, 0x39, 0x99, 0xad, 0x7a, 0x0a, 0xdd, 0x90, 0x04, 0xbe, 0x37, 0xc7, 0x53, - 0x1f, 0xcf, 0x88, 0xcf, 0x8d, 0x9a, 0x55, 0xb1, 0x5b, 0x4e, 0x27, 0x45, 0x5f, 0x4b, 0x10, 0x7d, - 0x03, 0x1d, 0x69, 0xcf, 0x0f, 0x58, 0xcc, 0x97, 0x24, 0xe4, 0x46, 0xdd, 0xaa, 0xd8, 0xda, 0xf8, - 0x30, 0x3b, 0xdd, 0x49, 0x91, 0x9c, 0x54, 0xaf, 0xfe, 0xfa, 0x50, 0x71, 0xca, 0x2b, 0x90, 0x05, - 0x1a, 0xa1, 0x78, 0xe6, 0x93, 0x97, 0xc4, 0x8d, 0x02, 0xa3, 0x61, 0xa9, 0x76, 0xd3, 0x29, 0x42, - 0xe8, 0x05, 0x1c, 0x26, 0xd3, 0x37, 0x38, 0x14, 0x1e, 0xf6, 0x1d, 0xc2, 0x03, 0x46, 0x39, 0x31, - 0x9a, 0x52, 0x7b, 0x3f, 0x89, 0x4c, 0x00, 0xbe, 0xf2, 0x82, 0x6f, 0x97, 0x11, 0x5d, 0x71, 0x03, - 0xa4, 0xb4, 0x80, 0xa0, 0xe7, 0x00, 0x7c, 0x89, 0x43, 0x77, 0xea, 0xd1, 0x33, 0x66, 0x68, 0xe5, - 0xaf, 0x72, 0x12, 0x33, 0xdf, 0xd1, 0x33, 0xe6, 0xb4, 0x78, 0x36, 0x8c, 0x9d, 0xf4, 0x19, 0x5b, - 0xcd, 0xf0, 0x7c, 0x35, 0x75, 0x89, 0x2f, 0x70, 0xee, 0x64, 0x3b, 0x71, 0x32, 0x63, 0x5f, 0xc6, - 0x64, 0xe6, 0xe4, 0x33, 0xa8, 0x13, 0xba, 0xf0, 0x28, 0x31, 0x3a, 0x96, 0x6a, 0x77, 0xc7, 0x28, - 0x7b, 0xc7, 0x2b, 0x89, 0x9e, 0x6e, 0x02, 0xe2, 0xa4, 0x8a, 0xef, 0xab, 0xcd, 0x96, 0x0e, 0x83, - 0x63, 0xe8, 0x94, 0x7c, 0x43, 0x5f, 0x43, 0x47, 0x7e, 0x84, 0xdc, 0x65, 0x55, 0xba, 0xdc, 0xcb, - 0x76, 0x7a, 0x5d, 0x20, 0x33, 0x93, 0x4b, 0x0b, 0x06, 0x17, 0xd0, 0x49, 0xfb, 0x34, 0x75, 0xe7, - 0x7d, 0x68, 0xfe, 0x8c, 0x43, 0xea, 0xd1, 0x05, 0x4f, 0x7a, 0xf5, 0x48, 0x71, 0x72, 0x04, 0x7d, - 0x05, 0x10, 0x77, 0x11, 0x27, 0xa1, 0x47, 0x92, 0xee, 0xd3, 0xc6, 0xef, 0xc5, 0x3d, 0xbf, 0x26, - 0x62, 0x49, 0x22, 0x3e, 0x9d, 0xb3, 0x60, 0x33, 0x3c, 0x95, 0xed, 0x18, 0x4b, 0x8e, 0x14, 0xa7, - 0xb0, 0x60, 0xd2, 0x84, 0x7a, 0x48, 0x78, 0xe4, 0x8b, 0xc1, 0x67, 0x85, 0xce, 0x47, 0x3d, 0xa8, - 0xfe, 0xc4, 0x19, 0x95, 0xef, 0x6b, 0x1f, 0x29, 0x8e, 0x9c, 0x4d, 0x00, 0x9a, 0x84, 0xce, 0x99, - 0xeb, 0xd1, 0xc5, 0xe0, 0xf7, 0x1a, 0x3c, 0x4e, 0xea, 0xc4, 0x74, 0x41, 0xf6, 0x08, 0x95, 0xbe, - 0x43, 0xa8, 0x3e, 0x05, 0xc4, 0x05, 0x0e, 0xc5, 0xf4, 0x9e, 0x68, 0xe9, 0x92, 0x39, 0x2d, 0xe4, - 0xcb, 0x06, 0x9d, 0x50, 0xb7, 0xac, 0x4d, 0x03, 0x46, 0xa8, 0x5b, 0x54, 0x7e, 0x02, 0xba, 0x47, - 0x05, 0x09, 0x2f, 0xb0, 0x7f, 0x27, 0x5a, 0x07, 0x19, 0xfe, 0x1f, 0xa1, 0xad, 0xed, 0x19, 0xda, - 0xfa, 0x5e, 0xa1, 0x6d, 0xec, 0x14, 0xda, 0xe6, 0x43, 0x43, 0xdb, 0xda, 0x23, 0xb4, 0xb0, 0x7b, - 0x68, 0xdb, 0xff, 0x13, 0xda, 0xce, 0x83, 0x42, 0xdb, 0xdd, 0x29, 0xb4, 0x07, 0x3b, 0x84, 0x56, - 0xd3, 0xdb, 0x83, 0x5f, 0x00, 0x15, 0x3b, 0xf7, 0xad, 0xc6, 0xec, 0xd9, 0x17, 0x00, 0xdb, 0xc2, - 0x90, 0x06, 0x0d, 0x97, 0x9c, 0xe1, 0xc8, 0x17, 0xba, 0x82, 0xba, 0x00, 0xdb, 0x0d, 0x75, 0x15, - 0x01, 0xa4, 0x17, 0xa5, 0xfe, 0x68, 0xfc, 0xab, 0x0a, 0x35, 0x59, 0x34, 0xfa, 0x32, 0x1b, 0xe4, - 0xff, 0x29, 0xc5, 0x6b, 0xad, 0x7f, 0x78, 0x07, 0x4d, 0x4e, 0xf7, 0x5c, 0x45, 0xaf, 0x00, 0xb6, - 0xa7, 0x46, 0x4f, 0xca, 0xb2, 0x42, 0x86, 0xfb, 0xfd, 0xfb, 0xa8, 0x6c, 0x9b, 0xc9, 0xd3, 0xab, - 0x7f, 0x4c, 0xe5, 0xea, 0xc6, 0x54, 0xaf, 0x6f, 0x4c, 0xf5, 0xef, 0x1b, 0x53, 0xfd, 0xed, 0xd6, - 0x54, 0xae, 0x6f, 0x4d, 0xe5, 0xcf, 0x5b, 0x53, 0xf9, 0xb1, 0x91, 0x5e, 0xf7, 0xb3, 0xba, 0xbc, - 0x75, 0x3f, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x9d, 0x9d, 0xab, 0x0a, 0x08, 0x00, 0x00, + // 848 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xcf, 0x8e, 0xdb, 0x44, + 0x1c, 0xb6, 0xbb, 0x49, 0x36, 0xf9, 0x39, 0xc9, 0xba, 0xa3, 0x2c, 0xb8, 0x01, 0x82, 0x09, 0xaa, + 0x08, 0x2b, 0xd8, 0x54, 0xa1, 0x70, 0x43, 0x82, 0xa5, 0x95, 0x16, 0x54, 0xa4, 0xd6, 0xc9, 0x89, + 0x8b, 0x35, 0x89, 0x7f, 0x9b, 0x98, 0x38, 0x33, 0xae, 0x67, 0x0c, 0xdd, 0x17, 0xe0, 0xcc, 0x33, + 0x70, 0xe1, 0x15, 0x78, 0x84, 0x3d, 0x56, 0xe2, 0xc2, 0x09, 0xc1, 0xee, 0x8b, 0x20, 0x8f, 0xff, + 0xc4, 0xae, 0x56, 0x90, 0xa8, 0x17, 0x2e, 0xf6, 0xcc, 0xf7, 0x7d, 0x33, 0xe3, 0xdf, 0xe7, 0xdf, + 0x27, 0x1b, 0xde, 0xa1, 0xa1, 0x3f, 0x7e, 0x1e, 0x63, 0x74, 0x99, 0x5e, 0xc3, 0x79, 0x7a, 0x3f, + 0x0d, 0x23, 0x2e, 0x39, 0x69, 0xc8, 0x15, 0x65, 0x5c, 0xf4, 0x7b, 0x4b, 0xbe, 0xe4, 0x0a, 0x1a, + 0x27, 0xa3, 0x94, 0xed, 0xdf, 0x13, 0x92, 0x47, 0x38, 0x56, 0xd7, 0x70, 0x3e, 0x96, 0x97, 0x21, + 0x8a, 0x8c, 0x7a, 0xb3, 0x4a, 0x45, 0xe1, 0x22, 0x23, 0xec, 0x2a, 0x11, 0x46, 0x7c, 0x53, 0x5d, + 0x3a, 0x9c, 0x01, 0x3c, 0x4b, 0x1e, 0x61, 0x2a, 0xa9, 0x14, 0xe4, 0x7d, 0xe8, 0x08, 0xba, 0x09, + 0x03, 0x14, 0xae, 0xe4, 0x92, 0x06, 0x96, 0x6e, 0xeb, 0xa3, 0x03, 0xa7, 0x9d, 0x81, 0xb3, 0x04, + 0x23, 0xef, 0x41, 0x3b, 0x44, 0xba, 0x76, 0x33, 0xd0, 0xba, 0xa3, 0x34, 0x46, 0x82, 0x4d, 0x53, + 0x68, 0xf8, 0x7b, 0x0d, 0xda, 0x6a, 0x5b, 0x07, 0x9f, 0xc7, 0x28, 0x24, 0xe9, 0x41, 0x5d, 0x55, + 0xaa, 0x36, 0x6c, 0x39, 0xe9, 0x84, 0x8c, 0xa1, 0xa5, 0x06, 0x4f, 0x03, 0xca, 0xac, 0xae, 0xad, + 0x8f, 0x8c, 0xc9, 0xdd, 0xd3, 0xd4, 0x84, 0xd3, 0x82, 0x70, 0xb6, 0x9a, 0xe4, 0x68, 0xe9, 0x6f, + 0xd0, 0x15, 0xb8, 0xe0, 0xcc, 0x2b, 0x8e, 0x4e, 0xb0, 0x69, 0x0a, 0x91, 0x0f, 0xe0, 0x28, 0x99, + 0xf2, 0x58, 0x16, 0xaa, 0x03, 0xa5, 0xea, 0x66, 0x70, 0x2e, 0x7c, 0x08, 0x6f, 0x6c, 0xe8, 0x0b, + 0x37, 0x42, 0xc1, 0x83, 0x58, 0xfa, 0x9c, 0x15, 0xfa, 0x9a, 0xd2, 0xf7, 0x36, 0xf4, 0x85, 0x53, + 0x90, 0xf9, 0xaa, 0xfb, 0xd0, 0x8d, 0x30, 0x0c, 0xfc, 0x05, 0x75, 0x03, 0x3a, 0xc7, 0x40, 0x58, + 0x75, 0xfb, 0x60, 0xd4, 0x72, 0x3a, 0x19, 0xfa, 0x44, 0x81, 0xe4, 0x4b, 0xe8, 0x28, 0xd3, 0xbf, + 0xa5, 0x72, 0xb1, 0xc2, 0x48, 0x58, 0x0d, 0xfb, 0x60, 0x64, 0x4c, 0x8e, 0xf3, 0xea, 0xa6, 0x65, + 0xf2, 0xac, 0x76, 0xf5, 0xe7, 0xbb, 0x9a, 0x53, 0x5d, 0x41, 0x6c, 0x30, 0x90, 0xd1, 0x79, 0x80, + 0x8f, 0xd0, 0x8b, 0x43, 0xeb, 0xd0, 0xd6, 0x47, 0x4d, 0xa7, 0x0c, 0x91, 0x87, 0x70, 0x9c, 0x4e, + 0x9f, 0xd2, 0x48, 0xfa, 0x34, 0x70, 0x50, 0x84, 0x9c, 0x09, 0xb4, 0x9a, 0x4a, 0x7b, 0x3b, 0x49, + 0x06, 0x00, 0x62, 0xed, 0x87, 0x5f, 0xad, 0x62, 0xb6, 0x16, 0x16, 0x28, 0x69, 0x09, 0x21, 0x0f, + 0x00, 0xc4, 0x8a, 0x46, 0x9e, 0xeb, 0xb3, 0x0b, 0x6e, 0x19, 0xd5, 0xb7, 0x32, 0x4d, 0x98, 0xaf, + 0xd9, 0x05, 0x77, 0x5a, 0x22, 0x1f, 0x26, 0x4e, 0x06, 0x9c, 0xaf, 0xe7, 0x74, 0xb1, 0x76, 0x3d, + 0x0c, 0x24, 0x2d, 0x9c, 0x6c, 0xa7, 0x4e, 0xe6, 0xec, 0xa3, 0x84, 0xcc, 0x9d, 0x3c, 0x81, 0x06, + 0xb2, 0xa5, 0xcf, 0xd0, 0xea, 0xd8, 0xfa, 0xa8, 0x3b, 0x21, 0xf9, 0x19, 0x8f, 0x15, 0x3a, 0xbb, + 0x0c, 0xd1, 0xc9, 0x14, 0xdf, 0xd4, 0x9a, 0x2d, 0x13, 0x86, 0xcf, 0xa0, 0x53, 0xf1, 0x8d, 0x7c, + 0x01, 0x1d, 0xf5, 0x12, 0x0a, 0x97, 0x75, 0xe5, 0x72, 0x2f, 0xdf, 0xe9, 0x49, 0x89, 0xcc, 0x4d, + 0xae, 0x2c, 0x18, 0xfe, 0xa2, 0x43, 0x27, 0x6b, 0xd4, 0xcc, 0x9e, 0xb7, 0xa1, 0xf9, 0x23, 0x8d, + 0x98, 0xcf, 0x96, 0x22, 0x6d, 0xd6, 0x73, 0xcd, 0x29, 0x10, 0xf2, 0x39, 0x40, 0xd2, 0x46, 0x02, + 0x23, 0x3f, 0xeb, 0x7c, 0x63, 0xf2, 0x56, 0x12, 0xa5, 0x0d, 0xca, 0x15, 0xc6, 0xc2, 0x5d, 0xf0, + 0xf0, 0xf2, 0x74, 0xa6, 0xfa, 0x31, 0x91, 0x9c, 0x6b, 0x4e, 0x69, 0x01, 0x39, 0x81, 0xba, 0x48, + 0x82, 0xa6, 0x5a, 0xd2, 0xd8, 0x96, 0xbc, 0x8d, 0xe0, 0xb9, 0xe6, 0xa4, 0x92, 0xb3, 0x26, 0x34, + 0x22, 0x14, 0x71, 0x20, 0x87, 0x1f, 0x97, 0x62, 0x42, 0x7a, 0x50, 0xfb, 0x5e, 0x70, 0xa6, 0x9e, + 0xad, 0x7d, 0xae, 0x39, 0x6a, 0x76, 0x06, 0xd0, 0x44, 0xb6, 0xe0, 0x9e, 0xcf, 0x96, 0xc3, 0xdf, + 0xea, 0x70, 0x37, 0xad, 0x89, 0xb2, 0x25, 0xee, 0x91, 0x40, 0x73, 0x87, 0x04, 0x7e, 0x04, 0x44, + 0x48, 0x1a, 0x49, 0xf7, 0x96, 0x1c, 0x9a, 0x8a, 0x99, 0x95, 0xc2, 0x38, 0x02, 0x13, 0x99, 0x57, + 0xd5, 0x66, 0x69, 0x44, 0xe6, 0x95, 0x95, 0x1f, 0x82, 0xe9, 0x33, 0x89, 0xd1, 0x0f, 0x34, 0x78, + 0x25, 0x87, 0x47, 0x39, 0xfe, 0x2f, 0x09, 0xaf, 0xef, 0x99, 0xf0, 0xc6, 0x5e, 0x09, 0x3f, 0xdc, + 0x29, 0xe1, 0xcd, 0xd7, 0x4d, 0x78, 0x6b, 0x8f, 0x84, 0xc3, 0xee, 0x09, 0x6f, 0xff, 0x47, 0xc2, + 0x3b, 0xaf, 0x95, 0xf0, 0xee, 0x4e, 0x09, 0x3f, 0xda, 0x21, 0xe1, 0x86, 0xd9, 0x1e, 0xfe, 0xaa, + 0x03, 0x29, 0xb7, 0xee, 0xff, 0x36, 0x93, 0x27, 0x9f, 0x02, 0x6c, 0xab, 0x20, 0x06, 0x1c, 0x7a, + 0x78, 0x41, 0xe3, 0x40, 0x9a, 0x1a, 0xe9, 0x02, 0x6c, 0x0f, 0x37, 0x75, 0x02, 0x90, 0x7d, 0xd8, + 0xcd, 0x3b, 0x93, 0x9f, 0x74, 0xa8, 0xab, 0x8d, 0xc9, 0x67, 0xf9, 0xa0, 0x57, 0x39, 0x30, 0x8b, + 0x6b, 0xff, 0xf8, 0x15, 0x34, 0x75, 0xe2, 0x81, 0x4e, 0x1e, 0x67, 0x1f, 0x6c, 0xe5, 0x10, 0xb9, + 0x57, 0x95, 0x95, 0x02, 0xdf, 0xef, 0xdf, 0x46, 0xe5, 0xdb, 0x9c, 0xdd, 0xbf, 0xfa, 0x7b, 0xa0, + 0x5d, 0x5d, 0x0f, 0xf4, 0x97, 0xd7, 0x03, 0xfd, 0xaf, 0xeb, 0x81, 0xfe, 0xf3, 0xcd, 0x40, 0x7b, + 0x79, 0x33, 0xd0, 0xfe, 0xb8, 0x19, 0x68, 0xdf, 0x1d, 0x66, 0xbf, 0x27, 0xf3, 0x86, 0xfa, 0x4b, + 0xf8, 0xe4, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x44, 0xb0, 0xce, 0xba, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -672,6 +741,39 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "api/query/querypb/query.proto", } +func (m *QueryStats) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryStats) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryStats) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PeakSamples != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.PeakSamples)) + i-- + dAtA[i] = 0x10 + } + if m.SamplesTotal != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SamplesTotal)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *QueryRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -908,6 +1010,27 @@ func (m *QueryResponse_Timeseries) MarshalToSizedBuffer(dAtA []byte) (int, error } return len(dAtA) - i, nil } +func (m *QueryResponse_Stats) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryResponse_Stats) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Stats != nil { + { + size, err := m.Stats.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func (m *QueryPlan) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1167,6 +1290,27 @@ func (m *QueryRangeResponse_Timeseries) MarshalToSizedBuffer(dAtA []byte) (int, } return len(dAtA) - i, nil } +func (m *QueryRangeResponse_Stats) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRangeResponse_Stats) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Stats != nil { + { + size, err := m.Stats.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1178,6 +1322,21 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QueryStats) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SamplesTotal != 0 { + n += 1 + sovQuery(uint64(m.SamplesTotal)) + } + if m.PeakSamples != 0 { + n += 1 + sovQuery(uint64(m.PeakSamples)) + } + return n +} + func (m *QueryRequest) Size() (n int) { if m == nil { return 0 @@ -1284,6 +1443,18 @@ func (m *QueryResponse_Timeseries) Size() (n int) { } return n } +func (m *QueryResponse_Stats) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Stats != nil { + l = m.Stats.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} func (m *QueryPlan) Size() (n int) { if m == nil { return 0 @@ -1405,6 +1576,18 @@ func (m *QueryRangeResponse_Timeseries) Size() (n int) { } return n } +func (m *QueryRangeResponse_Stats) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Stats != nil { + l = m.Stats.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 @@ -1412,6 +1595,94 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *QueryStats) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryStats: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryStats: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SamplesTotal", wireType) + } + m.SamplesTotal = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SamplesTotal |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PeakSamples", wireType) + } + m.PeakSamples = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PeakSamples |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1967,6 +2238,41 @@ func (m *QueryResponse) Unmarshal(dAtA []byte) error { } m.Result = &QueryResponse_Timeseries{v} iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &QueryStats{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Result = &QueryResponse_Stats{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2580,6 +2886,41 @@ func (m *QueryRangeResponse) Unmarshal(dAtA []byte) error { } m.Result = &QueryRangeResponse_Timeseries{v} iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &QueryStats{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Result = &QueryRangeResponse_Stats{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/pkg/api/query/querypb/query.proto b/pkg/api/query/querypb/query.proto index d6b5e4628f..6a55365a1b 100644 --- a/pkg/api/query/querypb/query.proto +++ b/pkg/api/query/querypb/query.proto @@ -28,6 +28,11 @@ enum EngineType { thanos = 2; } +message QueryStats { + int64 samples_total = 1; + int64 peak_samples = 2; +} + message QueryRequest { string query = 1; queryPlan queryPlan = 14; @@ -63,6 +68,9 @@ message QueryResponse { /// timeseries is one series from the result of the executed query. prometheus_copy.TimeSeries timeseries = 2; + + // performance stats + QueryStats stats = 3; } } @@ -105,6 +113,9 @@ message QueryRangeResponse { /// timeseries is one series from the result of the executed query. prometheus_copy.TimeSeries timeseries = 2; + + // performance stats + QueryStats stats = 3; } } diff --git a/pkg/api/query/querypb/responses.go b/pkg/api/query/querypb/responses.go index 7ade9c361c..eda01ca3d0 100644 --- a/pkg/api/query/querypb/responses.go +++ b/pkg/api/query/querypb/responses.go @@ -17,6 +17,14 @@ func NewQueryResponse(series *prompb.TimeSeries) *QueryResponse { } } +func NewQueryStatsResponse(stats *QueryStats) *QueryResponse { + return &QueryResponse{ + Result: &QueryResponse_Stats{ + Stats: stats, + }, + } +} + func NewQueryWarningsResponse(errs ...error) *QueryResponse { warnings := make([]string, 0, len(errs)) for _, err := range errs { @@ -37,6 +45,14 @@ func NewQueryRangeResponse(series *prompb.TimeSeries) *QueryRangeResponse { } } +func NewQueryRangeStatsResponse(stats *QueryStats) *QueryRangeResponse { + return &QueryRangeResponse{ + Result: &QueryRangeResponse_Stats{ + Stats: stats, + }, + } +} + func NewQueryRangeWarningsResponse(errs ...error) *QueryRangeResponse { warnings := make([]string, 0, len(errs)) for _, err := range errs { diff --git a/pkg/api/query/v1.go b/pkg/api/query/v1.go index a74be4637a..b0b9c6d708 100644 --- a/pkg/api/query/v1.go +++ b/pkg/api/query/v1.go @@ -52,6 +52,7 @@ import ( "github.com/thanos-io/thanos/pkg/exemplars" "github.com/thanos-io/thanos/pkg/exemplars/exemplarspb" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/gate" "github.com/thanos-io/thanos/pkg/logging" "github.com/thanos-io/thanos/pkg/metadata" @@ -121,13 +122,19 @@ func (f *QueryEngineFactory) GetPrometheusEngine() promql.QueryEngine { func (f *QueryEngineFactory) GetThanosEngine() ThanosEngine { f.createThanosEngine.Do(func() { + opts := engine.Opts{ + EngineOpts: f.engineOpts, + Engine: f.GetPrometheusEngine(), + EnableAnalysis: true, + EnableXFunctions: f.enableXFunctions, + } if f.thanosEngine != nil { return } if f.remoteEngineEndpoints == nil { - f.thanosEngine = engine.New(engine.Opts{EngineOpts: f.engineOpts, Engine: f.GetPrometheusEngine(), EnableAnalysis: true, EnableXFunctions: f.enableXFunctions}) + f.thanosEngine = engine.New(opts) } else { - f.thanosEngine = engine.NewDistributedEngine(engine.Opts{EngineOpts: f.engineOpts, Engine: f.GetPrometheusEngine(), EnableAnalysis: true}, f.remoteEngineEndpoints) + f.thanosEngine = engine.NewDistributedEngine(opts, f.remoteEngineEndpoints) } }) @@ -369,7 +376,7 @@ func (qapi *QueryAPI) parseStoreDebugMatchersParam(r *http.Request) (storeMatche } for _, s := range r.Form[StoreMatcherParam] { - matchers, err := parser.ParseMetricSelector(s) + matchers, err := extpromql.ParseMetricSelector(s) if err != nil { return nil, &api.ApiError{Typ: api.ErrorBadData, Err: err} } @@ -662,45 +669,48 @@ func (qapi *QueryAPI) query(r *http.Request) (interface{}, []error, *api.ApiErro return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {} } - // We are starting promQL tracing span here, because we have no control over promQL code. - span, ctx := tracing.StartSpan(ctx, "promql_instant_query") - defer span.Finish() - - var seriesStats []storepb.SeriesStatsCounter - qry, err := engine.NewInstantQuery( - ctx, - qapi.queryableCreate( - enableDedup, - replicaLabels, - storeDebugMatchers, - maxSourceResolution, - enablePartialResponse, - false, - shardInfo, - query.NewAggregateStatsReporter(&seriesStats), - ), - promql.NewPrometheusQueryOpts(false, lookbackDelta), - queryStr, - ts, + var ( + qry promql.Query + seriesStats []storepb.SeriesStatsCounter ) - - if err != nil { + if err := tracing.DoInSpanWithErr(ctx, "instant_query_create", func(ctx context.Context) error { + var err error + qry, err = engine.NewInstantQuery( + ctx, + qapi.queryableCreate( + enableDedup, + replicaLabels, + storeDebugMatchers, + maxSourceResolution, + enablePartialResponse, + false, + shardInfo, + query.NewAggregateStatsReporter(&seriesStats), + ), + promql.NewPrometheusQueryOpts(false, lookbackDelta), + queryStr, + ts, + ) + return err + }); err != nil { return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {} } - res := qry.Exec(ctx) + analysis, err := qapi.parseQueryAnalyzeParam(r, qry) if err != nil { return nil, nil, apiErr, func() {} } - tracing.DoInSpan(ctx, "query_gate_ismyturn", func(ctx context.Context) { - err = qapi.gate.Start(ctx) - }) - if err != nil { + if err := tracing.DoInSpanWithErr(ctx, "query_gate_ismyturn", qapi.gate.Start); err != nil { return nil, nil, &api.ApiError{Typ: api.ErrorExec, Err: err}, qry.Close } defer qapi.gate.Done() beforeRange := time.Now() + + var res *promql.Result + tracing.DoInSpan(ctx, "instant_query_exec", func(ctx context.Context) { + res = qry.Exec(ctx) + }) if res.Err != nil { switch res.Err.(type) { case promql.ErrQueryCanceled: @@ -962,48 +972,49 @@ func (qapi *QueryAPI) queryRange(r *http.Request) (interface{}, []error, *api.Ap // Record the query range requested. qapi.queryRangeHist.Observe(end.Sub(start).Seconds()) - // We are starting promQL tracing span here, because we have no control over promQL code. - span, ctx := tracing.StartSpan(ctx, "promql_range_query") - defer span.Finish() - - var seriesStats []storepb.SeriesStatsCounter - qry, err := engine.NewRangeQuery( - ctx, - qapi.queryableCreate( - enableDedup, - replicaLabels, - storeDebugMatchers, - maxSourceResolution, - enablePartialResponse, - false, - shardInfo, - query.NewAggregateStatsReporter(&seriesStats), - ), - promql.NewPrometheusQueryOpts(false, lookbackDelta), - queryStr, - start, - end, - step, + var ( + qry promql.Query + seriesStats []storepb.SeriesStatsCounter ) - if err != nil { + if err := tracing.DoInSpanWithErr(ctx, "range_query_create", func(ctx context.Context) error { + var err error + qry, err = engine.NewRangeQuery( + ctx, + qapi.queryableCreate( + enableDedup, + replicaLabels, + storeDebugMatchers, + maxSourceResolution, + enablePartialResponse, + false, + shardInfo, + query.NewAggregateStatsReporter(&seriesStats), + ), + promql.NewPrometheusQueryOpts(false, lookbackDelta), + queryStr, + start, + end, + step, + ) + return err + }); err != nil { return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {} } - - res := qry.Exec(ctx) - analysis, err := qapi.parseQueryAnalyzeParam(r, qry) if err != nil { return nil, nil, apiErr, func() {} } - tracing.DoInSpan(ctx, "query_gate_ismyturn", func(ctx context.Context) { - err = qapi.gate.Start(ctx) - }) - if err != nil { + if err := tracing.DoInSpanWithErr(ctx, "query_gate_ismyturn", qapi.gate.Start); err != nil { return nil, nil, &api.ApiError{Typ: api.ErrorExec, Err: err}, qry.Close } defer qapi.gate.Done() + var res *promql.Result + tracing.DoInSpan(ctx, "range_query_exec", func(ctx context.Context) { + res = qry.Exec(ctx) + + }) beforeRange := time.Now() if res.Err != nil { switch res.Err.(type) { diff --git a/pkg/block/fetcher.go b/pkg/block/fetcher.go index 62b52a8f16..d5406ae52a 100644 --- a/pkg/block/fetcher.go +++ b/pkg/block/fetcher.go @@ -638,8 +638,6 @@ func (f *BaseFetcher) fetch(ctx context.Context, metrics *FetcherMetrics, filter metrics.SyncFailures.Inc() } }() - metrics.Syncs.Inc() - metrics.ResetTx() // Run this in thread safe run group. // TODO(bwplotka): Consider custom singleflight with ttl. @@ -684,7 +682,6 @@ func (f *BaseFetcher) fetch(ctx context.Context, metrics *FetcherMetrics, filter } metrics.Synced.WithLabelValues(LoadedMeta).Set(float64(len(metas))) - metrics.Submit() if len(resp.metaErrs) > 0 { return metas, resp.partial, errors.Wrap(resp.metaErrs.Err(), "incomplete view") @@ -717,6 +714,9 @@ type MetaFetcher struct { // // Returned error indicates a failure in fetching metadata. Returned meta can be assumed as correct, with some blocks missing. func (f *MetaFetcher) Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) { + f.metrics.Syncs.Inc() + f.metrics.ResetTx() + metas, partial, err = f.wrapped.fetch(ctx, f.metrics, f.filters) if f.listener != nil { blocks := make([]metadata.Meta, 0, len(metas)) @@ -725,6 +725,8 @@ func (f *MetaFetcher) Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata. } f.listener(blocks, err) } + + f.metrics.Submit() return metas, partial, err } diff --git a/pkg/block/indexheader/binary_reader.go b/pkg/block/indexheader/binary_reader.go index c86185bfbf..1afaabb786 100644 --- a/pkg/block/indexheader/binary_reader.go +++ b/pkg/block/indexheader/binary_reader.go @@ -875,6 +875,7 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra // Iterate on the offset table. newSameRngs = newSameRngs[:0] + Iter: for d.Err() == nil { // Posting format entry is as follows: // │ ┌────────────────────────────────────────┐ │ @@ -916,6 +917,15 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra break } wantedValue = values[valueIndex] + // Only do this if there is no new range added. If there is an existing + // range we want to continue iterating the offset table to get the end. + if len(newSameRngs) == 0 && i+1 < len(e.offsets) { + // We want to limit this loop within e.offsets[i, i+1). So when the wanted value + // is >= e.offsets[i+1], go out of the loop and binary search again. + if wantedValue >= e.offsets[i+1].value { + break Iter + } + } } if i+1 == len(e.offsets) { @@ -942,7 +952,7 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra if len(newSameRngs) > 0 { // We added some ranges in this iteration. Use next posting offset as the end of our ranges. - // We know it exists as we never go further in this loop than e.offsets[i, i+1]. + // We know it exists as we never go further in this loop than e.offsets[i, i+1). skipNAndName(&d, &buf) d.UvarintBytes() // Label value. diff --git a/pkg/block/indexheader/header_test.go b/pkg/block/indexheader/header_test.go index 4130157a96..b94a857f64 100644 --- a/pkg/block/indexheader/header_test.go +++ b/pkg/block/indexheader/header_test.go @@ -7,9 +7,12 @@ import ( "context" "fmt" "math" + "math/rand" "path/filepath" + "sort" "strconv" "testing" + "time" "github.com/go-kit/log" "github.com/oklog/ulid" @@ -18,6 +21,7 @@ import ( "github.com/prometheus/prometheus/tsdb/encoding" "github.com/prometheus/prometheus/tsdb/fileutil" "github.com/prometheus/prometheus/tsdb/index" + "github.com/stretchr/testify/require" "github.com/thanos-io/objstore" "github.com/thanos-io/objstore/providers/filesystem" @@ -38,22 +42,25 @@ func TestReaders(t *testing.T) { // Create block index version 2. id1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, - {{Name: "a", Value: "5"}}, - {{Name: "a", Value: "6"}}, - {{Name: "a", Value: "7"}}, - {{Name: "a", Value: "8"}}, - {{Name: "a", Value: "9"}}, + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), + labels.FromStrings("a", "5"), + labels.FromStrings("a", "6"), + labels.FromStrings("a", "7"), + labels.FromStrings("a", "8"), + labels.FromStrings("a", "9"), // Missing 10 on purpose. - {{Name: "a", Value: "11"}}, - {{Name: "a", Value: "12"}}, - {{Name: "a", Value: "13"}}, - {{Name: "a", Value: "1"}, {Name: "longer-string", Value: "1"}}, - {{Name: "a", Value: "1"}, {Name: "longer-string", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "11"), + labels.FromStrings("a", "12"), + labels.FromStrings("a", "13"), + labels.FromStrings("a", "1", "longer-string", "1"), + labels.FromStrings("a", "1", "longer-string", "2"), + labels.FromStrings("cluster", "a-eu-west-1"), + labels.FromStrings("cluster", "b-eu-west-1"), + labels.FromStrings("cluster", "c-eu-west-1"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, id1.String()), metadata.NoneFunc)) @@ -80,7 +87,7 @@ func TestReaders(t *testing.T) { e2eutil.Copy(t, "./testdata/index_format_v1", filepath.Join(tmpDir, m.ULID.String())) _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, m.ULID.String()), metadata.Thanos{ - Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), + Labels: labels.FromStrings("ext1", "1").Map(), Downsample: metadata.ThanosDownsample{Resolution: 0}, Source: metadata.TestSource, }, &m.BlockMeta) @@ -108,15 +115,15 @@ func TestReaders(t *testing.T) { if id == id1 { testutil.Equals(t, 1, br.version) testutil.Equals(t, 2, br.indexVersion) - testutil.Equals(t, &BinaryTOC{Symbols: headerLen, PostingsOffsetTable: 70}, br.toc) - testutil.Equals(t, int64(710), br.indexLastPostingEnd) + testutil.Equals(t, &BinaryTOC{Symbols: headerLen, PostingsOffsetTable: 114}, br.toc) + testutil.Equals(t, int64(905), br.indexLastPostingEnd) testutil.Equals(t, 8, br.symbols.Size()) testutil.Equals(t, 0, len(br.postingsV1)) - testutil.Equals(t, 2, len(br.nameSymbols)) + testutil.Equals(t, 3, len(br.nameSymbols)) testutil.Equals(t, map[string]*postingValueOffsets{ "": { offsets: []postingOffset{{value: "", tableOff: 4}}, - lastValOffset: 440, + lastValOffset: 576, }, "a": { offsets: []postingOffset{ @@ -126,14 +133,21 @@ func TestReaders(t *testing.T) { {value: "7", tableOff: 75}, {value: "9", tableOff: 89}, }, - lastValOffset: 640, + lastValOffset: 776, + }, + "cluster": { + offsets: []postingOffset{ + {value: "a-eu-west-1", tableOff: 96}, + {value: "c-eu-west-1", tableOff: 142}, + }, + lastValOffset: 824, }, "longer-string": { offsets: []postingOffset{ - {value: "1", tableOff: 96}, - {value: "2", tableOff: 115}, + {value: "1", tableOff: 165}, + {value: "2", tableOff: 184}, }, - lastValOffset: 706, + lastValOffset: 901, }, }, br.postings) @@ -173,6 +187,17 @@ func TestReaders(t *testing.T) { testutil.Assert(t, rngs[2].End > rngs[2].Start) testutil.Equals(t, NotFoundRange, rngs[1]) + // 3 values exist and 3 values don't exist. + rngs, err = br.PostingsOffsets("cluster", "a-eu-west-1", "a-us-west-2", "b-eu-west-1", "b-us-east-1", "c-eu-west-1", "c-us-east-2") + testutil.Ok(t, err) + for i := 0; i < len(rngs); i++ { + if i%2 == 0 { + testutil.Assert(t, rngs[i].End > rngs[i].Start) + } else { + testutil.Equals(t, NotFoundRange, rngs[i]) + } + } + // Regression tests for https://github.com/thanos-io/thanos/issues/2213. // Most of not existing value was working despite bug, except in certain unlucky cases // it was causing "invalid size" errors. @@ -356,7 +381,7 @@ func prepareIndexV2Block(t testing.TB, tmpDir string, bkt objstore.Bucket) *meta e2eutil.Copy(t, "./testdata/index_format_v2", filepath.Join(tmpDir, m.ULID.String())) _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, m.ULID.String()), metadata.Thanos{ - Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), + Labels: labels.FromStrings("ext1", "1").Map(), Downsample: metadata.ThanosDownsample{Resolution: 0}, Source: metadata.TestSource, }, &m.BlockMeta) @@ -428,11 +453,11 @@ func benchmarkBinaryReaderLookupSymbol(b *testing.B, numSeries int) { // Generate series labels. seriesLabels := make([]labels.Labels, 0, numSeries) for i := 0; i < numSeries; i++ { - seriesLabels = append(seriesLabels, labels.Labels{{Name: "a", Value: strconv.Itoa(i)}}) + seriesLabels = append(seriesLabels, labels.FromStrings("a", strconv.Itoa(i))) } // Create a block. - id1, err := e2eutil.CreateBlock(ctx, tmpDir, seriesLabels, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + id1, err := e2eutil.CreateBlock(ctx, tmpDir, seriesLabels, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(b, err) testutil.Ok(b, block.Upload(ctx, logger, bkt, filepath.Join(tmpDir, id1.String()), metadata.NoneFunc)) @@ -521,3 +546,82 @@ func readSymbols(bs index.ByteSlice, version, off int) ([]string, map[uint32]str } return symbolSlice, symbols, errors.Wrap(d.Err(), "read symbols") } + +// The idea of this test case is to make sure that reader.PostingsOffsets and +// reader.PostingsOffset get the same index ranges for required label values. +func TestReaderPostingsOffsets(t *testing.T) { + ctx := context.Background() + + tmpDir := t.TempDir() + + possibleClusters := []string{"us-west-2", "us-east-1", "us-east-2", "eu-west-1", "eu-central-1", "ap-southeast-1", "ap-south-1"} + possiblePrefixes := []string{"a", "b", "c", "d", "1", "2", "3", "4"} + totalValues := []string{} + for i := 0; i < len(possibleClusters); i++ { + for j := 0; j < len(possiblePrefixes); j++ { + totalValues = append(totalValues, fmt.Sprintf("%s-%s", possiblePrefixes[j], possibleClusters[i])) + } + } + + rnd := rand.New(rand.NewSource(time.Now().Unix())) + // Pick 5 label values to be used in the block. + clusterLbls := make([]labels.Labels, 0) + valueSet := map[int]struct{}{} + for i := 0; i < 5; { + idx := rnd.Intn(len(totalValues)) + if _, ok := valueSet[idx]; ok { + continue + } + valueSet[idx] = struct{}{} + clusterLbls = append(clusterLbls, labels.FromStrings("cluster", totalValues[idx])) + i++ + } + + // Add additional labels. + lbls := append([]labels.Labels{ + labels.FromStrings("job", "1"), + labels.FromStrings("job", "2"), + labels.FromStrings("job", "3"), + labels.FromStrings("job", "4"), + labels.FromStrings("job", "5"), + labels.FromStrings("job", "6"), + labels.FromStrings("job", "7"), + labels.FromStrings("job", "8"), + labels.FromStrings("job", "9")}, clusterLbls...) + bkt, err := filesystem.NewBucket(filepath.Join(tmpDir, "bkt")) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, bkt.Close()) }() + id, err := e2eutil.CreateBlock(ctx, tmpDir, lbls, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) + testutil.Ok(t, err) + + testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, id.String()), metadata.NoneFunc)) + + fn := filepath.Join(tmpDir, id.String(), block.IndexHeaderFilename) + _, err = WriteBinary(ctx, bkt, id, fn) + testutil.Ok(t, err) + + br, err := NewBinaryReader(ctx, log.NewNopLogger(), nil, tmpDir, id, 3, NewBinaryReaderMetrics(nil)) + testutil.Ok(t, err) + + defer func() { testutil.Ok(t, br.Close()) }() + + for i := 0; i < 100; i++ { + vals := make([]string, 0, 15) + for j := 0; j < 15; j++ { + vals = append(vals, totalValues[rnd.Intn(len(totalValues))]) + } + sort.Strings(vals) + rngs, err := br.PostingsOffsets("cluster", vals...) + require.NoError(t, err) + rngs2 := make([]index.Range, 0) + for _, val := range vals { + rng2, err2 := br.PostingsOffset("cluster", val) + if err2 == NotFoundRangeErr { + rngs2 = append(rngs2, NotFoundRange) + } else { + rngs2 = append(rngs2, rng2) + } + } + require.Equal(t, rngs2, rngs, "Got mismatched results from batched and non-batched API.\nInput cluster labels: %v.\nValues queried: %v", clusterLbls, vals) + } +} diff --git a/pkg/block/indexheader/lazy_binary_reader_test.go b/pkg/block/indexheader/lazy_binary_reader_test.go index d740da99ab..73c47f06fe 100644 --- a/pkg/block/indexheader/lazy_binary_reader_test.go +++ b/pkg/block/indexheader/lazy_binary_reader_test.go @@ -61,9 +61,9 @@ func TestNewLazyBinaryReader_ShouldBuildIndexHeaderFromBucket(t *testing.T) { t.Run(fmt.Sprintf("lazyDownload=%v", lazyDownload), func(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) @@ -112,9 +112,9 @@ func TestNewLazyBinaryReader_ShouldRebuildCorruptedIndexHeader(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) @@ -155,9 +155,9 @@ func TestLazyBinaryReader_ShouldReopenOnUsageAfterClose(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) @@ -210,9 +210,9 @@ func TestLazyBinaryReader_unload_ShouldReturnErrorIfNotIdle(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) @@ -264,9 +264,9 @@ func TestLazyBinaryReader_LoadUnloadRaceCondition(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) diff --git a/pkg/block/indexheader/reader_pool_test.go b/pkg/block/indexheader/reader_pool_test.go index a7445f0fed..331d218724 100644 --- a/pkg/block/indexheader/reader_pool_test.go +++ b/pkg/block/indexheader/reader_pool_test.go @@ -48,9 +48,9 @@ func TestReaderPool_NewBinaryReader(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) @@ -87,9 +87,9 @@ func TestReaderPool_ShouldCloseIdleLazyReaders(t *testing.T) { // Create block. blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}}, - }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, 100, 0, 1000, labels.FromStrings("ext1", "1"), 124, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) meta, err := metadata.ReadFromDir(filepath.Join(tmpDir, blockID.String())) diff --git a/pkg/block/metadata/markers.go b/pkg/block/metadata/markers.go index 83273eb343..0a351a5fab 100644 --- a/pkg/block/metadata/markers.go +++ b/pkg/block/metadata/markers.go @@ -79,6 +79,8 @@ const ( IndexSizeExceedingNoCompactReason = "index-size-exceeding" // OutOfOrderChunksNoCompactReason is a reason of to no compact block with index contains out of order chunk so that the compaction is not blocked. OutOfOrderChunksNoCompactReason = "block-index-out-of-order-chunk" + // DownsampleVerticalCompactionNoCompactReason is a reason to not compact overlapping downsampled blocks as it does not make sense e.g. how to vertically compact the average. + DownsampleVerticalCompactionNoCompactReason = "downsample-vertical-compaction" ) // NoCompactMark marker stores reason of block being excluded from compaction if needed. diff --git a/pkg/block/metadata/meta.go b/pkg/block/metadata/meta.go index 2a2829b6b4..25924a5acf 100644 --- a/pkg/block/metadata/meta.go +++ b/pkg/block/metadata/meta.go @@ -22,12 +22,12 @@ import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" - "github.com/prometheus/prometheus/promql/parser" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/fileutil" "github.com/prometheus/prometheus/tsdb/tombstones" "gopkg.in/yaml.v3" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/runutil" ) @@ -161,7 +161,7 @@ type Rewrite struct { type Matchers []*labels.Matcher func (m *Matchers) UnmarshalYAML(value *yaml.Node) (err error) { - *m, err = parser.ParseMetricSelector(value.Value) + *m, err = extpromql.ParseMetricSelector(value.Value) if err != nil { return errors.Wrapf(err, "parse metric selector %v", value.Value) } diff --git a/pkg/cacheutil/memcached_client_test.go b/pkg/cacheutil/memcached_client_test.go index cac450ef9e..4951075720 100644 --- a/pkg/cacheutil/memcached_client_test.go +++ b/pkg/cacheutil/memcached_client_test.go @@ -13,15 +13,15 @@ import ( "time" "github.com/bradfitz/gomemcache/memcache" + "github.com/efficientgo/core/testutil" "github.com/go-kit/log" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" "github.com/sony/gobreaker" + "github.com/stretchr/testify/require" "go.uber.org/atomic" - "github.com/efficientgo/core/testutil" - "github.com/thanos-io/thanos/pkg/gate" "github.com/thanos-io/thanos/pkg/model" ) @@ -726,7 +726,7 @@ func TestMemcachedClient_SetAsync_CircuitBreaker(t *testing.T) { config := defaultMemcachedClientConfig config.Addresses = []string{"127.0.0.1:11211"} config.SetAsyncCircuitBreaker.Enabled = true - config.SetAsyncCircuitBreaker.OpenDuration = 2 * time.Millisecond + config.SetAsyncCircuitBreaker.OpenDuration = 10 * time.Millisecond config.SetAsyncCircuitBreaker.HalfOpenMaxRequests = 100 config.SetAsyncCircuitBreaker.MinRequests = testdata.minRequests config.SetAsyncCircuitBreaker.ConsecutiveFailures = testdata.consecutiveFailures @@ -750,7 +750,10 @@ func TestMemcachedClient_SetAsync_CircuitBreaker(t *testing.T) { // Trigger the state transaction. time.Sleep(time.Millisecond) testutil.Ok(t, client.SetAsync(strconv.Itoa(testdata.setErrors), []byte("value"), time.Second)) - testutil.Equals(t, gobreaker.StateOpen, cbimpl.State(), "state should be open") + + require.Eventuallyf(t, func() bool { + return cbimpl.State() == gobreaker.StateOpen + }, 2*time.Second, time.Millisecond, "circuit breaker did not open") time.Sleep(config.SetAsyncCircuitBreaker.OpenDuration) for i := testdata.setErrors; i < testdata.setErrors+10; i++ { diff --git a/pkg/clientconfig/http.go b/pkg/clientconfig/http.go index 1198ad7903..69f2baf165 100644 --- a/pkg/clientconfig/http.go +++ b/pkg/clientconfig/http.go @@ -162,21 +162,28 @@ func NewRoundTripperFromConfig(cfg config_util.HTTPClientConfig, transportConfig // If an authorization_credentials is provided, create a round tripper that will set the // Authorization header correctly on each request. if cfg.Authorization != nil && len(cfg.Authorization.Credentials) > 0 { - rt = config_util.NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, cfg.Authorization.Credentials, rt) + rt = config_util.NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, config_util.NewInlineSecret(string(cfg.Authorization.Credentials)), rt) } else if cfg.Authorization != nil && len(cfg.Authorization.CredentialsFile) > 0 { - rt = config_util.NewAuthorizationCredentialsFileRoundTripper(cfg.Authorization.Type, cfg.Authorization.CredentialsFile, rt) + rt = config_util.NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, config_util.NewFileSecret(cfg.Authorization.CredentialsFile), rt) } // Backwards compatibility, be nice with importers who would not have // called Validate(). if len(cfg.BearerToken) > 0 { - rt = config_util.NewAuthorizationCredentialsRoundTripper("Bearer", cfg.BearerToken, rt) + rt = config_util.NewAuthorizationCredentialsRoundTripper("Bearer", config_util.NewInlineSecret(string(cfg.BearerToken)), rt) } else if len(cfg.BearerTokenFile) > 0 { - rt = config_util.NewAuthorizationCredentialsFileRoundTripper("Bearer", cfg.BearerTokenFile, rt) + rt = config_util.NewAuthorizationCredentialsRoundTripper("Bearer", config_util.NewFileSecret(cfg.BearerTokenFile), rt) } if cfg.BasicAuth != nil { // TODO(yeya24): expose UsernameFile as a config. - rt = config_util.NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, "", cfg.BasicAuth.PasswordFile, rt) + username := config_util.NewInlineSecret(cfg.BasicAuth.Username) + var password config_util.SecretReader + if len(cfg.BasicAuth.PasswordFile) > 0 { + password = config_util.NewFileSecret(cfg.BasicAuth.PasswordFile) + } else { + password = config_util.NewInlineSecret(string(cfg.BasicAuth.Password)) + } + rt = config_util.NewBasicAuthRoundTripper(username, password, rt) } // Return a new configured RoundTripper. return rt, nil @@ -192,11 +199,18 @@ func NewRoundTripperFromConfig(cfg config_util.HTTPClientConfig, transportConfig return newRT(tlsConfig) } - return config_util.NewTLSRoundTripper(tlsConfig, config_util.TLSRoundTripperSettings{ - CAFile: cfg.TLSConfig.CAFile, - CertFile: cfg.TLSConfig.CertFile, - KeyFile: cfg.TLSConfig.KeyFile, - }, newRT) + rtConfig := config_util.TLSRoundTripperSettings{ + Cert: config_util.NewFileSecret(cfg.TLSConfig.CAFile), + } + if len(cfg.TLSConfig.CertFile) > 0 { + rtConfig.Cert = config_util.NewFileSecret(cfg.TLSConfig.CertFile) + } + + if len(cfg.TLSConfig.KeyFile) > 0 { + rtConfig.Key = config_util.NewFileSecret(cfg.TLSConfig.KeyFile) + } + + return config_util.NewTLSRoundTripper(tlsConfig, rtConfig, newRT) } // NewHTTPClient returns a new HTTP client. diff --git a/pkg/clientconfig/http_test.go b/pkg/clientconfig/http_test.go new file mode 100644 index 0000000000..eb1296da9d --- /dev/null +++ b/pkg/clientconfig/http_test.go @@ -0,0 +1,95 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package clientconfig + +import ( + "testing" + + "github.com/efficientgo/core/testutil" +) + +func TestNewHTTPClientConfigFromYAML(t *testing.T) { + for _, tc := range []struct { + desc string + cfg HTTPClientConfig + err bool + }{ + { + desc: "empty string", + cfg: HTTPClientConfig{}, + err: false, + }, + { + desc: "missing CA file", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "xxx", + }, + }, + err: true, + }, + { + desc: "invalid CA file", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "testdata/invalid.pem", + }, + }, + err: true, + }, + { + desc: "valid CA file", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "testdata/tls-ca-chain.pem", + }, + }, + err: false, + }, + { + desc: "invalid cert file", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "testdata/tls-ca-chain.pem", + CertFile: "testdata/invalid.pem", + KeyFile: "testdata/self-signed-client.key", + }, + }, + err: true, + }, + { + desc: "invalid key file", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "testdata/tls-ca-chain.pem", + CertFile: "testdata/self-signed-client.crt", + KeyFile: "testdata/invalid.pem", + }, + }, + err: true, + }, + { + desc: "valid CA, cert and key files", + cfg: HTTPClientConfig{ + TLSConfig: TLSConfig{ + CAFile: "testdata/tls-ca-chain.pem", + CertFile: "testdata/self-signed-client.crt", + KeyFile: "testdata/self-signed-client.key", + }, + }, + err: false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + _, err := NewHTTPClient(tc.cfg, "") + if tc.err { + t.Logf("err: %v", err) + testutil.NotOk(t, err) + return + } + + testutil.Ok(t, err) + }) + } +} diff --git a/pkg/clientconfig/testdata/invalid.pem b/pkg/clientconfig/testdata/invalid.pem new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/clientconfig/testdata/self-signed-client.crt b/pkg/clientconfig/testdata/self-signed-client.crt new file mode 100644 index 0000000000..a0a5cdc6ac --- /dev/null +++ b/pkg/clientconfig/testdata/self-signed-client.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFLjCCAxagAwIBAgIRAMMSh5NoexSCjSvDRf1fpgUwDQYJKoZIhvcNAQELBQAw +NjELMAkGA1UEBhMCVVMxEzARBgNVBAoTClByb21ldGhldXMxEjAQBgNVBAMTCWxv +Y2FsaG9zdDAgFw0yMjA3MDgwOTE1MDlaGA8yMDcyMDYyNTA5MTUwOVowNjELMAkG +A1UEBhMCVVMxEzARBgNVBAoTClByb21ldGhldXMxEjAQBgNVBAMTCWxvY2FsaG9z +dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALtrXxnHr7eUM7Xh7awY +LwompmuznbTa/8+OsihSaelUN6RDsAdm7eOMA7KMqZB5NOfeDqEqMIUoaoQ1gzIm +0BJ4dCgi99SnA8b0MjAGqUpRJ3gLLSXsPa5647gxUSP5zQ0hWMMgGaw4rJ9LDOtU +z2S8dtqKTHrXl34mpdsLrZyLXwyz8UJ83Jq2Ngx4cApZrbs+g1XlMRV8Vh89Z2bk +bbKmDYmIOhTeE1wLdrZ/XecEOvkGZcj3bWiO/yTnP8mTER2hTvSxUrpyHn/55LkU +8PR6wCO7hntZ9LLWxg85XTRdWL7cIyjgJgfL9+hVQQyNEjWC2+LTq1QExqa+IxoH +iL4xX/1y+6o1W5XKLf/uplgaWuSK+mjQeqc387DwYbj61QWOjCoaJA1wl6RHuGGV +6ygpdAO1l8o+2U8nuULHW5lx+1BtMG5ytAXy9dWPercs5L8gh1IRNCVXWKsQCCWg +iG67nErFV5iRFLuAIX7ixLKJ5MGp/fVKUI9V1EViM2GUU46PVAPhhlZ1qcygjbZ5 +CelBnQ/XvGof5b4zm4eEgCc0ZkqsQDeS5jPjTtES8/y5WEKqbyijmvx2P40nuO/d +aTxNretMwaptWzu+WXHih0WG2Sq85m41070xsIMEwlqSfdiOOPdax6393NJgkdM7 +5NKC3+pzcHK1S1+x/Guawv0NAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFIDATBgNV +HSUEDDAKBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC +AQBTLnU8jFCmYpPUBOqj/xzBqokiQK92axG/h/3JgB7fFSLzUCV3NtvwBVCU28rA +wHwBYPjmGhi1vyHha/hb6V2WMPt0jhMRpNxCf16dAMoyIoWNas88vU2Mef90Chfj +8e6wLtzqAquX/ruwIfsOMnbcSGuh+y54DspCXgsTZ9cnCI2lnQroXZi4WUqi3Enj +mFPpVc+mMlffGW6LISo3ehRLA7k3/01yJhqzpTQw44k9ZfJ7VXZTRJKJsaqeljzV +VfzDbDfW8ftbZ8IWQGAOQfTa23aHIYcvJfvyxpfQRyrwRxjGytLHoOH/G+1TZuOt +KBJ2Xdi9qrr+Wep4eNJm2cTBd1Fpr0hWZ9K27BwwYdZZF8Eu8eP8hSeRmA4PqzAj +HauCl8PgWJIWzMloXVZaGxiYX7sGVs79m/Yl9A6+p8RTpK7DVB9+sDIiD2bhiZqL +i9YWM8aD2cR20t2ZkuBBPlVTOouF/WotOWrLhT4J+SngkdmLkAjP/5jPFvpTfeGi +THyAmp4gigwaM0nIZskPcPCbkk+zFYPToyS49ZJwQMzqK2hkjyQ9LyzUdo9vlDjL +8lFjlUZzqaR0DF3pbf8fs5/16gPurR65SU/ebOs+uxZLYJrP2zKmeISE+q4AMudc +rQ0Z6KmGUiXnIvpB105UJ7jlXCxbsruc8gRTbjkgW7yoXg== +-----END CERTIFICATE----- diff --git a/pkg/clientconfig/testdata/self-signed-client.key b/pkg/clientconfig/testdata/self-signed-client.key new file mode 100644 index 0000000000..4e4b2c2eaf --- /dev/null +++ b/pkg/clientconfig/testdata/self-signed-client.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC7a18Zx6+3lDO1 +4e2sGC8KJqZrs5202v/PjrIoUmnpVDekQ7AHZu3jjAOyjKmQeTTn3g6hKjCFKGqE +NYMyJtASeHQoIvfUpwPG9DIwBqlKUSd4Cy0l7D2ueuO4MVEj+c0NIVjDIBmsOKyf +SwzrVM9kvHbaikx615d+JqXbC62ci18Ms/FCfNyatjYMeHAKWa27PoNV5TEVfFYf +PWdm5G2ypg2JiDoU3hNcC3a2f13nBDr5BmXI921ojv8k5z/JkxEdoU70sVK6ch5/ ++eS5FPD0esAju4Z7WfSy1sYPOV00XVi+3CMo4CYHy/foVUEMjRI1gtvi06tUBMam +viMaB4i+MV/9cvuqNVuVyi3/7qZYGlrkivpo0HqnN/Ow8GG4+tUFjowqGiQNcJek +R7hhlesoKXQDtZfKPtlPJ7lCx1uZcftQbTBucrQF8vXVj3q3LOS/IIdSETQlV1ir +EAgloIhuu5xKxVeYkRS7gCF+4sSyieTBqf31SlCPVdRFYjNhlFOOj1QD4YZWdanM +oI22eQnpQZ0P17xqH+W+M5uHhIAnNGZKrEA3kuYz407REvP8uVhCqm8oo5r8dj+N +J7jv3Wk8Ta3rTMGqbVs7vllx4odFhtkqvOZuNdO9MbCDBMJakn3Yjjj3Wset/dzS +YJHTO+TSgt/qc3BytUtfsfxrmsL9DQIDAQABAoICAAyGlIiIi/nc8cfKHbROuXYY +Ny8jhfq8WDRq+QUw3Ns3QbC8xVr5ShTXGrgoJnz9XMfSU2/5/dwoY1YKrYYAig9x +9XFpRN71eo8lauVCzLWmzth7Br1uGIE8vVNmGGIrI8Uo4WHJF24nK4JJ5cckl+fH +oLniXFIpbnqD4rnNAgFgXy3eKNWkuqmsW9hhhDts2uuUtfpbovgooyjbVbnOsnYq +GuWCMT+LyAdyzLBNutzhr39NKihQQQOn6u1wdxbluVMdoMVBxKGpVth+vwaPm7r7 +KTQ6KDa+QFhjekEyOERzqKa417C3qlMDEsJ4UCyikQD6ie+S7fRjjVM/ieEHd+AA +66CbJ8u3yfXxaicn+SPCeHVKd4GKmJgsg1KDSSg0+w5JWwmAiCJjEydX2HOdx2ys +SV2C4o+gxhA48U8ZgGTVoom0OgouQ7rnMd6n3juBDq2/Xp1FeDcE39yEffN7t4XN +vHfD7Hjp5capxVyEnpzu0tTVf8KP00NJKtS6I7d8IavUBCgFiJZFXJWdsbhgSsg9 +UdypUMd6rW81VaaKvi3JSjWwFpmUVAhr3hFNyQB9+2rxvDCWhUqFKWqjWdPfMgxx +qO6eam1S22vrZcyJVkfTzArFQd0J/41Ak0yErLJKLTDEYaBRxFPV0ujWskrmU96c +f+m4/k7p3sD8KooXfrERAoIBAQDWSmsFzSOugShur9phJV162XrtbOnV7n1Ko0Vu +U/ftohC5FNq0kHxAkY4kGMz2QHdJnqpQoJaCK8pJ+8nA1Osutt31tS3YrOotlNwk +KsFSiy+i9xf4NcOr9xKoSEstFPJeM650xPfVP1p4sq87BB2Z3uWfLtWnRxTJnpA2 +nwwtdrK5fO3pZnVlWQ4akqbndCjUWURXVOVxDHCyDdwoiz3BpGmVV6jCYanC3e3S +E7/OlRLJfRAXoCEbzFsQpsOYncaEG7cAz9pBBXA6VVyEPlVyMG0GHs30W7aG5Bfp +IcbhacGyjdV5Wwx8WGun1pOHoclLX7pJ6jOXLobpUVH4FUNTAoIBAQDf5gX9aBqK +QxBYcqhZ0aby9K9ZAXSRr03drf4s+TXSU7rUdBqV4BRj1cjQLB6pxpo2ryLoHhkf +tLVRnEWpRgSlfu7qSYxU8rNUacAKAPnebjQxU6NMVzFx7zDQz4TJT2StsxoSIw+l +O4MwWDvIxHcpjIrl1eZh79BSzrq5dsf3vrPCM+Xxivdkx82WJqiVX/LrY3l9R+kC +ud1b3O5vFdhpo8e0sygCdF0+sC0jwE82SCjMMGHMZWd74rmkuHFpJ1xSQf9/jRCf +yKhITI/su21FS4rn1rApWpzAvhfhV7HqnwWzFTtmLeGsI+yW4fb1j6oK7t/rVZ+p +lnwISXpOPBIfAoIBADnMttNIwsAV7F72pdOgLXeuY37Y6rWeb0MLiPW6RlxdY19Y +pakgc7NCz3EjE120g7hiyJOYzR/tSdHszT1q8MiX4ISeyu/vq/aBeWNz+NMX4dB2 +D4wOjGm86dZkMYrGZJ1OGVc7rZFiVjfKEoO7l3Rib9Mg4dYN0SiU0Vc6TSGSK6Dm +dpGG5lFg1PIL7mLtrPmh3lIj/wMgFOGh5Wk2LYEmpKf4jfdoOk7qZ3RLiWfiQ7// +MLD+qw+BbmquYIGwxNPrWdApQDhbjCrfzWWKHqf/Mdj9xBWOC0yVB3IFf0xbpzhP +E255RYPgoaESupZR6CahenDnb+TuUstp+M8OhSsCggEBANw/9gJ65yi9ohWv7MY2 +g+maI+gFk3tAnPOGFnR9TqGxdidKc2CeBtDS2/FUhXFzif5jOI5oFUToSjmW5bwH +wchfXn0gjqh9+0T9pkjw/tv9QuCHKyuM1noC1t2CVliF/j8U4X+X9+sN6RakpWLx +SVuZAoXnbfNHqoHbFToei8W9Vi2jSf7bOlRsbGPZcZtHwLonp7pDBAeHeSbF5dNn +BPWehHTQjHolqBhjzHPP2NxIDcIXkg00b6Ehvoc4XXAYpSvR+pmp1gGorUo57pbt +JSe2kVVRDwgPOAYuuWUWFFH9zuiE6WKxnb7ts+4VKRAVHCwXIjTpjN+Rxj+MsIDH +fPcCggEBAIRgZPwB6eI+rvYOPUGSeU681O+8/ZgjyAi8HSOk3dCc3J2fX31m/GsR +xM+FExbGYJ3BfdgB9YbLSI8eY7weJRodm0FoCuHePu81z4xj9yEi5hBodXhhDjQM +/xbgsSWeotQ+5lTmc5hgve1hl+3t09qNttHaELWASD+0ixBC6A6J4GB68ZKRIunW ++ZGiEvrNey6Uunf7T/Wgc+VDcA3HsniaY2yTZY/jWsmDxt/BAwUaQrNwAbHvm/1P +J04mvCreWfOITe7CURcLq4FMGzsCEXtdQ77/uJllew1Uv2Yn2WFUiqVxH+UicR1P +vOJ7/LvbOa8BlIMsprB2rz3PDSUSaIw= +-----END PRIVATE KEY----- diff --git a/pkg/clientconfig/testdata/tls-ca-chain.pem b/pkg/clientconfig/testdata/tls-ca-chain.pem new file mode 100644 index 0000000000..b67023a7d1 --- /dev/null +++ b/pkg/clientconfig/testdata/tls-ca-chain.pem @@ -0,0 +1,67 @@ +-----BEGIN CERTIFICATE----- +MIIF1DCCA7ygAwIBAgIRAMMSh5NoexSCjSvDRf1fpgIwDQYJKoZIhvcNAQELBQAw +ajELMAkGA1UEBhMCVVMxEzARBgNVBAoTClByb21ldGhldXMxKTAnBgNVBAsTIFBy +b21ldGhldXMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRswGQYDVQQDExJQcm9tZXRo +ZXVzIFJvb3QgQ0EwIBcNMjIwNzA4MDkxNTA2WhgPMjA3MjA2MjUwOTE1MDZaMGkx +CzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpQcm9tZXRoZXVzMSkwJwYDVQQLEyBQcm9t +ZXRoZXVzIENlcnRpZmljYXRlIEF1dGhvcml0eTEaMBgGA1UEAxMRUHJvbWV0aGV1 +cyBUTFMgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXtUbZhHR2 +xElyGJ+BwcZh4hm4dh1OhlJ6g98H2rEOK6bBxeO5YZnthfCnHI6WYN270ylusUc6 +JVkuU/1PO7NLYsl1D4ZIrRKQBWfg88BYrDO38HUkrm4aohlpT0+f7SiA7eRl1Mb5 +x6fi5BAVE5wnQJTE8VPBU+lXJB+SfZEixu+o1PlxVAdMYPAu1Yijakr1lDuZex+/ +j/700mihSAcwOvJ/+p4u2WNj0CMvQWiV5+VBZYrfpRN4/201FoyWILIv3HLq5OKp +Bpl/TvJ4J8oG1Cbzjm52qLgUOvHkAJ0I04DxWWywHF0VRumwLSqae0xo+KPPijj7 +bdnCx+vy37PbFOghzKzSIbPuccfKivVpChgy9n0kkgQhm9cgFE5SBuO6jfRwto0g +drSOMIzyXELDG0h0nB2gsPUHjD/OD1DT0VsW/9xXOPBfVgtPFn5LoZ8ninAFmk2r +ZiRJhCXhh+Rlw2F/s2STP66RnUGVdfP2syV+UlgJlE7EPE8cDbyfQqg7FTflq+t+ +HgXFCAkJ4S34+/qCbGv3DlbnC1lq+FiVwexm1TcfL/lYfhPr/J6VoeFZw4bjTPNa +jUILpsXv6IQzgPfCBxeZC6dDkK1D0cEXAqRRYKEFxdLnMjBcUZlWUV9uTuk01fDc +58bmlHt5sEqhcdUqHrR5PdoWJVOSbFwYBwIDAQABo3QwcjAOBgNVHQ8BAf8EBAMC +AqQwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTG +mh4eYNPmKKXi3dSJIs18ivSv8zAfBgNVHSMEGDAWgBRJPrEOm2ZrMgr9AFTz9LZy +0fDNNjANBgkqhkiG9w0BAQsFAAOCAgEAoc0OImcyyKSbVK63QA8VmD2o9Xr7abxX +o+f+QXWDqKAlNDAuXLYBjHMCc9YFsxXa9XkuKZeIxzop4h9iGG+fxMVPTx3T0gTm +MAuHcPka10z4Gy6ZxLzDmxJPkJ46b1n0K2fsv9XshzsHERz3VavwHXbC5mBo1CwI +6xLLtTWMuJdoyt0261D7Dat1JAFIWm2j+kxGvyIP0gNtRsUKOFA22Tlt42sEYnXa +7wmY7b15rndG69Xg9ZiVI5Mb/10gDJQcym23PXRn+JEgssE+WcYhll8f/LRmD49v +ZlBBD1dVoc9JyrgT+An+2Z8lE6wCSPqWSwhzvBW4dyB/u7Jn23dlV1SwJR8x/IaW +j/DhCELNqD6cSlRK3yjE/a2/iK0F6pNrVgKDY+/9uwFxwkjIRwqfcFtT6YpZ33mg +kSdTTbYpeg3XkLYZayE3ntzEhooyQdrJR6YyFVwsgcBCkeLrEbC7y/AG1MQEdKsZ +i3q730vztGQBR1ymPwgbB6qzGOXhmnhJHnQjeP2CJWnzDeOh2Vs4CxLAQZJ/dhYd +qrbYPAT8FJkp2PvoJP8zpmD7a8QC+6Gr17kl9OupPQrIIfxCXYZKDdGOlkDSUC16 +6y0E1WZnI+LVbQB1M584lB2/8jU4xqMqUPfoIcbjkjih9nvVA6t547527MeeTvXT +0ig2QvMFWMw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFtDCCA5ygAwIBAgIRAMMSh5NoexSCjSvDRf1fpgEwDQYJKoZIhvcNAQELBQAw +ajELMAkGA1UEBhMCVVMxEzARBgNVBAoTClByb21ldGhldXMxKTAnBgNVBAsTIFBy +b21ldGhldXMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRswGQYDVQQDExJQcm9tZXRo +ZXVzIFJvb3QgQ0EwIBcNMjIwNzA4MDkxNTA0WhgPMjA3MjA2MjUwOTE1MDRaMGox +CzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpQcm9tZXRoZXVzMSkwJwYDVQQLEyBQcm9t +ZXRoZXVzIENlcnRpZmljYXRlIEF1dGhvcml0eTEbMBkGA1UEAxMSUHJvbWV0aGV1 +cyBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArkzRPi21 +E299vXw4FBbMfCXI258SxvvjRVRuKdAHLOBpEEqkYH6r6ScbZaisBFtIePv4ddKl +rmv+nDwN84/KS54OOtw1cWD4AnDB0kL3B0pWXjTS1F/u57hRLxM6Ta0UubKbta/h +WqSOR/fAA5sgcl+JbbR61QWVeYYXg9bM8YGTwQMeJod26tIUeX/Reo9BHuiW4jPb +pvVf7rsOs8E2cGwfYjZu6Zj2qcCxQ/ivCpopKFLNlaKko/KlGDGz9KxK5X3ik+sE +fPK9LzLC0k2RLGc3EmcMkdyqE3VNih9nV9SalAXN5yBdYaWWjJXykty7ilU32MBF +yO4myL48vif2K68pD/CFhG8YmIOud3woMm1IYS9xlsYKf7+f5CNlxqz+eSoOGhcG +dSDNft3h5nuq9J/qb2rIgWMSc2puFNRsx+fis0kS5GvjVadR0lxtArbrNm4S+F22 +EjGxeBF5VIWiu31uppbdASIw6DTKcrSVVoWxq+Fk3OOB+7q+rornosop9a/omXGH +0cTmgarjJtMqa0TEQiUPQPPnmpC1joeC7/kh7aks93wfHtY73uAVnTjLGTOwlr50 +CgRShcRoLLN049V93l46AFHU/4HWns8dqgdcdGnvIdUCFik916pKDSvEc/DfMLGh +H6w9Xlg4+2LgCyG2/FBEMTj+bLoraydzyaECAwEAAaNTMFEwDgYDVR0PAQH/BAQD +AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +ST6xDptmazIK/QBU8/S2ctHwzTYwDQYJKoZIhvcNAQELBQADggIBAHM79R/uQwQX +vsBDfKyBXWFlrhHAgX8XAwMKHjstpQYCcJoiGLRJaMMjxj31T1tylqPdcxz88THN +uj9kVFYMo1GU5K9E9lq0LoWQBmX2R7/RgxWqB7FNS+S0xfGyeUb3YPVPI1yhtsKa +6mCtTuCVgsgs/hTa+umjtffxj7l+IQxD8Fq0RFBae+S0v5mjVC2sUVd6usqVt7F6 +LUVuYShyAI705guIV9nkz8ZyLzUBJnQAJ8g6DU+nLmdizigUG+JoD/hBbK2hvcjX +SL7JLAhYRI4kzWcYR0GUfDf2knFEWNhU8gCPnw70FHMD9QC3NKkQsPvyQRyJh99+ +ipwUFbGJJRYWjFBbUxlqZNqBg6+ylZNFGEnG42u2KvPXjgPdivlQWkrX6nG0ayyl +rYrvi0FawP3OBpCrhYhqsqkA2m+5L2Pl+J2SsDv4qmPB6fh7K0YDVB37AZSG+nfL +oXXpUtwfc9tR71S7GmgkcqYOkHfSzl7ecxXtE2xyl3zhkUPR9YcG+rQhXRRp0lxF +kR0EtGOGuvXMCQ/vBVPNEDS3jdceqIrIRI1yPUdhFkF7lrLsfFULllOt6qQWnhn2 +A2ObxHToohwuyri/v8QhqNI2Bg0jJHcAJi8I8taToAstCWrtn+WXyfj/QknAik47 +aOK9l5wSyyqPfkHybKvT6z9pqWUchJsz +-----END CERTIFICATE----- diff --git a/pkg/compact/compact.go b/pkg/compact/compact.go index 1cd634ffe4..cabbed73c1 100644 --- a/pkg/compact/compact.go +++ b/pkg/compact/compact.go @@ -16,6 +16,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" + "github.com/golang/groupcache/singleflight" "github.com/oklog/ulid" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -60,6 +61,8 @@ type Syncer struct { metrics *SyncerMetrics duplicateBlocksFilter block.DeduplicateFilter ignoreDeletionMarkFilter *block.IgnoreDeletionMarkFilter + + g singleflight.Group } // SyncerMetrics holds metrics tracked by the syncer. This struct and its fields are exported @@ -135,15 +138,22 @@ func UntilNextDownsampling(m *metadata.Meta) (time.Duration, error) { // SyncMetas synchronizes local state of block metas with what we have in the bucket. func (s *Syncer) SyncMetas(ctx context.Context) error { - s.mtx.Lock() - defer s.mtx.Unlock() + type metasContainer struct { + metas map[ulid.ULID]*metadata.Meta + partial map[ulid.ULID]error + } - metas, partial, err := s.fetcher.Fetch(ctx) + container, err := s.g.Do("", func() (interface{}, error) { + metas, partial, err := s.fetcher.Fetch(ctx) + return metasContainer{metas, partial}, err + }) if err != nil { return retry(err) } - s.blocks = metas - s.partial = partial + s.mtx.Lock() + s.blocks = container.(metasContainer).metas + s.partial = container.(metasContainer).partial + s.mtx.Unlock() return nil } @@ -172,9 +182,6 @@ func (s *Syncer) Metas() map[ulid.ULID]*metadata.Meta { // block with a higher compaction level. // Call to SyncMetas function is required to populate duplicateIDs in duplicateBlocksFilter. func (s *Syncer) GarbageCollect(ctx context.Context) error { - s.mtx.Lock() - defer s.mtx.Unlock() - begin := time.Now() // Ignore filter exists before deduplicate filter. @@ -209,7 +216,9 @@ func (s *Syncer) GarbageCollect(ctx context.Context) error { // Immediately update our in-memory state so no further call to SyncMetas is needed // after running garbage collection. + s.mtx.Lock() delete(s.blocks, id) + s.mtx.Unlock() s.metrics.GarbageCollectedBlocks.Inc() } s.metrics.GarbageCollections.Inc() @@ -842,17 +851,19 @@ type Compactor interface { // only be called concurrently with results of Plan(). // Can optionally pass a list of already open blocks, // to avoid having to reopen them. - // When resulting Block has 0 samples + // Prometheus always return one or no block. The interface allows returning more than one + // block for downstream users to experiment with compactor. + // When one resulting Block has 0 samples // * No block is written. // * The source dirs are marked Deletable. - // * Returns empty ulid.ULID{}. - Compact(dest string, dirs []string, open []*tsdb.Block) (ulid.ULID, error) - CompactWithBlockPopulator(dest string, dirs []string, open []*tsdb.Block, blockPopulator tsdb.BlockPopulator) (ulid.ULID, error) + // * Block is not included in the result. + Compact(dest string, dirs []string, open []*tsdb.Block) ([]ulid.ULID, error) + CompactWithBlockPopulator(dest string, dirs []string, open []*tsdb.Block, blockPopulator tsdb.BlockPopulator) ([]ulid.ULID, error) } // Compact plans and runs a single compaction against the group. The compacted result // is uploaded into the bucket the blocks were retrieved from. -func (cg *Group) Compact(ctx context.Context, dir string, planner Planner, comp Compactor, blockDeletableChecker BlockDeletableChecker, compactionLifecycleCallback CompactionLifecycleCallback) (shouldRerun bool, compID ulid.ULID, rerr error) { +func (cg *Group) Compact(ctx context.Context, dir string, planner Planner, comp Compactor, blockDeletableChecker BlockDeletableChecker, compactionLifecycleCallback CompactionLifecycleCallback) (shouldRerun bool, compIDs []ulid.ULID, rerr error) { cg.compactionRunsStarted.Inc() subDir := filepath.Join(dir, cg.Key()) @@ -869,7 +880,7 @@ func (cg *Group) Compact(ctx context.Context, dir string, planner Planner, comp }() if err := os.MkdirAll(subDir, 0750); err != nil { - return false, ulid.ULID{}, errors.Wrap(err, "create compaction group dir") + return false, nil, errors.Wrap(err, "create compaction group dir") } defer func() { @@ -889,17 +900,17 @@ func (cg *Group) Compact(ctx context.Context, dir string, planner Planner, comp errChan := make(chan error, 1) err := tracing.DoInSpanWithErr(ctx, "compaction_group", func(ctx context.Context) (err error) { - shouldRerun, compID, err = cg.compact(ctx, subDir, planner, comp, blockDeletableChecker, compactionLifecycleCallback, errChan) + shouldRerun, compIDs, err = cg.compact(ctx, subDir, planner, comp, blockDeletableChecker, compactionLifecycleCallback, errChan) return err }, opentracing.Tags{"group.key": cg.Key()}) errChan <- err close(errChan) if err != nil { cg.compactionFailures.Inc() - return false, ulid.ULID{}, err + return false, nil, err } cg.compactionRunsCompleted.Inc() - return shouldRerun, compID, nil + return shouldRerun, compIDs, nil } // Issue347Error is a type wrapper for errors that should invoke repair process for broken block. @@ -1105,7 +1116,7 @@ func RepairIssue347(ctx context.Context, logger log.Logger, bkt objstore.Bucket, return nil } -func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp Compactor, blockDeletableChecker BlockDeletableChecker, compactionLifecycleCallback CompactionLifecycleCallback, errChan chan error) (shouldRerun bool, compID ulid.ULID, _ error) { +func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp Compactor, blockDeletableChecker BlockDeletableChecker, compactionLifecycleCallback CompactionLifecycleCallback, errChan chan error) (bool, []ulid.ULID, error) { cg.mtx.Lock() defer cg.mtx.Unlock() @@ -1115,7 +1126,7 @@ func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp // TODO(bwplotka): It would really nice if we could still check for other overlaps than replica. In fact this should be checked // in syncer itself. Otherwise with vertical compaction enabled we will sacrifice this important check. if !cg.enableVerticalCompaction { - return false, ulid.ULID{}, halt(errors.Wrap(err, "pre compaction overlap check")) + return false, nil, halt(errors.Wrap(err, "pre compaction overlap check")) } overlappingBlocks = true @@ -1126,11 +1137,11 @@ func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp toCompact, e = planner.Plan(ctx, cg.metasByMinTime, errChan, cg.extensions) return e }); err != nil { - return false, ulid.ULID{}, errors.Wrap(err, "plan compaction") + return false, nil, errors.Wrap(err, "plan compaction") } if len(toCompact) == 0 { // Nothing to do. - return false, ulid.ULID{}, nil + return false, nil, nil } level.Info(cg.logger).Log("msg", "compaction available and planned", "plan", fmt.Sprintf("%v", toCompact)) @@ -1140,7 +1151,7 @@ func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp begin := groupCompactionBegin if err := compactionLifecycleCallback.PreCompactionCallback(ctx, cg.logger, cg, toCompact); err != nil { - return false, ulid.ULID{}, errors.Wrapf(err, "failed to run pre compaction callback for plan: %s", fmt.Sprintf("%v", toCompact)) + return false, nil, errors.Wrapf(err, "failed to run pre compaction callback for plan: %s", fmt.Sprintf("%v", toCompact)) } level.Info(cg.logger).Log("msg", "finished running pre compaction callback; downloading blocks", "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds(), "plan", fmt.Sprintf("%v", toCompact)) @@ -1197,25 +1208,26 @@ func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp sourceBlockStr := fmt.Sprintf("%v", toCompactDirs) if err := g.Wait(); err != nil { - return false, ulid.ULID{}, err + return false, nil, err } level.Info(cg.logger).Log("msg", "downloaded and verified blocks; compacting blocks", "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds(), "plan", sourceBlockStr) begin = time.Now() + var compIDs []ulid.ULID if err := tracing.DoInSpanWithErr(ctx, "compaction", func(ctx context.Context) (e error) { populateBlockFunc, e := compactionLifecycleCallback.GetBlockPopulator(ctx, cg.logger, cg) if e != nil { return e } - compID, e = comp.CompactWithBlockPopulator(dir, toCompactDirs, nil, populateBlockFunc) + compIDs, e = comp.CompactWithBlockPopulator(dir, toCompactDirs, nil, populateBlockFunc) return e }); err != nil { - return false, ulid.ULID{}, halt(errors.Wrapf(err, "compact blocks %v", toCompactDirs)) + return false, nil, halt(errors.Wrapf(err, "compact blocks %v", toCompactDirs)) } - if compID == (ulid.ULID{}) { - // Prometheus compactor found that the compacted block would have no samples. - level.Info(cg.logger).Log("msg", "compacted block would have no samples, deleting source blocks", "blocks", sourceBlockStr) + if len(compIDs) == 0 { + // No compacted blocks means all compacted blocks are of no sample. + level.Info(cg.logger).Log("msg", "no compacted blocks, deleting source blocks", "blocks", sourceBlockStr) for _, meta := range toCompact { if meta.Stats.NumSamples == 0 { if err := cg.deleteBlock(meta.ULID, filepath.Join(dir, meta.ULID.String()), blockDeletableChecker); err != nil { @@ -1223,99 +1235,103 @@ func (cg *Group) compact(ctx context.Context, dir string, planner Planner, comp } } } - // Even though this block was empty, there may be more work to do. - return true, ulid.ULID{}, nil + // Even though no compacted blocks, there may be more work to do. + return true, nil, nil } cg.compactions.Inc() if overlappingBlocks { cg.verticalCompactions.Inc() } - level.Info(cg.logger).Log("msg", "compacted blocks", "new", compID, + compIDStrings := make([]string, 0, len(compIDs)) + for _, compID := range compIDs { + compIDStrings = append(compIDStrings, compID.String()) + } + compIDStrs := fmt.Sprintf("%v", compIDStrings) + level.Info(cg.logger).Log("msg", "compacted blocks", "new", compIDStrs, "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds(), "overlapping_blocks", overlappingBlocks, "blocks", sourceBlockStr) - bdir := filepath.Join(dir, compID.String()) - index := filepath.Join(bdir, block.IndexFilename) - - if err := os.Remove(filepath.Join(bdir, "tombstones")); err != nil { - return false, ulid.ULID{}, errors.Wrap(err, "remove tombstones") - } + for _, compID := range compIDs { + bdir := filepath.Join(dir, compID.String()) + index := filepath.Join(bdir, block.IndexFilename) - newMeta, err := metadata.ReadFromDir(bdir) - if err != nil { - return false, ulid.ULID{}, errors.Wrap(err, "read new meta") - } + if err := os.Remove(filepath.Join(bdir, "tombstones")); err != nil { + return false, nil, errors.Wrap(err, "remove tombstones") + } - var stats block.HealthStats - // Ensure the output block is valid. - err = tracing.DoInSpanWithErr(ctx, "compaction_verify_index", func(ctx context.Context) error { - stats, err = block.GatherIndexHealthStats(ctx, cg.logger, index, newMeta.MinTime, newMeta.MaxTime) + newMeta, err := metadata.ReadFromDir(bdir) if err != nil { - return err + return false, nil, errors.Wrap(err, "read new meta") } - return stats.AnyErr() - }) - if !cg.acceptMalformedIndex && err != nil { - return false, ulid.ULID{}, halt(errors.Wrapf(err, "invalid result block %s", bdir)) - } - thanosMeta := metadata.Thanos{ - Labels: cg.labels.Map(), - Downsample: metadata.ThanosDownsample{Resolution: cg.resolution}, - Source: metadata.CompactorSource, - SegmentFiles: block.GetSegmentFiles(bdir), - Extensions: cg.extensions, - } - if stats.ChunkMaxSize > 0 { - thanosMeta.IndexStats.ChunkMaxSize = stats.ChunkMaxSize - } - if stats.SeriesMaxSize > 0 { - thanosMeta.IndexStats.SeriesMaxSize = stats.SeriesMaxSize - } - newMeta, err = metadata.InjectThanos(cg.logger, bdir, thanosMeta, nil) - if err != nil { - return false, ulid.ULID{}, errors.Wrapf(err, "failed to finalize the block %s", bdir) - } + var stats block.HealthStats + // Ensure the output block is valid. + err = tracing.DoInSpanWithErr(ctx, "compaction_verify_index", func(ctx context.Context) error { + stats, err = block.GatherIndexHealthStats(ctx, cg.logger, index, newMeta.MinTime, newMeta.MaxTime) + if err != nil { + return err + } + return stats.AnyErr() + }) + if !cg.acceptMalformedIndex && err != nil { + return false, nil, halt(errors.Wrapf(err, "invalid result block %s", bdir)) + } - // Ensure the output block is not overlapping with anything else, - // unless vertical compaction is enabled. - if !cg.enableVerticalCompaction { - if err := cg.areBlocksOverlapping(newMeta, toCompact...); err != nil { - return false, ulid.ULID{}, halt(errors.Wrapf(err, "resulted compacted block %s overlaps with something", bdir)) + thanosMeta := metadata.Thanos{ + Labels: cg.labels.Map(), + Downsample: metadata.ThanosDownsample{Resolution: cg.resolution}, + Source: metadata.CompactorSource, + SegmentFiles: block.GetSegmentFiles(bdir), + Extensions: cg.extensions, + } + if stats.ChunkMaxSize > 0 { + thanosMeta.IndexStats.ChunkMaxSize = stats.ChunkMaxSize + } + if stats.SeriesMaxSize > 0 { + thanosMeta.IndexStats.SeriesMaxSize = stats.SeriesMaxSize + } + newMeta, err = metadata.InjectThanos(cg.logger, bdir, thanosMeta, nil) + if err != nil { + return false, nil, errors.Wrapf(err, "failed to finalize the block %s", bdir) + } + // Ensure the output block is not overlapping with anything else, + // unless vertical compaction is enabled. + if !cg.enableVerticalCompaction { + if err := cg.areBlocksOverlapping(newMeta, toCompact...); err != nil { + return false, nil, halt(errors.Wrapf(err, "resulted compacted block %s overlaps with something", bdir)) + } } - } - begin = time.Now() + begin = time.Now() - err = tracing.DoInSpanWithErr(ctx, "compaction_block_upload", func(ctx context.Context) error { - return block.Upload(ctx, cg.logger, cg.bkt, bdir, cg.hashFunc, objstore.WithUploadConcurrency(cg.blockFilesConcurrency)) - }) - if err != nil { - return false, ulid.ULID{}, retry(errors.Wrapf(err, "upload of %s failed", compID)) + err = tracing.DoInSpanWithErr(ctx, "compaction_block_upload", func(ctx context.Context) error { + return block.Upload(ctx, cg.logger, cg.bkt, bdir, cg.hashFunc, objstore.WithUploadConcurrency(cg.blockFilesConcurrency)) + }) + if err != nil { + return false, nil, retry(errors.Wrapf(err, "upload of %s failed", compID)) + } + level.Info(cg.logger).Log("msg", "uploaded block", "result_block", compID, "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds()) + level.Info(cg.logger).Log("msg", "running post compaction callback", "result_block", compID) + if err := compactionLifecycleCallback.PostCompactionCallback(ctx, cg.logger, cg, compID); err != nil { + return false, nil, retry(errors.Wrapf(err, "failed to run post compaction callback for result block %s", compID)) + } + level.Info(cg.logger).Log("msg", "finished running post compaction callback", "result_block", compID) } - level.Info(cg.logger).Log("msg", "uploaded block", "result_block", compID, "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds()) // Mark for deletion the blocks we just compacted from the group and bucket so they do not get included // into the next planning cycle. // Eventually the block we just uploaded should get synced into the group again (including sync-delay). for _, meta := range toCompact { - err = tracing.DoInSpanWithErr(ctx, "compaction_block_delete", func(ctx context.Context) error { + if err := tracing.DoInSpanWithErr(ctx, "compaction_block_delete", func(ctx context.Context) error { return cg.deleteBlock(meta.ULID, filepath.Join(dir, meta.ULID.String()), blockDeletableChecker) - }, opentracing.Tags{"block.id": meta.ULID}) - if err != nil { - return false, ulid.ULID{}, retry(errors.Wrapf(err, "mark old block for deletion from bucket")) + }, opentracing.Tags{"block.id": meta.ULID}); err != nil { + return false, nil, retry(errors.Wrapf(err, "mark old block for deletion from bucket")) } cg.groupGarbageCollectedBlocks.Inc() } - level.Info(cg.logger).Log("msg", "running post compaction callback", "result_block", compID) - if err := compactionLifecycleCallback.PostCompactionCallback(ctx, cg.logger, cg, compID); err != nil { - return false, ulid.ULID{}, retry(errors.Wrapf(err, "failed to run post compaction callback for result block %s", compID)) - } - level.Info(cg.logger).Log("msg", "finished running post compaction callback", "result_block", compID) - level.Info(cg.logger).Log("msg", "finished compacting blocks", "duration", time.Since(groupCompactionBegin), - "duration_ms", time.Since(groupCompactionBegin).Milliseconds(), "result_block", compID, "source_blocks", sourceBlockStr) - return true, compID, nil + "duration_ms", time.Since(groupCompactionBegin).Milliseconds(), "result_blocks", compIDStrs, "source_blocks", sourceBlockStr) + return true, compIDs, nil } func (cg *Group) deleteBlock(id ulid.ULID, bdir string, blockDeletableChecker BlockDeletableChecker) error { diff --git a/pkg/compact/downsample/aggr.go b/pkg/compact/downsample/aggr.go index 7f16f5258d..7102829627 100644 --- a/pkg/compact/downsample/aggr.go +++ b/pkg/compact/downsample/aggr.go @@ -94,6 +94,10 @@ func (c AggrChunk) Get(t AggrType) (chunkenc.Chunk, error) { return chunkenc.FromData(chunkenc.Encoding(x[0]), x[1:]) } +func (c *AggrChunk) Reset(stream []byte) { + (*c) = stream +} + // AggrType represents an aggregation type. type AggrType uint8 diff --git a/pkg/compact/downsample/aggr_test.go b/pkg/compact/downsample/aggr_test.go index d2b44a461a..1db0ff9401 100644 --- a/pkg/compact/downsample/aggr_test.go +++ b/pkg/compact/downsample/aggr_test.go @@ -45,4 +45,16 @@ func TestAggrChunk(t *testing.T) { } } testutil.Equals(t, input, res) + + // Test reset + nc := &AggrChunk{} + nc.Reset(ac.Bytes()) + res = [5][]sample{} + for _, at := range []AggrType{AggrCount, AggrSum, AggrMin, AggrMax, AggrCounter} { + if c, err := nc.Get(at); err != ErrAggrNotExist { + testutil.Ok(t, err) + testutil.Ok(t, expandChunkIterator(c.Iterator(nil), &res[at])) + } + } + testutil.Equals(t, input, res) } diff --git a/pkg/compact/planner.go b/pkg/compact/planner.go index 783191cacf..6d7d03eea2 100644 --- a/pkg/compact/planner.go +++ b/pkg/compact/planner.go @@ -234,6 +234,67 @@ type largeTotalIndexSizeFilter struct { var _ Planner = &largeTotalIndexSizeFilter{} +type verticalCompactionDownsampleFilter struct { + bkt objstore.Bucket + markedForNoCompact prometheus.Counter + + *largeTotalIndexSizeFilter +} + +var _ Planner = &verticalCompactionDownsampleFilter{} + +func WithVerticalCompactionDownsampleFilter(with *largeTotalIndexSizeFilter, bkt objstore.Bucket, markedForNoCompact prometheus.Counter) Planner { + return &verticalCompactionDownsampleFilter{ + markedForNoCompact: markedForNoCompact, + bkt: bkt, + largeTotalIndexSizeFilter: with, + } +} + +func (v *verticalCompactionDownsampleFilter) Plan(ctx context.Context, metasByMinTime []*metadata.Meta, _ chan error, _ any) ([]*metadata.Meta, error) { + noCompactMarked := make(map[ulid.ULID]*metadata.NoCompactMark, 0) +PlanLoop: + for { + plan, err := v.plan(ctx, noCompactMarked, metasByMinTime) + if err != nil { + return nil, err + } + + if len(selectOverlappingMetas(plan)) == 0 { + return plan, nil + } + + // If we have downsampled blocks, we need to mark them as no compact because it's impossible to do that with vertical compaction. + // Technically, the resolution is part of the group key but do not attach ourselves to that level of detail. + var marked = false + for _, m := range plan { + if m.Thanos.Downsample.Resolution == 0 { + continue + } + if err := block.MarkForNoCompact( + ctx, + v.logger, + v.bkt, + m.ULID, + metadata.DownsampleVerticalCompactionNoCompactReason, + "verticalCompactionDownsampleFilter: Downsampled block, see https://github.com/thanos-io/thanos/issues/6775", + v.markedForNoCompact, + ); err != nil { + return nil, errors.Wrapf(err, "mark %v for no compaction", m.ULID.String()) + } + noCompactMarked[m.ULID] = &metadata.NoCompactMark{ID: m.ULID, Version: metadata.NoCompactMarkVersion1} + marked = true + } + + if marked { + continue PlanLoop + } + + return plan, nil + + } +} + // WithLargeTotalIndexSizeFilter wraps Planner with largeTotalIndexSizeFilter that checks the given plans and estimates total index size. // When found, it marks block for no compaction by placing no-compact-mark.json and updating cache. // NOTE: The estimation is very rough as it assumes extreme cases of indexes sharing no bytes, thus summing all source index sizes. @@ -243,16 +304,19 @@ func WithLargeTotalIndexSizeFilter(with *tsdbBasedPlanner, bkt objstore.Bucket, return &largeTotalIndexSizeFilter{tsdbBasedPlanner: with, bkt: bkt, totalMaxIndexSizeBytes: totalMaxIndexSizeBytes, markedForNoCompact: markedForNoCompact} } -func (t *largeTotalIndexSizeFilter) Plan(ctx context.Context, metasByMinTime []*metadata.Meta, _ chan error, _ any) ([]*metadata.Meta, error) { +func (t *largeTotalIndexSizeFilter) plan(ctx context.Context, extraNoCompactMarked map[ulid.ULID]*metadata.NoCompactMark, metasByMinTime []*metadata.Meta) ([]*metadata.Meta, error) { noCompactMarked := t.noCompBlocksFunc() - copiedNoCompactMarked := make(map[ulid.ULID]*metadata.NoCompactMark, len(noCompactMarked)) + copiedNoCompactMarked := make(map[ulid.ULID]*metadata.NoCompactMark, len(noCompactMarked)+len(extraNoCompactMarked)) for k, v := range noCompactMarked { copiedNoCompactMarked[k] = v } + for k, v := range extraNoCompactMarked { + copiedNoCompactMarked[k] = v + } PlanLoop: for { - plan, err := t.plan(copiedNoCompactMarked, metasByMinTime) + plan, err := t.tsdbBasedPlanner.plan(copiedNoCompactMarked, metasByMinTime) if err != nil { return nil, err } @@ -303,3 +367,7 @@ PlanLoop: return plan, nil } } + +func (t *largeTotalIndexSizeFilter) Plan(ctx context.Context, metasByMinTime []*metadata.Meta, _ chan error, _ any) ([]*metadata.Meta, error) { + return t.plan(ctx, nil, metasByMinTime) +} diff --git a/pkg/compactv2/chunk_series_set.go b/pkg/compactv2/chunk_series_set.go index fa3aa18d82..1f70427984 100644 --- a/pkg/compactv2/chunk_series_set.go +++ b/pkg/compactv2/chunk_series_set.go @@ -109,6 +109,7 @@ func (e errChunk) Appender() (chunkenc.Appender, error) { return nil, e. func (e errChunk) Iterator(chunkenc.Iterator) chunkenc.Iterator { return e.err } func (e errChunk) NumSamples() int { return 0 } func (e errChunk) Compact() {} +func (e errChunk) Reset(stream []byte) {} func (l *lazyPopulatableChunk) populate() { // TODO(bwplotka): In most cases we don't need to parse anything, just copy. Extend reader/writer for this. @@ -158,6 +159,13 @@ func (l *lazyPopulatableChunk) NumSamples() int { return l.populated.NumSamples() } +func (l *lazyPopulatableChunk) Reset(stream []byte) { + if l.populated == nil { + l.populate() + } + l.populated.Reset(stream) +} + func (l *lazyPopulatableChunk) Compact() { if l.populated == nil { l.populate() diff --git a/pkg/dedup/iter_test.go b/pkg/dedup/iter_test.go index 6b437160c9..36a5a36375 100644 --- a/pkg/dedup/iter_test.go +++ b/pkg/dedup/iter_test.go @@ -196,72 +196,72 @@ func toChunkedSeriesSlice(t testing.TB, set storepb.SeriesSet) []chunkedSeries { func TestOverlapSplitSet(t *testing.T) { input := []chunkedSeries{ { - lset: labels.Labels{{Name: "a", Value: "1_empty"}}, + lset: labels.FromStrings("a", "1_empty"), }, { - lset: labels.Labels{{Name: "a", Value: "2_nonoverlap"}}, + lset: labels.FromStrings("a", "2_nonoverlap"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 21, MaxTime: 100}, {MinTime: 110, MaxTime: 300}}, }, { - lset: labels.Labels{{Name: "a", Value: "3_tworeplicas"}}, + lset: labels.FromStrings("a", "3_tworeplicas"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 0, MaxTime: 30}, {MinTime: 21, MaxTime: 50}, {MinTime: 31, MaxTime: 60}, {MinTime: 100, MaxTime: 160}}, }, { - lset: labels.Labels{{Name: "a", Value: "4_nonoverlap"}}, + lset: labels.FromStrings("a", "4_nonoverlap"), chunks: []storepb.AggrChunk{{MinTime: 50, MaxTime: 55}, {MinTime: 56, MaxTime: 100}}, }, { - lset: labels.Labels{{Name: "a", Value: "5_minimaloverlap"}}, + lset: labels.FromStrings("a", "5_minimaloverlap"), chunks: []storepb.AggrChunk{{MinTime: 50, MaxTime: 55}, {MinTime: 55, MaxTime: 100}}, }, { - lset: labels.Labels{{Name: "a", Value: "6_fourreplica"}}, + lset: labels.FromStrings("a", "6_fourreplica"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 0, MaxTime: 30}, {MinTime: 1, MaxTime: 15}, {MinTime: 2, MaxTime: 36}, {MinTime: 16, MaxTime: 200}, {MinTime: 21, MaxTime: 50}, {MinTime: 31, MaxTime: 60}, {MinTime: 100, MaxTime: 160}}, }, } exp := []chunkedSeries{ { - lset: labels.Labels{{Name: "a", Value: "1_empty"}}, + lset: labels.FromStrings("a", "1_empty"), }, { - lset: labels.Labels{{Name: "a", Value: "2_nonoverlap"}}, + lset: labels.FromStrings("a", "2_nonoverlap"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 21, MaxTime: 100}, {MinTime: 110, MaxTime: 300}}, }, { - lset: labels.Labels{{Name: "a", Value: "3_tworeplicas"}}, + lset: labels.FromStrings("a", "3_tworeplicas"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 21, MaxTime: 50}, {MinTime: 100, MaxTime: 160}}, }, { - lset: labels.Labels{{Name: "a", Value: "3_tworeplicas"}}, + lset: labels.FromStrings("a", "3_tworeplicas"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 30}, {MinTime: 31, MaxTime: 60}}, }, { - lset: labels.Labels{{Name: "a", Value: "4_nonoverlap"}}, + lset: labels.FromStrings("a", "4_nonoverlap"), chunks: []storepb.AggrChunk{{MinTime: 50, MaxTime: 55}, {MinTime: 56, MaxTime: 100}}, }, { - lset: labels.Labels{{Name: "a", Value: "5_minimaloverlap"}}, + lset: labels.FromStrings("a", "5_minimaloverlap"), chunks: []storepb.AggrChunk{{MinTime: 50, MaxTime: 55}}, }, { - lset: labels.Labels{{Name: "a", Value: "5_minimaloverlap"}}, + lset: labels.FromStrings("a", "5_minimaloverlap"), chunks: []storepb.AggrChunk{{MinTime: 55, MaxTime: 100}}, }, { - lset: labels.Labels{{Name: "a", Value: "6_fourreplica"}}, + lset: labels.FromStrings("a", "6_fourreplica"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 20}, {MinTime: 21, MaxTime: 50}, {MinTime: 100, MaxTime: 160}}, }, { - lset: labels.Labels{{Name: "a", Value: "6_fourreplica"}}, + lset: labels.FromStrings("a", "6_fourreplica"), chunks: []storepb.AggrChunk{{MinTime: 0, MaxTime: 30}, {MinTime: 31, MaxTime: 60}}, }, { - lset: labels.Labels{{Name: "a", Value: "6_fourreplica"}}, + lset: labels.FromStrings("a", "6_fourreplica"), chunks: []storepb.AggrChunk{{MinTime: 1, MaxTime: 15}, {MinTime: 16, MaxTime: 200}}, }, { - lset: labels.Labels{{Name: "a", Value: "6_fourreplica"}}, + lset: labels.FromStrings("a", "6_fourreplica"), chunks: []storepb.AggrChunk{{MinTime: 2, MaxTime: 36}}, }, } @@ -281,46 +281,46 @@ func TestDedupSeriesSet(t *testing.T) { name: "Single dedup label", input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{60000, 3}, {70000, 4}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "3", "d", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{60000, 3}, {70000, 4}}, }, }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "3", "d", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, @@ -329,50 +329,50 @@ func TestDedupSeriesSet(t *testing.T) { name: "Multi dedup label", input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{60000, 3}, {70000, 4}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "3", "d", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{60000, 3}, {70000, 4}}, }, }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "3", "d", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + lset: labels.FromStrings("a", "1", "c", "4"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "2", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, @@ -381,16 +381,16 @@ func TestDedupSeriesSet(t *testing.T) { name: "Multi dedup label - some series don't have all dedup labels", input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{60000, 3}, {70000, 4}}, }, }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + lset: labels.FromStrings("a", "1", "c", "3"), samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, @@ -406,7 +406,7 @@ func TestDedupSeriesSet(t *testing.T) { isCounter: true, input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {10000, 8.0}, // Smaller timestamp, this will be chosen. CurrValue = 8.0. {20000, 9.0}, // Same. CurrValue = 9.0. @@ -419,7 +419,7 @@ func TestDedupSeriesSet(t *testing.T) { {100000, 9 + 6.0}, }, }, { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {10001, 8.0}, // Penalty 5000 will be added. // 20001 was app reset. No sample, because stale marker but removed by downsample.CounterSeriesIterator. Penalty 2 * (20000 - 10000) will be added. @@ -433,7 +433,7 @@ func TestDedupSeriesSet(t *testing.T) { }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{{10000, 8}, {20000, 9}, {45001, 9}, {55001, 10}, {65001, 11}, {90000, 14}, {100000, 15}}, }, }, @@ -444,12 +444,12 @@ func TestDedupSeriesSet(t *testing.T) { isCounter: false, input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {10000, 8.0}, {20000, 9.0}, {50001, 9 + 1.0}, {60000, 9 + 2.0}, {70000, 9 + 3.0}, {80000, 9 + 4.0}, {90000, 9 + 5.0}, {100000, 9 + 6.0}, }, }, { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {10001, 8.0}, {45001, 8 + 0.5}, {55001, 8 + 1.5}, {65001, 8 + 2.5}, }, @@ -457,7 +457,7 @@ func TestDedupSeriesSet(t *testing.T) { }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{{10000, 8}, {20000, 9}, {45001, 8.5}, {55001, 9.5}, {65001, 10.5}, {90000, 14}, {100000, 15}}, }, }, @@ -469,7 +469,7 @@ func TestDedupSeriesSet(t *testing.T) { isCounter: true, input: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {t: 1587690005791, f: 461968}, {t: 1587690020791, f: 462151}, {t: 1587690035797, f: 462336}, {t: 1587690050791, f: 462650}, {t: 1587690065791, f: 462813}, {t: 1587690080791, f: 462987}, {t: 1587690095791, f: 463095}, {t: 1587690110791, f: 463247}, {t: 1587690125791, f: 463440}, {t: 1587690140791, f: 463642}, {t: 1587690155791, f: 463811}, {t: 1587690170791, f: 464027}, {t: 1587690185791, f: 464308}, {t: 1587690200791, f: 464514}, {t: 1587690215791, f: 464798}, {t: 1587690230791, f: 465018}, {t: 1587690245791, f: 465215}, {t: 1587690260813, f: 465431}, {t: 1587690275791, f: 465651}, {t: 1587690290791, f: 465870}, {t: 1587690305791, f: 466070}, {t: 1587690320792, f: 466248}, @@ -495,7 +495,7 @@ func TestDedupSeriesSet(t *testing.T) { {t: 1587693530816, f: 510666}, {t: 1587693545791, f: 510871}, {t: 1587693560791, f: 511123}, {t: 1587693575791, f: 511303}, {t: 1587693590791, f: 511500}, }, }, { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: []sample{ {t: 1587690007139, f: 461993}, {t: 1587690022139, f: 462164}, {t: 1587690037139, f: 462409}, {t: 1587690052139, f: 462662}, {t: 1587690067139, f: 462824}, {t: 1587690082139, f: 462987}, {t: 1587690097155, f: 463108}, {t: 1587690112139, f: 463261}, {t: 1587690127139, f: 463465}, {t: 1587690142139, f: 463642}, {t: 1587690157139, f: 463823}, {t: 1587690172139, f: 464065}, {t: 1587690187139, f: 464333}, {t: 1587690202139, f: 464566}, {t: 1587690217139, f: 464811}, {t: 1587690232140, f: 465032}, {t: 1587690247139, f: 465229}, {t: 1587690262139, f: 465445}, {t: 1587690277139, f: 465700}, {t: 1587690292139, f: 465884}, @@ -526,7 +526,7 @@ func TestDedupSeriesSet(t *testing.T) { }, exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}}, + lset: labels.FromStrings("a", "1"), samples: expectedRealSeriesWithStaleMarkerDeduplicatedForRate, }, }, diff --git a/pkg/exemplars/multitsdb.go b/pkg/exemplars/multitsdb.go index c70811b8db..985f0b6bfe 100644 --- a/pkg/exemplars/multitsdb.go +++ b/pkg/exemplars/multitsdb.go @@ -6,6 +6,7 @@ package exemplars import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/promql/parser" + "github.com/thanos-io/thanos/pkg/extpromql" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -26,7 +27,7 @@ func NewMultiTSDB(tsdbExemplarsServers func() map[string]*TSDB) *MultiTSDB { // Exemplars returns all specified exemplars from a MultiTSDB instance. func (m *MultiTSDB) Exemplars(r *exemplarspb.ExemplarsRequest, s exemplarspb.Exemplars_ExemplarsServer) error { - expr, err := parser.ParseExpr(r.Query) + expr, err := extpromql.ParseExpr(r.Query) if err != nil { return status.Error(codes.Internal, err.Error()) } diff --git a/pkg/exemplars/proxy.go b/pkg/exemplars/proxy.go index e32b8645c1..c7d8fb911c 100644 --- a/pkg/exemplars/proxy.go +++ b/pkg/exemplars/proxy.go @@ -19,6 +19,8 @@ import ( "google.golang.org/grpc/status" "github.com/thanos-io/thanos/pkg/exemplars/exemplarspb" + "github.com/thanos-io/thanos/pkg/extpromql" + "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/tracing" ) @@ -58,7 +60,7 @@ func (s *Proxy) Exemplars(req *exemplarspb.ExemplarsRequest, srv exemplarspb.Exe span, ctx := tracing.StartSpan(srv.Context(), "proxy_exemplars") defer span.Finish() - expr, err := parser.ParseExpr(req.Query) + expr, err := extpromql.ParseExpr(req.Query) if err != nil { return err } @@ -85,28 +87,21 @@ func (s *Proxy) Exemplars(req *exemplarspb.ExemplarsRequest, srv exemplarspb.Exe for _, st := range s.exemplars() { queryParts = queryParts[:0] - Matchers: - for _, matchers := range selectors { - matcherSet := make(map[string]struct{}) - for _, m := range matchers { - for _, ls := range st.LabelSets { - if lv := ls.Get(m.Name); lv != "" { - if !m.Matches(lv) { - continue Matchers - } else { - // If the current matcher matches one external label, - // we don't add it to the current metric selector - // as Prometheus' Exemplars API cannot handle external labels. - continue - } - } - matcherSet[m.String()] = struct{}{} - } + for _, matcherSet := range selectors { + extLbls := st.LabelSets + if !store.LabelSetsMatch(matcherSet, extLbls...) { + continue } labelMatchers = labelMatchers[:0] - for m := range matcherSet { - labelMatchers = append(labelMatchers, m) + for _, m := range matcherSet { + if containsLabelName(m.Name, extLbls) { + // If the current matcher matches one external label, + // we don't add it to the current metric selector + // as Prometheus' Exemplars API cannot handle external labels. + continue + } + labelMatchers = append(labelMatchers, m.String()) } queryParts = append(queryParts, "{"+strings.Join(labelMatchers, ", ")+"}") @@ -164,6 +159,15 @@ func (s *Proxy) Exemplars(req *exemplarspb.ExemplarsRequest, srv exemplarspb.Exe return nil } +func containsLabelName(name string, sets []labels.Labels) bool { + for _, ls := range sets { + if ls.Get(name) != "" { + return true + } + } + return false +} + func (stream *exemplarsStream) receive(ctx context.Context) error { exemplars, err := stream.client.Exemplars(ctx, stream.request) if err != nil { diff --git a/pkg/exemplars/proxy_test.go b/pkg/exemplars/proxy_test.go index 7de5f6e2fa..0e0ca58f8e 100644 --- a/pkg/exemplars/proxy_test.go +++ b/pkg/exemplars/proxy_test.go @@ -12,6 +12,7 @@ import ( "sync" "testing" + "github.com/efficientgo/core/testutil" "github.com/go-kit/log" "github.com/pkg/errors" "github.com/prometheus/prometheus/model/labels" @@ -21,8 +22,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/efficientgo/core/testutil" "github.com/thanos-io/thanos/pkg/exemplars/exemplarspb" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/store/labelpb" "github.com/thanos-io/thanos/pkg/store/storepb" ) @@ -53,7 +54,7 @@ func (t *testExemplarClient) Recv() (*exemplarspb.ExemplarsResponse, error) { } func (t *testExemplarClient) Exemplars(ctx context.Context, in *exemplarspb.ExemplarsRequest, opts ...grpc.CallOption) (exemplarspb.Exemplars_ExemplarsClient, error) { - expr, err := parser.ParseExpr(in.Query) + expr, err := extpromql.ParseExpr(in.Query) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -243,6 +244,31 @@ func TestProxy(t *testing.T) { }), }, }, + { + name: "one external label matches one of the selector labels", + request: &exemplarspb.ExemplarsRequest{ + Query: `http_request_duration_bucket{cluster="A"}`, + PartialResponseStrategy: storepb.PartialResponseStrategy_WARN, + }, + clients: []*exemplarspb.ExemplarStore{ + { + ExemplarsClient: &testExemplarClient{ + response: exemplarspb.NewExemplarsResponse(&exemplarspb.ExemplarData{ + SeriesLabels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(map[string]string{"__name__": "http_request_duration_bucket"}))}, + Exemplars: []*exemplarspb.Exemplar{{Value: 1}}, + }), + }, + LabelSets: []labels.Labels{labels.FromMap(map[string]string{"cluster": "non-matching"}), labels.FromMap(map[string]string{"cluster": "A"})}, + }, + }, + server: &testExemplarServer{}, + wantResponses: []*exemplarspb.ExemplarsResponse{ + exemplarspb.NewExemplarsResponse(&exemplarspb.ExemplarData{ + SeriesLabels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(map[string]string{"__name__": "http_request_duration_bucket"}))}, + Exemplars: []*exemplarspb.Exemplar{{Value: 1}}, + }), + }, + }, { name: "external label selects stores", request: &exemplarspb.ExemplarsRequest{ @@ -341,12 +367,13 @@ func TestProxy(t *testing.T) { // for matched response for simplicity. Outer: for _, exp := range tc.wantResponses { + var lres *exemplarspb.ExemplarsResponse for _, res := range tc.server.responses { if reflect.DeepEqual(exp, res) { continue Outer } } - t.Errorf("miss expected response %v", exp) + t.Errorf("miss expected response %v. got: %v", exp, lres) } }) } diff --git a/pkg/extgrpc/client.go b/pkg/extgrpc/client.go index 15ccd03eb6..a6dcc7b633 100644 --- a/pkg/extgrpc/client.go +++ b/pkg/extgrpc/client.go @@ -9,8 +9,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" "google.golang.org/grpc" @@ -18,6 +17,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/keepalive" + grpcserver "github.com/thanos-io/thanos/pkg/server/grpc" "github.com/thanos-io/thanos/pkg/tls" "github.com/thanos-io/thanos/pkg/tracing" ) @@ -46,9 +46,14 @@ func EndpointGroupGRPCOpts() []grpc.DialOption { // StoreClientGRPCOpts creates gRPC dial options for connecting to a store client. func StoreClientGRPCOpts(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer, secure, skipVerify bool, cert, key, caCert, serverName string) ([]grpc.DialOption, error) { - grpcMets := grpc_prometheus.NewClientMetrics() - grpcMets.EnableClientHandlingTimeHistogram( - grpc_prometheus.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120, 240, 360, 720}), + grpcMets := grpc_prometheus.NewClientMetrics( + grpc_prometheus.WithClientHandlingTimeHistogram(grpc_prometheus.WithHistogramOpts( + &prometheus.HistogramOpts{ + Buckets: []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120, 240, 360, 720}, + NativeHistogramMaxBucketNumber: 256, + NativeHistogramBucketFactor: 1.1, + }, + )), ) dialOpts := []grpc.DialOption{ // We want to make sure that we can receive huge gRPC messages from storeAPI. @@ -56,18 +61,17 @@ func StoreClientGRPCOpts(logger log.Logger, reg prometheus.Registerer, tracer op // Current limit is ~2GB. // TODO(bplotka): Split sent chunks on store node per max 4MB chunks if needed. grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)), - grpc.WithUnaryInterceptor( - grpc_middleware.ChainUnaryClient( - grpcMets.UnaryClientInterceptor(), - tracing.UnaryClientInterceptor(tracer), - ), + grpc.WithChainUnaryInterceptor( + grpcserver.NewUnaryClientRequestIDInterceptor(), + grpcMets.UnaryClientInterceptor(), + tracing.UnaryClientInterceptor(tracer), ), - grpc.WithStreamInterceptor( - grpc_middleware.ChainStreamClient( - grpcMets.StreamClientInterceptor(), - tracing.StreamClientInterceptor(tracer), - ), + grpc.WithChainStreamInterceptor( + grpcserver.NewStreamClientRequestIDInterceptor(), + grpcMets.StreamClientInterceptor(), + tracing.StreamClientInterceptor(tracer), ), + grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: 10 * time.Second, Timeout: 5 * time.Second}), } if reg != nil { reg.MustRegister(grpcMets) diff --git a/pkg/extpromql/parser.go b/pkg/extpromql/parser.go new file mode 100644 index 0000000000..43d7188fdc --- /dev/null +++ b/pkg/extpromql/parser.go @@ -0,0 +1,66 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package extpromql + +import ( + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/promql/parser" + + "github.com/thanos-io/promql-engine/execution/function" +) + +// ParseExpr parses the input PromQL expression and returns the parsed representation. +func ParseExpr(input string) (parser.Expr, error) { + allFuncs := make(map[string]*parser.Function, len(function.XFunctions)+len(parser.Functions)) + for k, v := range parser.Functions { + allFuncs[k] = v + } + for k, v := range function.XFunctions { + allFuncs[k] = v + } + p := parser.NewParser(input, parser.WithFunctions(allFuncs)) + defer p.Close() + return p.ParseExpr() +} + +// ParseMetricSelector parses the provided textual metric selector into a list of +// label matchers. +func ParseMetricSelector(input string) ([]*labels.Matcher, error) { + expr, err := ParseExpr(input) + // because of the AST checking present in the ParseExpr function, + // we need to ignore the error if it is just the check for empty name matcher. + if err != nil && !isEmptyNameMatcherErr(err) { + return nil, err + } + + vs, ok := expr.(*parser.VectorSelector) + if !ok { + return nil, fmt.Errorf("expected type *parser.VectorSelector, got %T", expr) + } + + matchers := make([]*labels.Matcher, len(vs.LabelMatchers)) + for i, lm := range vs.LabelMatchers { + matchers[i] = &labels.Matcher{ + Type: lm.Type, + Name: lm.Name, + Value: lm.Value, + } + } + + return matchers, nil +} + +func isEmptyNameMatcherErr(err error) bool { + var parseErrs parser.ParseErrors + if errors.As(err, &parseErrs) { + return len(parseErrs) == 1 && + strings.HasSuffix(parseErrs[0].Error(), "vector selector must contain at least one non-empty matcher") + } + + return false +} diff --git a/pkg/extpromql/parser_test.go b/pkg/extpromql/parser_test.go new file mode 100644 index 0000000000..72ef7b26cb --- /dev/null +++ b/pkg/extpromql/parser_test.go @@ -0,0 +1,68 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package extpromql_test + +import ( + "fmt" + "testing" + + "github.com/efficientgo/core/testutil" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/promql/parser" + + "github.com/thanos-io/thanos/pkg/extpromql" +) + +func TestParseMetricSelector(t *testing.T) { + testCases := []struct { + name string + input string + }{ + { + name: "single selector", + input: `http_requests_total{method="GET"}`, + }, + { + name: "empty selectors", + input: `process_cpu_seconds_total`, + }, + { + name: "multiple selectors", + input: `http_requests_total{method="GET",code="200"}`, + }, + { + name: "multiple selectors with different matchers", + input: `http_requests_total{method="GET",code!="200"}`, + }, + { + name: "multiple selectors with regex", + input: `http_requests_total{method="GET",code=~"2.*"}`, + }, + { + name: "selector with negative regex", + input: `{code!~"2.*"}`, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + //lint:ignore faillint Testing against prometheus parser. + want, err := parser.ParseMetricSelector(tc.input) + if err != nil { + t.Fatalf("Prometheus ParseMetricSelector failed: %v", err) + } + + got, err := extpromql.ParseMetricSelector(tc.input) + if err != nil { + t.Fatalf("ParseMetricSelector failed: %v", err) + } + + testutil.Equals(t, stringFmt(want), stringFmt(got)) + }) + } +} + +func stringFmt(got []*labels.Matcher) string { + return fmt.Sprintf("%v", got) +} diff --git a/pkg/logging/grpc.go b/pkg/logging/grpc.go index 44387d395f..1aeeafd2fe 100644 --- a/pkg/logging/grpc.go +++ b/pkg/logging/grpc.go @@ -4,17 +4,12 @@ package logging import ( + "context" "fmt" - "math/rand" - "sort" - "strings" - "time" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/go-kit/log" + "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" - "github.com/oklog/ulid" - "google.golang.org/grpc/status" "gopkg.in/yaml.v2" ) @@ -79,17 +74,17 @@ func fillGlobalOptionConfig(reqLogConfig *RequestConfig, isgRPC bool) (string, b } // getGRPCLoggingOption returns the logging ENUM based on logStart and logEnd values. -func getGRPCLoggingOption(logStart, logEnd bool) (grpc_logging.Decision, error) { +func getGRPCLoggingOption(logStart, logEnd bool) (grpc_logging.Option, error) { if !logStart && !logEnd { - return grpc_logging.NoLogCall, nil + return grpc_logging.WithLogOnEvents(), nil } if !logStart && logEnd { - return grpc_logging.LogFinishCall, nil + return grpc_logging.WithLogOnEvents(grpc_logging.FinishCall), nil } if logStart && logEnd { - return grpc_logging.LogStartAndFinishCall, nil + return grpc_logging.WithLogOnEvents(grpc_logging.StartCall, grpc_logging.FinishCall), nil } - return -1, fmt.Errorf("log start call is not supported") + return nil, fmt.Errorf("log decision combination is not supported") } // validateLevel validates the list of level entries. @@ -104,104 +99,79 @@ func validateLevel(level string) error { return fmt.Errorf("the format of level is invalid. Expected INFO/DEBUG/ERROR/WARNING, got this %v", level) } -// NewGRPCOption adds in the config options and returns tags for logging middleware. -func NewGRPCOption(configYAML []byte) ([]tags.Option, []grpc_logging.Option, error) { - - // Configure tagOpts and logOpts. - tagOpts := []tags.Option{ - tags.WithFieldExtractor(func(_ string, req interface{}) map[string]string { - tagMap := tags.TagBasedRequestFieldExtractor("request-id")("", req) - // If a request-id exists for a given request. - if tagMap != nil { - if _, ok := tagMap["request-id"]; ok { - return tagMap - } - } - entropy := ulid.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0) - reqID := ulid.MustNew(ulid.Timestamp(time.Now()), entropy) - tagMap = make(map[string]string) - tagMap["request-id"] = reqID.String() - return tagMap - }), - } - logOpts := []grpc_logging.Option{ - grpc_logging.WithDecider(func(_ string, _ error) grpc_logging.Decision { - return grpc_logging.NoLogCall - }), - grpc_logging.WithLevels(DefaultCodeToLevelGRPC), - } +func InterceptorLogger(l log.Logger) grpc_logging.Logger { + return grpc_logging.LoggerFunc(func(_ context.Context, lvl grpc_logging.Level, msg string, fields ...any) { + largs := append([]any{"msg", msg}, fields...) + switch lvl { + case grpc_logging.LevelDebug: + _ = level.Debug(l).Log(largs...) + case grpc_logging.LevelInfo: + _ = level.Info(l).Log(largs...) + case grpc_logging.LevelWarn: + _ = level.Warn(l).Log(largs...) + case grpc_logging.LevelError: + _ = level.Error(l).Log(largs...) + default: + panic(fmt.Sprintf("unknown level %v", lvl)) + } + }) +} - // Unmarshal YAML. +// NewGRPCOption adds in the config options for logging middleware. +func NewGRPCOption(configYAML []byte) ([]grpc_logging.Option, []string, error) { + + var logOpts []grpc_logging.Option + + // Unmarshal YAML // if req logging is disabled. if len(configYAML) == 0 { - return tagOpts, logOpts, nil + return nil, nil, nil } reqLogConfig, err := NewRequestConfig(configYAML) // If unmarshalling is an issue. if err != nil { - return tagOpts, logOpts, err + return logOpts, nil, err } globalLevel, globalStart, globalEnd, err := fillGlobalOptionConfig(reqLogConfig, true) // If global options have invalid entries. if err != nil { - return tagOpts, logOpts, err + return logOpts, nil, err + } + if !globalStart && !globalEnd { + //Nothing to do + return nil, nil, nil } // If the level entry does not matches our entries. if err := validateLevel(globalLevel); err != nil { - return tagOpts, logOpts, err + return logOpts, nil, err } + logOpts = []grpc_logging.Option{ + grpc_logging.WithLevels(DefaultCodeToLevelGRPC), + grpc_logging.WithFieldsFromContext(GetTraceIDAndRequestIDAsField), + } // If the combination is valid, use them, otherwise return error. reqLogDecision, err := getGRPCLoggingOption(globalStart, globalEnd) if err != nil { - return tagOpts, logOpts, err + return logOpts, nil, err } if len(reqLogConfig.GRPC.Config) == 0 { - logOpts = []grpc_logging.Option{ - grpc_logging.WithDecider(func(_ string, err error) grpc_logging.Decision { - - runtimeLevel := grpc_logging.DefaultServerCodeToLevel(status.Code(err)) - for _, lvl := range MapAllowedLevels[globalLevel] { - if string(runtimeLevel) == strings.ToLower(lvl) { - return reqLogDecision - } - } - return grpc_logging.NoLogCall - }), - grpc_logging.WithLevels(DefaultCodeToLevelGRPC), - } - return tagOpts, logOpts, nil - } - - logOpts = []grpc_logging.Option{ - grpc_logging.WithLevels(DefaultCodeToLevelGRPC), + // If no config is present, use the global config. + logOpts = append(logOpts, reqLogDecision) + return logOpts, nil, nil } - methodNameSlice := []string{} + logOpts = append(logOpts, reqLogDecision) + var methodNameSlice []string for _, eachConfig := range reqLogConfig.GRPC.Config { - eachConfigMethodName := interceptors.FullMethod(eachConfig.Service, eachConfig.Method) + eachConfigMethodName := fmt.Sprintf("/%s/%s", eachConfig.Service, eachConfig.Method) methodNameSlice = append(methodNameSlice, eachConfigMethodName) } - logOpts = append(logOpts, []grpc_logging.Option{ - grpc_logging.WithDecider(func(runtimeMethodName string, err error) grpc_logging.Decision { - - idx := sort.SearchStrings(methodNameSlice, runtimeMethodName) - if idx < len(methodNameSlice) && methodNameSlice[idx] == runtimeMethodName { - runtimeLevel := grpc_logging.DefaultServerCodeToLevel(status.Code(err)) - for _, lvl := range MapAllowedLevels[globalLevel] { - if string(runtimeLevel) == strings.ToLower(lvl) { - return reqLogDecision - } - } - } - return grpc_logging.NoLogCall - }), - }...) - return tagOpts, logOpts, nil + return logOpts, methodNameSlice, nil } diff --git a/pkg/logging/options.go b/pkg/logging/options.go index 85eed878c0..0d3afbd6fe 100644 --- a/pkg/logging/options.go +++ b/pkg/logging/options.go @@ -4,14 +4,21 @@ package logging import ( + "context" "fmt" + "math/rand" "time" + "github.com/oklog/ulid" + "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/trace" + extflag "github.com/efficientgo/tools/extkingpin" "github.com/go-kit/log" "github.com/go-kit/log/level" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" + middleware "github.com/thanos-io/thanos/pkg/server/http/middleware" + "github.com/thanos-io/thanos/pkg/tracing/migration" "google.golang.org/grpc/codes" ) @@ -127,9 +134,9 @@ func DefaultCodeToLevel(logger log.Logger, code int) log.Logger { func DefaultCodeToLevelGRPC(c codes.Code) grpc_logging.Level { switch c { case codes.Unknown, codes.Unimplemented, codes.Internal, codes.DataLoss: - return grpc_logging.ERROR + return grpc_logging.LevelError default: - return grpc_logging.DEBUG + return grpc_logging.LevelDebug } } @@ -158,6 +165,33 @@ var MapAllowedLevels = map[string][]string{ "WARN": {"WARN", "ERROR"}, } +func GetTraceIDAndRequestIDAsField(ctx context.Context) grpc_logging.Fields { + logFields := grpc_logging.Fields{} + + //get traceID from context + span := opentracing.SpanFromContext(ctx) + TraceID, _ := migration.GetTraceIDFromBridgeSpan(span) + if span := trace.SpanContextFromContext(ctx); span.IsSampled() { + logFields = logFields.AppendUnique(grpc_logging.Fields{"traceID", TraceID}) + } + //get requestID from context + reqID, ok := middleware.RequestIDFromContext(ctx) + if ok { + logFields = logFields.AppendUnique(grpc_logging.Fields{"requestID", reqID}) + return logFields + } + + entropy := ulid.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0) + newReqID := ulid.MustNew(ulid.Timestamp(time.Now()), entropy).String() + logFields = logFields.AppendUnique(grpc_logging.Fields{"requestID", newReqID}) + + // Insert into context (Note: This updated context isn't being used later, so this might be redundant) + _ = middleware.NewContextWithRequestID(ctx, newReqID) + + return logFields + +} + // TODO: @yashrsharma44 - To be deprecated in the next release. func ParseHTTPOptions(reqLogConfig *extflag.PathOrContent) ([]Option, error) { // Default Option: No Logging. @@ -175,21 +209,17 @@ func ParseHTTPOptions(reqLogConfig *extflag.PathOrContent) ([]Option, error) { } // TODO: @yashrsharma44 - To be deprecated in the next release. -func ParsegRPCOptions(reqLogConfig *extflag.PathOrContent) ([]tags.Option, []grpc_logging.Option, error) { - // Default Option: No Logging. - logOpts := []grpc_logging.Option{grpc_logging.WithDecider(func(_ string, _ error) grpc_logging.Decision { - return grpc_logging.NoLogCall - })} - +func ParsegRPCOptions(reqLogConfig *extflag.PathOrContent) ([]grpc_logging.Option, []string, error) { + var logOpts []grpc_logging.Option configYAML, err := reqLogConfig.Content() if err != nil { - return []tags.Option{}, logOpts, fmt.Errorf("getting request logging config failed. %v", err) + return logOpts, nil, fmt.Errorf("getting request logging config failed. %v", err) } - tagOpts, logOpts, err := NewGRPCOption(configYAML) + logOpts, logFilterMethods, err := NewGRPCOption(configYAML) if err != nil { - return []tags.Option{}, logOpts, err + return logOpts, logFilterMethods, err } - return tagOpts, logOpts, nil + return logOpts, logFilterMethods, nil } diff --git a/pkg/promclient/promclient_e2e_test.go b/pkg/promclient/promclient_e2e_test.go index fec2b46b34..a253ce2485 100644 --- a/pkg/promclient/promclient_e2e_test.go +++ b/pkg/promclient/promclient_e2e_test.go @@ -42,10 +42,10 @@ func TestIsWALFileAccessible_e2e(t *testing.T) { func TestExternalLabels_e2e(t *testing.T) { e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { // Keep consistent with the config processing in function (*Client).ExternalLabels. - cfg := config.Config{GlobalConfig: config.GlobalConfig{ExternalLabels: []labels.Label{ - {Name: "region", Value: "eu-west"}, - {Name: "az", Value: "1"}, - }}} + cfg := config.Config{GlobalConfig: config.GlobalConfig{ExternalLabels: labels.FromMap(map[string]string{ + "region": "eu-west", + "az": "1", + })}} cfgData, err := yaml.Marshal(cfg) testutil.Ok(t, err) p.SetConfig(string(cfgData)) @@ -58,7 +58,7 @@ func TestExternalLabels_e2e(t *testing.T) { ext, err := NewDefaultClient().ExternalLabels(context.Background(), u) testutil.Ok(t, err) - testutil.Equals(t, 2, len(ext)) + testutil.Equals(t, 2, ext.Len()) testutil.Equals(t, "eu-west", ext.Get("region")) testutil.Equals(t, "1", ext.Get("az")) }) @@ -96,7 +96,7 @@ func TestSnapshot_e2e(t *testing.T) { 10, timestamp.FromTime(now.Add(-6*time.Hour)), timestamp.FromTime(now.Add(-4*time.Hour)), - nil, + labels.EmptyLabels(), 0, metadata.NoneFunc, ) @@ -167,7 +167,7 @@ func TestQueryRange_e2e(t *testing.T) { 10, timestamp.FromTime(now.Add(-2*time.Hour)), timestamp.FromTime(now), - nil, + labels.EmptyLabels(), 0, metadata.NoneFunc, ) diff --git a/pkg/query/endpointset.go b/pkg/query/endpointset.go index d81c586287..54a640059c 100644 --- a/pkg/query/endpointset.go +++ b/pkg/query/endpointset.go @@ -242,14 +242,16 @@ type endpointSetNodeCollector struct { labels []string connectionsWithAddr *prometheus.Desc connectionsWithKeys *prometheus.Desc + logger log.Logger } -func newEndpointSetNodeCollector(labels ...string) *endpointSetNodeCollector { +func newEndpointSetNodeCollector(logger log.Logger, labels ...string) *endpointSetNodeCollector { if len(labels) == 0 { labels = []string{string(ExternalLabels), string(StoreType)} } desc := "Number of gRPC connection to Store APIs. Opened connection means healthy store APIs available for Querier." return &endpointSetNodeCollector{ + logger: logger, storeNodes: map[component.Component]map[string]int{}, connectionsDesc: prometheus.NewDesc( "thanos_store_nodes_grpc_connections", @@ -334,7 +336,12 @@ func (c *endpointSetNodeCollector) Collect(ch chan<- prometheus.Metric) { lbls = append(lbls, storeTypeStr) } } - ch <- prometheus.MustNewConstMetric(c.connectionsDesc, prometheus.GaugeValue, float64(occurrences), lbls...) + select { + case ch <- prometheus.MustNewConstMetric(c.connectionsDesc, prometheus.GaugeValue, float64(occurrences), lbls...): + case <-time.After(1 * time.Second): + level.Warn(c.logger).Log("msg", "failed to collect endpointset metrics", "timeout", 1*time.Second) + return + } } } for replicaKey, occurrencesPerAddr := range c.storeNodesAddr { @@ -392,7 +399,7 @@ func NewEndpointSet( endpointInfoTimeout time.Duration, endpointMetricLabels ...string, ) *EndpointSet { - endpointsMetric := newEndpointSetNodeCollector(endpointMetricLabels...) + endpointsMetric := newEndpointSetNodeCollector(logger, endpointMetricLabels...) if reg != nil { reg.MustRegister(endpointsMetric) } @@ -464,8 +471,7 @@ func (e *EndpointSet) Update(ctx context.Context) { defer wg.Done() ctx, cancel := context.WithTimeout(ctx, e.endpointInfoTimeout) defer cancel() - - newRef, err := e.newEndpointRef(ctx, spec) + newRef, err := e.newEndpointRef(spec) if err != nil { level.Warn(e.logger).Log("msg", "new endpoint creation failed", "err", err, "address", spec.Addr()) return @@ -622,6 +628,7 @@ func (e *EndpointSet) GetStoreClients() []store.Client { metadata: er.metadata, groupKey: er.GroupKey(), replicaKey: er.ReplicaKey(), + status: er.status, }) er.mtx.RUnlock() } @@ -758,17 +765,12 @@ func (er *endpointRef) ReplicaKey() string { // newEndpointRef creates a new endpointRef with a gRPC channel to the given the IP address. // The call to newEndpointRef will return an error if establishing the channel fails. -func (e *EndpointSet) newEndpointRef(ctx context.Context, spec *GRPCEndpointSpec) (*endpointRef, error) { +func (e *EndpointSet) newEndpointRef(spec *GRPCEndpointSpec) (*endpointRef, error) { var dialOpts []grpc.DialOption dialOpts = append(dialOpts, e.dialOpts...) dialOpts = append(dialOpts, spec.dialOpts...) - // By default DialContext is non-blocking which means that any connection - // failure won't be reported/logged. Instead block until the connection is - // successfully established and return the details of the connection error - // if any. - dialOpts = append(dialOpts, grpc.WithReturnConnectionError()) - conn, err := grpc.DialContext(ctx, spec.Addr(), dialOpts...) + conn, err := grpc.NewClient(spec.Addr(), dialOpts...) if err != nil { return nil, errors.Wrap(err, "dialing connection") } @@ -897,7 +899,7 @@ func (er *endpointRef) LabelSets() []labels.Labels { er.mtx.RLock() defer er.mtx.RUnlock() - return er.labelSets() + return er.status.LabelSets } func (er *endpointRef) labelSets() []labels.Labels { diff --git a/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go b/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go index 6b858712f7..bcd5e9aeb1 100644 --- a/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go +++ b/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go @@ -334,7 +334,7 @@ func (s *StoreSet) getHealthyStores(ctx context.Context) map[string]*storeRef { store.Update(labelSets, minTime, maxTime) } else { // New store or was unhealthy and was removed in the past - create new one. - conn, err := grpc.DialContext(ctx, addr, s.dialOpts...) + conn, err := grpc.NewClient(addr, s.dialOpts...) if err != nil { s.updateStoreStatus(&storeRef{addr: addr}, err) level.Warn(s.logger).Log("msg", "update of store node failed", "err", errors.Wrap(err, "dialing connection"), "address", addr) diff --git a/pkg/query/remote_engine.go b/pkg/query/remote_engine.go index 2b0e67e056..f379d38017 100644 --- a/pkg/query/remote_engine.go +++ b/pkg/query/remote_engine.go @@ -22,10 +22,13 @@ import ( "github.com/thanos-io/promql-engine/api" + "github.com/opentracing/opentracing-go" "github.com/thanos-io/thanos/pkg/api/query/querypb" "github.com/thanos-io/thanos/pkg/info/infopb" + "github.com/thanos-io/thanos/pkg/server/http/middleware" "github.com/thanos-io/thanos/pkg/store/labelpb" "github.com/thanos-io/thanos/pkg/store/storepb/prompb" + grpc_tracing "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware" ) // Opts are the options for a PromQL query. @@ -187,10 +190,11 @@ func (r *remoteEngine) NewRangeQuery(_ context.Context, _ promql.QueryOpts, plan client: r.client, opts: r.opts, - plan: plan, - start: start, - end: end, - interval: interval, + plan: plan, + start: start, + end: end, + interval: interval, + remoteAddr: r.client.GetAddress(), }, nil } @@ -200,10 +204,11 @@ func (r *remoteEngine) NewInstantQuery(_ context.Context, _ promql.QueryOpts, pl client: r.client, opts: r.opts, - plan: plan, - start: ts, - end: ts, - interval: 0, + plan: plan, + start: ts, + end: ts, + interval: 0, + remoteAddr: r.client.GetAddress(), }, nil } @@ -212,21 +217,51 @@ type remoteQuery struct { client Client opts Opts - plan api.RemoteQuery - start time.Time - end time.Time - interval time.Duration + plan api.RemoteQuery + start time.Time + end time.Time + interval time.Duration + remoteAddr string + + samplesStats *stats.QuerySamples cancel context.CancelFunc } func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { start := time.Now() + defer func() { + keys := []any{ + "msg", "Executed remote query", + "query", r.plan.String(), + "time", time.Since(start), + } + if r.samplesStats != nil { + keys = append(keys, "remote_peak_samples", r.samplesStats.PeakSamples) + keys = append(keys, "remote_total_samples", r.samplesStats.TotalSamples) + } + level.Debug(r.logger).Log(keys...) + }() qctx, cancel := context.WithCancel(ctx) r.cancel = cancel defer cancel() + var ( + queryRange = r.end.Sub(r.start) + requestID, _ = middleware.RequestIDFromContext(qctx) + ) + qctx = grpc_tracing.ClientAddContextTags(qctx, opentracing.Tags{ + "query.expr": r.plan.String(), + "query.remote_address": r.remoteAddr, + "query.start": r.start.UTC().String(), + "query.end": r.end.UTC().String(), + "query.interval_seconds": r.interval.Seconds(), + "query.range_seconds": queryRange.Seconds(), + "query.range_human": queryRange, + "request_id": requestID, + }) + var maxResolution int64 if r.opts.AutoDownsample { maxResolution = int64(r.interval.Seconds() / 5) @@ -236,6 +271,8 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { level.Warn(r.logger).Log("msg", "Failed to encode query plan", "err", err) } + r.samplesStats = stats.NewQuerySamples(false) + // Instant query. if r.start == r.end { request := &querypb.QueryRequest{ @@ -259,6 +296,7 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { result = make(promql.Vector, 0) warnings annotations.Annotations builder = labels.NewScratchBuilder(8) + qryStats querypb.QueryStats ) for { msg, err := qry.Recv() @@ -273,8 +311,15 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { warnings.Add(errors.New(warn)) continue } + if s := msg.GetStats(); s != nil { + qryStats = *s + continue + } ts := msg.GetTimeseries() + if ts == nil { + continue + } builder.Reset() for _, l := range ts.Labels { builder.Add(strings.Clone(l.Name), strings.Clone(l.Value)) @@ -288,6 +333,8 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { result = append(result, promql.Sample{Metric: builder.Labels(), F: ts.Samples[0].Value, T: r.start.UnixMilli()}) } } + r.samplesStats.UpdatePeak(int(qryStats.PeakSamples)) + r.samplesStats.TotalSamples = qryStats.SamplesTotal return &promql.Result{ Value: result, @@ -318,6 +365,7 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { result = make(promql.Matrix, 0) warnings annotations.Annotations builder = labels.NewScratchBuilder(8) + qryStats querypb.QueryStats ) for { msg, err := qry.Recv() @@ -332,6 +380,10 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { warnings.Add(errors.New(warn)) continue } + if s := msg.GetStats(); s != nil { + qryStats = *s + continue + } ts := msg.GetTimeseries() if ts == nil { @@ -360,7 +412,8 @@ func (r *remoteQuery) Exec(ctx context.Context) *promql.Result { } result = append(result, series) } - level.Debug(r.logger).Log("msg", "Executed query", "query", r.plan.String(), "time", time.Since(start)) + r.samplesStats.UpdatePeak(int(qryStats.PeakSamples)) + r.samplesStats.TotalSamples = qryStats.SamplesTotal return &promql.Result{Value: result, Warnings: warnings} } @@ -369,7 +422,11 @@ func (r *remoteQuery) Close() { r.Cancel() } func (r *remoteQuery) Statement() parser.Statement { return nil } -func (r *remoteQuery) Stats() *stats.Statistics { return nil } +func (r *remoteQuery) Stats() *stats.Statistics { + return &stats.Statistics{ + Samples: r.samplesStats, + } +} func (r *remoteQuery) Cancel() { if r.cancel != nil { diff --git a/pkg/query/remote_engine_test.go b/pkg/query/remote_engine_test.go index bca79598e5..137bd73da1 100644 --- a/pkg/query/remote_engine_test.go +++ b/pkg/query/remote_engine_test.go @@ -14,12 +14,12 @@ import ( "github.com/go-kit/log" "github.com/pkg/errors" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" "github.com/thanos-io/promql-engine/logicalplan" "github.com/thanos-io/promql-engine/query" "google.golang.org/grpc" "github.com/thanos-io/thanos/pkg/api/query/querypb" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/info/infopb" "github.com/thanos-io/thanos/pkg/store/labelpb" ) @@ -34,7 +34,7 @@ func TestRemoteEngine_Warnings(t *testing.T) { end = time.Unix(120, 0) step = 30 * time.Second ) - qryExpr, err := parser.ParseExpr("up") + qryExpr, err := extpromql.ParseExpr("up") testutil.Ok(t, err) plan := logicalplan.NewFromAST(qryExpr, &query.Options{ diff --git a/pkg/query/test_test.go b/pkg/query/test_test.go index b8457870ca..d8af78c66d 100644 --- a/pkg/query/test_test.go +++ b/pkg/query/test_test.go @@ -24,6 +24,8 @@ import ( "github.com/prometheus/prometheus/promql/parser/posrange" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/util/teststorage" + + "github.com/thanos-io/thanos/pkg/extpromql" ) var ( @@ -261,7 +263,7 @@ func ParseStore(lines []string, i int) (int, *storeCmd, error) { } parts := patStore.FindStringSubmatch(lines[i]) - m, err := parser.ParseMetricSelector(parts[1]) + m, err := extpromql.ParseMetricSelector(parts[1]) if err != nil { return i, nil, raise(i, "invalid matcher definition %q: %s", parts[1], err) } @@ -322,7 +324,7 @@ func ParseEval(lines []string, i int) (int, *evalCmd, error) { at = parts[2] expr = parts[3] ) - _, err := parser.ParseExpr(expr) + _, err := extpromql.ParseExpr(expr) if err != nil { if perr, ok := err.(*parser.ParseErr); ok { perr.LineOffset = i diff --git a/pkg/queryfrontend/queryinstant_codec.go b/pkg/queryfrontend/queryinstant_codec.go index bc8786e470..0d22a76a75 100644 --- a/pkg/queryfrontend/queryinstant_codec.go +++ b/pkg/queryfrontend/queryinstant_codec.go @@ -17,14 +17,15 @@ import ( "github.com/opentracing/opentracing-go" otlog "github.com/opentracing/opentracing-go/log" "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/promql/parser" "github.com/weaveworks/common/httpgrpc" - "github.com/prometheus/prometheus/promql/parser" "github.com/thanos-io/thanos/internal/cortex/cortexpb" "github.com/thanos-io/thanos/internal/cortex/querier/queryrange" cortexutil "github.com/thanos-io/thanos/internal/cortex/util" "github.com/thanos-io/thanos/internal/cortex/util/spanlogger" queryv1 "github.com/thanos-io/thanos/pkg/api/query" + "github.com/thanos-io/thanos/pkg/extpromql" ) // queryInstantCodec is used to encode/decode Thanos instant query requests and responses. @@ -394,7 +395,7 @@ const ( ) func sortPlanForQuery(q string) (sortPlan, error) { - expr, err := parser.ParseExpr(q) + expr, err := extpromql.ParseExpr(q) if err != nil { return 0, err } diff --git a/pkg/queryfrontend/queryrange_codec.go b/pkg/queryfrontend/queryrange_codec.go index fca6ea7fc7..4de0dd387e 100644 --- a/pkg/queryfrontend/queryrange_codec.go +++ b/pkg/queryfrontend/queryrange_codec.go @@ -16,13 +16,12 @@ import ( "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" "github.com/weaveworks/common/httpgrpc" "github.com/thanos-io/thanos/internal/cortex/querier/queryrange" cortexutil "github.com/thanos-io/thanos/internal/cortex/util" - queryv1 "github.com/thanos-io/thanos/pkg/api/query" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/store/storepb" ) @@ -269,7 +268,7 @@ func parsePartialResponseParam(s string, defaultEnablePartialResponse bool) (boo func parseMatchersParam(ss url.Values, matcherParam string) ([][]*labels.Matcher, error) { matchers := make([][]*labels.Matcher, 0, len(ss[matcherParam])) for _, s := range ss[matcherParam] { - ms, err := parser.ParseMetricSelector(s) + ms, err := extpromql.ParseMetricSelector(s) if err != nil { return nil, httpgrpc.Errorf(http.StatusBadRequest, errCannotParse, matcherParam) } diff --git a/pkg/querysharding/analyzer.go b/pkg/querysharding/analyzer.go index 7b8e849bca..80cb8cb3a8 100644 --- a/pkg/querysharding/analyzer.go +++ b/pkg/querysharding/analyzer.go @@ -22,6 +22,8 @@ import ( lru "github.com/hashicorp/golang-lru/v2" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/promql/parser" + + "github.com/thanos-io/thanos/pkg/extpromql" ) var ( @@ -88,7 +90,7 @@ func (a *CachedQueryAnalyzer) Analyze(query string) (QueryAnalysis, error) { // // The le label is excluded from sharding. func (a *QueryAnalyzer) Analyze(query string) (QueryAnalysis, error) { - expr, err := parser.ParseExpr(query) + expr, err := extpromql.ParseExpr(query) if err != nil { return nonShardableQuery(), err } diff --git a/pkg/receive/handler.go b/pkg/receive/handler.go index 5368ee08ea..d5c1d7910d 100644 --- a/pkg/receive/handler.go +++ b/pkg/receive/handler.go @@ -711,32 +711,26 @@ type remoteWriteParams struct { alreadyReplicated bool } -func (h *Handler) gatherWriteStats(writes ...map[endpointReplica]map[string]trackedSeries) tenantRequestStats { +func (h *Handler) gatherWriteStats(localWrites map[endpointReplica]map[string]trackedSeries) tenantRequestStats { var stats tenantRequestStats = make(tenantRequestStats) - for _, write := range writes { - for er := range write { - if er.replica != 0 { - // TODO: this is a temporary solution to avoid duplicated counting - continue - } - for tenant, series := range write[er] { - samples := 0 + for er := range localWrites { + for tenant, series := range localWrites[er] { + samples := 0 - for _, ts := range series.timeSeries { - samples += len(ts.Samples) - } + for _, ts := range series.timeSeries { + samples += len(ts.Samples) + } - if st, ok := stats[tenant]; ok { - st.timeseries += len(series.timeSeries) - st.totalSamples += samples + if st, ok := stats[tenant]; ok { + st.timeseries += len(series.timeSeries) + st.totalSamples += samples - stats[tenant] = st - } else { - stats[tenant] = requestStats{ - timeseries: len(series.timeSeries), - totalSamples: samples, - } + stats[tenant] = st + } else { + stats[tenant] = requestStats{ + timeseries: len(series.timeSeries), + totalSamples: samples, } } } @@ -772,7 +766,7 @@ func (h *Handler) fanoutForward(ctx context.Context, params remoteWriteParams) ( return stats, err } - stats = h.gatherWriteStats(localWrites, remoteWrites) + stats = h.gatherWriteStats(localWrites) // Prepare a buffered channel to receive the responses from the local and remote writes. Remote writes will all go // asynchronously and with this capacity we will never block on writing to the channel. @@ -1353,7 +1347,7 @@ func newPeerGroup(backoff backoff.Backoff, forwardDelay prometheus.Histogram, as dialOpts: dialOpts, connections: map[string]*peerWorker{}, m: sync.RWMutex{}, - dialer: grpc.DialContext, + dialer: grpc.NewClient, peerStates: make(map[string]*retryState), expBackoff: backoff, forwardDelay: forwardDelay, @@ -1407,7 +1401,7 @@ type peerGroup struct { m sync.RWMutex // dialer is used for testing. - dialer func(ctx context.Context, target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) + dialer func(target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) } func (p *peerGroup) closeAll() error { @@ -1469,7 +1463,7 @@ func (p *peerGroup) getConnection(ctx context.Context, addr string) (WriteableSt if ok { return c, nil } - conn, err := p.dialer(ctx, addr, p.dialOpts...) + conn, err := p.dialer(addr, p.dialOpts...) if err != nil { p.markPeerUnavailableUnlocked(addr) dialError := errors.Wrap(err, "failed to dial peer") diff --git a/pkg/receive/handler_test.go b/pkg/receive/handler_test.go index 21fc61dd44..ab054765b7 100644 --- a/pkg/receive/handler_test.go +++ b/pkg/receive/handler_test.go @@ -79,7 +79,9 @@ func (r *dnsResolver) start() { } } -func (*dnsResolver) ResolveNow(_ resolver.ResolveNowOptions) {} +func (r *dnsResolver) ResolveNow(_ resolver.ResolveNowOptions) { + r.start() +} func (*dnsResolver) Close() {} @@ -1839,6 +1841,8 @@ func TestHandlerFlippingHashrings(t *testing.T) { } func TestIngestorRestart(t *testing.T) { + // TODO: fix this test. It has a data race. + t.Skip("Skipping this test case temporarily due to a data race") var err error logger := log.NewLogfmtLogger(os.Stderr) addr1, addr2, addr3 := "localhost:14090", "localhost:14091", "localhost:14092" @@ -1847,8 +1851,11 @@ func TestIngestorRestart(t *testing.T) { clientAddr := "ingestor.com" dnsBuilder := &dnsResolverBuilder{ - logger: logger, - addrStore: map[string][]string{clientAddr: {addr2}}, + logger: logger, + addrStore: map[string][]string{ + addr1: {addr1}, + clientAddr: {addr2}, + }, } resolver.Register(dnsBuilder) dialOpts := []grpc.DialOption{ diff --git a/pkg/receive/multitsdb.go b/pkg/receive/multitsdb.go index beeaa230ec..2c5ad509d1 100644 --- a/pkg/receive/multitsdb.go +++ b/pkg/receive/multitsdb.go @@ -6,6 +6,7 @@ package receive import ( "context" "fmt" + "io" "os" "path" "path/filepath" @@ -20,6 +21,9 @@ import ( "go.uber.org/atomic" "golang.org/x/exp/slices" "golang.org/x/sync/errgroup" + gmetadata "google.golang.org/grpc/metadata" + + "google.golang.org/grpc" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" @@ -27,6 +31,7 @@ import ( "github.com/prometheus/prometheus/tsdb" "github.com/thanos-io/objstore" + "github.com/thanos-io/thanos/pkg/api/status" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/component" @@ -94,14 +99,79 @@ func NewMultiTSDB( } type localClient struct { - storepb.StoreClient store *store.TSDBStore } -func newLocalClient(c storepb.StoreClient, store *store.TSDBStore) *localClient { +type seriesClientMapper struct { + ctx context.Context + series []*storepb.Series + + initiated bool + + store *store.TSDBStore + req storepb.SeriesRequest +} + +func (m *seriesClientMapper) Recv() (*storepb.SeriesResponse, error) { + if !m.initiated { + series, err := m.store.SeriesLocal(m.ctx, &m.req) + if err != nil { + return nil, err + } + m.series = series + m.initiated = true + } + if len(m.series) == 0 { + return nil, io.EOF + } + s := m.series[0] + m.series = m.series[1:] + return storepb.NewSeriesResponse(s), nil +} + +func (m *seriesClientMapper) Header() (gmetadata.MD, error) { + return nil, nil +} + +func (m *seriesClientMapper) Trailer() gmetadata.MD { + return nil +} + +func (m *seriesClientMapper) CloseSend() error { + return nil +} + +func (m *seriesClientMapper) Context() context.Context { + return m.ctx +} + +func (m *seriesClientMapper) RecvMsg(_ interface{}) error { + return nil +} + +func (m *seriesClientMapper) SendMsg(_ interface{}) error { + return nil +} + +func (l *localClient) Info(ctx context.Context, in *storepb.InfoRequest, opts ...grpc.CallOption) (*storepb.InfoResponse, error) { + return l.store.Info(ctx, in) +} + +func (l *localClient) Series(ctx context.Context, in *storepb.SeriesRequest, opts ...grpc.CallOption) (storepb.Store_SeriesClient, error) { + return &seriesClientMapper{ctx: ctx, store: l.store, req: *in}, nil +} + +func (l *localClient) LabelNames(ctx context.Context, in *storepb.LabelNamesRequest, opts ...grpc.CallOption) (*storepb.LabelNamesResponse, error) { + return l.store.LabelNames(ctx, in) +} + +func (l *localClient) LabelValues(ctx context.Context, in *storepb.LabelValuesRequest, opts ...grpc.CallOption) (*storepb.LabelValuesResponse, error) { + return l.store.LabelValues(ctx, in) +} + +func newLocalClient(store *store.TSDBStore) *localClient { return &localClient{ - StoreClient: c, - store: store, + store: store, } } @@ -210,7 +280,7 @@ func (t *tenant) store() *store.TSDBStore { return t.storeTSDB } -func (t *tenant) client(logger log.Logger) store.Client { +func (t *tenant) client() store.Client { t.mtx.RLock() defer t.mtx.RUnlock() @@ -219,8 +289,7 @@ func (t *tenant) client(logger log.Logger) store.Client { return nil } - client := storepb.ServerAsClient(store.NewRecoverableStoreServer(logger, tsdbStore)) - return newLocalClient(client, tsdbStore) + return newLocalClient(tsdbStore) } func (t *tenant) exemplars() *exemplars.TSDB { @@ -342,6 +411,7 @@ func (t *MultiTSDB) Prune(ctx context.Context) error { if t.tsdbOpts.RetentionDuration == 0 { return nil } + level.Info(t.logger).Log("msg", "Running pruning job") var ( wg sync.WaitGroup @@ -350,7 +420,6 @@ func (t *MultiTSDB) Prune(ctx context.Context) error { prunedTenants []string pmtx sync.Mutex ) - t.mtx.RLock() for tenantID, tenantInstance := range t.tenants { wg.Add(1) @@ -548,7 +617,7 @@ func (t *MultiTSDB) TSDBLocalClients() []store.Client { res := make([]store.Client, 0, len(t.tenants)) for _, tenant := range t.tenants { - client := tenant.client(t.logger) + client := tenant.client() if client != nil { res = append(res, client) } diff --git a/pkg/receive/multitsdb_test.go b/pkg/receive/multitsdb_test.go index 53d99cabfa..6f5dd01ae7 100644 --- a/pkg/receive/multitsdb_test.go +++ b/pkg/receive/multitsdb_test.go @@ -454,10 +454,10 @@ func TestMultiTSDBPrune(t *testing.T) { ) defer func() { testutil.Ok(t, m.Close()) }() - for i := 0; i < 100; i++ { - testutil.Ok(t, appendSample(m, "deleted-tenant", time.UnixMilli(int64(10+i)))) - testutil.Ok(t, appendSample(m, "compacted-tenant", time.Now().Add(-4*time.Hour))) - testutil.Ok(t, appendSample(m, "active-tenant", time.Now().Add(time.Duration(i)*time.Second))) + for step := time.Duration(0); step <= 2*time.Hour; step += time.Minute { + testutil.Ok(t, appendSample(m, "deleted-tenant", time.Now().Add(-9*time.Hour+step))) + testutil.Ok(t, appendSample(m, "compacted-tenant", time.Now().Add(-4*time.Hour+step))) + testutil.Ok(t, appendSample(m, "active-tenant", time.Now().Add(step))) } testutil.Equals(t, 3, len(m.TSDBLocalClients())) diff --git a/pkg/rules/rules.go b/pkg/rules/rules.go index 72f5db3a44..1777a45181 100644 --- a/pkg/rules/rules.go +++ b/pkg/rules/rules.go @@ -12,9 +12,9 @@ import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" "github.com/prometheus/prometheus/util/annotations" + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/rules/rulespb" "github.com/thanos-io/thanos/pkg/tracing" ) @@ -64,7 +64,7 @@ func (rr *GRPCClient) Rules(ctx context.Context, req *rulespb.RulesRequest) (*ru var err error matcherSets := make([][]*labels.Matcher, len(req.MatcherString)) for i, s := range req.MatcherString { - matcherSets[i], err = parser.ParseMetricSelector(s) + matcherSets[i], err = extpromql.ParseMetricSelector(s) if err != nil { return nil, nil, errors.Wrap(err, "parser ParseMetricSelector") } diff --git a/pkg/server/grpc/grpc.go b/pkg/server/grpc/grpc.go index ebdfc678b1..b883aa7d5b 100644 --- a/pkg/server/grpc/grpc.go +++ b/pkg/server/grpc/grpc.go @@ -9,14 +9,14 @@ import ( "net" "runtime/debug" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector" + "github.com/go-kit/log" "github.com/go-kit/log/level" - "github.com/grpc-ecosystem/go-grpc-middleware/providers/kit/v2" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" grpc_logging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" @@ -30,6 +30,7 @@ import ( "google.golang.org/grpc/status" "github.com/thanos-io/thanos/pkg/component" + logging_mw "github.com/thanos-io/thanos/pkg/logging" "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/tracing" ) @@ -47,7 +48,7 @@ type Server struct { // New creates a new gRPC Store API. // If rulesSrv is not nil, it also registers Rules API to the returned server. -func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer, logOpts []grpc_logging.Option, tagsOpts []tags.Option, comp component.Component, probe *prober.GRPCProbe, opts ...Option) *Server { +func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer, logOpts []grpc_logging.Option, logFilterMethods []string, comp component.Component, probe *prober.GRPCProbe, opts ...Option) *Server { logger = log.With(logger, "service", "gRPC/server", "component", comp.String()) options := options{ network: "tcp", @@ -56,10 +57,16 @@ func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer o.apply(&options) } - met := grpc_prometheus.NewServerMetrics() - met.EnableHandlingTimeHistogram( - grpc_prometheus.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}), + met := grpc_prometheus.NewServerMetrics( + grpc_prometheus.WithServerHandlingTimeHistogram( + grpc_prometheus.WithHistogramOpts(&prometheus.HistogramOpts{ + Buckets: []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}, + NativeHistogramMaxBucketNumber: 256, + NativeHistogramBucketFactor: 1.1, + }), + ), ) + panicsTotal := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "grpc_req_panics_recovered_total", Help: "Total number of gRPC requests recovered from internal panic.", @@ -77,19 +84,48 @@ func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer // TODO(bwplotka): https://github.com/grpc-ecosystem/go-grpc-middleware/issues/462 grpc.MaxSendMsgSize(math.MaxInt32), grpc.MaxRecvMsgSize(math.MaxInt32), - grpc_middleware.WithUnaryServerChain( + grpc.ChainUnaryInterceptor( + NewUnaryServerRequestIDInterceptor(), grpc_recovery.UnaryServerInterceptor(grpc_recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)), met.UnaryServerInterceptor(), - tags.UnaryServerInterceptor(tagsOpts...), tracing.UnaryServerInterceptor(tracer), - grpc_logging.UnaryServerInterceptor(kit.InterceptorLogger(logger), logOpts...), + selector.UnaryServerInterceptor(grpc_logging.UnaryServerInterceptor(logging_mw.InterceptorLogger(logger), logOpts...), selector.MatchFunc(func(ctx context.Context, c interceptors.CallMeta) bool { + //if RequestConfig.GRPC.Config was provided + for _, m := range logFilterMethods { + if m == c.FullMethod() { + return true + } + } + return false + })), + selector.UnaryServerInterceptor(grpc_logging.UnaryServerInterceptor(logging_mw.InterceptorLogger(logger), logOpts...), selector.MatchFunc(func(ctx context.Context, _ interceptors.CallMeta) bool { + //if RequestConfig.Options only was provided + if len(logFilterMethods) == 0 && logOpts != nil { + return true + } + return false + })), ), - grpc_middleware.WithStreamServerChain( + + grpc.ChainStreamInterceptor( + NewStreamServerRequestIDInterceptor(), grpc_recovery.StreamServerInterceptor(grpc_recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)), met.StreamServerInterceptor(), - tags.StreamServerInterceptor(tagsOpts...), tracing.StreamServerInterceptor(tracer), - grpc_logging.StreamServerInterceptor(kit.InterceptorLogger(logger), logOpts...), + selector.StreamServerInterceptor(grpc_logging.StreamServerInterceptor(logging_mw.InterceptorLogger(logger), logOpts...), selector.MatchFunc(func(ctx context.Context, c interceptors.CallMeta) bool { + for _, m := range logFilterMethods { + if m == c.FullMethod() { + return true + } + } + return false + })), + selector.StreamServerInterceptor(grpc_logging.StreamServerInterceptor(logging_mw.InterceptorLogger(logger), logOpts...), selector.MatchFunc(func(ctx context.Context, _ interceptors.CallMeta) bool { + if len(logFilterMethods) == 0 && logOpts != nil { + return true + } + return false + })), ), }...) diff --git a/pkg/server/grpc/request_id.go b/pkg/server/grpc/request_id.go new file mode 100644 index 0000000000..cca8175516 --- /dev/null +++ b/pkg/server/grpc/request_id.go @@ -0,0 +1,67 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package grpc + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/thanos-io/thanos/pkg/server/http/middleware" +) + +const requestIDKey = "request-id" + +func NewUnaryClientRequestIDInterceptor() grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + reqID, ok := middleware.RequestIDFromContext(ctx) + if ok { + ctx = metadata.AppendToOutgoingContext(ctx, requestIDKey, reqID) + } + return invoker(ctx, method, req, reply, cc, opts...) + } +} + +func NewUnaryServerRequestIDInterceptor() grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { + if vals := metadata.ValueFromIncomingContext(ctx, requestIDKey); len(vals) == 1 { + ctx = middleware.NewContextWithRequestID(ctx, vals[0]) + } + return handler(ctx, req) + } +} + +func NewStreamClientRequestIDInterceptor() grpc.StreamClientInterceptor { + return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + reqID, ok := middleware.RequestIDFromContext(ctx) + if ok { + ctx = metadata.AppendToOutgoingContext(ctx, requestIDKey, reqID) + } + return streamer(ctx, desc, cc, method, opts...) + } +} + +func NewStreamServerRequestIDInterceptor() grpc.StreamServerInterceptor { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if vals := metadata.ValueFromIncomingContext(ss.Context(), requestIDKey); len(vals) == 1 { + ctx := middleware.NewContextWithRequestID(ss.Context(), vals[0]) + return handler(srv, newStreamWithContext(ctx, ss)) + } + return handler(srv, ss) + } +} + +type streamWithContext struct { + grpc.ServerStream + ctx context.Context +} + +func newStreamWithContext(ctx context.Context, serverStream grpc.ServerStream) *streamWithContext { + return &streamWithContext{ServerStream: serverStream, ctx: ctx} +} + +func (s streamWithContext) Context() context.Context { + return s.ctx +} diff --git a/pkg/server/http/middleware/request_id.go b/pkg/server/http/middleware/request_id.go index fddeabf932..3a3da07a83 100644 --- a/pkg/server/http/middleware/request_id.go +++ b/pkg/server/http/middleware/request_id.go @@ -16,8 +16,8 @@ type ctxKey int const reqIDKey = ctxKey(0) -// newContextWithRequestID creates a context with a request id. -func newContextWithRequestID(ctx context.Context, rid string) context.Context { +// NewContextWithRequestID creates a context with a request id. +func NewContextWithRequestID(ctx context.Context, rid string) context.Context { return context.WithValue(ctx, reqIDKey, rid) } @@ -36,7 +36,7 @@ func RequestID(h http.Handler) http.HandlerFunc { reqID = ulid.MustNew(ulid.Timestamp(time.Now()), entropy).String() r.Header.Set("X-Request-ID", reqID) } - ctx := newContextWithRequestID(r.Context(), reqID) + ctx := NewContextWithRequestID(r.Context(), reqID) h.ServeHTTP(w, r.WithContext(ctx)) } } diff --git a/pkg/store/acceptance_test.go b/pkg/store/acceptance_test.go index d0921be50a..8dc415439c 100644 --- a/pkg/store/acceptance_test.go +++ b/pkg/store/acceptance_test.go @@ -887,7 +887,7 @@ func TestBucketStore_Acceptance(t *testing.T) { } for _, replica := range []string{"r1", "r2"} { - id := createBlockFromHead(tt, auxDir, h) + id := storetestutil.CreateBlockFromHead(tt, auxDir, h) auxBlockDir := filepath.Join(auxDir, id.String()) meta, err := metadata.ReadFromDir(auxBlockDir) @@ -999,37 +999,140 @@ func TestTSDBStore_Acceptance(t *testing.T) { } func TestProxyStoreWithTSDBSelector_Acceptance(t *testing.T) { + t.Skip("This is a known issue, we need to think how to fix it") + t.Cleanup(func() { custom.TolerantVerifyLeak(t) }) + ctx := context.Background() startStore := func(tt *testing.T, extLset labels.Labels, appendFn func(app storage.Appender)) storepb.StoreServer { - startNestedStore := func(tt *testing.T, extLset labels.Labels, appendFn func(app storage.Appender)) storepb.StoreServer { - db, err := e2eutil.NewTSDB() + startNestedStore := func(tt *testing.T, appendFn func(app storage.Appender), extLsets ...labels.Labels) storepb.StoreServer { + tmpDir := tt.TempDir() + bktDir := filepath.Join(tmpDir, "bkt") + auxDir := filepath.Join(tmpDir, "aux") + metaDir := filepath.Join(tmpDir, "meta") + + testutil.Ok(tt, os.MkdirAll(metaDir, os.ModePerm)) + testutil.Ok(tt, os.MkdirAll(auxDir, os.ModePerm)) + + bkt, err := filesystem.NewBucket(bktDir) testutil.Ok(tt, err) - tt.Cleanup(func() { testutil.Ok(tt, db.Close()) }) - appendFn(db.Appender(context.Background())) + tt.Cleanup(func() { testutil.Ok(tt, bkt.Close()) }) - return NewTSDBStore(nil, db, component.Rule, extLset) + headOpts := tsdb.DefaultHeadOptions() + headOpts.ChunkDirRoot = tmpDir + headOpts.ChunkRange = 1000 + h, err := tsdb.NewHead(nil, nil, nil, nil, headOpts, nil) + testutil.Ok(tt, err) + tt.Cleanup(func() { testutil.Ok(tt, h.Close()) }) + logger := log.NewNopLogger() + + appendFn(h.Appender(context.Background())) + + if h.NumSeries() == 0 { + tt.Skip("Bucket Store cannot handle empty HEAD") + } + + for _, extLset := range extLsets { + id := storetestutil.CreateBlockFromHead(tt, auxDir, h) + + auxBlockDir := filepath.Join(auxDir, id.String()) + meta, err := metadata.ReadFromDir(auxBlockDir) + testutil.Ok(t, err) + stats, err := block.GatherIndexHealthStats(ctx, logger, filepath.Join(auxBlockDir, block.IndexFilename), meta.MinTime, meta.MaxTime) + testutil.Ok(t, err) + _, err = metadata.InjectThanos(log.NewNopLogger(), auxBlockDir, metadata.Thanos{ + Labels: extLset.Map(), + Downsample: metadata.ThanosDownsample{Resolution: 0}, + Source: metadata.TestSource, + IndexStats: metadata.IndexStats{SeriesMaxSize: stats.SeriesMaxSize, ChunkMaxSize: stats.ChunkMaxSize}, + }, nil) + testutil.Ok(tt, err) + + testutil.Ok(tt, block.Upload(ctx, logger, bkt, auxBlockDir, metadata.NoneFunc)) + } + + chunkPool, err := NewDefaultChunkBytesPool(2e5) + testutil.Ok(tt, err) + + insBkt := objstore.WithNoopInstr(bkt) + baseBlockIDsFetcher := block.NewConcurrentLister(logger, insBkt) + metaFetcher, err := block.NewMetaFetcher(logger, 20, insBkt, baseBlockIDsFetcher, metaDir, nil, []block.MetadataFilter{ + block.NewTimePartitionMetaFilter(allowAllFilterConf.MinTime, allowAllFilterConf.MaxTime), + }) + testutil.Ok(tt, err) + bucketStore, err := NewBucketStore( + objstore.WithNoopInstr(bkt), + metaFetcher, + "", + NewChunksLimiterFactory(10e6), + NewSeriesLimiterFactory(10e6), + NewBytesLimiterFactory(10e6), + NewGapBasedPartitioner(PartitionerMaxGapSize), + 20, + true, + DefaultPostingOffsetInMemorySampling, + false, + false, + 1*time.Minute, + WithChunkPool(chunkPool), + WithFilterConfig(allowAllFilterConf), + ) + testutil.Ok(tt, err) + tt.Cleanup(func() { testutil.Ok(tt, bucketStore.Close()) }) + + testutil.Ok(tt, bucketStore.SyncBlocks(context.Background())) + + return bucketStore } - p1 := startNestedStore(tt, extLset, appendFn) - p2 := startNestedStore(tt, labels.FromStrings("some", "label"), appendFn) + extLset1 := labels.NewBuilder(extLset).Set("L1", "A").Set("L2", "B").Labels() + extLset2 := labels.NewBuilder(extLset).Set("L1", "C").Set("L2", "D").Labels() + extLset3 := labels.NewBuilder(extLset).Set("L1", "A").Set("L2", "D").Labels() + + p1 := startNestedStore(tt, appendFn, extLset1, extLset2, extLset3) clients := []Client{ - storetestutil.TestClient{StoreClient: storepb.ServerAsClient(p1), ExtLset: []labels.Labels{extLset}}, - storetestutil.TestClient{StoreClient: storepb.ServerAsClient(p2), ExtLset: []labels.Labels{labels.FromStrings("some", "label")}}, + storetestutil.TestClient{StoreClient: storepb.ServerAsClient(p1), ExtLset: []labels.Labels{extLset1, extLset2, extLset3}}, } relabelCfgs := []*relabel.Config{{ - SourceLabels: model.LabelNames([]model.LabelName{"some"}), - Regex: relabel.MustNewRegexp("label"), - Action: relabel.Drop, + SourceLabels: model.LabelNames([]model.LabelName{"L1", "L2"}), + Separator: "-", + Regex: relabel.MustNewRegexp("(A-B|C-D)"), + Action: relabel.Keep, }} return NewProxyStore(nil, nil, func() []Client { return clients }, component.Query, labels.EmptyLabels(), 0*time.Second, RetrievalStrategy(EagerRetrieval), WithTSDBSelector(NewTSDBSelector(relabelCfgs))) } - testStoreAPIsAcceptance(t, startStore) + client := startStore(t, labels.EmptyLabels(), func(app storage.Appender) { + _, err := app.Append(0, labels.FromStrings("a", "b"), 0, 0) + testutil.Ok(t, err) + testutil.Ok(t, app.Commit()) + }) + srv := newStoreSeriesServer(ctx) + + testutil.Ok(t, client.Series(&storepb.SeriesRequest{ + MinTime: minTime.Unix(), + MaxTime: maxTime.Unix(), + Matchers: []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "a", Value: "b"}, + }, + }, srv)) + + receivedLabels := make([]labels.Labels, 0) + for _, s := range srv.SeriesSet { + receivedLabels = append(receivedLabels, s.PromLabels()) + } + + // This fails currently because the method of using matchers cannot drop extLset3 even though we should only + // select extLset1 and extLset2 because of the TSDB Selector + testutil.Equals(t, receivedLabels, []labels.Labels{ + labels.FromStrings("L1", "A", "L2", "B", "a", "b"), + labels.FromStrings("L1", "C", "L2", "D", "a", "b"), + }) + } func TestProxyStoreWithReplicas_Acceptance(t *testing.T) { diff --git a/pkg/store/bucket.go b/pkg/store/bucket.go index f0fd1feda6..e342893cc7 100644 --- a/pkg/store/bucket.go +++ b/pkg/store/bucket.go @@ -62,6 +62,17 @@ import ( "github.com/thanos-io/thanos/pkg/tracing" ) +type StoreDataType int + +const ( + PostingsFetched StoreDataType = iota + PostingsTouched + SeriesFetched + SeriesTouched + ChunksFetched + ChunksTouched +) + const ( // MaxSamplesPerChunk is approximately the max number of samples that we may have in any given chunk. This is needed // for precalculating the number of samples that we may have to retrieve and decode for any given query @@ -388,10 +399,10 @@ type BucketStore struct { // seriesLimiterFactory creates a new limiter used to limit the number of touched series by each Series() call, // or LabelName and LabelValues calls when used with matchers. seriesLimiterFactory SeriesLimiterFactory - // bytesLimiterFactory creates a new limiter used to limit the amount of bytes fetched/touched by each Series() call. bytesLimiterFactory BytesLimiterFactory - partitioner Partitioner + + partitioner Partitioner filterConfig *FilterConfig advLabelSets []labelpb.ZLabelSet @@ -413,6 +424,8 @@ type BucketStore struct { blockEstimatedMaxChunkFunc BlockEstimator indexHeaderLazyDownloadStrategy indexheader.LazyDownloadIndexHeaderFunc + + requestLoggerFunc RequestLoggerFunc } func (s *BucketStore) validate() error { @@ -449,6 +462,20 @@ func WithLogger(logger log.Logger) BucketStoreOption { } } +type RequestLoggerFunc func(ctx context.Context, log log.Logger) log.Logger + +func NoopRequestLoggerFunc(_ context.Context, logger log.Logger) log.Logger { + return logger +} + +// WithRequestLoggerFunc sets the BucketStore to use the passed RequestLoggerFunc +// to initialize logger during query time. +func WithRequestLoggerFunc(loggerFunc RequestLoggerFunc) BucketStoreOption { + return func(s *BucketStore) { + s.requestLoggerFunc = loggerFunc + } +} + // WithRegistry sets a registry that BucketStore uses to register metrics with. func WithRegistry(reg prometheus.Registerer) BucketStoreOption { return func(s *BucketStore) { @@ -583,6 +610,7 @@ func NewBucketStore( seriesBatchSize: SeriesBatchSize, sortingStrategy: sortingStrategyStore, indexHeaderLazyDownloadStrategy: indexheader.AlwaysEagerDownloadIndexHeader, + requestLoggerFunc: NoopRequestLoggerFunc, } for _, option := range options { @@ -789,7 +817,6 @@ func (s *BucketStore) addBlock(ctx context.Context, meta *metadata.Meta) (err er b, err := newBucketBlock( ctx, - log.With(s.logger, "block", meta.ULID), s.metrics, meta, s.bkt, @@ -1047,7 +1074,7 @@ func newBlockSeriesClient( ) *blockSeriesClient { var chunkr *bucketChunkReader if !req.SkipChunks { - chunkr = b.chunkReader() + chunkr = b.chunkReader(logger) } extLset := b.extLset @@ -1063,7 +1090,7 @@ func newBlockSeriesClient( mint: req.MinTime, maxt: req.MaxTime, - indexr: b.indexReader(), + indexr: b.indexReader(logger), chunkr: chunkr, seriesLimiter: seriesLimiter, chunksLimiter: chunksLimiter, @@ -1479,6 +1506,8 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store seriesLimiter = s.seriesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("series", tenant)) queryStatsEnabled = false + + logger = s.requestLoggerFunc(ctx, s.logger) ) if req.Hints != nil { @@ -1515,7 +1544,7 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store blocks := bs.getFor(req.MinTime, req.MaxTime, req.MaxResolutionWindow, reqBlockMatchers) if s.debugLogging { - debugFoundBlockSetOverview(s.logger, req.MinTime, req.MaxTime, req.MaxResolutionWindow, bs.labels, blocks) + debugFoundBlockSetOverview(logger, req.MinTime, req.MaxTime, req.MaxResolutionWindow, bs.labels, blocks) } for _, b := range blocks { @@ -1531,7 +1560,7 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store blockClient := newBlockSeriesClient( srv.Context(), - s.logger, + log.With(logger, "block", blk.meta.ULID), blk, req, seriesLimiter, @@ -1641,10 +1670,12 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store s.metrics.cachedPostingsCompressedSizeBytes.WithLabelValues(tenant).Add(float64(stats.CachedPostingsCompressedSizeSum)) s.metrics.postingsSizeBytes.WithLabelValues(tenant).Observe(float64(int(stats.PostingsFetchedSizeSum) + int(stats.PostingsTouchedSizeSum))) - level.Debug(s.logger).Log("msg", "stats query processed", - "request", req, - "tenant", tenant, - "stats", fmt.Sprintf("%+v", stats), "err", err) + if s.debugLogging { + level.Debug(logger).Log("msg", "stats query processed", + "request", req, + "tenant", tenant, + "stats", fmt.Sprintf("%+v", stats), "err", err) + } }() // Concurrently get data from all blocks. @@ -1772,6 +1803,7 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq var sets [][]string var seriesLimiter = s.seriesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("series", tenant)) var bytesLimiter = s.bytesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("bytes", tenant)) + var logger = s.requestLoggerFunc(ctx, s.logger) for _, b := range s.blocks { b := b @@ -1793,7 +1825,8 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq resHints.AddQueriedBlock(b.meta.ULID) - indexr := b.indexReader() + blockLogger := log.With(logger, "block", b.meta.ULID) + indexr := b.indexReader(blockLogger) g.Go(func() error { span, newCtx := tracing.StartSpan(gctx, "bucket_store_block_label_names", tracing.Tags{ @@ -1803,7 +1836,7 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq "block.resolution": b.meta.Thanos.Downsample.Resolution, }) defer span.Finish() - defer runutil.CloseWithLogOnErr(s.logger, indexr, "label names") + defer runutil.CloseWithLogOnErr(blockLogger, indexr, "label names") var result []string if len(reqSeriesMatchersNoExtLabels) == 0 { @@ -1834,7 +1867,7 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq } blockClient := newBlockSeriesClient( newCtx, - s.logger, + blockLogger, b, seriesReq, seriesLimiter, @@ -1981,6 +2014,7 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR var sets [][]string var seriesLimiter = s.seriesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("series", tenant)) var bytesLimiter = s.bytesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("bytes", tenant)) + var logger = s.requestLoggerFunc(ctx, s.logger) for _, b := range s.blocks { b := b @@ -2012,7 +2046,9 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR resHints.AddQueriedBlock(b.meta.ULID) - indexr := b.indexReader() + blockLogger := log.With(logger, "block", b.meta.ULID) + indexr := b.indexReader(blockLogger) + g.Go(func() error { span, newCtx := tracing.StartSpan(gctx, "bucket_store_block_label_values", tracing.Tags{ "block.id": b.meta.ULID, @@ -2021,7 +2057,7 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR "block.resolution": b.meta.Thanos.Downsample.Resolution, }) defer span.Finish() - defer runutil.CloseWithLogOnErr(s.logger, indexr, "label values") + defer runutil.CloseWithLogOnErr(blockLogger, indexr, "label values") var result []string if len(reqSeriesMatchersNoExtLabels) == 0 { @@ -2045,7 +2081,7 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR } blockClient := newBlockSeriesClient( newCtx, - s.logger, + blockLogger, b, seriesReq, seriesLimiter, @@ -2275,7 +2311,6 @@ func (s *bucketBlockSet) labelMatchers(matchers ...*labels.Matcher) ([]*labels.M // bucketBlock represents a block that is located in a bucket. It holds intermediate // state for the block on local disk. type bucketBlock struct { - logger log.Logger metrics *bucketStoreMetrics bkt objstore.BucketReader meta *metadata.Meta @@ -2302,7 +2337,6 @@ type bucketBlock struct { func newBucketBlock( ctx context.Context, - logger log.Logger, metrics *bucketStoreMetrics, meta *metadata.Meta, bkt objstore.BucketReader, @@ -2327,7 +2361,6 @@ func newBucketBlock( extLset := labels.FromMap(meta.Thanos.Labels) relabelLabels := labels.NewBuilder(extLset).Set(block.BlockIDLabel, meta.ULID.String()).Labels() b = &bucketBlock{ - logger: logger, metrics: metrics, bkt: bkt, indexCache: indexCache, @@ -2366,12 +2399,12 @@ func (b *bucketBlock) indexFilename() string { return path.Join(b.meta.ULID.String(), block.IndexFilename) } -func (b *bucketBlock) readIndexRange(ctx context.Context, off, length int64) ([]byte, error) { +func (b *bucketBlock) readIndexRange(ctx context.Context, off, length int64, logger log.Logger) ([]byte, error) { r, err := b.bkt.GetRange(ctx, b.indexFilename(), off, length) if err != nil { return nil, errors.Wrap(err, "get range reader") } - defer runutil.CloseWithLogOnErr(b.logger, r, "readIndexRange close range reader") + defer runutil.CloseWithLogOnErr(logger, r, "readIndexRange close range reader") // Preallocate the buffer with the exact size so we don't waste allocations // while progressively growing an initial small buffer. The buffer capacity @@ -2384,7 +2417,7 @@ func (b *bucketBlock) readIndexRange(ctx context.Context, off, length int64) ([] return buf.Bytes(), nil } -func (b *bucketBlock) readChunkRange(ctx context.Context, seq int, off, length int64, chunkRanges byteRanges) (*[]byte, error) { +func (b *bucketBlock) readChunkRange(ctx context.Context, seq int, off, length int64, chunkRanges byteRanges, logger log.Logger) (*[]byte, error) { if seq < 0 || seq >= len(b.chunkObjs) { return nil, errors.Errorf("unknown segment file for index %d", seq) } @@ -2394,7 +2427,7 @@ func (b *bucketBlock) readChunkRange(ctx context.Context, seq int, off, length i if err != nil { return nil, errors.Wrap(err, "get range reader") } - defer runutil.CloseWithLogOnErr(b.logger, reader, "readChunkRange close range reader") + defer runutil.CloseWithLogOnErr(logger, reader, "readChunkRange close range reader") // Get a buffer from the pool. chunkBuffer, err := b.chunkPool.Get(chunkRanges.size()) @@ -2418,14 +2451,14 @@ func (b *bucketBlock) chunkRangeReader(ctx context.Context, seq int, off, length return b.bkt.GetRange(ctx, b.chunkObjs[seq], off, length) } -func (b *bucketBlock) indexReader() *bucketIndexReader { +func (b *bucketBlock) indexReader(logger log.Logger) *bucketIndexReader { b.pendingReaders.Add(1) - return newBucketIndexReader(b) + return newBucketIndexReader(b, logger) } -func (b *bucketBlock) chunkReader() *bucketChunkReader { +func (b *bucketBlock) chunkReader(logger log.Logger) *bucketChunkReader { b.pendingReaders.Add(1) - return newBucketChunkReader(b) + return newBucketChunkReader(b, logger) } // matchRelabelLabels verifies whether the block matches the given matchers. @@ -2462,9 +2495,10 @@ type bucketIndexReader struct { loadedSeries map[storage.SeriesRef][]byte indexVersion int + logger log.Logger } -func newBucketIndexReader(block *bucketBlock) *bucketIndexReader { +func newBucketIndexReader(block *bucketBlock, logger log.Logger) *bucketIndexReader { r := &bucketIndexReader{ block: block, dec: &index.Decoder{ @@ -2472,6 +2506,7 @@ func newBucketIndexReader(block *bucketBlock) *bucketIndexReader { }, stats: &queryStats{}, loadedSeries: map[storage.SeriesRef][]byte{}, + logger: logger, } return r } @@ -2857,12 +2892,11 @@ func (r *bucketIndexReader) fetchExpandedPostingsFromCache(ctx context.Context, if !hit { return false, nil, nil } - if err := bytesLimiter.Reserve(uint64(len(dataFromCache))); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(len(dataFromCache)), PostingsTouched); err != nil { return false, nil, httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while loading expanded postings from index cache: %s", err) } - r.stats.DataDownloadedSizeSum += units.Base2Bytes(len(dataFromCache)) - r.stats.postingsTouched++ - r.stats.PostingsTouchedSizeSum += units.Base2Bytes(len(dataFromCache)) + + r.stats.add(PostingsTouched, 1, len(dataFromCache)) p, closeFns, err := r.decodeCachedPostings(dataFromCache) defer func() { for _, closeFn := range closeFns { @@ -2871,13 +2905,13 @@ func (r *bucketIndexReader) fetchExpandedPostingsFromCache(ctx context.Context, }() // If failed to decode or expand cached postings, return and expand postings again. if err != nil { - level.Error(r.block.logger).Log("msg", "failed to decode cached expanded postings, refetch postings", "id", r.block.meta.ULID.String(), "err", err) + level.Error(r.logger).Log("msg", "failed to decode cached expanded postings, refetch postings", "id", r.block.meta.ULID.String(), "err", err) return false, nil, nil } ps, err := ExpandPostingsWithContext(ctx, p) if err != nil { - level.Error(r.block.logger).Log("msg", "failed to expand cached expanded postings, refetch postings", "id", r.block.meta.ULID.String(), "err", err) + level.Error(r.logger).Log("msg", "failed to expand cached expanded postings, refetch postings", "id", r.block.meta.ULID.String(), "err", err) return false, nil, nil } @@ -2931,10 +2965,9 @@ func (r *bucketIndexReader) fetchPostings(ctx context.Context, keys []labels.Lab // Fetch postings from the cache with a single call. fromCache, _ := r.block.indexCache.FetchMultiPostings(ctx, r.block.meta.ULID, keys, tenant) for _, dataFromCache := range fromCache { - if err := bytesLimiter.Reserve(uint64(len(dataFromCache))); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(len(dataFromCache)), PostingsTouched); err != nil { return nil, closeFns, httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while loading postings from index cache: %s", err) } - r.stats.DataDownloadedSizeSum += units.Base2Bytes(len(dataFromCache)) } // Iterate over all groups and fetch posting from cache. @@ -2946,8 +2979,7 @@ func (r *bucketIndexReader) fetchPostings(ctx context.Context, keys []labels.Lab } // Get postings for the given key from cache first. if b, ok := fromCache[key]; ok { - r.stats.postingsTouched++ - r.stats.PostingsTouchedSizeSum += units.Base2Bytes(len(b)) + r.stats.add(PostingsTouched, 1, len(b)) l, closer, err := r.decodeCachedPostings(b) if err != nil { @@ -2988,10 +3020,9 @@ func (r *bucketIndexReader) fetchPostings(ctx context.Context, keys []labels.Lab start := int64(part.Start) length := int64(part.End) - start - if err := bytesLimiter.Reserve(uint64(length)); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(length), PostingsFetched); err != nil { return nil, closeFns, httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while fetching postings: %s", err) } - r.stats.DataDownloadedSizeSum += units.Base2Bytes(length) } g, ctx := errgroup.WithContext(ctx) @@ -3017,14 +3048,13 @@ func (r *bucketIndexReader) fetchPostings(ctx context.Context, keys []labels.Lab if err != nil { return errors.Wrap(err, "read postings range") } - defer runutil.CloseWithLogOnErr(r.block.logger, partReader, "readIndexRange close range reader") + defer runutil.CloseWithLogOnErr(r.logger, partReader, "readIndexRange close range reader") brdr.Reset(partReader) rdr := newPostingsReaderBuilder(ctx, brdr, ptrs[i:j], start, length) stats.postingsFetchCount++ - stats.postingsFetched += j - i - stats.PostingsFetchedSizeSum += units.Base2Bytes(int(length)) + stats.add(PostingsFetched, j-i, int(length)) for rdr.Next() { diffVarintPostings, postingsCount, keyID := rdr.AtDiffVarint() @@ -3038,12 +3068,11 @@ func (r *bucketIndexReader) fetchPostings(ctx context.Context, keys []labels.Lab return errors.Wrap(err, "encoding with snappy") } - stats.postingsTouched++ - stats.PostingsTouchedSizeSum += units.Base2Bytes(int(len(diffVarintPostings))) stats.cachedPostingsCompressions += 1 stats.CachedPostingsOriginalSizeSum += units.Base2Bytes(len(diffVarintPostings)) stats.CachedPostingsCompressedSizeSum += units.Base2Bytes(len(dataToCache)) stats.CachedPostingsCompressionTimeSum += time.Since(startCompression) + stats.add(PostingsTouched, 1, len(diffVarintPostings)) r.block.indexCache.StorePostings(r.block.meta.ULID, keys[keyID], dataToCache, tenant) } @@ -3166,10 +3195,9 @@ func (r *bucketIndexReader) PreloadSeries(ctx context.Context, ids []storage.Ser fromCache, ids := r.block.indexCache.FetchMultiSeries(ctx, r.block.meta.ULID, ids, tenant) for id, b := range fromCache { r.loadedSeries[id] = b - if err := bytesLimiter.Reserve(uint64(len(b))); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(len(b)), SeriesTouched); err != nil { return httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while loading series from index cache: %s", err) } - r.stats.DataDownloadedSizeSum += units.Base2Bytes(len(b)) } parts := r.block.partitioner.Partition(len(ids), func(i int) (start, end uint64) { @@ -3195,22 +3223,18 @@ func (r *bucketIndexReader) loadSeries(ctx context.Context, ids []storage.Series r.stats.merge(stats) }() - if bytesLimiter != nil { - if err := bytesLimiter.Reserve(uint64(end - start)); err != nil { - return httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while fetching series: %s", err) - } - stats.DataDownloadedSizeSum += units.Base2Bytes(end - start) + if err := bytesLimiter.ReserveWithType(uint64(end-start), SeriesFetched); err != nil { + return httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while fetching series: %s", err) } - b, err := r.block.readIndexRange(ctx, int64(start), int64(end-start)) + b, err := r.block.readIndexRange(ctx, int64(start), int64(end-start), r.logger) if err != nil { return errors.Wrap(err, "read series range") } stats.seriesFetchCount++ - stats.seriesFetched += len(ids) stats.SeriesFetchDurationSum += time.Since(begin) - stats.SeriesFetchedSizeSum += units.Base2Bytes(int(end - start)) + stats.add(SeriesFetched, len(ids), int(end-start)) for i, id := range ids { c := b[uint64(id)-start:] @@ -3226,7 +3250,7 @@ func (r *bucketIndexReader) loadSeries(ctx context.Context, ids []storage.Series // Inefficient, but should be rare. r.block.metrics.seriesRefetches.WithLabelValues(tenant).Inc() - level.Warn(r.block.logger).Log("msg", "series size exceeded expected size; refetching", "id", id, "series length", n+int(l), "maxSeriesSize", r.block.estimatedMaxSeriesSize) + level.Warn(r.logger).Log("msg", "series size exceeded expected size; refetching", "id", id, "series length", n+int(l), "maxSeriesSize", r.block.estimatedMaxSeriesSize) // Fetch plus to get the size of next one if exists. return r.loadSeries(ctx, ids[i:], true, uint64(id), uint64(id)+uint64(n+int(l)+1), bytesLimiter, tenant) @@ -3313,8 +3337,7 @@ func (r *bucketIndexReader) LoadSeriesForTime(ref storage.SeriesRef, lset *[]sym return false, errors.Errorf("series %d not found", ref) } - r.stats.seriesTouched++ - r.stats.SeriesTouchedSizeSum += units.Base2Bytes(len(b)) + r.stats.add(SeriesTouched, 1, len(b)) return decodeSeriesForTime(b, lset, chks, skipChunks, mint, maxt) } @@ -3416,17 +3439,19 @@ type bucketChunkReader struct { chunkBytesMtx sync.Mutex stats *queryStats chunkBytes []*[]byte // Byte slice to return to the chunk pool on close. + logger log.Logger loadingChunksMtx sync.Mutex loadingChunks bool finishLoadingChks chan struct{} } -func newBucketChunkReader(block *bucketBlock) *bucketChunkReader { +func newBucketChunkReader(block *bucketBlock, logger log.Logger) *bucketChunkReader { return &bucketChunkReader{ block: block, stats: &queryStats{}, toLoad: make([][]loadIdx, len(block.chunkObjs)), + logger: logger, } } @@ -3500,10 +3525,9 @@ func (r *bucketChunkReader) load(ctx context.Context, res []seriesEntry, aggrs [ }) for _, p := range parts { - if err := bytesLimiter.Reserve(uint64(p.End - p.Start)); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(p.End-p.Start), ChunksFetched); err != nil { return httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while fetching chunks: %s", err) } - r.stats.DataDownloadedSizeSum += units.Base2Bytes(p.End - p.Start) } for _, p := range parts { @@ -3533,12 +3557,11 @@ func (r *bucketChunkReader) loadChunks(ctx context.Context, res []seriesEntry, a if err != nil { return errors.Wrap(err, "get range reader") } - defer runutil.CloseWithLogOnErr(r.block.logger, reader, "readChunkRange close range reader") + defer runutil.CloseWithLogOnErr(r.logger, reader, "readChunkRange close range reader") bufReader := bufio.NewReaderSize(reader, r.block.estimatedMaxChunkSize) stats.chunksFetchCount++ - stats.chunksFetched += len(pIdxs) - stats.ChunksFetchedSizeSum += units.Base2Bytes(int(part.End - part.Start)) + stats.add(ChunksFetched, len(pIdxs), int(part.End-part.Start)) var ( buf []byte @@ -3601,12 +3624,12 @@ func (r *bucketChunkReader) loadChunks(ctx context.Context, res []seriesEntry, a // There is also crc32 after the chunk, but we ignore that. chunkLen = n + 1 + int(chunkDataLen) if chunkLen <= len(cb) { - err = populateChunk(&(res[pIdx.seriesEntry].chks[pIdx.chunk]), rawChunk(cb[n:chunkLen]), aggrs, r.save, calculateChunkChecksum) + c := rawChunk(cb[n:chunkLen]) + err = populateChunk(&(res[pIdx.seriesEntry].chks[pIdx.chunk]), &c, aggrs, r.save, calculateChunkChecksum) if err != nil { return errors.Wrap(err, "populate chunk") } - stats.chunksTouched++ - stats.ChunksTouchedSizeSum += units.Base2Bytes(int(chunkDataLen)) + stats.add(ChunksTouched, 1, int(chunkDataLen)) continue } @@ -3615,12 +3638,11 @@ func (r *bucketChunkReader) loadChunks(ctx context.Context, res []seriesEntry, a fetchBegin = time.Now() // Read entire chunk into new buffer. // TODO: readChunkRange call could be avoided for any chunk but last in this particular part. - if err := bytesLimiter.Reserve(uint64(chunkLen)); err != nil { + if err := bytesLimiter.ReserveWithType(uint64(chunkLen), ChunksTouched); err != nil { return httpgrpc.Errorf(int(codes.ResourceExhausted), "exceeded bytes limit while fetching chunks: %s", err) } - stats.DataDownloadedSizeSum += units.Base2Bytes(chunkLen) - nb, err := r.block.readChunkRange(ctx, seq, int64(pIdx.offset), int64(chunkLen), []byteRange{{offset: 0, length: chunkLen}}) + nb, err := r.block.readChunkRange(ctx, seq, int64(pIdx.offset), int64(chunkLen), []byteRange{{offset: 0, length: chunkLen}}, r.logger) if err != nil { return errors.Wrapf(err, "preloaded chunk too small, expecting %d, and failed to fetch full chunk", chunkLen) } @@ -3628,15 +3650,15 @@ func (r *bucketChunkReader) loadChunks(ctx context.Context, res []seriesEntry, a return errors.Errorf("preloaded chunk too small, expecting %d", chunkLen) } - stats.chunksFetchCount++ - stats.ChunksFetchedSizeSum += units.Base2Bytes(len(*nb)) - err = populateChunk(&(res[pIdx.seriesEntry].chks[pIdx.chunk]), rawChunk((*nb)[n:]), aggrs, r.save, calculateChunkChecksum) + stats.add(ChunksFetched, 1, len(*nb)) + c := rawChunk((*nb)[n:]) + err = populateChunk(&(res[pIdx.seriesEntry].chks[pIdx.chunk]), &c, aggrs, r.save, calculateChunkChecksum) if err != nil { r.block.chunkPool.Put(nb) return errors.Wrap(err, "populate chunk") } - stats.chunksTouched++ - stats.ChunksTouchedSizeSum += units.Base2Bytes(int(chunkDataLen)) + + stats.add(ChunksTouched, 1, int(chunkDataLen)) r.block.chunkPool.Put(nb) } @@ -3667,24 +3689,28 @@ func (r *bucketChunkReader) save(b []byte) ([]byte, error) { // It is used to Store API responses which don't need to introspect and validate the chunk's contents. type rawChunk []byte -func (b rawChunk) Encoding() chunkenc.Encoding { - return chunkenc.Encoding(b[0]) +func (b *rawChunk) Reset(stream []byte) { + (*b) = stream +} + +func (b *rawChunk) Encoding() chunkenc.Encoding { + return chunkenc.Encoding((*b)[0]) } -func (b rawChunk) Bytes() []byte { - return b[1:] +func (b *rawChunk) Bytes() []byte { + return (*b)[1:] } -func (b rawChunk) Compact() {} +func (b *rawChunk) Compact() {} -func (b rawChunk) Iterator(_ chunkenc.Iterator) chunkenc.Iterator { +func (b *rawChunk) Iterator(_ chunkenc.Iterator) chunkenc.Iterator { panic("invalid call") } -func (b rawChunk) Appender() (chunkenc.Appender, error) { +func (b *rawChunk) Appender() (chunkenc.Appender, error) { panic("invalid call") } -func (b rawChunk) NumSamples() int { +func (b *rawChunk) NumSamples() int { panic("invalid call") } @@ -3733,6 +3759,35 @@ type queryStats struct { DataDownloadedSizeSum units.Base2Bytes } +func (s *queryStats) add(dataType StoreDataType, dataCount int, dataSize int) { + s.mtx.Lock() + defer s.mtx.Unlock() + + switch dataType { + case PostingsFetched: + s.postingsFetched += dataCount + s.PostingsFetchedSizeSum += units.Base2Bytes(dataSize) + case PostingsTouched: + s.postingsTouched += dataCount + s.PostingsTouchedSizeSum += units.Base2Bytes(dataSize) + case SeriesFetched: + s.seriesFetched += dataCount + s.SeriesFetchedSizeSum += units.Base2Bytes(dataSize) + case SeriesTouched: + s.seriesTouched += dataCount + s.SeriesTouchedSizeSum += units.Base2Bytes(dataSize) + case ChunksFetched: + s.chunksFetched += dataCount + s.ChunksFetchedSizeSum += units.Base2Bytes(dataSize) + case ChunksTouched: + s.chunksTouched += dataCount + s.ChunksTouchedSizeSum += units.Base2Bytes(dataSize) + default: + return + } + s.DataDownloadedSizeSum += units.Base2Bytes(dataSize) +} + func (s *queryStats) merge(o *queryStats) { s.mtx.Lock() defer s.mtx.Unlock() diff --git a/pkg/store/bucket_e2e_test.go b/pkg/store/bucket_e2e_test.go index c91fb4096d..cec72b374b 100644 --- a/pkg/store/bucket_e2e_test.go +++ b/pkg/store/bucket_e2e_test.go @@ -677,6 +677,46 @@ func TestBucketStore_Series_ChunksLimiter_e2e(t *testing.T) { } } +func TestBucketStore_Series_CustomBytesLimiters_e2e(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + bkt := objstore.NewInMemBucket() + + dir := t.TempDir() + + s := prepareStoreWithTestBlocks(t, dir, bkt, false, NewChunksLimiterFactory(0), NewSeriesLimiterFactory(0), func(_ prometheus.Counter) BytesLimiter { + return &bytesLimiterMock{ + limitFunc: func(_ uint64, dataType StoreDataType) error { + if dataType == PostingsFetched { + return fmt.Errorf("error reserving data type: PostingsFetched") + } + + return nil + }, + } + }, emptyRelabelConfig, allowAllFilterConf) + testutil.Ok(t, s.store.SyncBlocks(ctx)) + + req := &storepb.SeriesRequest{ + Matchers: []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "a", Value: "1"}, + }, + MinTime: minTimeDuration.PrometheusTimestamp(), + MaxTime: maxTimeDuration.PrometheusTimestamp(), + } + + s.cache.SwapWith(noopCache{}) + srv := newStoreSeriesServer(ctx) + err := s.store.Series(req, srv) + + testutil.NotOk(t, err) + testutil.Assert(t, strings.Contains(err.Error(), "exceeded bytes limit")) + testutil.Assert(t, strings.Contains(err.Error(), "error reserving data type: PostingsFetched")) + status, ok := status.FromError(err) + testutil.Equals(t, true, ok) + testutil.Equals(t, codes.ResourceExhausted, status.Code()) +} + func TestBucketStore_LabelNames_e2e(t *testing.T) { objtesting.ForeachStore(t, func(t *testing.T, bkt objstore.Bucket) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/pkg/store/bucket_test.go b/pkg/store/bucket_test.go index 642376a33f..c0f9d5aa75 100644 --- a/pkg/store/bucket_test.go +++ b/pkg/store/bucket_test.go @@ -68,6 +68,12 @@ import ( var emptyRelabelConfig = make([]*relabel.Config, 0) +func TestRawChunkReset(t *testing.T) { + r := rawChunk([]byte{1, 2}) + r.Reset([]byte{3, 4}) + testutil.Equals(t, []byte(r), []byte{3, 4}) +} + func TestBucketBlock_Property(t *testing.T) { parameters := gopter.DefaultTestParameters() parameters.Rng.Seed(2000) @@ -216,7 +222,7 @@ func TestBucketFilterExtLabelsMatchers(t *testing.T) { }, }, } - b, _ := newBucketBlock(context.Background(), log.NewNopLogger(), newBucketStoreMetrics(nil), meta, bkt, path.Join(dir, blockID.String()), nil, nil, nil, nil, nil, nil) + b, _ := newBucketBlock(context.Background(), newBucketStoreMetrics(nil), meta, bkt, path.Join(dir, blockID.String()), nil, nil, nil, nil, nil, nil) ms := []*labels.Matcher{ {Type: labels.MatchNotEqual, Name: "a", Value: "b"}, } @@ -264,7 +270,7 @@ func TestBucketBlock_matchLabels(t *testing.T) { }, } - b, err := newBucketBlock(context.Background(), log.NewNopLogger(), newBucketStoreMetrics(nil), meta, bkt, path.Join(dir, blockID.String()), nil, nil, nil, nil, nil, nil) + b, err := newBucketBlock(context.Background(), newBucketStoreMetrics(nil), meta, bkt, path.Join(dir, blockID.String()), nil, nil, nil, nil, nil, nil) testutil.Ok(t, err) cases := []struct { @@ -694,11 +700,11 @@ func TestBucketStore_TSDBInfo(t *testing.T) { defer func() { testutil.Ok(t, bucketStore.Close()) }() testutil.Ok(t, bucketStore.SyncBlocks(ctx)) - actual := bucketStore.TSDBInfos() - sort.Slice(actual, func(i, j int) bool { - return actual[i].Labels.String() < actual[j].Labels.String() + infos := bucketStore.TSDBInfos() + slices.SortFunc(infos, func(a, b infopb.TSDBInfo) int { + return strings.Compare(a.Labels.String(), b.Labels.String()) }) - testutil.Equals(t, []infopb.TSDBInfo{ + testutil.Equals(t, infos, []infopb.TSDBInfo{ { Labels: labelpb.ZLabelSet{Labels: []labelpb.ZLabel{{Name: "a", Value: "b"}}}, MinTime: 0, @@ -714,7 +720,7 @@ func TestBucketStore_TSDBInfo(t *testing.T) { MinTime: 0, MaxTime: 2000, }, - }, actual) + }) } func TestBucketStore_Info(t *testing.T) { @@ -1080,10 +1086,10 @@ func TestReadIndexCache_LoadSeries(t *testing.T) { }, }, bkt: bkt, - logger: log.NewNopLogger(), metrics: s, indexCache: noopCache{}, } + logger := log.NewNopLogger() buf := encoding.Encbuf{} buf.PutByte(0) @@ -1100,6 +1106,7 @@ func TestReadIndexCache_LoadSeries(t *testing.T) { block: b, stats: &queryStats{}, loadedSeries: map[storage.SeriesRef][]byte{}, + logger: logger, } // Success with no refetches. @@ -1190,7 +1197,7 @@ func uploadTestBlock(t testing.TB, tmpDir string, bkt objstore.Bucket, series in dir := filepath.Join(tmpDir, "tmp") testutil.Ok(t, os.MkdirAll(dir, os.ModePerm)) - id := createBlockFromHead(t, dir, h) + id := storetestutil.CreateBlockFromHead(t, dir, h) bdir := filepath.Join(dir, id.String()) meta, err := metadata.ReadFromDir(bdir) testutil.Ok(t, err) @@ -1231,18 +1238,6 @@ func appendTestData(t testing.TB, app storage.Appender, series int) { testutil.Ok(t, app.Commit()) } -func createBlockFromHead(t testing.TB, dir string, head *tsdb.Head) ulid.ULID { - compactor, err := tsdb.NewLeveledCompactor(context.Background(), nil, log.NewNopLogger(), []int64{1000000}, nil, nil) - testutil.Ok(t, err) - testutil.Ok(t, os.MkdirAll(dir, 0777)) - - // Add +1 millisecond to block maxt because block intervals are half-open: [b.MinTime, b.MaxTime). - // Because of this block intervals are always +1 than the total samples it includes. - ulid, err := compactor.Write(dir, head, head.MinTime(), head.MaxTime()+1, nil) - testutil.Ok(t, err) - return ulid -} - // Very similar benchmark to ths: https://github.com/prometheus/prometheus/blob/1d1732bc25cc4b47f513cb98009a4eb91879f175/tsdb/querier_bench_test.go#L82, // but with postings results check when run as test. func benchmarkExpandedPostings( @@ -1277,6 +1272,7 @@ func benchmarkExpandedPostings( }) iRegexBigValueSet := labels.MustNewMatcher(labels.MatchRegexp, "uniq", strings.Join(bigValueSet, "|")) + logger := log.NewNopLogger() series = series / 5 cases := []struct { name string @@ -1309,7 +1305,6 @@ func benchmarkExpandedPostings( for _, c := range cases { t.Run(c.name, func(t testutil.TB) { b := &bucketBlock{ - logger: log.NewNopLogger(), metrics: newBucketStoreMetrics(nil), indexHeaderReader: r, indexCache: noopCache{}, @@ -1318,7 +1313,7 @@ func benchmarkExpandedPostings( partitioner: NewGapBasedPartitioner(PartitionerMaxGapSize), } - indexr := newBucketIndexReader(b) + indexr := newBucketIndexReader(b, logger) t.ResetTimer() for i := 0; i < t.N(); i++ { @@ -1342,7 +1337,6 @@ func TestExpandedPostingsEmptyPostings(t *testing.T) { r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id, DefaultPostingOffsetInMemorySampling, indexheader.NewBinaryReaderMetrics(nil)) testutil.Ok(t, err) b := &bucketBlock{ - logger: log.NewNopLogger(), metrics: newBucketStoreMetrics(nil), indexHeaderReader: r, indexCache: noopCache{}, @@ -1351,7 +1345,8 @@ func TestExpandedPostingsEmptyPostings(t *testing.T) { partitioner: NewGapBasedPartitioner(PartitionerMaxGapSize), } - indexr := newBucketIndexReader(b) + logger := log.NewNopLogger() + indexr := newBucketIndexReader(b, logger) matcher1 := labels.MustNewMatcher(labels.MatchEqual, "j", "foo") // Match nothing. matcher2 := labels.MustNewMatcher(labels.MatchRegexp, "i", "500.*") @@ -1376,7 +1371,6 @@ func TestLazyExpandedPostingsEmptyPostings(t *testing.T) { r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id, DefaultPostingOffsetInMemorySampling, indexheader.NewBinaryReaderMetrics(nil)) testutil.Ok(t, err) b := &bucketBlock{ - logger: log.NewNopLogger(), metrics: newBucketStoreMetrics(nil), indexHeaderReader: r, indexCache: noopCache{}, @@ -1386,7 +1380,8 @@ func TestLazyExpandedPostingsEmptyPostings(t *testing.T) { estimatedMaxSeriesSize: 20, } - indexr := newBucketIndexReader(b) + logger := log.NewNopLogger() + indexr := newBucketIndexReader(b, logger) // matcher1 and matcher2 will match nothing after intersection. matcher1 := labels.MustNewMatcher(labels.MatchEqual, "j", "foo") matcher2 := labels.MustNewMatcher(labels.MatchRegexp, "n", "1_.*") @@ -1491,7 +1486,7 @@ func benchBucketSeries(t testutil.TB, sampleType chunkenc.ValueType, skipChunk, SkipChunks: t.IsBenchmark() || skipChunk, SampleType: sampleType, }) - id := createBlockFromHead(t, blockDir, head) + id := storetestutil.CreateBlockFromHead(t, blockDir, head) testutil.Ok(t, head.Close()) blockIDDir := filepath.Join(blockDir, id.String()) meta, err := metadata.ReadFromDir(blockIDDir) @@ -1708,7 +1703,7 @@ func TestBucketSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { testutil.Ok(t, app.Commit()) blockDir := filepath.Join(tmpDir, "tmp") - id := createBlockFromHead(t, blockDir, h) + id := storetestutil.CreateBlockFromHead(t, blockDir, h) meta, err := metadata.InjectThanos(log.NewNopLogger(), filepath.Join(blockDir, id.String()), thanosMeta, nil) testutil.Ok(t, err) @@ -1716,7 +1711,6 @@ func TestBucketSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { b1 = &bucketBlock{ indexCache: indexCache, - logger: logger, metrics: newBucketStoreMetrics(nil), bkt: bkt, meta: meta, @@ -1749,7 +1743,7 @@ func TestBucketSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { testutil.Ok(t, app.Commit()) blockDir := filepath.Join(tmpDir, "tmp2") - id := createBlockFromHead(t, blockDir, h) + id := storetestutil.CreateBlockFromHead(t, blockDir, h) meta, err := metadata.InjectThanos(log.NewNopLogger(), filepath.Join(blockDir, id.String()), thanosMeta, nil) testutil.Ok(t, err) @@ -1757,7 +1751,6 @@ func TestBucketSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { b2 = &bucketBlock{ indexCache: indexCache, - logger: logger, metrics: newBucketStoreMetrics(nil), bkt: bkt, meta: meta, @@ -1789,6 +1782,7 @@ func TestBucketSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { seriesLimiterFactory: NewSeriesLimiterFactory(0), bytesLimiterFactory: NewBytesLimiterFactory(0), seriesBatchSize: SeriesBatchSize, + requestLoggerFunc: NoopRequestLoggerFunc, } t.Run("invoke series for one block. Fill the cache on the way.", func(t *testing.T) { @@ -2043,7 +2037,7 @@ func TestSeries_BlockWithMultipleChunks(t *testing.T) { testutil.Ok(t, app.Commit()) } - blk := createBlockFromHead(t, headOpts.ChunkDirRoot, h) + blk := storetestutil.CreateBlockFromHead(t, headOpts.ChunkDirRoot, h) thanosMeta := metadata.Thanos{ Labels: labels.FromStrings("ext1", "1").Map(), @@ -2356,7 +2350,7 @@ func createBlockWithOneSeriesWithStep(t testutil.TB, dir string, lbls labels.Lab } testutil.Ok(t, app.Commit()) - return createBlockFromHead(t, dir, h) + return storetestutil.CreateBlockFromHead(t, dir, h) } func setupStoreForHintsTest(t *testing.T) (testutil.TB, *BucketStore, []*storepb.Series, []*storepb.Series, ulid.ULID, ulid.ULID, func()) { @@ -2393,7 +2387,7 @@ func setupStoreForHintsTest(t *testing.T) (testutil.TB, *BucketStore, []*storepb PrependLabels: extLset, Random: random, }) - block1 := createBlockFromHead(t, bktDir, head) + block1 := storetestutil.CreateBlockFromHead(t, bktDir, head) testutil.Ok(t, head.Close()) head2, seriesSet2 := storetestutil.CreateHeadWithSeries(t, 1, storetestutil.HeadGenOptions{ TSDBDir: filepath.Join(tmpDir, "1"), @@ -2402,7 +2396,7 @@ func setupStoreForHintsTest(t *testing.T) (testutil.TB, *BucketStore, []*storepb PrependLabels: extLset, Random: random, }) - block2 := createBlockFromHead(t, bktDir, head2) + block2 := storetestutil.CreateBlockFromHead(t, bktDir, head2) testutil.Ok(t, head2.Close()) for _, blockID := range []ulid.ULID{block1, block2} { @@ -2606,7 +2600,7 @@ func TestSeries_ChunksHaveHashRepresentation(t *testing.T) { } testutil.Ok(t, app.Commit()) - blk := createBlockFromHead(t, headOpts.ChunkDirRoot, h) + blk := storetestutil.CreateBlockFromHead(t, headOpts.ChunkDirRoot, h) thanosMeta := metadata.Thanos{ Labels: labels.FromStrings("ext1", "1").Map(), @@ -2754,7 +2748,7 @@ func BenchmarkBucketBlock_readChunkRange(b *testing.B) { testutil.Ok(b, err) // Create a bucket block with only the dependencies we need for the benchmark. - blk, err := newBucketBlock(context.Background(), logger, newBucketStoreMetrics(nil), blockMeta, bkt, tmpDir, nil, chunkPool, nil, nil, nil, nil) + blk, err := newBucketBlock(context.Background(), newBucketStoreMetrics(nil), blockMeta, bkt, tmpDir, nil, chunkPool, nil, nil, nil, nil) testutil.Ok(b, err) b.ResetTimer() @@ -2763,7 +2757,7 @@ func BenchmarkBucketBlock_readChunkRange(b *testing.B) { offset := int64(0) length := readLengths[n%len(readLengths)] - _, err := blk.readChunkRange(ctx, 0, offset, length, byteRanges{{offset: 0, length: int(length)}}) + _, err := blk.readChunkRange(ctx, 0, offset, length, byteRanges{{offset: 0, length: int(length)}}, logger) if err != nil { b.Fatal(err.Error()) } @@ -2805,7 +2799,7 @@ func prepareBucket(b *testing.B, resolutionLevel compact.ResolutionLevel) (*buck Random: rand.New(rand.NewSource(120)), SkipChunks: true, }) - blockID := createBlockFromHead(b, tmpDir, head) + blockID := storetestutil.CreateBlockFromHead(b, tmpDir, head) // Upload the block to the bucket. thanosMeta := metadata.Thanos{ @@ -2843,7 +2837,7 @@ func prepareBucket(b *testing.B, resolutionLevel compact.ResolutionLevel) (*buck testutil.Ok(b, err) // Create a bucket block with only the dependencies we need for the benchmark. - blk, err := newBucketBlock(context.Background(), logger, newBucketStoreMetrics(nil), blockMeta, bkt, tmpDir, indexCache, chunkPool, indexHeaderReader, partitioner, nil, nil) + blk, err := newBucketBlock(context.Background(), newBucketStoreMetrics(nil), blockMeta, bkt, tmpDir, indexCache, chunkPool, indexHeaderReader, partitioner, nil, nil) testutil.Ok(b, err) return blk, blockMeta } @@ -3459,6 +3453,7 @@ func TestExpandedPostingsRace(t *testing.T) { testutil.Ok(t, bkt.Close()) }) + logger := log.NewNopLogger() // Create a block. head, _ := storetestutil.CreateHeadWithSeries(t, 0, storetestutil.HeadGenOptions{ TSDBDir: filepath.Join(tmpDir, "head"), @@ -3469,7 +3464,7 @@ func TestExpandedPostingsRace(t *testing.T) { Random: rand.New(rand.NewSource(120)), SkipChunks: true, }) - blockID := createBlockFromHead(t, tmpDir, head) + blockID := storetestutil.CreateBlockFromHead(t, tmpDir, head) bucketBlocks := make([]*bucketBlock, 0, blockCount) @@ -3498,7 +3493,6 @@ func TestExpandedPostingsRace(t *testing.T) { blk, err := newBucketBlock( context.Background(), - log.NewLogfmtLogger(os.Stderr), newBucketStoreMetrics(nil), m, bkt, @@ -3543,7 +3537,7 @@ func TestExpandedPostingsRace(t *testing.T) { i := i bb := bb go func(i int, bb *bucketBlock) { - refs, err := bb.indexReader().ExpandedPostings(context.Background(), m, NewBytesLimiterFactory(0)(nil), false, dummyCounter, tenancy.DefaultTenant) + refs, err := bb.indexReader(logger).ExpandedPostings(context.Background(), m, NewBytesLimiterFactory(0)(nil), false, dummyCounter, tenancy.DefaultTenant) testutil.Ok(t, err) defer wg.Done() @@ -3606,7 +3600,7 @@ func TestBucketStoreDedupOnBlockSeriesSet(t *testing.T) { testutil.Ok(t, err) testutil.Ok(t, app.Commit()) - id := createBlockFromHead(t, auxDir, h) + id := storetestutil.CreateBlockFromHead(t, auxDir, h) auxBlockDir := filepath.Join(auxDir, id.String()) _, err = metadata.InjectThanos(log.NewNopLogger(), auxBlockDir, metadata.Thanos{ @@ -3825,7 +3819,7 @@ func TestBucketStoreStreamingSeriesLimit(t *testing.T) { testutil.Ok(t, err) testutil.Ok(t, app.Commit()) - id := createBlockFromHead(t, auxDir, h) + id := storetestutil.CreateBlockFromHead(t, auxDir, h) auxBlockDir := filepath.Join(auxDir, id.String()) _, err = metadata.InjectThanos(log.NewNopLogger(), auxBlockDir, metadata.Thanos{ @@ -3846,6 +3840,9 @@ func TestBucketStoreStreamingSeriesLimit(t *testing.T) { }) testutil.Ok(t, err) + firstBytesLimiterChecked := false + secondBytesLimiterChecked := false + // Set series limit to 2. Only pass if series limiter applies // for lazy postings only. bucketStore, err := NewBucketStore( @@ -3854,7 +3851,24 @@ func TestBucketStoreStreamingSeriesLimit(t *testing.T) { "", NewChunksLimiterFactory(10e6), NewSeriesLimiterFactory(2), - NewBytesLimiterFactory(10e6), + func(_ prometheus.Counter) BytesLimiter { + return &compositeBytesLimiterMock{ + limiters: []BytesLimiter{ + &bytesLimiterMock{ + limitFunc: func(_ uint64, _ StoreDataType) error { + firstBytesLimiterChecked = true + return nil + }, + }, + &bytesLimiterMock{ + limitFunc: func(_ uint64, _ StoreDataType) error { + secondBytesLimiterChecked = true + return nil + }, + }, + }, + } + }, NewGapBasedPartitioner(PartitionerMaxGapSize), 20, true, @@ -3885,4 +3899,27 @@ func TestBucketStoreStreamingSeriesLimit(t *testing.T) { srv := newStoreSeriesServer(context.Background()) testutil.Ok(t, bucketStore.Series(req, srv)) testutil.Equals(t, 2, len(srv.SeriesSet)) + testutil.Equals(t, true, firstBytesLimiterChecked) + testutil.Equals(t, true, secondBytesLimiterChecked) +} + +type bytesLimiterMock struct { + limitFunc func(uint64, StoreDataType) error +} + +func (m *bytesLimiterMock) ReserveWithType(num uint64, dataType StoreDataType) error { + return m.limitFunc(num, dataType) +} + +type compositeBytesLimiterMock struct { + limiters []BytesLimiter +} + +func (m *compositeBytesLimiterMock) ReserveWithType(num uint64, dataType StoreDataType) error { + for _, l := range m.limiters { + if err := l.ReserveWithType(num, dataType); err != nil { + return err + } + } + return nil } diff --git a/pkg/store/flushable.go b/pkg/store/flushable.go index 6be9c544c5..33680c3c89 100644 --- a/pkg/store/flushable.go +++ b/pkg/store/flushable.go @@ -16,6 +16,7 @@ type sortingStrategy uint64 const ( sortingStrategyStore sortingStrategy = iota + 1 sortingStrategyNone + sortingStrategyStoreSendNoop ) // flushableServer is an extension of storepb.Store_SeriesServer with a Flush method. @@ -34,6 +35,8 @@ func newFlushableServer( return &resortingServer{Store_SeriesServer: upstream} case sortingStrategyNone: return &passthroughServer{Store_SeriesServer: upstream} + case sortingStrategyStoreSendNoop: + return &resortingServer{Store_SeriesServer: upstream, notSend: true} default: // should not happen. panic("unexpected sorting strategy") @@ -53,11 +56,15 @@ func (p *passthroughServer) Flush() error { return nil } // Data is resorted and sent to an upstream server upon calling Flush. type resortingServer struct { storepb.Store_SeriesServer - series []*storepb.Series + series []*storepb.Series + notSend bool } func (r *resortingServer) Send(response *storepb.SeriesResponse) error { if response.GetSeries() == nil { + if r.notSend { + return nil + } return r.Store_SeriesServer.Send(response) } @@ -74,6 +81,9 @@ func (r *resortingServer) Flush() error { labelpb.ZLabelsToPromLabels(b.Labels), ) }) + if r.notSend { + return nil + } for _, response := range r.series { if err := r.Store_SeriesServer.Send(storepb.NewSeriesResponse(response)); err != nil { return err diff --git a/pkg/store/lazy_postings.go b/pkg/store/lazy_postings.go index 9469be9b47..1858b7dee4 100644 --- a/pkg/store/lazy_postings.go +++ b/pkg/store/lazy_postings.go @@ -8,6 +8,7 @@ import ( "math" "strings" + "github.com/go-kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" @@ -54,14 +55,18 @@ func optimizePostingsFetchByDownloadedBytes(r *bucketIndexReader, postingGroups return nil, false, errors.Wrapf(err, "postings offsets for %s", pg.name) } - for _, r := range rngs { - if r == indexheader.NotFoundRange { + for _, rng := range rngs { + if rng == indexheader.NotFoundRange { continue } + if rng.End <= rng.Start { + level.Error(r.logger).Log("msg", "invalid index range, fallback to non lazy posting optimization") + return postingGroups, false, nil + } // Each range starts from the #entries field which is 4 bytes. // Need to subtract it when calculating number of postings. // https://github.com/prometheus/prometheus/blob/v2.46.0/tsdb/docs/format/index.md. - pg.cardinality += (r.End - r.Start - 4) / 4 + pg.cardinality += (rng.End - rng.Start - 4) / 4 } // If the posting group adds keys, 0 cardinality means the posting doesn't exist. // If the posting group removes keys, no posting ranges found is fine as it is a noop. diff --git a/pkg/store/lazy_postings_test.go b/pkg/store/lazy_postings_test.go index 08e30b6d5b..bec95ac413 100644 --- a/pkg/store/lazy_postings_test.go +++ b/pkg/store/lazy_postings_test.go @@ -254,12 +254,12 @@ func (h *mockIndexHeaderReader) LabelNames() ([]string, error) { return nil, nil func TestOptimizePostingsFetchByDownloadedBytes(t *testing.T) { ctx := context.Background() - logger := log.NewNopLogger() dir := t.TempDir() bkt, err := filesystem.NewBucket(dir) testutil.Ok(t, err) defer func() { testutil.Ok(t, bkt.Close()) }() + logger := log.NewNopLogger() inputError := errors.New("random") blockID := ulid.MustNew(1, nil) meta := &metadata.Meta{ @@ -555,9 +555,9 @@ func TestOptimizePostingsFetchByDownloadedBytes(t *testing.T) { t.Run(tc.name, func(t *testing.T) { headerReader := &mockIndexHeaderReader{postings: tc.inputPostings, err: tc.inputError} registry := prometheus.NewRegistry() - block, err := newBucketBlock(ctx, logger, newBucketStoreMetrics(registry), meta, bkt, path.Join(dir, blockID.String()), nil, nil, headerReader, nil, nil, nil) + block, err := newBucketBlock(ctx, newBucketStoreMetrics(registry), meta, bkt, path.Join(dir, blockID.String()), nil, nil, headerReader, nil, nil, nil) testutil.Ok(t, err) - ir := newBucketIndexReader(block) + ir := newBucketIndexReader(block, logger) dummyCounter := promauto.With(registry).NewCounter(prometheus.CounterOpts{Name: "test"}) pgs, emptyPosting, err := optimizePostingsFetchByDownloadedBytes(ir, tc.postingGroups, tc.seriesMaxSize, tc.seriesMatchRatio, dummyCounter) if err != nil { diff --git a/pkg/store/limiter.go b/pkg/store/limiter.go index f564e11443..993330cc85 100644 --- a/pkg/store/limiter.go +++ b/pkg/store/limiter.go @@ -34,7 +34,7 @@ type BytesLimiter interface { // Reserve bytes out of the total amount of bytes enforced by the limiter. // Returns an error if the limit has been exceeded. This function must be // goroutine safe. - Reserve(num uint64) error + ReserveWithType(num uint64, dataType StoreDataType) error } // ChunksLimiterFactory is used to create a new ChunksLimiter. The factory is useful for @@ -64,6 +64,10 @@ func NewLimiter(limit uint64, ctr prometheus.Counter) *Limiter { // Reserve implements ChunksLimiter. func (l *Limiter) Reserve(num uint64) error { + return l.ReserveWithType(num, 0) +} + +func (l *Limiter) ReserveWithType(num uint64, _ StoreDataType) error { if l == nil { return nil } diff --git a/pkg/store/prometheus_test.go b/pkg/store/prometheus_test.go index ac7060a04a..f4b694e5ba 100644 --- a/pkg/store/prometheus_test.go +++ b/pkg/store/prometheus_test.go @@ -218,17 +218,6 @@ func TestPrometheusStore_SeriesLabels_e2e(t *testing.T) { }, expectedErr: errors.New("rpc error: code = InvalidArgument desc = no matchers specified (excluding external labels)"), }, - { - req: &storepb.SeriesRequest{ - SkipChunks: true, - Matchers: []storepb.LabelMatcher{ - {Type: storepb.LabelMatcher_RE, Name: "wrong-chars-in-label-name(hyphen)", Value: "adsf"}, - }, - MinTime: baseT - 10000000000, - MaxTime: baseT + 10000000000, - }, - expectedErr: errors.New("rpc error: code = InvalidArgument desc = expected 2xx response, got 400. Body: {\"status\":\"error\",\"errorType\":\"bad_data\",\"error\":\"invalid parameter \\\"match[]\\\": 1:7: parse error: unexpected character inside braces: '-'\"}"), - }, { req: &storepb.SeriesRequest{ SkipChunks: true, diff --git a/pkg/store/proxy.go b/pkg/store/proxy.go index 723c3f667f..311e0d5986 100644 --- a/pkg/store/proxy.go +++ b/pkg/store/proxy.go @@ -319,25 +319,10 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. if !match { return nil } + if len(matchers) == 0 { return status.Error(codes.InvalidArgument, errors.New("no matchers specified (excluding selector labels)").Error()) } - storeMatchers, _ := storepb.PromMatchersToMatchers(matchers...) // Error would be returned by matchesExternalLabels, so skip check. - - storeDebugMsgs := []string{} - r := &storepb.SeriesRequest{ - MinTime: originalRequest.MinTime, - MaxTime: originalRequest.MaxTime, - Matchers: storeMatchers, - Aggregates: originalRequest.Aggregates, - MaxResolutionWindow: originalRequest.MaxResolutionWindow, - SkipChunks: originalRequest.SkipChunks, - QueryHints: originalRequest.QueryHints, - PartialResponseDisabled: originalRequest.PartialResponseDisabled, - PartialResponseStrategy: originalRequest.PartialResponseStrategy, - ShardInfo: originalRequest.ShardInfo, - WithoutReplicaLabels: originalRequest.WithoutReplicaLabels, - } // We may arrive here either via the promql engine // or as a result of a grpc call in layered queries @@ -368,31 +353,29 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. mp[key1][key2]++ } - for _, st := range s.stores() { - // We might be able to skip the store if its meta information indicates it cannot have series matching our query. - if ok, reason := storeMatches(ctx, st, s.debugLogging, originalRequest.MinTime, originalRequest.MaxTime, matchers...); !ok { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) - } - continue - } - matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) - if !matches { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) - } - continue - } - storeLabelSets = append(storeLabelSets, extraMatchers...) - - stores = append(stores, st) + stores, storeLabelSets, storeDebugMsgs := s.matchingStores(ctx, originalRequest.MinTime, originalRequest.MaxTime, matchers) + for _, st := range stores { bumpCounter(st.GroupKey(), st.ReplicaKey(), groupReplicaStores) } if len(stores) == 0 { level.Debug(reqLogger).Log("err", ErrorNoStoresMatched, "stores", strings.Join(storeDebugMsgs, ";")) return nil } - r.Matchers = append(r.Matchers, MatchersForLabelSets(storeLabelSets)...) + + storeMatchers, _ := storepb.PromMatchersToMatchers(matchers...) // Error would be returned by matchesExternalLabels, so skip check. + r := &storepb.SeriesRequest{ + MinTime: originalRequest.MinTime, + MaxTime: originalRequest.MaxTime, + Matchers: append(storeMatchers, MatchersForLabelSets(storeLabelSets)...), + Aggregates: originalRequest.Aggregates, + MaxResolutionWindow: originalRequest.MaxResolutionWindow, + SkipChunks: originalRequest.SkipChunks, + QueryHints: originalRequest.QueryHints, + PartialResponseDisabled: originalRequest.PartialResponseDisabled, + PartialResponseStrategy: originalRequest.PartialResponseStrategy, + ShardInfo: originalRequest.ShardInfo, + WithoutReplicaLabels: originalRequest.WithoutReplicaLabels, + } storeResponses := make([]respSet, 0, len(stores)) @@ -428,9 +411,6 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. for _, st := range stores { st := st - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) - } respSet, err := newAsyncRespSet(ctx, st, r, s.responseTimeout, s.retrievalStrategy, &s.buffers, r.ShardInfo, reqLogger, s.metrics.emptyStreamResponses) if err != nil { @@ -496,134 +476,67 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. return nil } -// storeMatches returns boolean if the given store may hold data for the given label matchers, time ranges and debug store matches gathered from context. -func storeMatches(ctx context.Context, s Client, debugLogging bool, mint, maxt int64, matchers ...*labels.Matcher) (ok bool, reason string) { - var storeDebugMatcher [][]*labels.Matcher - if ctxVal := ctx.Value(StoreMatcherKey); ctxVal != nil { - if value, ok := ctxVal.([][]*labels.Matcher); ok { - storeDebugMatcher = value - } - } - - storeMinTime, storeMaxTime := s.TimeRange() - if mint > storeMaxTime || maxt < storeMinTime { - if debugLogging { - reason = fmt.Sprintf("does not have data within this time period: [%v,%v]. Store time ranges: [%v,%v]", mint, maxt, storeMinTime, storeMaxTime) - } - return false, reason - } - - if ok, reason := storeMatchDebugMetadata(s, storeDebugMatcher); !ok { - return false, reason - } - - extLset := s.LabelSets() - if !labelSetsMatch(matchers, extLset...) { - if debugLogging { - reason = fmt.Sprintf("external labels %v does not match request label matchers: %v", extLset, matchers) - } - return false, reason - } - return true, "" -} - -// storeMatchDebugMetadata return true if the store's address match the storeDebugMatchers. -func storeMatchDebugMetadata(s Client, storeDebugMatchers [][]*labels.Matcher) (ok bool, reason string) { - if len(storeDebugMatchers) == 0 { - return true, "" - } - - addr, isLocal := s.Addr() - if isLocal { - return false, "the store is not remote, cannot match __address__" +// LabelNames returns all known label names. +func (s *ProxyStore) LabelNames(ctx context.Context, originalRequest *storepb.LabelNamesRequest) (*storepb.LabelNamesResponse, error) { + // TODO(bwplotka): This should be part of request logger, otherwise it does not make much sense. Also, could be + // tiggered by tracing span to reduce cognitive load. + reqLogger := log.With(s.logger, "component", "proxy") + if s.debugLogging { + reqLogger = log.With(reqLogger, "request", originalRequest.String()) } - - match := false - for _, sm := range storeDebugMatchers { - match = match || labelSetsMatch(sm, labels.FromStrings("__address__", addr)) + match, matchers, err := matchesExternalLabels(originalRequest.Matchers, s.selectorLabels) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) } if !match { - return false, fmt.Sprintf("__address__ %v does not match debug store metadata matchers: %v", addr, storeDebugMatchers) - } - return true, "" -} - -// labelSetsMatch returns false if all label-set do not match the matchers (aka: OR is between all label-sets). -func labelSetsMatch(matchers []*labels.Matcher, lset ...labels.Labels) bool { - if len(lset) == 0 { - return true - } - - for _, ls := range lset { - notMatched := false - for _, m := range matchers { - if lv := ls.Get(m.Name); ls.Has(m.Name) && !m.Matches(lv) { - notMatched = true - break - } - } - if !notMatched { - return true - } + return &storepb.LabelNamesResponse{}, nil } - return false -} - -// LabelNames returns all known label names. -func (s *ProxyStore) LabelNames(ctx context.Context, r *storepb.LabelNamesRequest) ( - *storepb.LabelNamesResponse, error, -) { - var ( - warnings []string - names [][]string - mtx sync.Mutex - g, gctx = errgroup.WithContext(ctx) - storeDebugMsgs []string - ) // We may arrive here either via the promql engine // or as a result of a grpc call in layered queries - tenant, foundTenant := tenancy.GetTenantFromGRPCMetadata(gctx) + tenant, foundTenant := tenancy.GetTenantFromGRPCMetadata(ctx) if !foundTenant { - level.Debug(s.logger).Log("msg", "using tenant from context instead of metadata") - if gctx.Value(tenancy.TenantKey) != nil { - tenant = gctx.Value(tenancy.TenantKey).(string) + level.Debug(reqLogger).Log("msg", "using tenant from context instead of metadata") + if ctx.Value(tenancy.TenantKey) != nil { + tenant = ctx.Value(tenancy.TenantKey).(string) } } - gctx = metadata.AppendToOutgoingContext(gctx, tenancy.DefaultTenantHeader, tenant) + ctx = metadata.AppendToOutgoingContext(ctx, tenancy.DefaultTenantHeader, tenant) level.Debug(s.logger).Log("msg", "Tenant info in LabelNames()", "tenant", tenant) - for _, st := range s.stores() { - st := st - - // We might be able to skip the store if its meta information indicates it cannot have series matching our query. - if ok, reason := storeMatches(gctx, st, s.debugLogging, r.Start, r.End); !ok { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) - } - continue - } - matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) - if !matches { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) - } - continue - } + stores, storeLabelSets, storeDebugMsgs := s.matchingStores(ctx, originalRequest.Start, originalRequest.End, matchers) + if len(stores) == 0 { + level.Debug(reqLogger).Log("err", ErrorNoStoresMatched, "stores", strings.Join(storeDebugMsgs, ";")) + return &storepb.LabelNamesResponse{}, nil + } + storeMatchers, _ := storepb.PromMatchersToMatchers(matchers...) // Error would be returned by matchesExternalLabels, so skip check. + r := &storepb.LabelNamesRequest{ + PartialResponseDisabled: originalRequest.PartialResponseDisabled, + Start: originalRequest.Start, + End: originalRequest.End, + Matchers: append(storeMatchers, MatchersForLabelSets(storeLabelSets)...), + WithoutReplicaLabels: originalRequest.WithoutReplicaLabels, + } - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) - } + var ( + warnings []string + names [][]string + mtx sync.Mutex + g, gctx = errgroup.WithContext(ctx) + ) + for _, st := range stores { + st := st + storeID, storeAddr, isLocalStore := storeInfo(st) g.Go(func() error { - resp, err := st.LabelNames(gctx, &storepb.LabelNamesRequest{ - PartialResponseDisabled: r.PartialResponseDisabled, - Start: r.Start, - End: r.End, - Matchers: append(r.Matchers, MatchersForLabelSets(extraMatchers)...), - WithoutReplicaLabels: r.WithoutReplicaLabels, + span, spanCtx := tracing.StartSpan(gctx, "proxy.label_names", tracing.Tags{ + "store.id": storeID, + "store.addr": storeAddr, + "store.is_local": isLocalStore, }) + defer span.Finish() + resp, err := st.LabelNames(spanCtx, r) if err != nil { err = errors.Wrapf(err, "fetch label names from store %s", st) if r.PartialResponseDisabled { @@ -644,12 +557,12 @@ func (s *ProxyStore) LabelNames(ctx context.Context, r *storepb.LabelNamesReques return nil }) } + level.Debug(reqLogger).Log("msg", "LabelNames: started fanout streams", "status", strings.Join(storeDebugMsgs, ";")) if err := g.Wait(); err != nil { return nil, err } - level.Debug(s.logger).Log("msg", strings.Join(storeDebugMsgs, ";")) return &storepb.LabelNamesResponse{ Names: strutil.MergeUnsortedSlices(names...), Warnings: warnings, @@ -657,60 +570,66 @@ func (s *ProxyStore) LabelNames(ctx context.Context, r *storepb.LabelNamesReques } // LabelValues returns all known label values for a given label name. -func (s *ProxyStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequest) ( +func (s *ProxyStore) LabelValues(ctx context.Context, originalRequest *storepb.LabelValuesRequest) ( *storepb.LabelValuesResponse, error, ) { - var ( - warnings []string - all [][]string - mtx sync.Mutex - g, gctx = errgroup.WithContext(ctx) - storeDebugMsgs []string - ) - if r.Label == "" { + // TODO(bwplotka): This should be part of request logger, otherwise it does not make much sense. Also, could be + // tiggered by tracing span to reduce cognitive load. + reqLogger := log.With(s.logger, "component", "proxy") + if s.debugLogging { + reqLogger = log.With(reqLogger, "request", originalRequest.String()) + } + + if originalRequest.Label == "" { return nil, status.Error(codes.InvalidArgument, "label name parameter cannot be empty") } + match, matchers, err := matchesExternalLabels(originalRequest.Matchers, s.selectorLabels) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + if !match { + return &storepb.LabelValuesResponse{}, nil + } + // We may arrive here either via the promql engine // or as a result of a grpc call in layered queries - tenant, foundTenant := tenancy.GetTenantFromGRPCMetadata(gctx) + tenant, foundTenant := tenancy.GetTenantFromGRPCMetadata(ctx) if !foundTenant { - level.Debug(s.logger).Log("msg", "using tenant from context instead of metadata") - if gctx.Value(tenancy.TenantKey) != nil { - tenant = gctx.Value(tenancy.TenantKey).(string) + level.Debug(reqLogger).Log("msg", "using tenant from context instead of metadata") + if ctx.Value(tenancy.TenantKey) != nil { + tenant = ctx.Value(tenancy.TenantKey).(string) } } - gctx = metadata.AppendToOutgoingContext(gctx, tenancy.DefaultTenantHeader, tenant) - level.Debug(s.logger).Log("msg", "Tenant info in LabelValues()", "tenant", tenant) - - for _, st := range s.stores() { - st := st + ctx = metadata.AppendToOutgoingContext(ctx, tenancy.DefaultTenantHeader, tenant) + level.Debug(reqLogger).Log("msg", "Tenant info in LabelValues()", "tenant", tenant) - storeAddr, isLocalStore := st.Addr() - storeID := labelpb.PromLabelSetsToString(st.LabelSets()) - if storeID == "" { - storeID = "Store Gateway" - } + stores, storeLabelSets, storeDebugMsgs := s.matchingStores(ctx, originalRequest.Start, originalRequest.End, matchers) + if len(stores) == 0 { + level.Debug(reqLogger).Log("err", ErrorNoStoresMatched, "stores", strings.Join(storeDebugMsgs, ";")) + return &storepb.LabelValuesResponse{}, nil + } + storeMatchers, _ := storepb.PromMatchersToMatchers(matchers...) // Error would be returned by matchesExternalLabels, so skip check. + r := &storepb.LabelValuesRequest{ + Label: originalRequest.Label, + PartialResponseDisabled: originalRequest.PartialResponseDisabled, + Start: originalRequest.Start, + End: originalRequest.End, + Matchers: append(storeMatchers, MatchersForLabelSets(storeLabelSets)...), + WithoutReplicaLabels: originalRequest.WithoutReplicaLabels, + } - // We might be able to skip the store if its meta information indicates it cannot have series matching our query. - if ok, reason := storeMatches(gctx, st, s.debugLogging, r.Start, r.End); !ok { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) - } - continue - } - matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) - if !matches { - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) - } - continue - } - if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) - } + var ( + warnings []string + all [][]string + mtx sync.Mutex + g, gctx = errgroup.WithContext(ctx) + ) + for _, st := range stores { + st := st + storeID, storeAddr, isLocalStore := storeInfo(st) g.Go(func() error { span, spanCtx := tracing.StartSpan(gctx, "proxy.label_values", tracing.Tags{ "store.id": storeID, @@ -719,23 +638,15 @@ func (s *ProxyStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequ }) defer span.Finish() - resp, err := st.LabelValues(spanCtx, &storepb.LabelValuesRequest{ - Label: r.Label, - PartialResponseDisabled: r.PartialResponseDisabled, - Start: r.Start, - End: r.End, - Matchers: append(r.Matchers, MatchersForLabelSets(extraMatchers)...), - WithoutReplicaLabels: r.WithoutReplicaLabels, - }) + resp, err := st.LabelValues(spanCtx, r) if err != nil { - msg := "fetch label values from store %s" - err = errors.Wrapf(err, msg, st) + err = errors.Wrapf(err, "fetch label values from store %s", st) if r.PartialResponseDisabled { return err } mtx.Lock() - warnings = append(warnings, errors.Wrapf(err, msg, st).Error()) + warnings = append(warnings, err.Error()) mtx.Unlock() return nil } @@ -748,14 +659,118 @@ func (s *ProxyStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequ return nil }) } + level.Debug(reqLogger).Log("msg", "LabelValues: started fanout streams", "status", strings.Join(storeDebugMsgs, ";")) if err := g.Wait(); err != nil { return nil, err } - level.Debug(s.logger).Log("msg", strings.Join(storeDebugMsgs, ";")) return &storepb.LabelValuesResponse{ Values: strutil.MergeUnsortedSlices(all...), Warnings: warnings, }, nil } + +func storeInfo(st Client) (storeID string, storeAddr string, isLocalStore bool) { + storeAddr, isLocalStore = st.Addr() + storeID = labelpb.PromLabelSetsToString(st.LabelSets()) + if storeID == "" { + storeID = "Store Gateway" + } + return storeID, storeAddr, isLocalStore +} + +// TODO: consider moving the following functions into something like "pkg/pruneutils" since it is also used for exemplars. + +func (s *ProxyStore) matchingStores(ctx context.Context, minTime, maxTime int64, matchers []*labels.Matcher) ([]Client, []labels.Labels, []string) { + var ( + stores []Client + storeLabelSets []labels.Labels + storeDebugMsgs []string + ) + for _, st := range s.stores() { + // We might be able to skip the store if its meta information indicates it cannot have series matching our query. + if ok, reason := storeMatches(ctx, st, minTime, maxTime, matchers...); !ok { + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) + continue + } + matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) + if !matches { + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) + continue + } + storeLabelSets = append(storeLabelSets, extraMatchers...) + + stores = append(stores, st) + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) + } + + return stores, storeLabelSets, storeDebugMsgs +} + +// storeMatches returns boolean if the given store may hold data for the given label matchers, time ranges and debug store matches gathered from context. +func storeMatches(ctx context.Context, s Client, mint, maxt int64, matchers ...*labels.Matcher) (ok bool, reason string) { + var storeDebugMatcher [][]*labels.Matcher + if ctxVal := ctx.Value(StoreMatcherKey); ctxVal != nil { + if value, ok := ctxVal.([][]*labels.Matcher); ok { + storeDebugMatcher = value + } + } + + storeMinTime, storeMaxTime := s.TimeRange() + if mint > storeMaxTime || maxt < storeMinTime { + return false, fmt.Sprintf("does not have data within this time period: [%v,%v]. Store time ranges: [%v,%v]", mint, maxt, storeMinTime, storeMaxTime) + } + + if ok, reason := storeMatchDebugMetadata(s, storeDebugMatcher); !ok { + return false, reason + } + + extLset := s.LabelSets() + if !LabelSetsMatch(matchers, extLset...) { + return false, fmt.Sprintf("external labels %v does not match request label matchers: %v", extLset, matchers) + } + return true, "" +} + +// storeMatchDebugMetadata return true if the store's address match the storeDebugMatchers. +func storeMatchDebugMetadata(s Client, storeDebugMatchers [][]*labels.Matcher) (ok bool, reason string) { + if len(storeDebugMatchers) == 0 { + return true, "" + } + + addr, isLocal := s.Addr() + if isLocal { + return false, "the store is not remote, cannot match __address__" + } + + match := false + for _, sm := range storeDebugMatchers { + match = match || LabelSetsMatch(sm, labels.FromStrings("__address__", addr)) + } + if !match { + return false, fmt.Sprintf("__address__ %v does not match debug store metadata matchers: %v", addr, storeDebugMatchers) + } + return true, "" +} + +// LabelSetsMatch returns false if all label-set do not match the matchers (aka: OR is between all label-sets). +func LabelSetsMatch(matchers []*labels.Matcher, lset ...labels.Labels) bool { + if len(lset) == 0 { + return true + } + + for _, ls := range lset { + notMatched := false + for _, m := range matchers { + if lv := ls.Get(m.Name); ls.Has(m.Name) && !m.Matches(lv) { + notMatched = true + break + } + } + if !notMatched { + return true + } + } + return false +} diff --git a/pkg/store/proxy_merge.go b/pkg/store/proxy_merge.go index 4c316ca420..6dce3927a0 100644 --- a/pkg/store/proxy_merge.go +++ b/pkg/store/proxy_merge.go @@ -14,11 +14,11 @@ import ( "github.com/cespare/xxhash/v2" "github.com/go-kit/log" "github.com/go-kit/log/level" - grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tracing" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" + grpc_opentracing "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware" "github.com/thanos-io/thanos/pkg/losertree" "github.com/thanos-io/thanos/pkg/store/labelpb" @@ -373,7 +373,6 @@ func newLazyRespSet( } resp, err := cl.Recv() - if err != nil { if err == io.EOF { l.bufferedResponsesMtx.Lock() @@ -386,10 +385,10 @@ func newLazyRespSet( var rerr error // If timer is already stopped if t != nil && !t.Stop() { - if errors.Is(err, context.Canceled) { - // The per-Recv timeout has been reached. - rerr = errors.Wrapf(err, "failed to receive any data in %s from %s", l.frameTimeout, st) + if t.C != nil { + <-t.C // Drain the channel if it was already stopped. } + rerr = errors.Wrapf(err, "failed to receive any data in %s from %s", l.frameTimeout, st) } else { rerr = errors.Wrapf(err, "receive series from %s", st) } @@ -466,16 +465,10 @@ func newAsyncRespSet( var span opentracing.Span var closeSeries context.CancelFunc - storeAddr, isLocalStore := st.Addr() - storeID := labelpb.PromLabelSetsToString(st.LabelSets()) - if storeID == "" { - storeID = "Store Gateway" - } - + storeID, storeAddr, isLocalStore := storeInfo(st) seriesCtx := grpc_opentracing.ClientAddContextTags(ctx, opentracing.Tags{ "target": storeAddr, }) - span, seriesCtx = tracing.StartSpan(seriesCtx, "proxy.series", tracing.Tags{ "store.id": storeID, "store.is_local": isLocalStore, @@ -644,7 +637,6 @@ func newEagerRespSet( } resp, err := cl.Recv() - if err != nil { if err == io.EOF { return false @@ -653,11 +645,10 @@ func newEagerRespSet( var rerr error // If timer is already stopped if t != nil && !t.Stop() { - <-t.C // Drain the channel if it was already stopped. - if errors.Is(err, context.Canceled) { - // The per-Recv timeout has been reached. - rerr = errors.Wrapf(err, "failed to receive any data in %s from %s", l.frameTimeout, storeName) + if t.C != nil { + <-t.C // Drain the channel if it was already stopped. } + rerr = errors.Wrapf(err, "failed to receive any data in %s from %s", l.frameTimeout, storeName) } else { rerr = errors.Wrapf(err, "receive series from %s", storeName) } diff --git a/pkg/store/proxy_test.go b/pkg/store/proxy_test.go index 98f51a8b09..8dd4c2190b 100644 --- a/pkg/store/proxy_test.go +++ b/pkg/store/proxy_test.go @@ -1842,7 +1842,7 @@ func TestStoreMatches(t *testing.T) { }, } { t.Run("", func(t *testing.T) { - ok, reason := storeMatches(context.TODO(), c.s, true, c.mint, c.maxt, c.ms...) + ok, reason := storeMatches(context.TODO(), c.s, c.mint, c.maxt, c.ms...) testutil.Equals(t, c.expectedMatch, ok) testutil.Equals(t, c.expectedReason, reason) diff --git a/pkg/store/storepb/custom_test.go b/pkg/store/storepb/custom_test.go index eff2be6e80..4a1c6d83c2 100644 --- a/pkg/store/storepb/custom_test.go +++ b/pkg/store/storepb/custom_test.go @@ -12,10 +12,11 @@ import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/efficientgo/core/testutil" + + "github.com/thanos-io/thanos/pkg/extpromql" "github.com/thanos-io/thanos/pkg/store/labelpb" ) @@ -520,8 +521,8 @@ func TestMatchersToString_Translate(t *testing.T) { testutil.Equals(t, c.expected, MatchersToString(ms...)) // Is this parsable? - promMsParsed, err := parser.ParseMetricSelector(c.expected) - testutil.Ok(t, err) + promMsParsed, err := extpromql.ParseMetricSelector(c.expected) + testutil.Ok(t, err, "unexpected error parsing %q", c.expected) testutil.Assert(t, len(promMs) == len(promMsParsed)) for i := 0; i < len(promMs); i++ { testutil.Equals(t, promMs[i].String(), promMsParsed[i].String()) diff --git a/pkg/store/storepb/testutil/series.go b/pkg/store/storepb/testutil/series.go index c5c4896bd7..d7d719e281 100644 --- a/pkg/store/storepb/testutil/series.go +++ b/pkg/store/storepb/testutil/series.go @@ -68,9 +68,10 @@ func CreateBlockFromHead(t testing.TB, dir string, head *tsdb.Head) ulid.ULID { // Add +1 millisecond to block maxt because block intervals are half-open: [b.MinTime, b.MaxTime). // Because of this block intervals are always +1 than the total samples it includes. - ulid, err := compactor.Write(dir, head, head.MinTime(), head.MaxTime()+1, nil) + ulids, err := compactor.Write(dir, head, head.MinTime(), head.MaxTime()+1, nil) testutil.Ok(t, err) - return ulid + testutil.Assert(t, len(ulids) > 0) + return ulids[0] } // CreateHeadWithSeries returns head filled with given samples and same series returned in separate list for assertion purposes. diff --git a/pkg/store/tsdb.go b/pkg/store/tsdb.go index fea2708eaf..7448562018 100644 --- a/pkg/store/tsdb.go +++ b/pkg/store/tsdb.go @@ -166,10 +166,35 @@ type CloseDelegator interface { Delegate(io.Closer) } +type noopUpstream struct { + ctx context.Context + storepb.Store_SeriesServer +} + +func (n *noopUpstream) Context() context.Context { + return n.ctx +} + +func (s *TSDBStore) SeriesLocal(ctx context.Context, r *storepb.SeriesRequest) ([]*storepb.Series, error) { + srv := newFlushableServer(&noopUpstream{ctx: ctx}, sortingStrategyStoreSendNoop) + if err := s.Series(r, srv); err != nil { + return nil, err + } + + rs := srv.(*resortingServer) + + return rs.series, nil +} + // Series returns all series for a requested time range and label matcher. The returned data may // exceed the requested time bounds. func (s *TSDBStore) Series(r *storepb.SeriesRequest, seriesSrv storepb.Store_SeriesServer) error { - srv := newFlushableServer(seriesSrv, sortingStrategyStore) + var srv flushableServer + if fs, ok := seriesSrv.(flushableServer); !ok { + srv = newFlushableServer(seriesSrv, sortingStrategyStore) + } else { + srv = fs + } match, matchers, err := matchesExternalLabels(r.Matchers, s.getExtLset()) if err != nil { diff --git a/pkg/store/tsdb_selector.go b/pkg/store/tsdb_selector.go index c9beef6e77..463ab96b14 100644 --- a/pkg/store/tsdb_selector.go +++ b/pkg/store/tsdb_selector.go @@ -69,13 +69,13 @@ func MatchersForLabelSets(labelSets []labels.Labels) []storepb.LabelMatcher { labelNameValues = make(map[string]map[string]struct{}) ) for _, labelSet := range labelSets { - for _, lbl := range labelSet { - if _, ok := labelNameValues[lbl.Name]; !ok { - labelNameValues[lbl.Name] = make(map[string]struct{}) + labelSet.Range(func(l labels.Label) { + if _, ok := labelNameValues[l.Name]; !ok { + labelNameValues[l.Name] = make(map[string]struct{}) } - labelNameCounts[lbl.Name]++ - labelNameValues[lbl.Name][lbl.Value] = struct{}{} - } + labelNameCounts[l.Name]++ + labelNameValues[l.Name][l.Value] = struct{}{} + }) } // If a label name is missing from a label set, force an empty value matcher for diff --git a/pkg/store/tsdb_selector_test.go b/pkg/store/tsdb_selector_test.go index cb3e0c07b4..745c4edb2e 100644 --- a/pkg/store/tsdb_selector_test.go +++ b/pkg/store/tsdb_selector_test.go @@ -26,29 +26,28 @@ func TestMatchersForLabelSets(t *testing.T) { }, { name: "single label set with single label", - labelSets: []labels.Labels{{ - labels.Label{Name: "a", Value: "1"}, - }}, + labelSets: []labels.Labels{ + labels.FromStrings("a", "1"), + }, want: []storepb.LabelMatcher{ {Type: storepb.LabelMatcher_RE, Name: "a", Value: "1"}, }, }, { name: "multiple labels with same label name", - labelSets: []labels.Labels{{ - labels.Label{Name: "a", Value: "1"}, - labels.Label{Name: "a", Value: "2"}, - }}, + labelSets: []labels.Labels{ + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, want: []storepb.LabelMatcher{ {Type: storepb.LabelMatcher_RE, Name: "a", Value: "1|2"}, }, }, { name: "multiple labels with different label name", - labelSets: []labels.Labels{{ - labels.Label{Name: "a", Value: "1"}, - labels.Label{Name: "b", Value: "2"}, - }}, + labelSets: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + }, want: []storepb.LabelMatcher{ {Type: storepb.LabelMatcher_RE, Name: "a", Value: "1"}, {Type: storepb.LabelMatcher_RE, Name: "b", Value: "2"}, @@ -56,22 +55,20 @@ func TestMatchersForLabelSets(t *testing.T) { }, { name: "multiple label sets with same label name", - labelSets: []labels.Labels{{ - labels.Label{Name: "a", Value: "1"}, - }, { - labels.Label{Name: "a", Value: "2"}, - }}, + labelSets: []labels.Labels{ + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2"), + }, want: []storepb.LabelMatcher{ {Type: storepb.LabelMatcher_RE, Name: "a", Value: "1|2"}, }, }, { name: "multiple label sets with different label name", - labelSets: []labels.Labels{{ - labels.Label{Name: "a", Value: "1"}, - }, { - labels.Label{Name: "b", Value: "2"}, - }}, + labelSets: []labels.Labels{ + labels.FromStrings("a", "1"), + labels.FromStrings("b", "2"), + }, want: []storepb.LabelMatcher{ {Type: storepb.LabelMatcher_RE, Name: "a", Value: "1|^$"}, {Type: storepb.LabelMatcher_RE, Name: "b", Value: "2|^$"}, diff --git a/pkg/store/tsdb_test.go b/pkg/store/tsdb_test.go index 61b4875bfc..acd9daf02a 100644 --- a/pkg/store/tsdb_test.go +++ b/pkg/store/tsdb_test.go @@ -257,7 +257,7 @@ func TestTSDBStore_SeriesAccessWithDelegateClosing(t *testing.T) { Random: random, SkipChunks: true, }) - _ = createBlockFromHead(t, tmpDir, head) + _ = storetestutil.CreateBlockFromHead(t, tmpDir, head) testutil.Ok(t, head.Close()) head, _ = storetestutil.CreateHeadWithSeries(t, 1, storetestutil.HeadGenOptions{ @@ -270,7 +270,7 @@ func TestTSDBStore_SeriesAccessWithDelegateClosing(t *testing.T) { }) testutil.Ok(t, head.Close()) - db, err := tsdb.OpenDBReadOnly(tmpDir, logger) + db, err := tsdb.OpenDBReadOnly(tmpDir, "", logger) testutil.Ok(t, err) dbToClose := make(chan *tsdb.DBReadOnly, 1) @@ -426,7 +426,7 @@ func TestTSDBStore_SeriesAccessWithoutDelegateClosing(t *testing.T) { Random: random, SkipChunks: true, }) - _ = createBlockFromHead(t, tmpDir, head) + _ = storetestutil.CreateBlockFromHead(t, tmpDir, head) testutil.Ok(t, head.Close()) head, _ = storetestutil.CreateHeadWithSeries(t, 1, storetestutil.HeadGenOptions{ @@ -439,7 +439,7 @@ func TestTSDBStore_SeriesAccessWithoutDelegateClosing(t *testing.T) { }) testutil.Ok(t, head.Close()) - db, err := tsdb.OpenDBReadOnly(tmpDir, logger) + db, err := tsdb.OpenDBReadOnly(tmpDir, "", logger) testutil.Ok(t, err) t.Cleanup(func() { if db != nil { @@ -566,7 +566,7 @@ func benchTSDBStoreSeries(t testutil.TB, totalSamples, totalSeries int) { resps[j] = append(resps[j], storepb.NewSeriesResponse(created[i])) } - _ = createBlockFromHead(t, tmpDir, head) + _ = storetestutil.CreateBlockFromHead(t, tmpDir, head) testutil.Ok(t, head.Close()) } @@ -583,7 +583,7 @@ func benchTSDBStoreSeries(t testutil.TB, totalSamples, totalSeries int) { resps[3] = append(resps[3], storepb.NewSeriesResponse(created[i])) } - db, err := tsdb.OpenDBReadOnly(tmpDir, logger) + db, err := tsdb.OpenDBReadOnly(tmpDir, "", logger) testutil.Ok(t, err) defer func() { testutil.Ok(t, db.Close()) }() diff --git a/pkg/tenancy/tenancy.go b/pkg/tenancy/tenancy.go index aec0bad86a..9da1372933 100644 --- a/pkg/tenancy/tenancy.go +++ b/pkg/tenancy/tenancy.go @@ -11,8 +11,9 @@ import ( "github.com/pkg/errors" "github.com/prometheus-community/prom-label-proxy/injectproxy" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" "google.golang.org/grpc/metadata" + + "github.com/thanos-io/thanos/pkg/extpromql" ) type contextKey int @@ -148,7 +149,7 @@ func EnforceQueryTenancy(tenantLabel string, tenant string, query string) (strin e := injectproxy.NewEnforcer(false, labelMatcher) - expr, err := parser.ParseExpr(query) + expr, err := extpromql.ParseExpr(query) if err != nil { return "", errors.Wrap(err, "error parsing query string, when enforcing tenenacy") } @@ -178,7 +179,7 @@ func getLabelMatchers(formMatchers []string, tenant string, enforceTenancy bool, } for _, s := range formMatchers { - matchers, err := parser.ParseMetricSelector(s) + matchers, err := extpromql.ParseMetricSelector(s) if err != nil { return nil, err } diff --git a/pkg/tenancy/tenancy_test.go b/pkg/tenancy/tenancy_test.go index c5c9563c44..ca41793346 100644 --- a/pkg/tenancy/tenancy_test.go +++ b/pkg/tenancy/tenancy_test.go @@ -8,18 +8,16 @@ import ( "testing" "time" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "github.com/efficientgo/core/testutil" + "github.com/pkg/errors" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/tenancy" - - "github.com/pkg/errors" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" storetestutil "github.com/thanos-io/thanos/pkg/store/storepb/testutil" ) @@ -196,3 +194,37 @@ func TestTenantProxyPassing(t *testing.T) { _ = q.Series(&storepb.SeriesRequest{Matchers: seriesMatchers}, &storeSeriesServer{ctx: ctx}) }) } + +func TestEnforceQueryTenancy(t *testing.T) { + tests := []struct { + name string + tenantLabel string + tenant string + query string + expectedQuery string + }{ + { + name: "vector selector query", + tenantLabel: "tenant_id", + tenant: "test-tenant", + query: `{__name__="test_metric", job="test_job"}`, + expectedQuery: `{__name__="test_metric",job="test_job",tenant_id="test-tenant"}`, + }, + { + name: "with aggregation and extended functions", + tenantLabel: "tenant_id", + tenant: "test-tenant", + query: `sum by (job) (xrate(test_metric{job="test_job"}[5m]))`, + expectedQuery: `sum by (job) (xrate(test_metric{job="test_job",tenant_id="test-tenant"}[5m]))`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resultQuery, err := tenancy.EnforceQueryTenancy(tt.tenantLabel, tt.tenant, tt.query) + testutil.Ok(t, err) + + testutil.Equals(t, tt.expectedQuery, resultQuery) + }) + } +} diff --git a/pkg/testutil/e2eutil/prometheus.go b/pkg/testutil/e2eutil/prometheus.go index 4faba4fafd..39aab94eab 100644 --- a/pkg/testutil/e2eutil/prometheus.go +++ b/pkg/testutil/e2eutil/prometheus.go @@ -605,14 +605,14 @@ func createBlock( return id, errors.Wrap(err, "create compactor") } - id, err = c.Write(dir, h, mint, maxt, nil) + ids, err := c.Write(dir, h, mint, maxt, nil) if err != nil { return id, errors.Wrap(err, "write block") } - - if id.Compare(ulid.ULID{}) == 0 { + if len(ids) == 0 { return id, errors.Errorf("nothing to write, asked for %d samples", numSamples) } + id = ids[0] blockDir := filepath.Join(dir, id.String()) logger := log.NewNopLogger() @@ -769,14 +769,15 @@ func CreateBlockWithChurn( return id, errors.Wrap(err, "create compactor") } - id, err = c.Write(dir, h, mint, maxt, nil) + ids, err := c.Write(dir, h, mint, maxt, nil) if err != nil { return id, errors.Wrap(err, "write block") } - if id.Compare(ulid.ULID{}) == 0 { + if len(ids) == 0 { return id, errors.Errorf("nothing to write, asked for %d samples", numSamples) } + id = ids[0] blockDir := filepath.Join(dir, id.String()) logger := log.NewNopLogger() diff --git a/pkg/tracing/grpc.go b/pkg/tracing/grpc.go index 78b4391bf8..93ec18cd18 100644 --- a/pkg/tracing/grpc.go +++ b/pkg/tracing/grpc.go @@ -7,8 +7,8 @@ import ( "context" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" - grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tracing" - opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go" + grpc_opentracing "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware" "google.golang.org/grpc" ) diff --git a/pkg/tracing/http.go b/pkg/tracing/http.go index 21b6663f4f..0ea07c9e00 100644 --- a/pkg/tracing/http.go +++ b/pkg/tracing/http.go @@ -14,6 +14,8 @@ import ( "github.com/go-kit/log/level" "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" + + "github.com/thanos-io/thanos/pkg/server/http/middleware" "github.com/thanos-io/thanos/pkg/tracing/migration" ) @@ -32,6 +34,9 @@ func HTTPMiddleware(tracer opentracing.Tracer, name string, logger log.Logger, n } opts := []opentracing.StartSpanOption{ext.RPCServerOption(wireContext)} + if requestID, ok := middleware.RequestIDFromContext(r.Context()); ok { + opts = append(opts, opentracing.Tag{Key: "request_id", Value: requestID}) + } // Check for force tracing header and add it as a tag at the start of span. // This is required for the OpenTelemetry sampler to force tracing. if r.Header.Get(ForceTracingBaggageKey) != "" { diff --git a/pkg/tracing/interceptors/client.go b/pkg/tracing/interceptors/client.go new file mode 100644 index 0000000000..a45ec8fcb5 --- /dev/null +++ b/pkg/tracing/interceptors/client.go @@ -0,0 +1,85 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +// gRPC Prometheus monitoring interceptors for client-side gRPC. + +package interceptors + +import ( + "context" + "time" + + "google.golang.org/grpc" +) + +// UnaryClientInterceptor is a gRPC client-side interceptor that provides reporting for Unary RPCs. +func UnaryClientInterceptor(reportable ClientReportable) grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + r := newReport(Unary, method) + reporter, newCtx := reportable.ClientReporter(ctx, req, r.rpcType, r.service, r.method) + + reporter.PostMsgSend(req, nil, time.Since(r.startTime)) + err := invoker(newCtx, method, req, reply, cc, opts...) + reporter.PostMsgReceive(reply, err, time.Since(r.startTime)) + + reporter.PostCall(err, time.Since(r.startTime)) + return err + } +} + +// StreamClientInterceptor is a gRPC client-side interceptor that provides reporting for Stream RPCs. +func StreamClientInterceptor(reportable ClientReportable) grpc.StreamClientInterceptor { + return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + r := newReport(clientStreamType(desc), method) + reporter, newCtx := reportable.ClientReporter(ctx, nil, r.rpcType, r.service, r.method) + + clientStream, err := streamer(newCtx, desc, cc, method, opts...) + if err != nil { + reporter.PostCall(err, time.Since(r.startTime)) + return nil, err + } + return &monitoredClientStream{ClientStream: clientStream, startTime: r.startTime, reporter: reporter}, nil + } +} + +func clientStreamType(desc *grpc.StreamDesc) GRPCType { + if desc.ClientStreams && !desc.ServerStreams { + return ClientStream + } else if !desc.ClientStreams && desc.ServerStreams { + return ServerStream + } + return BidiStream +} + +// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to report. +type monitoredClientStream struct { + grpc.ClientStream + + startTime time.Time + reporter Reporter +} + +func (s *monitoredClientStream) SendMsg(m interface{}) error { + start := time.Now() + err := s.ClientStream.SendMsg(m) + s.reporter.PostMsgSend(m, err, time.Since(start)) + return err +} + +func (s *monitoredClientStream) RecvMsg(m interface{}) error { + start := time.Now() + err := s.ClientStream.RecvMsg(m) + s.reporter.PostMsgReceive(m, err, time.Since(start)) + + if err == nil { + return nil + } + + s.reporter.PostCall(err, time.Since(s.startTime)) + return err +} diff --git a/pkg/tracing/interceptors/reporter.go b/pkg/tracing/interceptors/reporter.go new file mode 100644 index 0000000000..4ccdb0b61e --- /dev/null +++ b/pkg/tracing/interceptors/reporter.go @@ -0,0 +1,87 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package interceptors + +import ( + "context" + "fmt" + "strings" + "time" + + "google.golang.org/grpc/codes" +) + +type GRPCType string + +const ( + Unary GRPCType = "unary" + ClientStream GRPCType = "client_stream" + ServerStream GRPCType = "server_stream" + BidiStream GRPCType = "bidi_stream" +) + +var ( + AllCodes = []codes.Code{ + codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, + codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, + codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, + codes.Unavailable, codes.DataLoss, + } +) + +func splitMethodName(fullMethod string) (string, string) { + fullMethod = strings.TrimPrefix(fullMethod, "/") // remove leading slash + if i := strings.Index(fullMethod, "/"); i >= 0 { + return fullMethod[:i], fullMethod[i+1:] + } + return "unknown", "unknown" +} + +func FullMethod(service, method string) string { + return fmt.Sprintf("/%s/%s", service, method) +} + +type ClientReportable interface { + ClientReporter(ctx context.Context, reqProtoOrNil interface{}, typ GRPCType, service string, method string) (Reporter, context.Context) +} + +type ServerReportable interface { + ServerReporter(ctx context.Context, reqProtoOrNil interface{}, typ GRPCType, service string, method string) (Reporter, context.Context) +} + +type Reporter interface { + PostCall(err error, rpcDuration time.Duration) + + PostMsgSend(reqProto interface{}, err error, sendDuration time.Duration) + PostMsgReceive(replyProto interface{}, err error, recvDuration time.Duration) +} + +var _ Reporter = NoopReporter{} + +type NoopReporter struct{} + +func (NoopReporter) PostCall(error, time.Duration) {} +func (NoopReporter) PostMsgSend(interface{}, error, time.Duration) {} +func (NoopReporter) PostMsgReceive(interface{}, error, time.Duration) {} + +type report struct { + rpcType GRPCType + service string + method string + startTime time.Time +} + +func newReport(typ GRPCType, fullMethod string) report { + r := report{ + startTime: time.Now(), + rpcType: typ, + } + r.service, r.method = splitMethodName(fullMethod) + return r +} diff --git a/pkg/tracing/interceptors/server.go b/pkg/tracing/interceptors/server.go new file mode 100644 index 0000000000..7bfed7bae5 --- /dev/null +++ b/pkg/tracing/interceptors/server.go @@ -0,0 +1,79 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +// gRPC Prometheus monitoring interceptors for server-side gRPC. + +package interceptors + +import ( + "context" + "time" + + "google.golang.org/grpc" +) + +// UnaryServerInterceptor is a gRPC server-side interceptor that provides reporting for Unary RPCs. +func UnaryServerInterceptor(reportable ServerReportable) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + r := newReport(Unary, info.FullMethod) + reporter, newCtx := reportable.ServerReporter(ctx, req, r.rpcType, r.service, r.method) + + reporter.PostMsgReceive(req, nil, time.Since(r.startTime)) + resp, err := handler(newCtx, req) + reporter.PostMsgSend(resp, err, time.Since(r.startTime)) + + reporter.PostCall(err, time.Since(r.startTime)) + return resp, err + } +} + +// StreamServerInterceptor is a gRPC server-side interceptor that provides reporting for Streaming RPCs. +func StreamServerInterceptor(reportable ServerReportable) grpc.StreamServerInterceptor { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + r := newReport(ServerStream, info.FullMethod) + reporter, newCtx := reportable.ServerReporter(ss.Context(), nil, streamRPCType(info), r.service, r.method) + err := handler(srv, &monitoredServerStream{ServerStream: ss, newCtx: newCtx, reporter: reporter}) + reporter.PostCall(err, time.Since(r.startTime)) + return err + } +} + +func streamRPCType(info *grpc.StreamServerInfo) GRPCType { + if info.IsClientStream && !info.IsServerStream { + return ClientStream + } else if !info.IsClientStream && info.IsServerStream { + return ServerStream + } + return BidiStream +} + +// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to report. +type monitoredServerStream struct { + grpc.ServerStream + + newCtx context.Context + reporter Reporter +} + +func (s *monitoredServerStream) Context() context.Context { + return s.newCtx +} + +func (s *monitoredServerStream) SendMsg(m interface{}) error { + start := time.Now() + err := s.ServerStream.SendMsg(m) + s.reporter.PostMsgSend(m, err, time.Since(start)) + return err +} + +func (s *monitoredServerStream) RecvMsg(m interface{}) error { + start := time.Now() + err := s.ServerStream.RecvMsg(m) + s.reporter.PostMsgReceive(m, err, time.Since(start)) + return err +} diff --git a/pkg/tracing/otlp/config_yaml.go b/pkg/tracing/otlp/config_yaml.go index b8aa6f9dc8..abce5370e2 100644 --- a/pkg/tracing/otlp/config_yaml.go +++ b/pkg/tracing/otlp/config_yaml.go @@ -22,6 +22,7 @@ type retryConfig struct { type Config struct { ClientType string `yaml:"client_type"` ServiceName string `yaml:"service_name"` + ResourceAttributes map[string]string `yaml:"resource_attributes"` ReconnectionPeriod time.Duration `yaml:"reconnection_period"` Compression string `yaml:"compression"` Insecure bool `yaml:"insecure"` diff --git a/pkg/tracing/otlp/otlp.go b/pkg/tracing/otlp/otlp.go index bf29d3622b..cb5220240a 100644 --- a/pkg/tracing/otlp/otlp.go +++ b/pkg/tracing/otlp/otlp.go @@ -8,6 +8,8 @@ import ( "strconv" "strings" + "go.opentelemetry.io/otel/attribute" + "github.com/thanos-io/thanos/pkg/tracing/migration" "github.com/go-kit/log" @@ -70,26 +72,27 @@ func NewTracerProvider(ctx context.Context, logger log.Logger, conf []byte) (*tr if err != nil { logger.Log(err) } - tp := newTraceProvider(ctx, processor, logger, config.ServiceName, sampler) + tp := newTraceProvider(ctx, processor, logger, config.ServiceName, config.ResourceAttributes, sampler) return tp, nil } -func newTraceProvider(ctx context.Context, processor tracesdk.SpanProcessor, logger log.Logger, serviceName string, sampler tracesdk.Sampler) *tracesdk.TracerProvider { - var ( - r *resource.Resource - err error - ) +func newTraceProvider( + ctx context.Context, + processor tracesdk.SpanProcessor, + logger log.Logger, + serviceName string, + attrs map[string]string, + sampler tracesdk.Sampler, +) *tracesdk.TracerProvider { + resourceAttrs := make([]attribute.KeyValue, 0, len(attrs)+1) if serviceName != "" { - r, err = resource.New( - ctx, - resource.WithAttributes(semconv.ServiceNameKey.String(serviceName)), - ) - } else { - r, err = resource.New( - ctx, - ) + resourceAttrs = append(resourceAttrs, semconv.ServiceNameKey.String(serviceName)) + } + for k, v := range attrs { + resourceAttrs = append(resourceAttrs, attribute.String(k, v)) } + r, err := resource.New(ctx, resource.WithAttributes(resourceAttrs...)) if err != nil { level.Warn(logger).Log("msg", "jaeger: detecting resources for tracing provider failed", "err", err) } diff --git a/pkg/tracing/otlp/otlp_test.go b/pkg/tracing/otlp/otlp_test.go index 1f651e9c87..c0c0c8c0dc 100644 --- a/pkg/tracing/otlp/otlp_test.go +++ b/pkg/tracing/otlp/otlp_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/efficientgo/core/testutil" + "github.com/thanos-io/thanos/pkg/tracing" "github.com/thanos-io/thanos/pkg/tracing/migration" @@ -20,12 +21,7 @@ import ( func TestContextTracing_ClientEnablesTracing(t *testing.T) { exp := tracetest.NewInMemoryExporter() - tracerOtel := newTraceProvider( - context.Background(), - tracesdk.NewSimpleSpanProcessor(exp), - log.NewNopLogger(), - "thanos", - tracesdk.AlwaysSample()) + tracerOtel := newTraceProvider(context.Background(), tracesdk.NewSimpleSpanProcessor(exp), log.NewNopLogger(), "thanos", nil, tracesdk.AlwaysSample()) tracer, _ := migration.Bridge(tracerOtel, log.NewNopLogger()) clientRoot, _ := tracing.StartSpan(tracing.ContextWithTracer(context.Background(), tracer), "a") diff --git a/pkg/tracing/tracing_middleware/client.go b/pkg/tracing/tracing_middleware/client.go new file mode 100644 index 0000000000..77167c957f --- /dev/null +++ b/pkg/tracing/tracing_middleware/client.go @@ -0,0 +1,106 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package tracing_middleware + +import ( + "context" + + "io" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + + "github.com/thanos-io/thanos/pkg/tracing/interceptors" + "github.com/thanos-io/thanos/pkg/tracing/util/metautils" +) + +type opentracingClientReporter struct { + typ interceptors.GRPCType + svcName, methodName string + + clientSpan opentracing.Span +} + +func (o *opentracingClientReporter) PostCall(err error, _ time.Duration) { + // Finish span. + if err != nil && err != io.EOF { + ext.Error.Set(o.clientSpan, true) + o.clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + } + o.clientSpan.Finish() +} + +func (o *opentracingClientReporter) PostMsgSend(interface{}, error, time.Duration) {} + +func (o *opentracingClientReporter) PostMsgReceive(interface{}, error, time.Duration) {} + +type opentracingClientReportable struct { + tracer opentracing.Tracer + filterOutFunc FilterFunc +} + +func (o *opentracingClientReportable) ClientReporter(ctx context.Context, _ interface{}, typ interceptors.GRPCType, service string, method string) (interceptors.Reporter, context.Context) { + if o.filterOutFunc != nil && !o.filterOutFunc(ctx, method) { + return interceptors.NoopReporter{}, ctx + } + + newCtx, clientSpan := newClientSpanFromContext(ctx, o.tracer, interceptors.FullMethod(service, method)) + mock := &opentracingClientReporter{typ: typ, svcName: service, methodName: method, clientSpan: clientSpan} + return mock, newCtx +} + +// UnaryClientInterceptor returns a new unary client interceptor for OpenTracing. +func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor { + o := evaluateOptions(opts) + return interceptors.UnaryClientInterceptor(&opentracingClientReportable{tracer: o.tracer, filterOutFunc: o.filterOutFunc}) +} + +// StreamClientInterceptor returns a new streaming client interceptor for OpenTracing. +func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { + o := evaluateOptions(opts) + return interceptors.StreamClientInterceptor(&opentracingClientReportable{tracer: o.tracer, filterOutFunc: o.filterOutFunc}) +} + +// ClientAddContextTags returns a context with specified opentracing tags, which +// are used by UnaryClientInterceptor/StreamClientInterceptor when creating a +// new span. +func ClientAddContextTags(ctx context.Context, tags opentracing.Tags) context.Context { + return context.WithValue(ctx, clientSpanTagKey{}, tags) +} + +type clientSpanTagKey struct{} + +func newClientSpanFromContext(ctx context.Context, tracer opentracing.Tracer, fullMethodName string) (context.Context, opentracing.Span) { + var parentSpanCtx opentracing.SpanContext + if parent := opentracing.SpanFromContext(ctx); parent != nil { + parentSpanCtx = parent.Context() + } + opts := []opentracing.StartSpanOption{ + opentracing.ChildOf(parentSpanCtx), + ext.SpanKindRPCClient, + grpcTag, + } + if tagx := ctx.Value(clientSpanTagKey{}); tagx != nil { + if opt, ok := tagx.(opentracing.StartSpanOption); ok { + opts = append(opts, opt) + } + } + clientSpan := tracer.StartSpan(fullMethodName, opts...) + // Make sure we add this to the metadata of the call, so it gets propagated: + md := metautils.ExtractOutgoing(ctx).Clone() + if err := tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, metadataTextMap(md)); err != nil { + grpclog.Infof("grpc_opentracing: failed serializing trace information: %v", err) + } + ctxWithMetadata := md.ToOutgoing(ctx) + return opentracing.ContextWithSpan(ctxWithMetadata, clientSpan), clientSpan +} diff --git a/pkg/tracing/tracing_middleware/doc.go b/pkg/tracing/tracing_middleware/doc.go new file mode 100644 index 0000000000..d0db22e1db --- /dev/null +++ b/pkg/tracing/tracing_middleware/doc.go @@ -0,0 +1,29 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +// Package tracing_middleware +/* +tracing is a "parent" package for gRPC logging middlewares. + +This middleware relies on OpenTracing as our tracing interface. + +OpenTracing Interceptors + +These are both client-side and server-side interceptors for OpenTracing. They are a provider-agnostic, with backends +such as Zipkin, or Google Stackdriver Trace. + +For a service that sends out requests and receives requests, you *need* to use both, otherwise downstream requests will +not have the appropriate requests propagated. + +All server-side spans are tagged with grpc_ctxtags information. + +For more information see: +http://opentracing.io/documentation/ +https://github.com/opentracing/specification/blob/master/semantic_conventions.md +*/ +package tracing_middleware diff --git a/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.pb.go b/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.pb.go new file mode 100644 index 0000000000..315ffdf8ad --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.pb.go @@ -0,0 +1,1630 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: fields.proto + +// This file is used for grpctesting discovery of log fields from requests using reflection and gogo proto more tags. + +package gogotestpb + +import ( + fmt "fmt" + io "io" + math "math" + time "time" + + _ "github.com/gogo/protobuf/gogoproto" + _ "github.com/gogo/protobuf/types" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// 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.ProtoPackageIsVersion2 // please upgrade the proto package + +type Metadata struct { + Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty" log_field:"meta_tags"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{0} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) +} +func (m *Metadata) XXX_Size() int { + return m.Size() +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetTags() []string { + if m != nil { + return m.Tags + } + return nil +} + +type PingId struct { + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" log_field:"ping_id"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PingId) Reset() { *m = PingId{} } +func (m *PingId) String() string { return proto.CompactTextString(m) } +func (*PingId) ProtoMessage() {} +func (*PingId) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{1} +} +func (m *PingId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PingId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PingId.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PingId) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingId.Merge(m, src) +} +func (m *PingId) XXX_Size() int { + return m.Size() +} +func (m *PingId) XXX_DiscardUnknown() { + xxx_messageInfo_PingId.DiscardUnknown(m) +} + +var xxx_messageInfo_PingId proto.InternalMessageInfo + +func (m *PingId) GetId() int32 { + if m != nil { + return m.Id + } + return 0 +} + +type Ping struct { + Id *PingId `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ping) Reset() { *m = Ping{} } +func (m *Ping) String() string { return proto.CompactTextString(m) } +func (*Ping) ProtoMessage() {} +func (*Ping) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{2} +} +func (m *Ping) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Ping.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Ping) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ping.Merge(m, src) +} +func (m *Ping) XXX_Size() int { + return m.Size() +} +func (m *Ping) XXX_DiscardUnknown() { + xxx_messageInfo_Ping.DiscardUnknown(m) +} + +var xxx_messageInfo_Ping proto.InternalMessageInfo + +func (m *Ping) GetId() *PingId { + if m != nil { + return m.Id + } + return nil +} + +func (m *Ping) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +type PingRequest struct { + Ping *Ping `protobuf:"bytes,1,opt,name=ping,proto3" json:"ping,omitempty"` + Meta *Metadata `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PingRequest) Reset() { *m = PingRequest{} } +func (m *PingRequest) String() string { return proto.CompactTextString(m) } +func (*PingRequest) ProtoMessage() {} +func (*PingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{3} +} +func (m *PingRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PingRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingRequest.Merge(m, src) +} +func (m *PingRequest) XXX_Size() int { + return m.Size() +} +func (m *PingRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PingRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PingRequest proto.InternalMessageInfo + +func (m *PingRequest) GetPing() *Ping { + if m != nil { + return m.Ping + } + return nil +} + +func (m *PingRequest) GetMeta() *Metadata { + if m != nil { + return m.Meta + } + return nil +} + +type Pong struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" log_field:"pong_id"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Pong) Reset() { *m = Pong{} } +func (m *Pong) String() string { return proto.CompactTextString(m) } +func (*Pong) ProtoMessage() {} +func (*Pong) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{4} +} +func (m *Pong) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Pong) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Pong.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Pong) XXX_Merge(src proto.Message) { + xxx_messageInfo_Pong.Merge(m, src) +} +func (m *Pong) XXX_Size() int { + return m.Size() +} +func (m *Pong) XXX_DiscardUnknown() { + xxx_messageInfo_Pong.DiscardUnknown(m) +} + +var xxx_messageInfo_Pong proto.InternalMessageInfo + +func (m *Pong) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +type PongRequest struct { + Pong *Pong `protobuf:"bytes,1,opt,name=pong,proto3" json:"pong,omitempty"` + Meta *Metadata `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PongRequest) Reset() { *m = PongRequest{} } +func (m *PongRequest) String() string { return proto.CompactTextString(m) } +func (*PongRequest) ProtoMessage() {} +func (*PongRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{5} +} +func (m *PongRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PongRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PongRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PongRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PongRequest.Merge(m, src) +} +func (m *PongRequest) XXX_Size() int { + return m.Size() +} +func (m *PongRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PongRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PongRequest proto.InternalMessageInfo + +func (m *PongRequest) GetPong() *Pong { + if m != nil { + return m.Pong + } + return nil +} + +func (m *PongRequest) GetMeta() *Metadata { + if m != nil { + return m.Meta + } + return nil +} + +type GoGoProtoStdTime struct { + Timestamp *time.Time `protobuf:"bytes,1,opt,name=timestamp,proto3,stdtime" json:"timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoGoProtoStdTime) Reset() { *m = GoGoProtoStdTime{} } +func (m *GoGoProtoStdTime) String() string { return proto.CompactTextString(m) } +func (*GoGoProtoStdTime) ProtoMessage() {} +func (*GoGoProtoStdTime) Descriptor() ([]byte, []int) { + return fileDescriptor_d39ad626ec0e575e, []int{6} +} +func (m *GoGoProtoStdTime) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GoGoProtoStdTime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GoGoProtoStdTime.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GoGoProtoStdTime) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoGoProtoStdTime.Merge(m, src) +} +func (m *GoGoProtoStdTime) XXX_Size() int { + return m.Size() +} +func (m *GoGoProtoStdTime) XXX_DiscardUnknown() { + xxx_messageInfo_GoGoProtoStdTime.DiscardUnknown(m) +} + +var xxx_messageInfo_GoGoProtoStdTime proto.InternalMessageInfo + +func (m *GoGoProtoStdTime) GetTimestamp() *time.Time { + if m != nil { + return m.Timestamp + } + return nil +} + +func init() { + proto.RegisterType((*Metadata)(nil), "grpc_middleware.gogotestpb.Metadata") + proto.RegisterType((*PingId)(nil), "grpc_middleware.gogotestpb.PingId") + proto.RegisterType((*Ping)(nil), "grpc_middleware.gogotestpb.Ping") + proto.RegisterType((*PingRequest)(nil), "grpc_middleware.gogotestpb.PingRequest") + proto.RegisterType((*Pong)(nil), "grpc_middleware.gogotestpb.Pong") + proto.RegisterType((*PongRequest)(nil), "grpc_middleware.gogotestpb.PongRequest") + proto.RegisterType((*GoGoProtoStdTime)(nil), "grpc_middleware.gogotestpb.GoGoProtoStdTime") +} + +func init() { proto.RegisterFile("fields.proto", fileDescriptor_d39ad626ec0e575e) } + +var fileDescriptor_d39ad626ec0e575e = []byte{ + // 387 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x3d, 0x6e, 0xdb, 0x30, + 0x14, 0xc7, 0x4b, 0x57, 0x36, 0x2a, 0xba, 0x43, 0xc1, 0xba, 0xa8, 0x2b, 0x14, 0x92, 0x40, 0x14, + 0xa8, 0x97, 0x4a, 0xa8, 0xdb, 0xa1, 0xed, 0xd0, 0x41, 0x8b, 0x91, 0x21, 0x80, 0xc0, 0x78, 0xca, + 0x22, 0xd0, 0x21, 0x4d, 0x10, 0x90, 0x4c, 0xc5, 0xa2, 0x93, 0x29, 0x77, 0xc8, 0x98, 0x23, 0x65, + 0xcc, 0x09, 0x9c, 0xc0, 0xb9, 0x81, 0x4f, 0x10, 0x90, 0xf2, 0x57, 0x10, 0xe4, 0x03, 0xc8, 0x46, + 0x42, 0xff, 0xdf, 0xe3, 0xef, 0x3d, 0x3d, 0xf8, 0x7e, 0x2c, 0x79, 0xce, 0xaa, 0xa8, 0x9c, 0x2a, + 0xad, 0x90, 0x27, 0xa6, 0xe5, 0x51, 0x56, 0x48, 0xc6, 0x72, 0x7e, 0x4a, 0xa7, 0x3c, 0x12, 0x4a, + 0x28, 0xcd, 0x2b, 0x5d, 0x8e, 0xbc, 0x8e, 0x39, 0xdb, 0x58, 0x6c, 0x4e, 0x35, 0xe1, 0x05, 0x42, + 0x29, 0x91, 0xf3, 0xd8, 0xde, 0x46, 0xb3, 0x71, 0xac, 0x65, 0xc1, 0x2b, 0x4d, 0x8b, 0xb2, 0x0e, + 0xe0, 0xbf, 0xf0, 0xdd, 0x3e, 0xd7, 0x94, 0x51, 0x4d, 0xd1, 0x0f, 0xe8, 0x68, 0x2a, 0xaa, 0x2e, + 0x08, 0xdf, 0xf6, 0xdc, 0xe4, 0xcb, 0x72, 0x1e, 0x7c, 0xca, 0x95, 0xc8, 0xac, 0xc2, 0x3f, 0x5c, + 0x70, 0x4d, 0x33, 0xf3, 0x1d, 0x13, 0x1b, 0xc3, 0x3f, 0x61, 0x2b, 0x95, 0x13, 0xb1, 0xc7, 0xd0, + 0x77, 0xd8, 0x90, 0xac, 0x0b, 0x42, 0xd0, 0x6b, 0x26, 0x9f, 0x97, 0xf3, 0xe0, 0xe3, 0x0e, 0x56, + 0xca, 0x89, 0xc8, 0x24, 0xc3, 0xa4, 0x21, 0x19, 0x4e, 0xa1, 0x63, 0x10, 0xd4, 0xdf, 0x00, 0xed, + 0x3e, 0x8e, 0x1e, 0xef, 0x2a, 0xaa, 0x1f, 0x30, 0x2c, 0xea, 0xc0, 0xe6, 0x09, 0xcd, 0x67, 0xbc, + 0xdb, 0x08, 0x41, 0xcf, 0x25, 0xf5, 0x05, 0x9f, 0xc1, 0xb6, 0xc9, 0x10, 0x7e, 0x3c, 0xe3, 0x95, + 0x46, 0xbf, 0xa1, 0x63, 0x1e, 0x5c, 0x95, 0x0e, 0x9f, 0x2b, 0x4d, 0x6c, 0x1a, 0xfd, 0x81, 0x8e, + 0xe9, 0xce, 0x56, 0x6e, 0xf7, 0xbf, 0x3d, 0x45, 0xad, 0x87, 0x45, 0x2c, 0x81, 0x63, 0xe8, 0xa4, + 0x6a, 0x22, 0x76, 0x26, 0xe0, 0x3e, 0x9c, 0x80, 0xda, 0x99, 0x80, 0xf1, 0x55, 0xf7, 0x7d, 0xd5, + 0x0b, 0x7d, 0x95, 0xf5, 0x55, 0xaf, 0xf2, 0x25, 0xf0, 0xc3, 0x40, 0x0d, 0x54, 0x6a, 0xfe, 0xfd, + 0x81, 0x66, 0x43, 0x59, 0x70, 0xf4, 0x1f, 0xba, 0x9b, 0xad, 0x58, 0x89, 0x78, 0x51, 0xbd, 0x37, + 0xd1, 0x7a, 0x6f, 0xa2, 0xe1, 0x3a, 0x91, 0x38, 0xe7, 0xd7, 0x01, 0x20, 0x5b, 0x24, 0xf9, 0x7a, + 0xb9, 0xf0, 0xc1, 0xd5, 0xc2, 0x07, 0x37, 0x0b, 0x1f, 0x5c, 0xdc, 0xfa, 0x6f, 0x0e, 0xe1, 0x56, + 0x60, 0xd4, 0xb2, 0x25, 0x7e, 0xdd, 0x05, 0x00, 0x00, 0xff, 0xff, 0x28, 0x7e, 0xe2, 0x59, 0xca, + 0x02, 0x00, 0x00, +} + +func (m *Metadata) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Tags) > 0 { + for _, s := range m.Tags { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PingId) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingId) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Id)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Ping) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Ping) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Id.Size())) + n1, err := m.Id.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintFields(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PingRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Ping != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Ping.Size())) + n2, err := m.Ping.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Meta != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Meta.Size())) + n3, err := m.Meta.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Pong) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Pong) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Id) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintFields(dAtA, i, uint64(len(m.Id))) + i += copy(dAtA[i:], m.Id) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PongRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PongRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Pong != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Pong.Size())) + n4, err := m.Pong.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + if m.Meta != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintFields(dAtA, i, uint64(m.Meta.Size())) + n5, err := m.Meta.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *GoGoProtoStdTime) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GoGoProtoStdTime) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Timestamp != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintFields(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp))) + n6, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Timestamp, dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintFields(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Metadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Tags) > 0 { + for _, s := range m.Tags { + l = len(s) + n += 1 + l + sovFields(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PingId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovFields(uint64(m.Id)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Ping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = m.Id.Size() + n += 1 + l + sovFields(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovFields(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PingRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ping != nil { + l = m.Ping.Size() + n += 1 + l + sovFields(uint64(l)) + } + if m.Meta != nil { + l = m.Meta.Size() + n += 1 + l + sovFields(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Pong) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovFields(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PongRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pong != nil { + l = m.Pong.Size() + n += 1 + l + sovFields(uint64(l)) + } + if m.Meta != nil { + l = m.Meta.Size() + n += 1 + l + sovFields(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *GoGoProtoStdTime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Timestamp != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp) + n += 1 + l + sovFields(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovFields(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozFields(x uint64) (n int) { + return sovFields(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Metadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tags = append(m.Tags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingId) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Ping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Ping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Ping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Id == nil { + m.Id = &PingId{} + } + if err := m.Id.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ping == nil { + m.Ping = &Ping{} + } + if err := m.Ping.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Meta == nil { + m.Meta = &Metadata{} + } + if err := m.Meta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Pong) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Pong: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Pong: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PongRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PongRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PongRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pong", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pong == nil { + m.Pong = &Pong{} + } + if err := m.Pong.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Meta == nil { + m.Meta = &Metadata{} + } + if err := m.Meta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GoGoProtoStdTime) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GoGoProtoStdTime: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GoGoProtoStdTime: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFields + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthFields + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthFields + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Timestamp == nil { + m.Timestamp = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFields(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthFields + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipFields(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowFields + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowFields + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowFields + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthFields + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthFields + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowFields + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipFields(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthFields + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthFields = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowFields = fmt.Errorf("proto: integer overflow") +) diff --git a/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.proto b/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.proto new file mode 100644 index 0000000000..1c7546dffc --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/gogotestpb/fields.proto @@ -0,0 +1,50 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +syntax = "proto3"; + +// This file is used for grpctesting discovery of log fields from requests using reflection and gogo proto more tags. +package grpc_middleware.gogotestpb; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option (gogoproto.gogoproto_import) = false; + +option go_package = "gogotestpb"; + +message Metadata { + repeated string tags = 1 [(gogoproto.moretags) = "log_field:\"meta_tags\""]; +} + +message PingId { + int32 id = 1 [(gogoproto.moretags) = "log_field:\"ping_id\""]; +} + +message Ping { + PingId id = 1; + string value = 2; +} + +message PingRequest { + Ping ping = 1; + Metadata meta = 2; +} + +message Pong { + string id = 1 [(gogoproto.moretags) = "log_field:\"pong_id\""]; +} + +message PongRequest { + Pong pong = 1; + Metadata meta = 2; +} + +message GoGoProtoStdTime { + google.protobuf.Timestamp timestamp = 1 [(gogoproto.stdtime) = true]; +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/interceptor_suite.go b/pkg/tracing/tracing_middleware/grpctesting/interceptor_suite.go new file mode 100644 index 0000000000..15856885f2 --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/interceptor_suite.go @@ -0,0 +1,209 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package grpctesting + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "flag" + "math/big" + "net" + "sync" + "time" + + "google.golang.org/grpc/credentials/insecure" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware/grpctesting/testpb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" +) + +var ( + flagTls = flag.Bool("use_tls", true, "whether all gRPC middleware tests should use tls") + certPEM []byte + keyPEM []byte +) + +// InterceptorTestSuite is a testify/Suite that starts a gRPC PingService server and a client. +type InterceptorTestSuite struct { + suite.Suite + + TestService testpb.TestServiceServer + ServerOpts []grpc.ServerOption + ClientOpts []grpc.DialOption + + serverAddr string + ServerListener net.Listener + Server *grpc.Server + clientConn *grpc.ClientConn + Client testpb.TestServiceClient + + restartServerWithDelayedStart chan time.Duration + serverRunning chan bool + + cancels []context.CancelFunc +} + +func (s *InterceptorTestSuite) SetupSuite() { + s.restartServerWithDelayedStart = make(chan time.Duration) + s.serverRunning = make(chan bool) + + s.serverAddr = "127.0.0.1:0" + var err error + certPEM, keyPEM, err = generateCertAndKey([]string{"localhost", "example.com"}) + require.NoError(s.T(), err, "unable to generate test certificate/key") + + go func() { + for { + var err error + s.ServerListener, err = net.Listen("tcp", s.serverAddr) + s.serverAddr = s.ServerListener.Addr().String() + require.NoError(s.T(), err, "must be able to allocate a port for serverListener") + if *flagTls { + cert, err := tls.X509KeyPair(certPEM, keyPEM) + require.NoError(s.T(), err, "unable to load test TLS certificate") + creds := credentials.NewServerTLSFromCert(&cert) + s.ServerOpts = append(s.ServerOpts, grpc.Creds(creds)) + } + // This is the point where we hook up the interceptor. + s.Server = grpc.NewServer(s.ServerOpts...) + // Create a service if the instantiator hasn't provided one. + if s.TestService == nil { + s.TestService = &TestPingService{T: s.T()} + } + testpb.RegisterTestServiceServer(s.Server, s.TestService) + + w := sync.WaitGroup{} + w.Add(1) + go func() { + _ = s.Server.Serve(s.ServerListener) + w.Done() + }() + if s.Client == nil { + s.Client = s.NewClient(s.ClientOpts...) + } + + s.serverRunning <- true + + d := <-s.restartServerWithDelayedStart + s.Server.Stop() + time.Sleep(d) + w.Wait() + } + }() + + select { + case <-s.serverRunning: + case <-time.After(2 * time.Second): + s.T().Fatal("server failed to start before deadline") + } +} + +func (s *InterceptorTestSuite) RestartServer(delayedStart time.Duration) <-chan bool { + s.restartServerWithDelayedStart <- delayedStart + time.Sleep(10 * time.Millisecond) + return s.serverRunning +} + +func (s *InterceptorTestSuite) NewClient(dialOpts ...grpc.DialOption) testpb.TestServiceClient { + var err error + if *flagTls { + cp := x509.NewCertPool() + if !cp.AppendCertsFromPEM(certPEM) { + s.T().Fatal("failed to append certificate") + } + creds := credentials.NewTLS(&tls.Config{ServerName: "localhost", RootCAs: cp}) + dialOpts = append(dialOpts, grpc.WithTransportCredentials(creds)) + } else { + dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } + s.clientConn, err = grpc.NewClient(s.ServerAddr(), dialOpts...) + require.NoError(s.T(), err, "must not error on client Dial") + return testpb.NewTestServiceClient(s.clientConn) +} + +func (s *InterceptorTestSuite) ServerAddr() string { + return s.serverAddr +} + +func (s *InterceptorTestSuite) SimpleCtx() context.Context { + ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second) + s.cancels = append(s.cancels, cancel) + return ctx +} + +func (s *InterceptorTestSuite) DeadlineCtx(deadline time.Time) context.Context { + ctx, cancel := context.WithDeadline(context.TODO(), deadline) + s.cancels = append(s.cancels, cancel) + return ctx +} + +func (s *InterceptorTestSuite) TearDownSuite() { + time.Sleep(10 * time.Millisecond) + if s.ServerListener != nil { + s.Server.GracefulStop() + s.T().Logf("stopped grpc.Server at: %v", s.ServerAddr()) + _ = s.ServerListener.Close() + } + if s.clientConn != nil { + _ = s.clientConn.Close() + } + for _, c := range s.cancels { + c() + } +} + +// generateCertAndKey copied from https://github.com/johanbrandhorst/certify/blob/master/issuers/vault/vault_suite_test.go#L255 +// with minor modifications. +func generateCertAndKey(san []string) ([]byte, []byte, error) { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, nil, err + } + notBefore := time.Now() + notAfter := notBefore.Add(time.Hour) + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return nil, nil, err + } + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: "example.com", + }, + NotBefore: notBefore, + NotAfter: notAfter, + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + DNSNames: san, + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv) + if err != nil { + return nil, nil, err + } + certOut := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: derBytes, + }) + keyOut := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(priv), + }) + + return certOut, keyOut, nil +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/mutex_readerwriter.go b/pkg/tracing/tracing_middleware/grpctesting/mutex_readerwriter.go new file mode 100644 index 0000000000..44ed5249c8 --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/mutex_readerwriter.go @@ -0,0 +1,39 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package grpctesting + +import ( + "io" + "sync" +) + +// MutexReadWriter is a io.ReadWriter that can be read and worked on from multiple go routines. +type MutexReadWriter struct { + sync.Mutex + rw io.ReadWriter +} + +// NewMutexReadWriter creates a new thread-safe io.ReadWriter. +func NewMutexReadWriter(rw io.ReadWriter) *MutexReadWriter { + return &MutexReadWriter{rw: rw} +} + +// Write implements the io.Writer interface. +func (m *MutexReadWriter) Write(p []byte) (int, error) { + m.Lock() + defer m.Unlock() + return m.rw.Write(p) +} + +// Read implements the io.Reader interface. +func (m *MutexReadWriter) Read(p []byte) (int, error) { + m.Lock() + defer m.Unlock() + return m.rw.Read(p) +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/pingservice.go b/pkg/tracing/tracing_middleware/grpctesting/pingservice.go new file mode 100644 index 0000000000..6d64ed6d7c --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/pingservice.go @@ -0,0 +1,81 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +/* +Package `grpc_testing` provides helper functions for testing validators in this package. +*/ + +package grpctesting + +import ( + "context" + "io" + "testing" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware/grpctesting/testpb" +) + +const ( + // DefaultPongValue is the default value used. + DefaultResponseValue = "default_response_value" + // ListResponseCount is the expected number of responses to PingList. + ListResponseCount = 100 +) + +type TestPingService struct { + T *testing.T +} + +func (s *TestPingService) PingEmpty(_ context.Context, _ *testpb.Empty) (*testpb.PingResponse, error) { + return &testpb.PingResponse{Value: DefaultResponseValue, Counter: 0}, nil +} + +func (s *TestPingService) Ping(_ context.Context, ping *testpb.PingRequest) (*testpb.PingResponse, error) { + // Send user trailers and headers. + return &testpb.PingResponse{Value: ping.Value, Counter: 0}, nil +} + +func (s *TestPingService) PingError(_ context.Context, ping *testpb.PingRequest) (*testpb.Empty, error) { + code := codes.Code(ping.ErrorCodeReturned) + return nil, status.Errorf(code, "Userspace error.") +} + +func (s *TestPingService) PingList(ping *testpb.PingRequest, stream testpb.TestService_PingListServer) error { + if ping.ErrorCodeReturned != 0 { + return status.Errorf(codes.Code(ping.ErrorCodeReturned), "foobar") + } + // Send user trailers and headers. + for i := 0; i < ListResponseCount; i++ { + if err := stream.Send(&testpb.PingResponse{Value: ping.Value, Counter: int32(i)}); err != nil { + return err + } + } + return nil +} + +func (s *TestPingService) PingStream(stream testpb.TestService_PingStreamServer) error { + count := 0 + for { + ping, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + return err + } + if err := stream.Send(&testpb.PingResponse{Value: ping.Value, Counter: int32(count)}); err != nil { + return err + } + + count += 1 + } + return nil +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_extractfields.pb.go b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_extractfields.pb.go new file mode 100644 index 0000000000..ab1f0191c7 --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_extractfields.pb.go @@ -0,0 +1,10 @@ +// Manual code for logging field extraction tests. + +package testpb + +const TestServiceFullName = "grpc_middleware.testpb.TestService" + +// This is implementing tags.requestFieldsExtractor. +func (m *PingRequest) ExtractRequestFields(appendToMap map[string]string) { + appendToMap["value"] = m.Value +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_validator.pb.go b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_validator.pb.go new file mode 100644 index 0000000000..f123c70b76 --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.manual_validator.pb.go @@ -0,0 +1,12 @@ +// Manual code for validation tests. + +package testpb + +import "github.com/pkg/errors" + +func (m *PingRequest) Validate() error { + if m.SleepTimeMs > 10000 { + return errors.New("cannot sleep for more than 10s") + } + return nil +} diff --git a/pkg/tracing/tracing_middleware/grpctesting/testpb/test.pb.go b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.pb.go new file mode 100644 index 0000000000..bba2dd4f3a --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.pb.go @@ -0,0 +1,1037 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: test.proto + +package testpb + +import ( + context "context" + fmt "fmt" + io "io" + math "math" + + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" +) + +// 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.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Empty struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{0} +} +func (m *Empty) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Empty.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Empty) XXX_Merge(src proto.Message) { + xxx_messageInfo_Empty.Merge(m, src) +} +func (m *Empty) XXX_Size() int { + return m.Size() +} +func (m *Empty) XXX_DiscardUnknown() { + xxx_messageInfo_Empty.DiscardUnknown(m) +} + +var xxx_messageInfo_Empty proto.InternalMessageInfo + +type PingRequest struct { + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + SleepTimeMs int32 `protobuf:"varint,2,opt,name=sleep_time_ms,json=sleepTimeMs,proto3" json:"sleep_time_ms,omitempty"` + ErrorCodeReturned uint32 `protobuf:"varint,3,opt,name=error_code_returned,json=errorCodeReturned,proto3" json:"error_code_returned,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PingRequest) Reset() { *m = PingRequest{} } +func (m *PingRequest) String() string { return proto.CompactTextString(m) } +func (*PingRequest) ProtoMessage() {} +func (*PingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{1} +} +func (m *PingRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PingRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingRequest.Merge(m, src) +} +func (m *PingRequest) XXX_Size() int { + return m.Size() +} +func (m *PingRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PingRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PingRequest proto.InternalMessageInfo + +func (m *PingRequest) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *PingRequest) GetSleepTimeMs() int32 { + if m != nil { + return m.SleepTimeMs + } + return 0 +} + +func (m *PingRequest) GetErrorCodeReturned() uint32 { + if m != nil { + return m.ErrorCodeReturned + } + return 0 +} + +type PingResponse struct { + Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` + Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PingResponse) Reset() { *m = PingResponse{} } +func (m *PingResponse) String() string { return proto.CompactTextString(m) } +func (*PingResponse) ProtoMessage() {} +func (*PingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{2} +} +func (m *PingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PingResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingResponse.Merge(m, src) +} +func (m *PingResponse) XXX_Size() int { + return m.Size() +} +func (m *PingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PingResponse proto.InternalMessageInfo + +func (m *PingResponse) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *PingResponse) GetCounter() int32 { + if m != nil { + return m.Counter + } + return 0 +} + +func init() { + proto.RegisterType((*Empty)(nil), "grpc_middleware.testpb.Empty") + proto.RegisterType((*PingRequest)(nil), "grpc_middleware.testpb.PingRequest") + proto.RegisterType((*PingResponse)(nil), "grpc_middleware.testpb.PingResponse") +} + +func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } + +var fileDescriptor_c161fcfdc0c3ff1e = []byte{ + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x52, 0xcd, 0x4a, 0x33, 0x31, + 0x14, 0x6d, 0xbe, 0x7e, 0x6d, 0xed, 0xad, 0x5d, 0x18, 0x8b, 0x0c, 0x82, 0xa5, 0x44, 0x17, 0xb3, + 0x1a, 0x8a, 0xee, 0x5d, 0x28, 0xee, 0x14, 0x34, 0x2d, 0x82, 0x82, 0x0c, 0xed, 0xcc, 0xa5, 0x04, + 0x9a, 0x49, 0x4c, 0x32, 0x2d, 0x3e, 0x9f, 0x1b, 0x97, 0x3e, 0x82, 0xf4, 0x49, 0x24, 0x69, 0x85, + 0x2e, 0xb4, 0x74, 0xd1, 0xe5, 0x3d, 0xe7, 0x70, 0x7e, 0x42, 0x00, 0x1c, 0x5a, 0x97, 0x68, 0xa3, + 0x9c, 0xa2, 0x47, 0x13, 0xa3, 0xb3, 0x54, 0x8a, 0x3c, 0x9f, 0xe2, 0x7c, 0x64, 0x30, 0xf1, 0x9c, + 0x1e, 0xb3, 0x06, 0xd4, 0x6e, 0xa4, 0x76, 0x6f, 0x6c, 0x0e, 0xad, 0x7b, 0x51, 0x4c, 0x38, 0xbe, + 0x96, 0x68, 0x1d, 0xed, 0x40, 0x6d, 0x36, 0x9a, 0x96, 0x18, 0x91, 0x1e, 0x89, 0x9b, 0x7c, 0x79, + 0x50, 0x06, 0x6d, 0x3b, 0x45, 0xd4, 0xa9, 0x13, 0x12, 0x53, 0x69, 0xa3, 0x7f, 0x3d, 0x12, 0xd7, + 0x78, 0x2b, 0x80, 0x43, 0x21, 0xf1, 0xce, 0xd2, 0x04, 0x0e, 0xd1, 0x18, 0x65, 0xd2, 0x4c, 0xe5, + 0x98, 0x1a, 0x74, 0xa5, 0x29, 0x30, 0x8f, 0xaa, 0x3d, 0x12, 0xb7, 0xf9, 0x41, 0xa0, 0xae, 0x55, + 0x8e, 0x7c, 0x45, 0xb0, 0x4b, 0xd8, 0x5f, 0x06, 0x5b, 0xad, 0x0a, 0x8b, 0x3e, 0xf9, 0x71, 0x3d, + 0x39, 0x1c, 0x34, 0x82, 0x46, 0xa6, 0xca, 0xc2, 0xa1, 0x59, 0x65, 0xfe, 0x9c, 0xe7, 0xef, 0x55, + 0x68, 0x0d, 0xd1, 0xba, 0x01, 0x9a, 0x99, 0xc8, 0x90, 0x72, 0x68, 0x7a, 0xbf, 0xb0, 0x8a, 0x9e, + 0x24, 0xbf, 0xef, 0x4e, 0x02, 0x7d, 0x7c, 0xf6, 0x17, 0xbd, 0xde, 0x88, 0x55, 0xe8, 0x00, 0xfe, + 0x7b, 0x84, 0x9e, 0x6e, 0xd6, 0x87, 0xa7, 0xdb, 0xda, 0xf4, 0x61, 0x55, 0xd4, 0xbf, 0xc8, 0x76, + 0xce, 0x9b, 0xd7, 0xb0, 0x0a, 0x7d, 0x82, 0x3d, 0xaf, 0xbf, 0x15, 0xd6, 0xed, 0xb4, 0x6b, 0x9f, + 0xd0, 0x17, 0x00, 0x8f, 0x0d, 0x9c, 0xc1, 0x91, 0xdc, 0xa9, 0x79, 0x4c, 0xfa, 0xe4, 0xaa, 0xf3, + 0xb1, 0xe8, 0x92, 0xcf, 0x45, 0x97, 0x7c, 0x2d, 0xba, 0xe4, 0xb9, 0xbe, 0x14, 0x8e, 0xeb, 0xe1, + 0xf3, 0x5e, 0x7c, 0x07, 0x00, 0x00, 0xff, 0xff, 0x92, 0x21, 0xeb, 0x3f, 0xca, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// TestServiceClient is the client API for TestService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type TestServiceClient interface { + PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) + Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) + PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) + PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) + PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) +} + +type testServiceClient struct { + cc *grpc.ClientConn +} + +func NewTestServiceClient(cc *grpc.ClientConn) TestServiceClient { + return &testServiceClient{cc} +} + +func (c *testServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) { + out := new(PingResponse) + err := c.cc.Invoke(ctx, "/grpc_middleware.testpb.TestService/PingEmpty", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { + out := new(PingResponse) + err := c.cc.Invoke(ctx, "/grpc_middleware.testpb.TestService/Ping", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/grpc_middleware.testpb.TestService/PingError", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) { + stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[0], "/grpc_middleware.testpb.TestService/PingList", opts...) + if err != nil { + return nil, err + } + x := &testServicePingListClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type TestService_PingListClient interface { + Recv() (*PingResponse, error) + grpc.ClientStream +} + +type testServicePingListClient struct { + grpc.ClientStream +} + +func (x *testServicePingListClient) Recv() (*PingResponse, error) { + m := new(PingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[1], "/grpc_middleware.testpb.TestService/PingStream", opts...) + if err != nil { + return nil, err + } + x := &testServicePingStreamClient{stream} + return x, nil +} + +type TestService_PingStreamClient interface { + Send(*PingRequest) error + Recv() (*PingResponse, error) + grpc.ClientStream +} + +type testServicePingStreamClient struct { + grpc.ClientStream +} + +func (x *testServicePingStreamClient) Send(m *PingRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *testServicePingStreamClient) Recv() (*PingResponse, error) { + m := new(PingResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// TestServiceServer is the server API for TestService service. +type TestServiceServer interface { + PingEmpty(context.Context, *Empty) (*PingResponse, error) + Ping(context.Context, *PingRequest) (*PingResponse, error) + PingError(context.Context, *PingRequest) (*Empty, error) + PingList(*PingRequest, TestService_PingListServer) error + PingStream(TestService_PingStreamServer) error +} + +func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { + s.RegisterService(&_TestService_serviceDesc, srv) +} + +func _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).PingEmpty(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc_middleware.testpb.TestService/PingEmpty", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).PingEmpty(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc_middleware.testpb.TestService/Ping", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).Ping(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).PingError(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc_middleware.testpb.TestService/PingError", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).PingError(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PingRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(TestServiceServer).PingList(m, &testServicePingListServer{stream}) +} + +type TestService_PingListServer interface { + Send(*PingResponse) error + grpc.ServerStream +} + +type testServicePingListServer struct { + grpc.ServerStream +} + +func (x *testServicePingListServer) Send(m *PingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TestServiceServer).PingStream(&testServicePingStreamServer{stream}) +} + +type TestService_PingStreamServer interface { + Send(*PingResponse) error + Recv() (*PingRequest, error) + grpc.ServerStream +} + +type testServicePingStreamServer struct { + grpc.ServerStream +} + +func (x *testServicePingStreamServer) Send(m *PingResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *testServicePingStreamServer) Recv() (*PingRequest, error) { + m := new(PingRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _TestService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc_middleware.testpb.TestService", + HandlerType: (*TestServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PingEmpty", + Handler: _TestService_PingEmpty_Handler, + }, + { + MethodName: "Ping", + Handler: _TestService_Ping_Handler, + }, + { + MethodName: "PingError", + Handler: _TestService_PingError_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "PingList", + Handler: _TestService_PingList_Handler, + ServerStreams: true, + }, + { + StreamName: "PingStream", + Handler: _TestService_PingStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "test.proto", +} + +func (m *Empty) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Empty) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PingRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Value) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTest(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if m.SleepTimeMs != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTest(dAtA, i, uint64(m.SleepTimeMs)) + } + if m.ErrorCodeReturned != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintTest(dAtA, i, uint64(m.ErrorCodeReturned)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PingResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Value) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTest(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if m.Counter != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTest(dAtA, i, uint64(m.Counter)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintTest(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Empty) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PingRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTest(uint64(l)) + } + if m.SleepTimeMs != 0 { + n += 1 + sovTest(uint64(m.SleepTimeMs)) + } + if m.ErrorCodeReturned != 0 { + n += 1 + sovTest(uint64(m.ErrorCodeReturned)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTest(uint64(l)) + } + if m.Counter != 0 { + n += 1 + sovTest(uint64(m.Counter)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovTest(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozTest(x uint64) (n int) { + return sovTest(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Empty) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Empty: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Empty: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SleepTimeMs", wireType) + } + m.SleepTimeMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SleepTimeMs |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorCodeReturned", wireType) + } + m.ErrorCodeReturned = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ErrorCodeReturned |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Counter", wireType) + } + m.Counter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Counter |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTest(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTest + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthTest + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipTest(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthTest + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthTest = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTest = fmt.Errorf("proto: integer overflow") +) diff --git a/pkg/tracing/tracing_middleware/grpctesting/testpb/test.proto b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.proto new file mode 100644 index 0000000000..5c0d0b3af5 --- /dev/null +++ b/pkg/tracing/tracing_middleware/grpctesting/testpb/test.proto @@ -0,0 +1,40 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +syntax = "proto3"; + +package grpc_middleware.testpb; + +option go_package = "testpb"; + +message Empty { +} + +message PingRequest { + string value = 1; + int32 sleep_time_ms = 2; + uint32 error_code_returned = 3; +} + +message PingResponse { + string Value = 1; + int32 counter = 2; +} + +service TestService { + rpc PingEmpty(Empty) returns (PingResponse) {} + + rpc Ping(PingRequest) returns (PingResponse) {} + + rpc PingError(PingRequest) returns (Empty) {} + + rpc PingList(PingRequest) returns (stream PingResponse) {} + + rpc PingStream(stream PingRequest) returns (stream PingResponse) {} + +} diff --git a/pkg/tracing/tracing_middleware/interceptors_test.go b/pkg/tracing/tracing_middleware/interceptors_test.go new file mode 100644 index 0000000000..39f6b4d451 --- /dev/null +++ b/pkg/tracing/tracing_middleware/interceptors_test.go @@ -0,0 +1,266 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package tracing_middleware_test + +import ( + "context" + "fmt" + + "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware" + "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware/grpctesting" + + "io" + "net/http" + "strconv" + "strings" + "testing" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/mocktracer" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + + "github.com/thanos-io/thanos/pkg/tracing/tracing_middleware/grpctesting/testpb" +) + +var ( + goodPing = &testpb.PingRequest{Value: "something", SleepTimeMs: 9999} + fakeInboundTraceId = 1337 + fakeInboundSpanId = 999 + traceHeaderName = "uber-trace-id" +) + +type tracingAssertService struct { + testpb.TestServiceServer + T *testing.T +} + +func (s *tracingAssertService) PingError(ctx context.Context, ping *testpb.PingRequest) (*testpb.Empty, error) { + assert.NotNil(s.T, opentracing.SpanFromContext(ctx), "handlers must have the spancontext in their context, otherwise propagation will fail") + return s.TestServiceServer.PingError(ctx, ping) +} + +func TestTaggingSuite(t *testing.T) { + mockTracer := mocktracer.New() + opts := []tracing_middleware.Option{ + tracing_middleware.WithTracer(mockTracer), + tracing_middleware.WithTraceHeaderName(traceHeaderName), + } + s := &OpentracingSuite{ + mockTracer: mockTracer, + InterceptorTestSuite: makeInterceptorTestSuite(t, opts), + } + suite.Run(t, s) +} + +func TestTaggingSuiteJaeger(t *testing.T) { + mockTracer := mocktracer.New() + mockTracer.RegisterInjector(opentracing.HTTPHeaders, jaegerFormatInjector{}) + mockTracer.RegisterExtractor(opentracing.HTTPHeaders, jaegerFormatExtractor{}) + opts := []tracing_middleware.Option{ + tracing_middleware.WithTracer(mockTracer), + } + s := &OpentracingSuite{ + mockTracer: mockTracer, + InterceptorTestSuite: makeInterceptorTestSuite(t, opts), + } + suite.Run(t, s) +} + +func makeInterceptorTestSuite(t *testing.T, opts []tracing_middleware.Option) *grpctesting.InterceptorTestSuite { + return &grpctesting.InterceptorTestSuite{ + TestService: &tracingAssertService{TestServiceServer: &grpctesting.TestPingService{T: t}, T: t}, + ClientOpts: []grpc.DialOption{ + grpc.WithUnaryInterceptor(tracing_middleware.UnaryClientInterceptor(opts...)), + grpc.WithStreamInterceptor(tracing_middleware.StreamClientInterceptor(opts...)), + }, + ServerOpts: []grpc.ServerOption{ + grpc.ChainStreamInterceptor( + //tags.StreamServerInterceptor(tags.WithFieldExtractor(tags.CodeGenRequestFieldExtractor)), + tracing_middleware.StreamServerInterceptor(opts...)), + grpc.ChainUnaryInterceptor( + //tags.UnaryServerInterceptor(tags.WithFieldExtractor(tags.CodeGenRequestFieldExtractor)), + tracing_middleware.UnaryServerInterceptor(opts...)), + }, + } +} + +type OpentracingSuite struct { + *grpctesting.InterceptorTestSuite + mockTracer *mocktracer.MockTracer +} + +func (s *OpentracingSuite) SetupTest() { + s.mockTracer.Reset() +} + +func (s *OpentracingSuite) createContextFromFakeHttpRequestParent(ctx context.Context, sampled bool) context.Context { + jFlag := 0 + if sampled { + jFlag = 1 + } + + hdr := http.Header{} + hdr.Set(traceHeaderName, fmt.Sprintf("%d:%d:%d:%d", fakeInboundTraceId, fakeInboundSpanId, fakeInboundSpanId, jFlag)) + hdr.Set("mockpfx-ids-traceid", fmt.Sprint(fakeInboundTraceId)) + hdr.Set("mockpfx-ids-spanid", fmt.Sprint(fakeInboundSpanId)) + hdr.Set("mockpfx-ids-sampled", fmt.Sprint(sampled)) + + parentSpanContext, err := s.mockTracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(hdr)) + require.NoError(s.T(), err, "parsing a fake HTTP request headers shouldn't fail, ever") + fakeSpan := s.mockTracer.StartSpan( + "/fake/parent/http/request", + // this is magical, it attaches the new span to the parent parentSpanContext, and creates an unparented one if empty. + opentracing.ChildOf(parentSpanContext), + ) + fakeSpan.Finish() + return opentracing.ContextWithSpan(ctx, fakeSpan) +} + +func (s *OpentracingSuite) assertTracesCreated(methodName string) (clientSpan *mocktracer.MockSpan, serverSpan *mocktracer.MockSpan) { + spans := s.mockTracer.FinishedSpans() + for _, span := range spans { + s.T().Logf("span: %v, tags: %v", span, span.Tags()) + } + require.Len(s.T(), spans, 3, "should record 3 spans: one fake inbound, one client, one server") + traceIdAssert := fmt.Sprintf("traceId=%d", fakeInboundTraceId) + for _, span := range spans { + assert.Contains(s.T(), span.String(), traceIdAssert, "not part of the fake parent trace: %v", span) + if span.OperationName == methodName { + kind := fmt.Sprintf("%v", span.Tag("span.kind")) + if kind == "client" { + clientSpan = span + } else if kind == "server" { + serverSpan = span + } + assert.EqualValues(s.T(), span.Tag("component"), "gRPC", "span must be tagged with gRPC component") + } + } + require.NotNil(s.T(), clientSpan, "client span must be there") + require.NotNil(s.T(), serverSpan, "server span must be there") + //assert.EqualValues(s.T(), serverSpan.Tag("grpc.request.value"), "something", "tags must be propagated, in this case ones from request fields") + return clientSpan, serverSpan +} + +func (s *OpentracingSuite) TestPing_PropagatesTraces() { + ctx := s.createContextFromFakeHttpRequestParent(s.SimpleCtx(), true) + _, err := s.Client.Ping(ctx, goodPing) + require.NoError(s.T(), err, "there must be not be an on a successful call") + s.assertTracesCreated("/" + testpb.TestServiceFullName + "/Ping") +} + +func (s *OpentracingSuite) TestPing_ClientContextTags() { + const name = "opentracing.custom" + ctx := tracing_middleware.ClientAddContextTags( + s.createContextFromFakeHttpRequestParent(s.SimpleCtx(), true), + opentracing.Tags{name: ""}, + ) + + _, err := s.Client.Ping(ctx, goodPing) + require.NoError(s.T(), err, "there must be not be an on a successful call") + + for _, span := range s.mockTracer.FinishedSpans() { + if span.OperationName == "/"+testpb.TestServiceFullName+"/Ping" { + kind := fmt.Sprintf("%v", span.Tag("span.kind")) + if kind == "client" { + assert.Contains(s.T(), span.Tags(), name, "custom opentracing.Tags must be included in context") + } + } + } +} + +func (s *OpentracingSuite) TestPingList_PropagatesTraces() { + ctx := s.createContextFromFakeHttpRequestParent(s.SimpleCtx(), true) + stream, err := s.Client.PingList(ctx, goodPing) + require.NoError(s.T(), err, "should not fail on establishing the stream") + for { + _, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(s.T(), err, "reading stream should not fail") + } + s.assertTracesCreated("/" + testpb.TestServiceFullName + "/PingList") +} + +func (s *OpentracingSuite) TestPingError_PropagatesTraces() { + ctx := s.createContextFromFakeHttpRequestParent(s.SimpleCtx(), true) + erroringPing := &testpb.PingRequest{Value: "something", ErrorCodeReturned: uint32(codes.OutOfRange)} + _, err := s.Client.PingError(ctx, erroringPing) + require.Error(s.T(), err, "there must be an error returned here") + clientSpan, serverSpan := s.assertTracesCreated("/" + testpb.TestServiceFullName + "/PingError") + assert.Equal(s.T(), true, clientSpan.Tag("error"), "client span needs to be marked as an error") + assert.Equal(s.T(), true, serverSpan.Tag("error"), "server span needs to be marked as an error") +} + +func (s *OpentracingSuite) TestPingEmpty_NotSampleTraces() { + ctx := s.createContextFromFakeHttpRequestParent(s.SimpleCtx(), false) + _, err := s.Client.PingEmpty(ctx, &testpb.Empty{}) + require.NoError(s.T(), err, "there must be not be an on a successful call") +} + +type jaegerFormatInjector struct{} + +func (jaegerFormatInjector) Inject(ctx mocktracer.MockSpanContext, carrier interface{}) error { + w := carrier.(opentracing.TextMapWriter) + flags := 0 + if ctx.Sampled { + flags = 1 + } + w.Set(traceHeaderName, fmt.Sprintf("%d:%d::%d", ctx.TraceID, ctx.SpanID, flags)) + + return nil +} + +type jaegerFormatExtractor struct{} + +func (jaegerFormatExtractor) Extract(carrier interface{}) (mocktracer.MockSpanContext, error) { + rval := mocktracer.MockSpanContext{Sampled: true} + reader, ok := carrier.(opentracing.TextMapReader) + if !ok { + return rval, opentracing.ErrInvalidCarrier + } + err := reader.ForeachKey(func(key, val string) error { + lowerKey := strings.ToLower(key) + switch { + case lowerKey == traceHeaderName: + parts := strings.Split(val, ":") + if len(parts) != 4 { + return errors.New("invalid trace id format") + } + traceId, err := strconv.Atoi(parts[0]) + if err != nil { + return err + } + rval.TraceID = traceId + spanId, err := strconv.Atoi(parts[1]) + if err != nil { + return err + } + rval.SpanID = spanId + flags, err := strconv.Atoi(parts[3]) + if err != nil { + return err + } + rval.Sampled = flags%2 == 1 + } + return nil + }) + if rval.TraceID == 0 || rval.SpanID == 0 { + return rval, opentracing.ErrSpanContextNotFound + } + if err != nil { + return rval, err + } + return rval, nil +} diff --git a/pkg/tracing/tracing_middleware/metadata.go b/pkg/tracing/tracing_middleware/metadata.go new file mode 100644 index 0000000000..8e3531ffde --- /dev/null +++ b/pkg/tracing/tracing_middleware/metadata.go @@ -0,0 +1,55 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package tracing_middleware + +import ( + "encoding/base64" + "strings" + + "google.golang.org/grpc/metadata" +) + +const ( + binHdrSuffix = "-bin" +) + +// metadataTextMap extends a metadata.MD to be an opentracing textmap. +type metadataTextMap metadata.MD + +// Set is a opentracing.TextMapReader interface that extracts values. +func (m metadataTextMap) Set(key, val string) { + // gRPC allows for complex binary values to be written. + encodedKey, encodedVal := encodeKeyValue(key, val) + // The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append + // we just override. + m[encodedKey] = []string{encodedVal} +} + +// ForeachKey is a opentracing.TextMapReader interface that extracts values. +func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error { + for k, vv := range m { + for _, v := range vv { + if err := callback(k, v); err != nil { + return err + } + } + } + return nil +} + +// encodeKeyValue encodes key and value qualified for transmission via gRPC. +// note: copy pasted from private values of grpc.metadata +func encodeKeyValue(k, v string) (string, string) { + k = strings.ToLower(k) + if strings.HasSuffix(k, binHdrSuffix) { + val := base64.StdEncoding.EncodeToString([]byte(v)) + v = string(val) + } + return k, v +} diff --git a/pkg/tracing/tracing_middleware/options.go b/pkg/tracing/tracing_middleware/options.go new file mode 100644 index 0000000000..d64e3a140b --- /dev/null +++ b/pkg/tracing/tracing_middleware/options.go @@ -0,0 +1,72 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package tracing_middleware + +import ( + "context" + + "github.com/opentracing/opentracing-go" +) + +var ( + defaultOptions = &options{ + filterOutFunc: nil, + tracer: nil, + } +) + +// FilterFunc allows users to provide a function that filters out certain methods from being traced. +// +// If it returns false, the given request will not be traced. +type FilterFunc func(ctx context.Context, fullMethodName string) bool + +type options struct { + filterOutFunc FilterFunc + tracer opentracing.Tracer + traceHeaderName string +} + +func evaluateOptions(opts []Option) *options { + optCopy := &options{} + *optCopy = *defaultOptions + for _, o := range opts { + o(optCopy) + } + if optCopy.tracer == nil { + optCopy.tracer = opentracing.GlobalTracer() + } + if optCopy.traceHeaderName == "" { + optCopy.traceHeaderName = "uber-trace-id" + } + return optCopy +} + +type Option func(*options) + +// WithFilterFunc customizes the function used for deciding whether a given call is traced or not. +func WithFilterFunc(f FilterFunc) Option { + return func(o *options) { + o.filterOutFunc = f + } +} + +// WithTraceHeaderName customizes the trace header name where trace metadata passed with requests. +// Default one is `uber-trace-id`. +func WithTraceHeaderName(name string) Option { + return func(o *options) { + o.traceHeaderName = name + } +} + +// WithTracer sets a custom tracer to be used for this middleware, otherwise the opentracing.GlobalTracer is used. +func WithTracer(tracer opentracing.Tracer) Option { + return func(o *options) { + o.tracer = tracer + } +} diff --git a/pkg/tracing/tracing_middleware/server.go b/pkg/tracing/tracing_middleware/server.go new file mode 100644 index 0000000000..bf5019248b --- /dev/null +++ b/pkg/tracing/tracing_middleware/server.go @@ -0,0 +1,94 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package tracing_middleware + +import ( + "context" + + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + + "github.com/thanos-io/thanos/pkg/tracing/interceptors" + "github.com/thanos-io/thanos/pkg/tracing/util/metautils" +) + +var ( + grpcTag = opentracing.Tag{Key: string(ext.Component), Value: "gRPC"} +) + +type opentracingServerReporter struct { + ctx context.Context + typ interceptors.GRPCType + service, method string + + serverSpan opentracing.Span +} + +func (o *opentracingServerReporter) PostCall(err error, _ time.Duration) { + if err != nil { + ext.Error.Set(o.serverSpan, true) + o.serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + } + o.serverSpan.Finish() +} + +func (o *opentracingServerReporter) PostMsgSend(interface{}, error, time.Duration) {} + +func (o *opentracingServerReporter) PostMsgReceive(interface{}, error, time.Duration) {} + +type opentracingServerReportable struct { + tracer opentracing.Tracer + // This is only used for server. TODO: Investigate if needed in client. + traceHeaderName string + filterOutFunc FilterFunc +} + +func (o *opentracingServerReportable) ServerReporter(ctx context.Context, _ interface{}, typ interceptors.GRPCType, service string, method string) (interceptors.Reporter, context.Context) { + if o.filterOutFunc != nil && !o.filterOutFunc(ctx, interceptors.FullMethod(service, method)) { + return interceptors.NoopReporter{}, ctx + } + + newCtx, serverSpan := newServerSpanFromInbound(ctx, o.tracer, interceptors.FullMethod(service, method)) + mock := &opentracingServerReporter{ctx: newCtx, typ: typ, service: service, method: method, serverSpan: serverSpan} + return mock, newCtx +} + +// UnaryServerInterceptor returns a new unary server interceptor for OpenTracing. +func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { + o := evaluateOptions(opts) + return interceptors.UnaryServerInterceptor(&opentracingServerReportable{tracer: o.tracer, traceHeaderName: o.traceHeaderName, filterOutFunc: o.filterOutFunc}) +} + +// StreamServerInterceptor returns a new streaming server interceptor for OpenTracing. +func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { + o := evaluateOptions(opts) + return interceptors.StreamServerInterceptor(&opentracingServerReportable{tracer: o.tracer, traceHeaderName: o.traceHeaderName, filterOutFunc: o.filterOutFunc}) +} + +func newServerSpanFromInbound(ctx context.Context, tracer opentracing.Tracer, fullMethodName string) (context.Context, opentracing.Span) { + md := metautils.ExtractIncoming(ctx) + parentSpanContext, err := tracer.Extract(opentracing.HTTPHeaders, metadataTextMap(md)) + if err != nil && err != opentracing.ErrSpanContextNotFound { + grpclog.Infof("grpc_opentracing: failed parsing trace information: %v", err) + } + + serverSpan := tracer.StartSpan( + fullMethodName, + // this is magical, it attaches the new span to the parent parentSpanContext, and creates an unparented one if empty. + ext.RPCServerOption(parentSpanContext), + grpcTag, + ) + + return opentracing.ContextWithSpan(ctx, serverSpan), serverSpan +} diff --git a/pkg/tracing/util/metautils/doc.go b/pkg/tracing/util/metautils/doc.go new file mode 100644 index 0000000000..8905a81538 --- /dev/null +++ b/pkg/tracing/util/metautils/doc.go @@ -0,0 +1,24 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +/* +Package `metautils` provides convenience functions for dealing with gRPC metadata.MD objects inside +Context handlers. + +While the upstream grpc-go package contains decent functionality (see https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md) +they are hard to use. + +The majority of functions center around the NiceMD, which is a convenience wrapper around metadata.MD. For example +the following code allows you to easily extract incoming metadata (server handler) and put it into a new client context +metadata. + + nmd := metautils.ExtractIncoming(serverCtx).Clone(":authorization", ":custom") + clientCtx := nmd.Set("x-client-header", "2").Set("x-another", "3").ToOutgoing(ctx) +*/ + +package metautils diff --git a/pkg/tracing/util/metautils/nicemd.go b/pkg/tracing/util/metautils/nicemd.go new file mode 100644 index 0000000000..40c93e806d --- /dev/null +++ b/pkg/tracing/util/metautils/nicemd.go @@ -0,0 +1,131 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package metautils + +import ( + "context" + "strings" + + "google.golang.org/grpc/metadata" +) + +// NiceMD is a convenience wrapper defining extra functions on the metadata. +type NiceMD metadata.MD + +// ExtractIncoming extracts an inbound metadata from the server-side context. +// +// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns +// a new empty NiceMD. +func ExtractIncoming(ctx context.Context) NiceMD { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return NiceMD(metadata.Pairs()) + } + return NiceMD(md) +} + +// ExtractOutgoing extracts an outbound metadata from the client-side context. +// +// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns +// a new empty NiceMD. +func ExtractOutgoing(ctx context.Context) NiceMD { + md, ok := metadata.FromOutgoingContext(ctx) + if !ok { + return NiceMD(metadata.Pairs()) + } + return NiceMD(md) +} + +// Clone performs a *deep* copy of the metadata.MD. +// +// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted +// all keys get copied. +func (m NiceMD) Clone(copiedKeys ...string) NiceMD { + newMd := NiceMD(metadata.Pairs()) + for k, vv := range m { + found := false + if len(copiedKeys) == 0 { + found = true + } else { + for _, allowedKey := range copiedKeys { + if strings.EqualFold(allowedKey, k) { + found = true + break + } + } + } + if !found { + continue + } + newMd[k] = make([]string, len(vv)) + copy(newMd[k], vv) + } + return NiceMD(newMd) +} + +// ToOutgoing sets the given NiceMD as a client-side context for dispatching. +func (m NiceMD) ToOutgoing(ctx context.Context) context.Context { + return metadata.NewOutgoingContext(ctx, metadata.MD(m)) +} + +// ToIncoming sets the given NiceMD as a server-side context for dispatching. +// +// This is mostly useful in ServerInterceptors.. +func (m NiceMD) ToIncoming(ctx context.Context) context.Context { + return metadata.NewIncomingContext(ctx, metadata.MD(m)) +} + +// Get retrieves a single value from the metadata. +// +// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set, +// an empty string is returned. +// +// The function is binary-key safe. +func (m NiceMD) Get(key string) string { + k, _ := encodeKeyValue(key, "") + vv, ok := m[k] + if !ok { + return "" + } + return vv[0] +} + +// Del retrieves a single value from the metadata. +// +// It works analogously to http.Header.Del, deleting all values if they exist. +// +// The function is binary-key safe. + +func (m NiceMD) Del(key string) NiceMD { + k, _ := encodeKeyValue(key, "") + delete(m, k) + return m +} + +// Set sets the given value in a metadata. +// +// It works analogously to http.Header.Set, overwriting all previous metadata values. +// +// The function is binary-key safe. +func (m NiceMD) Set(key string, value string) NiceMD { + k, v := encodeKeyValue(key, value) + m[k] = []string{v} + return m +} + +// Add retrieves a single value from the metadata. +// +// It works analogously to http.Header.Add, as it appends to any existing values associated with key. +// +// The function is binary-key safe. +func (m NiceMD) Add(key string, value string) NiceMD { + k, v := encodeKeyValue(key, value) + m[k] = append(m[k], v) + return m +} diff --git a/pkg/tracing/util/metautils/nicemd_test.go b/pkg/tracing/util/metautils/nicemd_test.go new file mode 100644 index 0000000000..cbe79b1ede --- /dev/null +++ b/pkg/tracing/util/metautils/nicemd_test.go @@ -0,0 +1,94 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package metautils_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "google.golang.org/grpc/metadata" + + "github.com/thanos-io/thanos/pkg/tracing/util/metautils" +) + +var parentKey struct{} + +var ( + testPairs = []string{"singlekey", "uno", "multikey", "one", "multikey", "two", "multikey", "three"} + parentCtx = context.WithValue(context.TODO(), parentKey, "parentValue") +) + +func assertRetainsParentContext(t *testing.T, ctx context.Context) { + x := ctx.Value(parentKey) + assert.EqualValues(t, "parentValue", x, "context must contain parentCtx") +} + +func TestNiceMD_Get(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + assert.Equal(t, "uno", nmd.Get("singlekey"), "for present single-key value it should return it") + assert.Equal(t, "one", nmd.Get("multikey"), "for present multi-key should return first value") + assert.Empty(t, nmd.Get("nokey"), "for non existing key should return stuff") +} + +func TestNiceMD_Del(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + assert.Equal(t, "uno", nmd.Get("singlekey"), "for present single-key value it should return it") + nmd.Del("singlekey").Del("doesnt exist") + assert.Empty(t, nmd.Get("singlekey"), "after deletion singlekey shouldn't exist") +} + +func TestNiceMD_Add(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + nmd.Add("multikey", "four").Add("newkey", "something") + assert.EqualValues(t, []string{"one", "two", "three", "four"}, nmd["multikey"], "append should add a new four at the end") + assert.EqualValues(t, []string{"something"}, nmd["newkey"], "append should be able to create new keys") +} + +func TestNiceMD_Set(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + nmd.Set("multikey", "one").Set("newkey", "something").Set("newkey", "another") + assert.EqualValues(t, []string{"one"}, nmd["multikey"], "set should override existing multi keys") + assert.EqualValues(t, []string{"another"}, nmd["newkey"], "set should override new keys") +} + +func TestNiceMD_Clone(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + fullCopied := nmd.Clone() + assert.Equal(t, len(fullCopied), len(nmd), "clone full should copy all keys") + assert.Equal(t, "uno", fullCopied.Get("singlekey"), "full copied should have content") + subCopied := nmd.Clone("multikey") + assert.Len(t, subCopied, 1, "sub copied clone should only have one key") + assert.Empty(t, subCopied.Get("singlekey"), "there shouldn't be a singlekey in the subcopied") + + // Test side effects and full copying: + assert.EqualValues(t, subCopied["multikey"], nmd["multikey"], "before overwrites multikey should have the same values") + subCopied["multikey"][1] = "modifiedtwo" + assert.NotEqual(t, subCopied["multikey"], nmd["multikey"], "before overwrites multikey should have the same values") +} + +func TestNiceMD_ToOutgoing(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + nCtx := nmd.ToOutgoing(parentCtx) + assertRetainsParentContext(t, nCtx) + + eCtx := metautils.ExtractOutgoing(nCtx).Clone().Set("newvalue", "something").ToOutgoing(nCtx) + assertRetainsParentContext(t, eCtx) + assert.NotEqual(t, metautils.ExtractOutgoing(nCtx), metautils.ExtractOutgoing(eCtx), "the niceMD pointed to by ectx and nctx are different.") +} + +func TestNiceMD_ToIncoming(t *testing.T) { + nmd := metautils.NiceMD(metadata.Pairs(testPairs...)) + nCtx := nmd.ToIncoming(parentCtx) + assertRetainsParentContext(t, nCtx) + + eCtx := metautils.ExtractIncoming(nCtx).Clone().Set("newvalue", "something").ToIncoming(nCtx) + assertRetainsParentContext(t, eCtx) + assert.NotEqual(t, metautils.ExtractIncoming(nCtx), metautils.ExtractIncoming(eCtx), "the niceMD pointed to by ectx and nctx are different.") +} diff --git a/pkg/tracing/util/metautils/single_key.go b/pkg/tracing/util/metautils/single_key.go new file mode 100644 index 0000000000..8521d87646 --- /dev/null +++ b/pkg/tracing/util/metautils/single_key.go @@ -0,0 +1,26 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +/* +This was copied over from https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2.0.0-rc.3 +and modified to support tracing in Thanos till migration to Otel is supported. +*/ + +package metautils + +import ( + "encoding/base64" + "strings" +) + +const ( + binHdrSuffix = "-bin" +) + +func encodeKeyValue(k, v string) (string, string) { + k = strings.ToLower(k) + if strings.HasSuffix(k, binHdrSuffix) { + return k, base64.StdEncoding.EncodeToString([]byte(v)) + } + return k, v +} diff --git a/pkg/ui/react-app/package-lock.json b/pkg/ui/react-app/package-lock.json index f1f1e0c172..4f3bea4e9e 100644 --- a/pkg/ui/react-app/package-lock.json +++ b/pkg/ui/react-app/package-lock.json @@ -3606,29 +3606,62 @@ "node": ">=8" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "devOptional": true, "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "devOptional": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@lezer/common": { @@ -4386,9 +4419,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/express": { @@ -4999,148 +5032,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -6103,10 +6136,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -6117,26 +6151,35 @@ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, "node_modules/browserslist": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz", - "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "devOptional": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "caniuse-lite": "^1.0.30001313", - "electron-to-chromium": "^1.4.76", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" } }, "node_modules/bser": { @@ -6244,14 +6287,24 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001316", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001316.tgz", - "integrity": "sha512-JgUdNoZKxPZFzbzJwy4hDSyGuH/gXz2rN51QmoR8cBQsVo58llD3A0vlRKKRt8FGf5u69P9eQyIH8/z9vN/S0Q==", + "version": "1.0.30001617", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz", + "integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==", "devOptional": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -7642,9 +7695,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.82", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.82.tgz", - "integrity": "sha512-Ks+ANzLoIrFDUOJdjxYMH6CMKB8UQo5modAwvSZTxgF+vEs/U7G5IbWFUp6dS4klPkTDVdxbORuk8xAXXhMsWw==", + "version": "1.4.762", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.762.tgz", + "integrity": "sha512-rrFvGweLxPwwSwJOjIopy3Vr+J3cIPtZzuc74bmlvmBIgQO3VYJDvVrlj94iKZ3ukXUH64Ex31hSfRTLqvjYJQ==", "devOptional": true }, "node_modules/emittery": { @@ -7683,9 +7736,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", - "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -7889,9 +7942,9 @@ "dev": true }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", + "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==", "dev": true }, "node_modules/es-to-primitive": { @@ -7911,8 +7964,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "devOptional": true, "engines": { "node": ">=6" @@ -9055,8 +9109,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -9403,9 +9458,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", "dev": true }, "node_modules/fs.realpath": { @@ -9631,9 +9686,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/gud": { @@ -10144,9 +10199,9 @@ } }, "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "node_modules/ipaddr.js": { @@ -10319,6 +10374,7 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { "node": ">=0.12.0" @@ -13849,12 +13905,6 @@ "node": ">=4" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", @@ -14183,12 +14233,12 @@ } }, "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -14575,9 +14625,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "devOptional": true }, "node_modules/normalize-path": { @@ -17912,9 +17962,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -18007,9 +18057,9 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -18975,14 +19025,14 @@ } }, "node_modules/terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "dependencies": { - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "bin": { @@ -18993,16 +19043,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -19026,19 +19076,10 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/terser/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -19053,15 +19094,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -19123,6 +19155,7 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { "is-number": "^7.0.0" @@ -19405,6 +19438,36 @@ "yarn": "*" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz", + "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==", + "devOptional": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", @@ -19554,9 +19617,9 @@ } }, "node_modules/watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -19583,34 +19646,34 @@ } }, "node_modules/webpack": { - "version": "5.70.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz", - "integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.2", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.16.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-better-errors": "^1.0.2", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -19630,13 +19693,13 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" @@ -19906,9 +19969,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -19918,9 +19981,9 @@ } }, "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -23059,26 +23122,53 @@ } } }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "devOptional": true }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "devOptional": true }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "devOptional": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@lezer/common": { @@ -23600,9 +23690,9 @@ } }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/express": { @@ -24092,148 +24182,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -24980,10 +25070,11 @@ } }, "braces": { - "version": "3.0.2", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-process-hrtime": { @@ -24991,16 +25082,15 @@ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, "browserslist": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz", - "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "devOptional": true, "requires": { - "caniuse-lite": "^1.0.30001313", - "electron-to-chromium": "^1.4.76", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, "bser": { @@ -25084,9 +25174,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001316", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001316.tgz", - "integrity": "sha512-JgUdNoZKxPZFzbzJwy4hDSyGuH/gXz2rN51QmoR8cBQsVo58llD3A0vlRKKRt8FGf5u69P9eQyIH8/z9vN/S0Q==", + "version": "1.0.30001617", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz", + "integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==", "devOptional": true }, "case-sensitive-paths-webpack-plugin": { @@ -26129,9 +26219,9 @@ } }, "electron-to-chromium": { - "version": "1.4.82", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.82.tgz", - "integrity": "sha512-Ks+ANzLoIrFDUOJdjxYMH6CMKB8UQo5modAwvSZTxgF+vEs/U7G5IbWFUp6dS4klPkTDVdxbORuk8xAXXhMsWw==", + "version": "1.4.762", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.762.tgz", + "integrity": "sha512-rrFvGweLxPwwSwJOjIopy3Vr+J3cIPtZzuc74bmlvmBIgQO3VYJDvVrlj94iKZ3ukXUH64Ex31hSfRTLqvjYJQ==", "devOptional": true }, "emittery": { @@ -26158,9 +26248,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", - "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -26326,9 +26416,9 @@ "dev": true }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", + "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==", "dev": true }, "es-to-primitive": { @@ -26342,8 +26432,9 @@ } }, "escalade": { - "version": "3.1.1", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "devOptional": true }, "escape-html": { @@ -27181,8 +27272,9 @@ "dev": true }, "fill-range": { - "version": "7.0.1", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "requires": { "to-regex-range": "^5.0.1" } @@ -27421,9 +27513,9 @@ } }, "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", "dev": true }, "fs.realpath": { @@ -27584,9 +27676,9 @@ } }, "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "gud": { @@ -27971,9 +28063,9 @@ } }, "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "ipaddr.js": { @@ -28083,6 +28175,7 @@ }, "is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { @@ -30743,12 +30836,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "devOptional": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "json-parse-even-better-errors": { "version": "2.3.1", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", @@ -31020,12 +31107,12 @@ "dev": true }, "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "requires": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" } }, "memoize-one": { @@ -31319,9 +31406,9 @@ "dev": true }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "devOptional": true }, "normalize-path": { @@ -33647,9 +33734,9 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -33727,9 +33814,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -34474,21 +34561,21 @@ } }, "terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "requires": { - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "commander": { @@ -34496,34 +34583,20 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true } } }, "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" } }, "test-exclude": { @@ -34578,6 +34651,7 @@ }, "to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { "is-number": "^7.0.0" @@ -34789,6 +34863,16 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz", + "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==", + "devOptional": true, + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", @@ -34915,9 +34999,9 @@ } }, "watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -34938,60 +35022,60 @@ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { - "version": "5.70.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz", - "integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.2", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.16.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-better-errors": "^1.0.2", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "requires": {} } } }, "webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "requires": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" diff --git a/pkg/ui/react-app/src/pages/graph/Panel.tsx b/pkg/ui/react-app/src/pages/graph/Panel.tsx index 4355a8f1ed..288385374d 100644 --- a/pkg/ui/react-app/src/pages/graph/Panel.tsx +++ b/pkg/ui/react-app/src/pages/graph/Panel.tsx @@ -247,7 +247,7 @@ class Panel extends Component { // Create request headers const requestHeaders: HeadersInit = new Headers(); - requestHeaders.set('Content-Type', 'application/json'); + requestHeaders.set('Content-Type', 'application/x-www-form-urlencoded'); if (this.props.options.forceTracing) { requestHeaders.set('X-Thanos-Force-Tracing', 'true'); @@ -257,9 +257,10 @@ class Panel extends Component { requestHeaders.set(tenantHeader, this.props.options.tenant); } - fetch(`${this.props.pathPrefix}${path}?${params}`, { - method: 'GET', + fetch(`${this.props.pathPrefix}${path}`, { + method: 'POST', headers: requestHeaders, + body: params, cache: 'no-store', credentials: 'same-origin', signal: abortController.signal, diff --git a/pkg/ui/react-app/src/utils/index.ts b/pkg/ui/react-app/src/utils/index.ts index 50b6cca5d0..7cbd8ce8ea 100644 --- a/pkg/ui/react-app/src/utils/index.ts +++ b/pkg/ui/react-app/src/utils/index.ts @@ -287,7 +287,8 @@ export const encodePanelOptionsToQueryString = (panels: PanelMeta[]): string => }; export const createExpressionLink = (expr: string): string => { - return `../graph?g0.expr=${encodeURIComponent(expr)}&g0.tab=1&g0.stacked=0&g0.range_input=1h`; + const alertSourceTemplate = '/graph?g0.expr={{.Expr}}&g0.tab=1'; + return `${alertSourceTemplate.replace('{{.Expr}}', encodeURIComponent(expr))}&g0.stacked=0&g0.range_input=1h`; }; export const createExternalExpressionLink = (expr: string): string => { diff --git a/pkg/ui/static/react/asset-manifest.json b/pkg/ui/static/react/asset-manifest.json index 838abcc58a..b4505043e8 100644 --- a/pkg/ui/static/react/asset-manifest.json +++ b/pkg/ui/static/react/asset-manifest.json @@ -1,15 +1,15 @@ { "files": { - "main.css": "./static/css/main.5a4981c4.css", - "main.js": "./static/js/main.0792ff52.js", + "main.css": "./static/css/main.17d667f4.css", + "main.js": "./static/js/main.20f9b436.js", "static/media/codicon.ttf": "./static/media/codicon.b3726f0165bf67ac6849.ttf", "index.html": "./index.html", "static/media/index.cjs": "./static/media/index.cd351d7c31d0d3fccf96.cjs", - "main.5a4981c4.css.map": "./static/css/main.5a4981c4.css.map", - "main.0792ff52.js.map": "./static/js/main.0792ff52.js.map" + "main.17d667f4.css.map": "./static/css/main.17d667f4.css.map", + "main.20f9b436.js.map": "./static/js/main.20f9b436.js.map" }, "entrypoints": [ - "static/css/main.5a4981c4.css", - "static/js/main.0792ff52.js" + "static/css/main.17d667f4.css", + "static/js/main.20f9b436.js" ] } \ No newline at end of file diff --git a/pkg/ui/static/react/index.html b/pkg/ui/static/react/index.html index 976977ee2e..26a5878a12 100644 --- a/pkg/ui/static/react/index.html +++ b/pkg/ui/static/react/index.html @@ -1 +1 @@ -Thanos | Highly available Prometheus setup
\ No newline at end of file +Thanos | Highly available Prometheus setup
\ No newline at end of file diff --git a/pkg/ui/static/react/static/css/main.17d667f4.css b/pkg/ui/static/react/static/css/main.17d667f4.css new file mode 100644 index 0000000000..0fb47bee91 --- /dev/null +++ b/pkg/ui/static/react/static/css/main.17d667f4.css @@ -0,0 +1,6 @@ +/*!@preserve + * Tempus Dominus Bootstrap4 v5.39.0 (https://tempusdominus.github.io/bootstrap-4/) + * Copyright 2016-2020 Jonathan Peterson and contributors + * Licensed under MIT (https://github.com/tempusdominus/bootstrap-3/blob/master/LICENSE) + */.bootstrap-datetimepicker-widget .btn[data-action=clear]:after,.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]:after,.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]:after,.bootstrap-datetimepicker-widget .btn[data-action=incrementHours]:after,.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]:after,.bootstrap-datetimepicker-widget .btn[data-action=showHours]:after,.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]:after,.bootstrap-datetimepicker-widget .btn[data-action=today]:after,.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]:after,.bootstrap-datetimepicker-widget .picker-switch:after,.bootstrap-datetimepicker-widget table th.next:after,.bootstrap-datetimepicker-widget table th.prev:after,.sr-only{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}body.tempusdominus-bootstrap-datetimepicker-widget-day-click,body.tempusdominus-bootstrap-datetimepicker-widget-day-click *{cursor:pointer!important}body.tempusdominus-bootstrap-datetimepicker-widget-day-click{position:relative!important}.tempusdominus-bootstrap-datetimepicker-widget-day-click-glass-panel{bottom:0;cursor:pointer!important;left:0;position:absolute;right:0;top:0;z-index:999999999999}.bootstrap-datetimepicker-widget .datepicker-days tbody td{cursor:pointer}.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{display:block;margin:2px 0;padding:4px;width:14rem}.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks,.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons{width:16rem}.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks.tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons{width:17rem}@media (min-width:576px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:after,.bootstrap-datetimepicker-widget.dropdown-menu:before{content:"";display:inline-block;position:absolute}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before{border-bottom:7px solid #0003;border-left:7px solid #0000;border-right:7px solid #0000;left:7px;top:-7px}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after{border-bottom:6px solid #fff;border-left:6px solid #0000;border-right:6px solid #0000;left:8px;top:-6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:before{border-left:7px solid #0000;border-right:7px solid #0000;border-top:7px solid #0003;bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:after{border-left:6px solid #0000;border-right:6px solid #0000;border-top:6px solid #fff;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.float-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.dropdown-menu.float-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget.dropdown-menu.wider{width:16rem}.bootstrap-datetimepicker-widget .list-unstyled{margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{font-size:1.2em;font-weight:700;margin:0;width:54px}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]{font-family:Arial,sans-serif,-apple-system,system-ui,Segoe UI,Roboto,Helvetica Neue,Noto Sans,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;height:38px;text-align:center;width:38px}.bootstrap-datetimepicker-widget .btn[data-action=incrementHours]:after{content:"Increment Hours"}.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]:after{content:"Increment Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]:after{content:"Decrement Hours"}.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]:after{content:"Decrement Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=showHours]:after{content:"Show Hours"}.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]:after{content:"Show Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]:after{content:"Toggle AM/PM"}.bootstrap-datetimepicker-widget .btn[data-action=clear]:after{content:"Clear the picker"}.bootstrap-datetimepicker-widget .btn[data-action=today]:after{content:"Set the date to today"}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget .picker-switch:after{content:"Toggle Date and Time Screens"}.bootstrap-datetimepicker-widget .picker-switch td{height:auto;line-height:inherit;margin:0;padding:0;width:auto}.bootstrap-datetimepicker-widget .picker-switch td span{height:2.5em;line-height:2.5;width:100%}.bootstrap-datetimepicker-widget .picker-switch.picker-switch-with-feathers-icons td span{height:2.8em;line-height:2.8}.bootstrap-datetimepicker-widget table{margin:0;width:100%}.bootstrap-datetimepicker-widget table td,.bootstrap-datetimepicker-widget table th{border-radius:.25rem;text-align:center}.bootstrap-datetimepicker-widget table th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table th.picker-switch{width:145px}.bootstrap-datetimepicker-widget table th.disabled,.bootstrap-datetimepicker-widget table th.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget table th.prev:after{content:"Previous Month"}.bootstrap-datetimepicker-widget table th.next:after{content:"Next Month"}.bootstrap-datetimepicker-widget table thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#e9ecef}.bootstrap-datetimepicker-widget table td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget table td.cw{color:#6c757d;cursor:default;font-size:.8em;height:20px;line-height:20px}.bootstrap-datetimepicker-widget table td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table td.day:hover,.bootstrap-datetimepicker-widget table td.hour:hover,.bootstrap-datetimepicker-widget table td.minute:hover,.bootstrap-datetimepicker-widget table td.second:hover{background:#e9ecef;cursor:pointer}.bootstrap-datetimepicker-widget table td.new,.bootstrap-datetimepicker-widget table td.old{color:#6c757d}.bootstrap-datetimepicker-widget table td.today{position:relative}.bootstrap-datetimepicker-widget table td.today:before{border-color:#0003 #0000 #007bff;border-style:solid;border-width:0 0 7px 7px;bottom:4px;content:"";display:inline-block;position:absolute;right:4px}.bootstrap-datetimepicker-widget table td.active,.bootstrap-datetimepicker-widget table td.active:hover{background-color:#007bff;color:#fff;text-shadow:0 -1px 0 #00000040}.bootstrap-datetimepicker-widget table td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget table td.disabled,.bootstrap-datetimepicker-widget table td.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget table td span{border-radius:.25rem;cursor:pointer;display:inline-block;height:54px;line-height:54px;margin-bottom:2px;margin-top:2px;width:54px}.bootstrap-datetimepicker-widget table td span:hover{background:#e9ecef}.bootstrap-datetimepicker-widget table td span.active{background-color:#007bff;color:#fff;text-shadow:0 -1px 0 #00000040}.bootstrap-datetimepicker-widget table td span.old{color:#6c757d}.bootstrap-datetimepicker-widget table td span.disabled,.bootstrap-datetimepicker-widget table td span.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget.usetwentyfour td.hour{height:27px;line-height:27px}.bootstrap-datetimepicker-widget .timepicker .timepicker-picker a.btn{color:#007bff;color:var(--blue,#007bff)}.bootstrap-datetimepicker-widget .timepicker .timepicker-picker a.btn:hover{color:#0056b3}.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=togglePeriod],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.day,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.hour,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.minute,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.second{cursor:default;pointer-events:none}.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=togglePeriod]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.day:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.hour:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.minute:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.second:hover{background:0 0}.input-group [data-toggle=datetimepicker]{cursor:pointer}.ScrapePoolPanel_container__mwUUe{margin-top:-12px}.ScrapePoolPanel_title__SgTOh{cursor:pointer;font-size:20px;font-weight:700}.ScrapePoolPanel_danger__4lB8E{color:#f24141}.ScrapePoolPanel_table__fR2-c{width:100%}.ScrapePoolPanel_cell__7hR2J{word-wrap:break-word;height:auto;word-break:break-all}.ScrapePoolPanel_endpoint__FMY2G,.ScrapePoolPanel_labels__iJ\+7v{width:25%}.ScrapePoolPanel_last-scrape__Fu0ek,.ScrapePoolPanel_state__AncRn{width:10%}.ScrapePoolPanel_errors__etLp1{width:30%}.TargetLabels_discovered__H1zfq{white-space:nowrap}.NotFound_container__qQ5PC{height:85vh;width:100%}.ErrorBoundary_container__q5-zp,.NotFound_container__qQ5PC{align-items:center;display:flex;flex-direction:column;justify-content:center}.ErrorBoundary_container__q5-zp{min-height:100vh}button.ErrorBoundary_detailsBtn__iTaIc{font-size:1.2em;margin:2em 0}.ErrorBoundary_errorDiv__CKpY3{font-family:monospace;white-space:pre-wrap}.blocks_container__VvRYV{--top:72px;display:flex;min-height:calc(100vh - var(--top));position:relative;z-index:1}.blocks_grid__ZazGZ{width:100%}.blocks_sources__rl8vd{max-height:calc(100vh - var(--top)*2);overflow-y:auto;scrollbar-color:#b1b1b1 #0000;scrollbar-width:thin}.blocks_sources__rl8vd::-webkit-scrollbar{width:8px}.blocks_sources__rl8vd::-webkit-scrollbar-thumb{background-color:#b1b1b1;border-radius:6px}.blocks_blockDetails__ytMWm{box-sizing:border-box;margin-right:-15px;margin-top:-16px;max-width:55vw;min-width:0;overflow-x:hidden;overflow-y:auto;transition:all .2s ease-in-out;width:0}.blocks_blockDetails__ytMWm.blocks_open__DNi1D{box-shadow:0 10px 20px #00000030,0 6px 6px #0000003b;min-width:420px;padding:2em}.blocks_detailsTop__XTw42{align-items:center;display:flex;flex-wrap:wrap-reverse;justify-content:space-between;width:100%}.blocks_header__rBZkV{font-size:1.1em;font-weight:700;margin:0;padding:0}.blocks_closeBtn__xObeQ{background:none;border:none;font-size:2em;transform:translateY(-10%)}.blocks_timeRangeDiv__0Lht-{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;height:var(--top);justify-content:space-evenly;padding:0 3em}.blocks_timeRange__2JnqI{font-size:.9em;justify-content:space-between}.blocks_source__5eSF5,.blocks_timeRange__2JnqI{align-items:center;display:flex;width:100%}.blocks_title__tLgxv{box-sizing:border-box;padding:0 1em}.blocks_title__tLgxv>span{box-sizing:border-box;display:block;margin:0;overflow:hidden;text-align:center;text-overflow:ellipsis;width:8vw}.blocks_rowsContainer__WJLAk{border-left:3px solid teal;box-sizing:border-box;display:flex;flex-direction:column;width:100%}.blocks_row__XXEWv{--block-height:1.2em;box-sizing:initial;height:var(--block-height);margin:.1em 0;overflow-x:hidden;position:relative;width:100%}.blocks_blockSpan__-rVfz{border:none;box-sizing:border-box;height:100%;margin:0;min-width:.5%;min-width:0;mix-blend-mode:multiply;padding:0;position:absolute}.blocks_blockSpan__-rVfz:focus,.blocks_blockSpan__-rVfz:hover{box-shadow:inset 0 0 0 .2rem #0000004d;outline:none}.blocks_res-0__pFlet{--level-1:#bd96ee;--level-2:#9250e2;--level-3:#7c2cdd;--level-4:#681fc1;--level-5:#4c178c;--level-6:#391169}.blocks_res-300000__YMCfv{--level-1:#f15bb5;--level-2:#ef43aa;--level-3:#eb1e99;--level-4:#ce1283;--level-5:#a90f6b;--level-6:#830b53}.blocks_res-3600000__c4rnR{--level-1:#70dbff;--level-2:#47d1ff;--level-3:#1fc7ff;--level-4:#00b8f5;--level-5:#09c;--level-6:#007aa3}.blocks_level-1__mY8uI{background:var(--level-1)}.blocks_level-2__tLoFQ{background:var(--level-2)}.blocks_level-3__Tt6M3{background:var(--level-3)}.blocks_level-4__adSpx{background:var(--level-4)}.blocks_level-5__A2uEj{background:var(--level-5)}.blocks_level-6__93k19{background:var(--level-6)}.blocks_blockInput__Ktii1{margin-bottom:12px}.blocks_blockFilter__qqbPg{align-items:center;display:flex;flex-direction:row}.rc-slider{border-radius:6px;height:14px;padding:5px 0;position:relative;touch-action:none;width:100%}.rc-slider,.rc-slider *{-webkit-tap-highlight-color:rgba(0,0,0,0);box-sizing:border-box}.rc-slider-rail{background-color:#e9e9e9;width:100%}.rc-slider-rail,.rc-slider-track{border-radius:6px;height:4px;position:absolute}.rc-slider-track{background-color:#abe2fb;left:0}.rc-slider-handle{background-color:#fff;border:2px solid #96dbfa;border-radius:50%;cursor:pointer;cursor:-webkit-grab;cursor:grab;height:14px;margin-top:-5px;position:absolute;touch-action:pan-x;width:14px}.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging{border-color:#57c5f7;box-shadow:0 0 0 5px #96dbfa}.rc-slider-handle:focus{outline:none}.rc-slider-handle-click-focused:focus{border-color:#96dbfa;box-shadow:unset}.rc-slider-handle:hover{border-color:#57c5f7}.rc-slider-handle:active{border-color:#57c5f7;box-shadow:0 0 5px #57c5f7;cursor:grabbing}.rc-slider-mark{font-size:12px;left:0;position:absolute;top:18px;width:100%}.rc-slider-mark-text{color:#999;cursor:pointer;display:inline-block;position:absolute;text-align:center;vertical-align:middle}.rc-slider-mark-text-active{color:#666}.rc-slider-step{background:#0000;height:4px;position:absolute;width:100%}.rc-slider-dot{background-color:#fff;border:2px solid #e9e9e9;border-radius:50%;bottom:-2px;cursor:pointer;height:8px;margin-left:-4px;position:absolute;vertical-align:middle;width:8px}.rc-slider-dot-active{border-color:#96dbfa}.rc-slider-dot-reverse{margin-right:-4px}.rc-slider-disabled{background-color:#e9e9e9}.rc-slider-disabled .rc-slider-track{background-color:#ccc}.rc-slider-disabled .rc-slider-dot,.rc-slider-disabled .rc-slider-handle{background-color:#fff;border-color:#ccc;box-shadow:none;cursor:not-allowed}.rc-slider-disabled .rc-slider-dot,.rc-slider-disabled .rc-slider-mark-text{cursor:not-allowed!important}.rc-slider-vertical{height:100%;padding:0 5px;width:14px}.rc-slider-vertical .rc-slider-rail{height:100%;width:4px}.rc-slider-vertical .rc-slider-track{bottom:0;left:5px;width:4px}.rc-slider-vertical .rc-slider-handle{margin-left:-5px;touch-action:pan-y}.rc-slider-vertical .rc-slider-mark{height:100%;left:18px;top:0}.rc-slider-vertical .rc-slider-step{height:100%;width:4px}.rc-slider-vertical .rc-slider-dot{left:2px;margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:first-child,.rc-slider-vertical .rc-slider-dot:last-child{margin-bottom:-4px}.rc-slider-tooltip-zoom-down-appear,.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-leave{animation-duration:.3s;animation-fill-mode:both;animation-play-state:paused;display:block!important}.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active,.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active{animation-name:rcSliderTooltipZoomDownIn;animation-play-state:running}.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active{animation-name:rcSliderTooltipZoomDownOut;animation-play-state:running}.rc-slider-tooltip-zoom-down-appear,.rc-slider-tooltip-zoom-down-enter{animation-timing-function:cubic-bezier(.23,1,.32,1);transform:scale(0)}.rc-slider-tooltip-zoom-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes rcSliderTooltipZoomDownIn{0%{opacity:0;transform:scale(0);transform-origin:50% 100%}to{transform:scale(1);transform-origin:50% 100%}}@keyframes rcSliderTooltipZoomDownOut{0%{transform:scale(1);transform-origin:50% 100%}to{opacity:0;transform:scale(0);transform-origin:50% 100%}}.rc-slider-tooltip{left:-9999px;position:absolute;top:-9999px;visibility:visible}.rc-slider-tooltip,.rc-slider-tooltip *{-webkit-tap-highlight-color:rgba(0,0,0,0);box-sizing:border-box}.rc-slider-tooltip-hidden{display:none}.rc-slider-tooltip-placement-top{padding:4px 0 8px}.rc-slider-tooltip-inner{background-color:#6c6c6c;border-radius:6px;box-shadow:0 0 4px #d9d9d9;color:#fff;font-size:12px;height:24px;line-height:1;min-width:24px;padding:6px 2px;text-align:center;text-decoration:none}.rc-slider-tooltip-arrow{border-color:#0000;border-style:solid;height:0;position:absolute;width:0}.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow{border-top-color:#6c6c6c;border-width:4px 4px 0;bottom:4px;left:50%;margin-left:-4px}html{scroll-padding-top:56px}@font-face{font-family:codicon;src:local("codicon"),url(../../static/media/codicon.b3726f0165bf67ac6849.ttf) format("truetype")}*,:after,:before{box-sizing:border-box}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{background-color:#fff;color:#212529;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;line-height:1.5;margin:0;text-align:left}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:initial;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;margin-top:0}p{margin-bottom:1rem;margin-top:0}abbr[data-original-title],abbr[title]{border-bottom:0;cursor:help;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}a{background-color:initial;color:#007bff;text-decoration:none}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{-ms-overflow-style:scrollbar;margin-bottom:1rem;margin-top:0;overflow:auto}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{caption-side:bottom;color:#6c757d;padding-bottom:.75rem;padding-top:.75rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{color:inherit;display:block;font-size:1.5rem;line-height:inherit;margin-bottom:.5rem;max-width:100%;padding:0;white-space:normal;width:100%}progress{vertical-align:initial}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:none;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}output{display:inline-block}summary{cursor:pointer;display:list-item}template{display:none}[hidden]{display:none!important}body.bootstrap{background-color:#fff;color:#212529;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;line-height:1.5;margin:0;text-align:left}.bootstrap :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.bootstrap .h1,.bootstrap .h2,.bootstrap .h3,.bootstrap .h4,.bootstrap .h5,.bootstrap .h6,.bootstrap h1,.bootstrap h2,.bootstrap h3,.bootstrap h4,.bootstrap h5,.bootstrap h6{font-weight:500;line-height:1.2;margin-bottom:.5rem}.bootstrap .h1,.bootstrap h1{font-size:2.5rem}.bootstrap .h2,.bootstrap h2{font-size:2rem}.bootstrap .h3,.bootstrap h3{font-size:1.75rem}.bootstrap .h4,.bootstrap h4{font-size:1.5rem}.bootstrap .h5,.bootstrap h5{font-size:1.25rem}.bootstrap .h6,.bootstrap h6{font-size:1rem}.bootstrap .lead{font-size:1.25rem;font-weight:300}.bootstrap .display-1{font-size:6rem;font-weight:300;line-height:1.2}.bootstrap .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.bootstrap .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.bootstrap .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}.bootstrap hr{border:0;border-top:1px solid #0000001a;margin-bottom:1rem;margin-top:1rem}.bootstrap .small,.bootstrap small{font-size:80%;font-weight:400}.bootstrap .mark,.bootstrap mark{background-color:#fcf8e3;padding:.2em}.bootstrap .list-inline,.bootstrap .list-unstyled{list-style:none;padding-left:0}.bootstrap .list-inline-item{display:inline-block}.bootstrap .list-inline-item:not(:last-child){margin-right:.5rem}.bootstrap .initialism{font-size:90%;text-transform:uppercase}.bootstrap .blockquote{font-size:1.25rem;margin-bottom:1rem}.bootstrap .blockquote-footer{color:#6c757d;display:block;font-size:80%}.bootstrap .blockquote-footer:before{content:"— "}.bootstrap .img-fluid,.bootstrap .img-thumbnail{height:auto;max-width:100%}.bootstrap .img-thumbnail{background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;padding:.25rem}.bootstrap .figure{display:inline-block}.bootstrap .figure-img{line-height:1;margin-bottom:.5rem}.bootstrap .figure-caption{color:#6c757d;font-size:90%}.bootstrap code{word-wrap:break-word;color:#e83e8c;font-size:87.5%}a>.bootstrap code{color:inherit}.bootstrap kbd{background-color:#212529;border-radius:.2rem;color:#fff;font-size:87.5%;padding:.2rem .4rem}.bootstrap kbd kbd{font-size:100%;font-weight:700;padding:0}.bootstrap pre{color:#212529;display:block;font-size:87.5%}.bootstrap pre code{color:inherit;font-size:inherit;word-break:normal}.bootstrap .pre-scrollable{max-height:340px;overflow-y:scroll}.bootstrap .container,.bootstrap .container-fluid,.bootstrap .container-lg,.bootstrap .container-md,.bootstrap .container-sm,.bootstrap .container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media(min-width:576px){.bootstrap .container,.bootstrap .container-sm{max-width:540px}}@media(min-width:768px){.bootstrap .container,.bootstrap .container-md,.bootstrap .container-sm{max-width:720px}}@media(min-width:992px){.bootstrap .container,.bootstrap .container-lg,.bootstrap .container-md,.bootstrap .container-sm{max-width:960px}}@media(min-width:1200px){.bootstrap .container,.bootstrap .container-lg,.bootstrap .container-md,.bootstrap .container-sm,.bootstrap .container-xl{max-width:1140px}}.bootstrap .row{display:flex;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.bootstrap .no-gutters{margin-left:0;margin-right:0}.bootstrap .no-gutters>.col,.bootstrap .no-gutters>[class*=col-]{padding-left:0;padding-right:0}.bootstrap .col,.bootstrap .col-1,.bootstrap .col-10,.bootstrap .col-11,.bootstrap .col-12,.bootstrap .col-2,.bootstrap .col-3,.bootstrap .col-4,.bootstrap .col-5,.bootstrap .col-6,.bootstrap .col-7,.bootstrap .col-8,.bootstrap .col-9,.bootstrap .col-auto,.bootstrap .col-lg,.bootstrap .col-lg-1,.bootstrap .col-lg-10,.bootstrap .col-lg-11,.bootstrap .col-lg-12,.bootstrap .col-lg-2,.bootstrap .col-lg-3,.bootstrap .col-lg-4,.bootstrap .col-lg-5,.bootstrap .col-lg-6,.bootstrap .col-lg-7,.bootstrap .col-lg-8,.bootstrap .col-lg-9,.bootstrap .col-lg-auto,.bootstrap .col-md,.bootstrap .col-md-1,.bootstrap .col-md-10,.bootstrap .col-md-11,.bootstrap .col-md-12,.bootstrap .col-md-2,.bootstrap .col-md-3,.bootstrap .col-md-4,.bootstrap .col-md-5,.bootstrap .col-md-6,.bootstrap .col-md-7,.bootstrap .col-md-8,.bootstrap .col-md-9,.bootstrap .col-md-auto,.bootstrap .col-sm,.bootstrap .col-sm-1,.bootstrap .col-sm-10,.bootstrap .col-sm-11,.bootstrap .col-sm-12,.bootstrap .col-sm-2,.bootstrap .col-sm-3,.bootstrap .col-sm-4,.bootstrap .col-sm-5,.bootstrap .col-sm-6,.bootstrap .col-sm-7,.bootstrap .col-sm-8,.bootstrap .col-sm-9,.bootstrap .col-sm-auto,.bootstrap .col-xl,.bootstrap .col-xl-1,.bootstrap .col-xl-10,.bootstrap .col-xl-11,.bootstrap .col-xl-12,.bootstrap .col-xl-2,.bootstrap .col-xl-3,.bootstrap .col-xl-4,.bootstrap .col-xl-5,.bootstrap .col-xl-6,.bootstrap .col-xl-7,.bootstrap .col-xl-8,.bootstrap .col-xl-9,.bootstrap .col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}.bootstrap .col{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap .row-cols-1>*{flex:0 0 100%;max-width:100%}.bootstrap .row-cols-2>*{flex:0 0 50%;max-width:50%}.bootstrap .row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap .row-cols-4>*{flex:0 0 25%;max-width:25%}.bootstrap .row-cols-5>*{flex:0 0 20%;max-width:20%}.bootstrap .row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap .col-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap .col-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap .col-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap .col-3{flex:0 0 25%;max-width:25%}.bootstrap .col-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap .col-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap .col-6{flex:0 0 50%;max-width:50%}.bootstrap .col-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap .col-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap .col-9{flex:0 0 75%;max-width:75%}.bootstrap .col-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap .col-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap .col-12{flex:0 0 100%;max-width:100%}.bootstrap .order-first{order:-1}.bootstrap .order-last{order:13}.bootstrap .order-0{order:0}.bootstrap .order-1{order:1}.bootstrap .order-2{order:2}.bootstrap .order-3{order:3}.bootstrap .order-4{order:4}.bootstrap .order-5{order:5}.bootstrap .order-6{order:6}.bootstrap .order-7{order:7}.bootstrap .order-8{order:8}.bootstrap .order-9{order:9}.bootstrap .order-10{order:10}.bootstrap .order-11{order:11}.bootstrap .order-12{order:12}.bootstrap .offset-1{margin-left:8.33333333%}.bootstrap .offset-2{margin-left:16.66666667%}.bootstrap .offset-3{margin-left:25%}.bootstrap .offset-4{margin-left:33.33333333%}.bootstrap .offset-5{margin-left:41.66666667%}.bootstrap .offset-6{margin-left:50%}.bootstrap .offset-7{margin-left:58.33333333%}.bootstrap .offset-8{margin-left:66.66666667%}.bootstrap .offset-9{margin-left:75%}.bootstrap .offset-10{margin-left:83.33333333%}.bootstrap .offset-11{margin-left:91.66666667%}@media(min-width:576px){.bootstrap .col-sm{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.bootstrap .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.bootstrap .row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.bootstrap .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.bootstrap .row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap .col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap .col-sm-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap .col-sm-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap .col-sm-3{flex:0 0 25%;max-width:25%}.bootstrap .col-sm-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap .col-sm-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap .col-sm-6{flex:0 0 50%;max-width:50%}.bootstrap .col-sm-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap .col-sm-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap .col-sm-9{flex:0 0 75%;max-width:75%}.bootstrap .col-sm-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap .col-sm-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap .col-sm-12{flex:0 0 100%;max-width:100%}.bootstrap .order-sm-first{order:-1}.bootstrap .order-sm-last{order:13}.bootstrap .order-sm-0{order:0}.bootstrap .order-sm-1{order:1}.bootstrap .order-sm-2{order:2}.bootstrap .order-sm-3{order:3}.bootstrap .order-sm-4{order:4}.bootstrap .order-sm-5{order:5}.bootstrap .order-sm-6{order:6}.bootstrap .order-sm-7{order:7}.bootstrap .order-sm-8{order:8}.bootstrap .order-sm-9{order:9}.bootstrap .order-sm-10{order:10}.bootstrap .order-sm-11{order:11}.bootstrap .order-sm-12{order:12}.bootstrap .offset-sm-0{margin-left:0}.bootstrap .offset-sm-1{margin-left:8.33333333%}.bootstrap .offset-sm-2{margin-left:16.66666667%}.bootstrap .offset-sm-3{margin-left:25%}.bootstrap .offset-sm-4{margin-left:33.33333333%}.bootstrap .offset-sm-5{margin-left:41.66666667%}.bootstrap .offset-sm-6{margin-left:50%}.bootstrap .offset-sm-7{margin-left:58.33333333%}.bootstrap .offset-sm-8{margin-left:66.66666667%}.bootstrap .offset-sm-9{margin-left:75%}.bootstrap .offset-sm-10{margin-left:83.33333333%}.bootstrap .offset-sm-11{margin-left:91.66666667%}}@media(min-width:768px){.bootstrap .col-md{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap .row-cols-md-1>*{flex:0 0 100%;max-width:100%}.bootstrap .row-cols-md-2>*{flex:0 0 50%;max-width:50%}.bootstrap .row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap .row-cols-md-4>*{flex:0 0 25%;max-width:25%}.bootstrap .row-cols-md-5>*{flex:0 0 20%;max-width:20%}.bootstrap .row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap .col-md-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap .col-md-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap .col-md-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap .col-md-3{flex:0 0 25%;max-width:25%}.bootstrap .col-md-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap .col-md-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap .col-md-6{flex:0 0 50%;max-width:50%}.bootstrap .col-md-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap .col-md-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap .col-md-9{flex:0 0 75%;max-width:75%}.bootstrap .col-md-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap .col-md-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap .col-md-12{flex:0 0 100%;max-width:100%}.bootstrap .order-md-first{order:-1}.bootstrap .order-md-last{order:13}.bootstrap .order-md-0{order:0}.bootstrap .order-md-1{order:1}.bootstrap .order-md-2{order:2}.bootstrap .order-md-3{order:3}.bootstrap .order-md-4{order:4}.bootstrap .order-md-5{order:5}.bootstrap .order-md-6{order:6}.bootstrap .order-md-7{order:7}.bootstrap .order-md-8{order:8}.bootstrap .order-md-9{order:9}.bootstrap .order-md-10{order:10}.bootstrap .order-md-11{order:11}.bootstrap .order-md-12{order:12}.bootstrap .offset-md-0{margin-left:0}.bootstrap .offset-md-1{margin-left:8.33333333%}.bootstrap .offset-md-2{margin-left:16.66666667%}.bootstrap .offset-md-3{margin-left:25%}.bootstrap .offset-md-4{margin-left:33.33333333%}.bootstrap .offset-md-5{margin-left:41.66666667%}.bootstrap .offset-md-6{margin-left:50%}.bootstrap .offset-md-7{margin-left:58.33333333%}.bootstrap .offset-md-8{margin-left:66.66666667%}.bootstrap .offset-md-9{margin-left:75%}.bootstrap .offset-md-10{margin-left:83.33333333%}.bootstrap .offset-md-11{margin-left:91.66666667%}}@media(min-width:992px){.bootstrap .col-lg{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.bootstrap .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.bootstrap .row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.bootstrap .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.bootstrap .row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap .col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap .col-lg-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap .col-lg-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap .col-lg-3{flex:0 0 25%;max-width:25%}.bootstrap .col-lg-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap .col-lg-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap .col-lg-6{flex:0 0 50%;max-width:50%}.bootstrap .col-lg-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap .col-lg-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap .col-lg-9{flex:0 0 75%;max-width:75%}.bootstrap .col-lg-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap .col-lg-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap .col-lg-12{flex:0 0 100%;max-width:100%}.bootstrap .order-lg-first{order:-1}.bootstrap .order-lg-last{order:13}.bootstrap .order-lg-0{order:0}.bootstrap .order-lg-1{order:1}.bootstrap .order-lg-2{order:2}.bootstrap .order-lg-3{order:3}.bootstrap .order-lg-4{order:4}.bootstrap .order-lg-5{order:5}.bootstrap .order-lg-6{order:6}.bootstrap .order-lg-7{order:7}.bootstrap .order-lg-8{order:8}.bootstrap .order-lg-9{order:9}.bootstrap .order-lg-10{order:10}.bootstrap .order-lg-11{order:11}.bootstrap .order-lg-12{order:12}.bootstrap .offset-lg-0{margin-left:0}.bootstrap .offset-lg-1{margin-left:8.33333333%}.bootstrap .offset-lg-2{margin-left:16.66666667%}.bootstrap .offset-lg-3{margin-left:25%}.bootstrap .offset-lg-4{margin-left:33.33333333%}.bootstrap .offset-lg-5{margin-left:41.66666667%}.bootstrap .offset-lg-6{margin-left:50%}.bootstrap .offset-lg-7{margin-left:58.33333333%}.bootstrap .offset-lg-8{margin-left:66.66666667%}.bootstrap .offset-lg-9{margin-left:75%}.bootstrap .offset-lg-10{margin-left:83.33333333%}.bootstrap .offset-lg-11{margin-left:91.66666667%}}@media(min-width:1200px){.bootstrap .col-xl{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.bootstrap .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.bootstrap .row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.bootstrap .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.bootstrap .row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap .col-xl-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap .col-xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap .col-xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap .col-xl-3{flex:0 0 25%;max-width:25%}.bootstrap .col-xl-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap .col-xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap .col-xl-6{flex:0 0 50%;max-width:50%}.bootstrap .col-xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap .col-xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap .col-xl-9{flex:0 0 75%;max-width:75%}.bootstrap .col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap .col-xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap .col-xl-12{flex:0 0 100%;max-width:100%}.bootstrap .order-xl-first{order:-1}.bootstrap .order-xl-last{order:13}.bootstrap .order-xl-0{order:0}.bootstrap .order-xl-1{order:1}.bootstrap .order-xl-2{order:2}.bootstrap .order-xl-3{order:3}.bootstrap .order-xl-4{order:4}.bootstrap .order-xl-5{order:5}.bootstrap .order-xl-6{order:6}.bootstrap .order-xl-7{order:7}.bootstrap .order-xl-8{order:8}.bootstrap .order-xl-9{order:9}.bootstrap .order-xl-10{order:10}.bootstrap .order-xl-11{order:11}.bootstrap .order-xl-12{order:12}.bootstrap .offset-xl-0{margin-left:0}.bootstrap .offset-xl-1{margin-left:8.33333333%}.bootstrap .offset-xl-2{margin-left:16.66666667%}.bootstrap .offset-xl-3{margin-left:25%}.bootstrap .offset-xl-4{margin-left:33.33333333%}.bootstrap .offset-xl-5{margin-left:41.66666667%}.bootstrap .offset-xl-6{margin-left:50%}.bootstrap .offset-xl-7{margin-left:58.33333333%}.bootstrap .offset-xl-8{margin-left:66.66666667%}.bootstrap .offset-xl-9{margin-left:75%}.bootstrap .offset-xl-10{margin-left:83.33333333%}.bootstrap .offset-xl-11{margin-left:91.66666667%}}.bootstrap .table{color:#212529;margin-bottom:1rem;width:100%}.bootstrap .table td,.bootstrap .table th{border-top:1px solid #dee2e6;padding:.75rem;vertical-align:top}.bootstrap .table thead th{border-bottom:2px solid #dee2e6;vertical-align:bottom}.bootstrap .table tbody+tbody{border-top:2px solid #dee2e6}.bootstrap .table-sm td,.bootstrap .table-sm th{padding:.3rem}.bootstrap .table-bordered,.bootstrap .table-bordered td,.bootstrap .table-bordered th{border:1px solid #dee2e6}.bootstrap .table-bordered thead td,.bootstrap .table-bordered thead th{border-bottom-width:2px}.bootstrap .table-borderless tbody+tbody,.bootstrap .table-borderless td,.bootstrap .table-borderless th,.bootstrap .table-borderless thead th{border:0}.bootstrap .table-striped tbody tr:nth-of-type(odd){background-color:#0000000d}.bootstrap .table-hover tbody tr:hover{background-color:rgba(0,0,0,.075);color:#212529}.bootstrap .table-primary,.bootstrap .table-primary>td,.bootstrap .table-primary>th{background-color:#b8daff}.bootstrap .table-primary tbody+tbody,.bootstrap .table-primary td,.bootstrap .table-primary th,.bootstrap .table-primary thead th{border-color:#7abaff}.bootstrap .table-hover .table-primary:hover,.bootstrap .table-hover .table-primary:hover>td,.bootstrap .table-hover .table-primary:hover>th{background-color:#9fcdff}.bootstrap .table-secondary,.bootstrap .table-secondary>td,.bootstrap .table-secondary>th{background-color:#d6d8db}.bootstrap .table-secondary tbody+tbody,.bootstrap .table-secondary td,.bootstrap .table-secondary th,.bootstrap .table-secondary thead th{border-color:#b3b7bb}.bootstrap .table-hover .table-secondary:hover,.bootstrap .table-hover .table-secondary:hover>td,.bootstrap .table-hover .table-secondary:hover>th{background-color:#c8cbcf}.bootstrap .table-success,.bootstrap .table-success>td,.bootstrap .table-success>th{background-color:#c3e6cb}.bootstrap .table-success tbody+tbody,.bootstrap .table-success td,.bootstrap .table-success th,.bootstrap .table-success thead th{border-color:#8fd19e}.bootstrap .table-hover .table-success:hover,.bootstrap .table-hover .table-success:hover>td,.bootstrap .table-hover .table-success:hover>th{background-color:#b1dfbb}.bootstrap .table-info,.bootstrap .table-info>td,.bootstrap .table-info>th{background-color:#bee5eb}.bootstrap .table-info tbody+tbody,.bootstrap .table-info td,.bootstrap .table-info th,.bootstrap .table-info thead th{border-color:#86cfda}.bootstrap .table-hover .table-info:hover,.bootstrap .table-hover .table-info:hover>td,.bootstrap .table-hover .table-info:hover>th{background-color:#abdde5}.bootstrap .table-warning,.bootstrap .table-warning>td,.bootstrap .table-warning>th{background-color:#ffeeba}.bootstrap .table-warning tbody+tbody,.bootstrap .table-warning td,.bootstrap .table-warning th,.bootstrap .table-warning thead th{border-color:#ffdf7e}.bootstrap .table-hover .table-warning:hover,.bootstrap .table-hover .table-warning:hover>td,.bootstrap .table-hover .table-warning:hover>th{background-color:#ffe8a1}.bootstrap .table-danger,.bootstrap .table-danger>td,.bootstrap .table-danger>th{background-color:#f5c6cb}.bootstrap .table-danger tbody+tbody,.bootstrap .table-danger td,.bootstrap .table-danger th,.bootstrap .table-danger thead th{border-color:#ed969e}.bootstrap .table-hover .table-danger:hover,.bootstrap .table-hover .table-danger:hover>td,.bootstrap .table-hover .table-danger:hover>th{background-color:#f1b0b7}.bootstrap .table-light,.bootstrap .table-light>td,.bootstrap .table-light>th{background-color:#fdfdfe}.bootstrap .table-light tbody+tbody,.bootstrap .table-light td,.bootstrap .table-light th,.bootstrap .table-light thead th{border-color:#fbfcfc}.bootstrap .table-hover .table-light:hover,.bootstrap .table-hover .table-light:hover>td,.bootstrap .table-hover .table-light:hover>th{background-color:#ececf6}.bootstrap .table-dark,.bootstrap .table-dark>td,.bootstrap .table-dark>th{background-color:#c6c8ca}.bootstrap .table-dark tbody+tbody,.bootstrap .table-dark td,.bootstrap .table-dark th,.bootstrap .table-dark thead th{border-color:#95999c}.bootstrap .table-hover .table-dark:hover,.bootstrap .table-hover .table-dark:hover>td,.bootstrap .table-hover .table-dark:hover>th{background-color:#b9bbbe}.bootstrap .table-active,.bootstrap .table-active>td,.bootstrap .table-active>th,.bootstrap .table-hover .table-active:hover,.bootstrap .table-hover .table-active:hover>td,.bootstrap .table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.bootstrap .table .thead-dark th{background-color:#343a40;border-color:#454d55;color:#fff}.bootstrap .table .thead-light th{background-color:#e9ecef;border-color:#dee2e6;color:#495057}.bootstrap .table-dark{background-color:#343a40;color:#fff}.bootstrap .table-dark td,.bootstrap .table-dark th,.bootstrap .table-dark thead th{border-color:#454d55}.bootstrap .table-dark.table-bordered{border:0}.bootstrap .table-dark.table-striped tbody tr:nth-of-type(odd){background-color:#ffffff0d}.bootstrap .table-dark.table-hover tbody tr:hover{background-color:hsla(0,0%,100%,.075);color:#fff}@media(max-width:575.98px){.bootstrap .table-responsive-sm{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap .table-responsive-sm>.table-bordered{border:0}}@media(max-width:767.98px){.bootstrap .table-responsive-md{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap .table-responsive-md>.table-bordered{border:0}}@media(max-width:991.98px){.bootstrap .table-responsive-lg{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap .table-responsive-lg>.table-bordered{border:0}}@media(max-width:1199.98px){.bootstrap .table-responsive-xl{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap .table-responsive-xl>.table-bordered{border:0}}.bootstrap .table-responsive{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap .table-responsive>.table-bordered{border:0}.bootstrap .form-control{background-clip:padding-box;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;color:#495057;display:block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.bootstrap .form-control{transition:none}}.bootstrap .form-control::-ms-expand{background-color:initial;border:0}.bootstrap .form-control:focus{background-color:#fff;border-color:#80bdff;box-shadow:0 0 0 .2rem #007bff40;color:#495057;outline:0}.bootstrap .form-control::placeholder{color:#6c757d;opacity:1}.bootstrap .form-control:disabled,.bootstrap .form-control[readonly]{background-color:#e9ecef;opacity:1}.bootstrap input[type=date].form-control,.bootstrap input[type=datetime-local].form-control,.bootstrap input[type=month].form-control,.bootstrap input[type=time].form-control{-webkit-appearance:none;appearance:none}.bootstrap select.form-control:-moz-focusring{color:#0000;text-shadow:0 0 0 #495057}.bootstrap select.form-control:focus::-ms-value{background-color:#fff;color:#495057}.bootstrap .form-control-file,.bootstrap .form-control-range{display:block;width:100%}.bootstrap .col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.bootstrap .col-form-label-lg{font-size:1.25rem;line-height:1.5;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.bootstrap .col-form-label-sm{font-size:.875rem;line-height:1.5;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.bootstrap .form-control-plaintext{background-color:initial;border:solid #0000;border-width:1px 0;color:#212529;display:block;font-size:1rem;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.bootstrap .form-control-plaintext.form-control-lg,.bootstrap .form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.bootstrap .form-control-sm{border-radius:.2rem;font-size:.875rem;height:calc(1.5em + .5rem + 2px);line-height:1.5;padding:.25rem .5rem}.bootstrap .form-control-lg{border-radius:.3rem;font-size:1.25rem;height:calc(1.5em + 1rem + 2px);line-height:1.5;padding:.5rem 1rem}.bootstrap select.form-control[multiple],.bootstrap select.form-control[size],.bootstrap textarea.form-control{height:auto}.bootstrap .form-group{margin-bottom:1rem}.bootstrap .form-text{display:block;margin-top:.25rem}.bootstrap .form-row{display:flex;flex-wrap:wrap;margin-left:-5px;margin-right:-5px}.bootstrap .form-row>.col,.bootstrap .form-row>[class*=col-]{padding-left:5px;padding-right:5px}.bootstrap .form-check{display:block;padding-left:1.25rem;position:relative}.bootstrap .form-check-input{margin-left:-1.25rem;margin-top:.3rem;position:absolute}.bootstrap .form-check-input:disabled~.form-check-label,.bootstrap .form-check-input[disabled]~.form-check-label{color:#6c757d}.bootstrap .form-check-label{margin-bottom:0}.bootstrap .form-check-inline{align-items:center;display:inline-flex;margin-right:.75rem;padding-left:0}.bootstrap .form-check-inline .form-check-input{margin-left:0;margin-right:.3125rem;margin-top:0;position:static}.bootstrap .valid-feedback{color:#28a745;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap .valid-tooltip{background-color:#28a745e6;border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap .valid-tooltip,.form-row>[class*=col-]>.bootstrap .valid-tooltip{left:5px}.bootstrap .is-valid~.valid-feedback,.bootstrap .is-valid~.valid-tooltip{display:block}.bootstrap .form-control.is-valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#28a745;padding-right:calc(1.5em + .75rem)!important}.bootstrap .form-control.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap select.form-control.is-valid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap .custom-select.is-valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap .custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap .form-check-input.is-valid~.form-check-label{color:#28a745}.bootstrap .form-check-input.is-valid~.valid-feedback,.bootstrap .form-check-input.is-valid~.valid-tooltip{display:block}.bootstrap .custom-control-input.is-valid~.custom-control-label{color:#28a745}.bootstrap .custom-control-input.is-valid~.custom-control-label:before{border-color:#28a745}.bootstrap .custom-control-input.is-valid:checked~.custom-control-label:before{background-color:#34ce57;border-color:#34ce57}.bootstrap .custom-control-input.is-valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #28a74540}.bootstrap .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.bootstrap .custom-file-input.is-valid~.custom-file-label{border-color:#28a745}.bootstrap .custom-file-input.is-valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap .invalid-feedback{color:#dc3545;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap .invalid-tooltip{background-color:#dc3545e6;border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap .invalid-tooltip,.form-row>[class*=col-]>.bootstrap .invalid-tooltip{left:5px}.bootstrap .is-invalid~.invalid-feedback,.bootstrap .is-invalid~.invalid-tooltip{display:block}.bootstrap .form-control.is-invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important}.bootstrap .form-control.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap select.form-control.is-invalid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap .custom-select.is-invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap .custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap .form-check-input.is-invalid~.form-check-label{color:#dc3545}.bootstrap .form-check-input.is-invalid~.invalid-feedback,.bootstrap .form-check-input.is-invalid~.invalid-tooltip{display:block}.bootstrap .custom-control-input.is-invalid~.custom-control-label{color:#dc3545}.bootstrap .custom-control-input.is-invalid~.custom-control-label:before{border-color:#dc3545}.bootstrap .custom-control-input.is-invalid:checked~.custom-control-label:before{background-color:#e4606d;border-color:#e4606d}.bootstrap .custom-control-input.is-invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #dc354540}.bootstrap .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap .custom-file-input.is-invalid~.custom-file-label{border-color:#dc3545}.bootstrap .custom-file-input.is-invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap .form-inline{align-items:center;display:flex;flex-flow:row wrap}.bootstrap .form-inline .form-check{width:100%}@media(min-width:576px){.bootstrap .form-inline label{align-items:center;display:flex;justify-content:center;margin-bottom:0}.bootstrap .form-inline .form-group{align-items:center;display:flex;flex:0 0 auto;flex-flow:row wrap;margin-bottom:0}.bootstrap .form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.bootstrap .form-inline .form-control-plaintext{display:inline-block}.bootstrap .form-inline .custom-select,.bootstrap .form-inline .input-group{width:auto}.bootstrap .form-inline .form-check{align-items:center;display:flex;justify-content:center;padding-left:0;width:auto}.bootstrap .form-inline .form-check-input{flex-shrink:0;margin-left:0;margin-right:.25rem;margin-top:0;position:relative}.bootstrap .form-inline .custom-control{align-items:center;justify-content:center}.bootstrap .form-inline .custom-control-label{margin-bottom:0}}.bootstrap .was-validated .valid-feedback{color:#28a745;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap .was-validated .valid-tooltip{background-color:#28a745e6;border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap .was-validated .valid-tooltip,.form-row>[class*=col-]>.bootstrap .was-validated .valid-tooltip{left:5px}.bootstrap .was-validated.is-valid~.valid-feedback,.bootstrap .was-validated.is-valid~.valid-tooltip,.bootstrap .was-validated:valid~.valid-feedback,.bootstrap .was-validated:valid~.valid-tooltip{display:block}.bootstrap .was-validated .form-control.is-valid,.bootstrap .was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#28a745;padding-right:calc(1.5em + .75rem)!important}.bootstrap .was-validated .form-control.is-valid:focus,.bootstrap .was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap .was-validated select.form-control.is-valid,.bootstrap .was-validated select.form-control:valid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap .was-validated textarea.form-control.is-valid,.bootstrap .was-validated textarea.form-control:valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap .was-validated .custom-select.is-valid,.bootstrap .was-validated .custom-select:valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap .was-validated .custom-select.is-valid:focus,.bootstrap .was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap .was-validated .form-check-input.is-valid~.form-check-label,.bootstrap .was-validated .form-check-input:valid~.form-check-label{color:#28a745}.bootstrap .was-validated .form-check-input.is-valid~.valid-feedback,.bootstrap .was-validated .form-check-input.is-valid~.valid-tooltip,.bootstrap .was-validated .form-check-input:valid~.valid-feedback,.bootstrap .was-validated .form-check-input:valid~.valid-tooltip{display:block}.bootstrap .was-validated .custom-control-input.is-valid~.custom-control-label,.bootstrap .was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.bootstrap .was-validated .custom-control-input.is-valid~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.bootstrap .was-validated .custom-control-input.is-valid:checked~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:valid:checked~.custom-control-label:before{background-color:#34ce57;border-color:#34ce57}.bootstrap .was-validated .custom-control-input.is-valid:focus~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #28a74540}.bootstrap .was-validated .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.bootstrap .was-validated .custom-file-input.is-valid~.custom-file-label,.bootstrap .was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.bootstrap .was-validated .custom-file-input.is-valid:focus~.custom-file-label,.bootstrap .was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap .was-validated .is-valid~.valid-feedback,.bootstrap .was-validated .is-valid~.valid-tooltip,.bootstrap .was-validated :valid~.valid-feedback,.bootstrap .was-validated :valid~.valid-tooltip{display:block}.bootstrap .was-validated .invalid-feedback{color:#dc3545;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap .was-validated .invalid-tooltip{background-color:#dc3545e6;border-radius:.25rem;color:#fff;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap .was-validated .invalid-tooltip,.form-row>[class*=col-]>.bootstrap .was-validated .invalid-tooltip{left:5px}.bootstrap .was-validated.is-invalid~.invalid-feedback,.bootstrap .was-validated.is-invalid~.invalid-tooltip,.bootstrap .was-validated:invalid~.invalid-feedback,.bootstrap .was-validated:invalid~.invalid-tooltip{display:block}.bootstrap .was-validated .form-control.is-invalid,.bootstrap .was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important}.bootstrap .was-validated .form-control.is-invalid:focus,.bootstrap .was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap .was-validated select.form-control.is-invalid,.bootstrap .was-validated select.form-control:invalid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap .was-validated textarea.form-control.is-invalid,.bootstrap .was-validated textarea.form-control:invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap .was-validated .custom-select.is-invalid,.bootstrap .was-validated .custom-select:invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap .was-validated .custom-select.is-invalid:focus,.bootstrap .was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap .was-validated .form-check-input.is-invalid~.form-check-label,.bootstrap .was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.bootstrap .was-validated .form-check-input.is-invalid~.invalid-feedback,.bootstrap .was-validated .form-check-input.is-invalid~.invalid-tooltip,.bootstrap .was-validated .form-check-input:invalid~.invalid-feedback,.bootstrap .was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.bootstrap .was-validated .custom-control-input.is-invalid~.custom-control-label,.bootstrap .was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.bootstrap .was-validated .custom-control-input.is-invalid~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.bootstrap .was-validated .custom-control-input.is-invalid:checked~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:invalid:checked~.custom-control-label:before{background-color:#e4606d;border-color:#e4606d}.bootstrap .was-validated .custom-control-input.is-invalid:focus~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #dc354540}.bootstrap .was-validated .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap .was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap .was-validated .custom-file-input.is-invalid~.custom-file-label,.bootstrap .was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.bootstrap .was-validated .custom-file-input.is-invalid:focus~.custom-file-label,.bootstrap .was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap .was-validated .is-invalid~.invalid-feedback,.bootstrap .was-validated .is-invalid~.invalid-tooltip,.bootstrap .was-validated :invalid~.invalid-feedback,.bootstrap .was-validated :invalid~.invalid-tooltip{display:block}.bootstrap .btn{background-color:initial;border:1px solid #0000;border-radius:.25rem;color:#212529;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;user-select:none;vertical-align:middle}@media(prefers-reduced-motion:reduce){.bootstrap .btn{transition:none}}.bootstrap .btn:hover{color:#212529;text-decoration:none}.bootstrap .btn.focus,.bootstrap .btn:focus{box-shadow:0 0 0 .2rem #007bff40;outline:0}.bootstrap .btn.disabled,.bootstrap .btn:disabled{opacity:.65}.bootstrap .btn:not(:disabled):not(.disabled){cursor:pointer}.bootstrap a.btn.disabled,.bootstrap fieldset:disabled a.btn{pointer-events:none}.bootstrap .btn-primary{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap .btn-primary:hover{background-color:#0069d9;border-color:#0062cc;color:#fff}.bootstrap .btn-primary.focus,.bootstrap .btn-primary:focus{background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem #268fff80;color:#fff}.bootstrap .btn-primary.disabled,.bootstrap .btn-primary:disabled{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap .btn-primary:not(:disabled):not(.disabled).active,.bootstrap .btn-primary:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-primary.dropdown-toggle{background-color:#0062cc;border-color:#005cbf;color:#fff}.bootstrap .btn-primary:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-primary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #268fff80}.bootstrap .btn-secondary{background-color:#6c757d;border-color:#6c757d;color:#fff}.bootstrap .btn-secondary:hover{background-color:#5a6268;border-color:#545b62;color:#fff}.bootstrap .btn-secondary.focus,.bootstrap .btn-secondary:focus{background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem #828a9180;color:#fff}.bootstrap .btn-secondary.disabled,.bootstrap .btn-secondary:disabled{background-color:#6c757d;border-color:#6c757d;color:#fff}.bootstrap .btn-secondary:not(:disabled):not(.disabled).active,.bootstrap .btn-secondary:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-secondary.dropdown-toggle{background-color:#545b62;border-color:#4e555b;color:#fff}.bootstrap .btn-secondary:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #828a9180}.bootstrap .btn-success{background-color:#28a745;border-color:#28a745;color:#fff}.bootstrap .btn-success:hover{background-color:#218838;border-color:#1e7e34;color:#fff}.bootstrap .btn-success.focus,.bootstrap .btn-success:focus{background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem #48b46180;color:#fff}.bootstrap .btn-success.disabled,.bootstrap .btn-success:disabled{background-color:#28a745;border-color:#28a745;color:#fff}.bootstrap .btn-success:not(:disabled):not(.disabled).active,.bootstrap .btn-success:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-success.dropdown-toggle{background-color:#1e7e34;border-color:#1c7430;color:#fff}.bootstrap .btn-success:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-success:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #48b46180}.bootstrap .btn-info{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.bootstrap .btn-info.focus,.bootstrap .btn-info:focus,.bootstrap .btn-info:hover{background-color:#138496;border-color:#117a8b;color:#fff}.bootstrap .btn-info.focus,.bootstrap .btn-info:focus{box-shadow:0 0 0 .2rem #3ab0c380}.bootstrap .btn-info.disabled,.bootstrap .btn-info:disabled{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.bootstrap .btn-info:not(:disabled):not(.disabled).active,.bootstrap .btn-info:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-info.dropdown-toggle{background-color:#117a8b;border-color:#10707f;color:#fff}.bootstrap .btn-info:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-info:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #3ab0c380}.bootstrap .btn-warning{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap .btn-warning:hover{background-color:#e0a800;border-color:#d39e00;color:#212529}.bootstrap .btn-warning.focus,.bootstrap .btn-warning:focus{background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem #deaa0c80;color:#212529}.bootstrap .btn-warning.disabled,.bootstrap .btn-warning:disabled{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap .btn-warning:not(:disabled):not(.disabled).active,.bootstrap .btn-warning:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-warning.dropdown-toggle{background-color:#d39e00;border-color:#c69500;color:#212529}.bootstrap .btn-warning:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-warning:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #deaa0c80}.bootstrap .btn-danger{background-color:#dc3545;border-color:#dc3545;color:#fff}.bootstrap .btn-danger:hover{background-color:#c82333;border-color:#bd2130;color:#fff}.bootstrap .btn-danger.focus,.bootstrap .btn-danger:focus{background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem #e1536180;color:#fff}.bootstrap .btn-danger.disabled,.bootstrap .btn-danger:disabled{background-color:#dc3545;border-color:#dc3545;color:#fff}.bootstrap .btn-danger:not(:disabled):not(.disabled).active,.bootstrap .btn-danger:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-danger.dropdown-toggle{background-color:#bd2130;border-color:#b21f2d;color:#fff}.bootstrap .btn-danger:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-danger:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #e1536180}.bootstrap .btn-light{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap .btn-light.focus,.bootstrap .btn-light:focus,.bootstrap .btn-light:hover{background-color:#e2e6ea;border-color:#dae0e5;color:#212529}.bootstrap .btn-light.focus,.bootstrap .btn-light:focus{box-shadow:0 0 0 .2rem #d8d9db80}.bootstrap .btn-light.disabled,.bootstrap .btn-light:disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap .btn-light:not(:disabled):not(.disabled).active,.bootstrap .btn-light:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-light.dropdown-toggle{background-color:#dae0e5;border-color:#d3d9df;color:#212529}.bootstrap .btn-light:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-light:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #d8d9db80}.bootstrap .btn-dark{background-color:#343a40;border-color:#343a40;color:#fff}.bootstrap .btn-dark.focus,.bootstrap .btn-dark:focus,.bootstrap .btn-dark:hover{background-color:#23272b;border-color:#1d2124;color:#fff}.bootstrap .btn-dark.focus,.bootstrap .btn-dark:focus{box-shadow:0 0 0 .2rem #52585d80}.bootstrap .btn-dark.disabled,.bootstrap .btn-dark:disabled{background-color:#343a40;border-color:#343a40;color:#fff}.bootstrap .btn-dark:not(:disabled):not(.disabled).active,.bootstrap .btn-dark:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-dark.dropdown-toggle{background-color:#1d2124;border-color:#171a1d;color:#fff}.bootstrap .btn-dark:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-dark:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #52585d80}.bootstrap .btn-outline-primary{border-color:#007bff;color:#007bff}.bootstrap .btn-outline-primary:hover{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap .btn-outline-primary.focus,.bootstrap .btn-outline-primary:focus{box-shadow:0 0 0 .2rem #007bff80}.bootstrap .btn-outline-primary.disabled,.bootstrap .btn-outline-primary:disabled{background-color:initial;color:#007bff}.bootstrap .btn-outline-primary:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-primary:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-primary.dropdown-toggle{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap .btn-outline-primary:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #007bff80}.bootstrap .btn-outline-secondary{border-color:#6c757d;color:#6c757d}.bootstrap .btn-outline-secondary:hover{background-color:#6c757d;border-color:#6c757d;color:#fff}.bootstrap .btn-outline-secondary.focus,.bootstrap .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem #6c757d80}.bootstrap .btn-outline-secondary.disabled,.bootstrap .btn-outline-secondary:disabled{background-color:initial;color:#6c757d}.bootstrap .btn-outline-secondary:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-secondary.dropdown-toggle{background-color:#6c757d;border-color:#6c757d;color:#fff}.bootstrap .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #6c757d80}.bootstrap .btn-outline-success{border-color:#28a745;color:#28a745}.bootstrap .btn-outline-success:hover{background-color:#28a745;border-color:#28a745;color:#fff}.bootstrap .btn-outline-success.focus,.bootstrap .btn-outline-success:focus{box-shadow:0 0 0 .2rem #28a74580}.bootstrap .btn-outline-success.disabled,.bootstrap .btn-outline-success:disabled{background-color:initial;color:#28a745}.bootstrap .btn-outline-success:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-success:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-success.dropdown-toggle{background-color:#28a745;border-color:#28a745;color:#fff}.bootstrap .btn-outline-success:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #28a74580}.bootstrap .btn-outline-info{border-color:#17a2b8;color:#17a2b8}.bootstrap .btn-outline-info:hover{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.bootstrap .btn-outline-info.focus,.bootstrap .btn-outline-info:focus{box-shadow:0 0 0 .2rem #17a2b880}.bootstrap .btn-outline-info.disabled,.bootstrap .btn-outline-info:disabled{background-color:initial;color:#17a2b8}.bootstrap .btn-outline-info:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-info:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-info.dropdown-toggle{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.bootstrap .btn-outline-info:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #17a2b880}.bootstrap .btn-outline-warning{border-color:#ffc107;color:#ffc107}.bootstrap .btn-outline-warning:hover{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap .btn-outline-warning.focus,.bootstrap .btn-outline-warning:focus{box-shadow:0 0 0 .2rem #ffc10780}.bootstrap .btn-outline-warning.disabled,.bootstrap .btn-outline-warning:disabled{background-color:initial;color:#ffc107}.bootstrap .btn-outline-warning:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-warning:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-warning.dropdown-toggle{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap .btn-outline-warning:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #ffc10780}.bootstrap .btn-outline-danger{border-color:#dc3545;color:#dc3545}.bootstrap .btn-outline-danger:hover{background-color:#dc3545;border-color:#dc3545;color:#fff}.bootstrap .btn-outline-danger.focus,.bootstrap .btn-outline-danger:focus{box-shadow:0 0 0 .2rem #dc354580}.bootstrap .btn-outline-danger.disabled,.bootstrap .btn-outline-danger:disabled{background-color:initial;color:#dc3545}.bootstrap .btn-outline-danger:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-danger:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-danger.dropdown-toggle{background-color:#dc3545;border-color:#dc3545;color:#fff}.bootstrap .btn-outline-danger:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #dc354580}.bootstrap .btn-outline-light{border-color:#f8f9fa;color:#f8f9fa}.bootstrap .btn-outline-light:hover{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap .btn-outline-light.focus,.bootstrap .btn-outline-light:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.bootstrap .btn-outline-light.disabled,.bootstrap .btn-outline-light:disabled{background-color:initial;color:#f8f9fa}.bootstrap .btn-outline-light:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-light:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-light.dropdown-toggle{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap .btn-outline-light:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.bootstrap .btn-outline-dark{border-color:#343a40;color:#343a40}.bootstrap .btn-outline-dark:hover{background-color:#343a40;border-color:#343a40;color:#fff}.bootstrap .btn-outline-dark.focus,.bootstrap .btn-outline-dark:focus{box-shadow:0 0 0 .2rem #343a4080}.bootstrap .btn-outline-dark.disabled,.bootstrap .btn-outline-dark:disabled{background-color:initial;color:#343a40}.bootstrap .btn-outline-dark:not(:disabled):not(.disabled).active,.bootstrap .btn-outline-dark:not(:disabled):not(.disabled):active,.show>.bootstrap .btn-outline-dark.dropdown-toggle{background-color:#343a40;border-color:#343a40;color:#fff}.bootstrap .btn-outline-dark:not(:disabled):not(.disabled).active:focus,.bootstrap .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.bootstrap .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #343a4080}.bootstrap .btn-link{color:#007bff;font-weight:400;text-decoration:none}.bootstrap .btn-link:hover{color:#0056b3;text-decoration:underline}.bootstrap .btn-link.focus,.bootstrap .btn-link:focus{text-decoration:underline}.bootstrap .btn-link.disabled,.bootstrap .btn-link:disabled{color:#6c757d;pointer-events:none}.bootstrap .btn-group-lg>.btn,.bootstrap .btn-lg{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.bootstrap .btn-group-sm>.btn,.bootstrap .btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap .btn-block{display:block;width:100%}.bootstrap .btn-block+.btn-block{margin-top:.5rem}.bootstrap input[type=button].btn-block,.bootstrap input[type=reset].btn-block,.bootstrap input[type=submit].btn-block{width:100%}.bootstrap .fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.bootstrap .fade{transition:none}}.bootstrap .fade:not(.show){opacity:0}.bootstrap .collapse:not(.show){display:none}.bootstrap .collapsing{height:0;overflow:hidden;position:relative;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.bootstrap .collapsing{transition:none}}.bootstrap .dropdown,.bootstrap .dropleft,.bootstrap .dropright,.bootstrap .dropup{position:relative}.bootstrap .dropdown-toggle{white-space:nowrap}.bootstrap .dropdown-toggle:after{border-bottom:0;border-left:.3em solid #0000;border-right:.3em solid #0000;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap .dropdown-toggle:empty:after{margin-left:0}.bootstrap .dropdown-menu{background-clip:padding-box;background-color:#fff;border:1px solid #00000026;border-radius:.25rem;color:#212529;display:none;float:left;font-size:1rem;left:0;list-style:none;margin:.125rem 0 0;min-width:10rem;padding:.5rem 0;position:absolute;text-align:left;top:100%;z-index:1000}.bootstrap .dropdown-menu-left{left:0;right:auto}.bootstrap .dropdown-menu-right{left:auto;right:0}@media(min-width:576px){.bootstrap .dropdown-menu-sm-left{left:0;right:auto}.bootstrap .dropdown-menu-sm-right{left:auto;right:0}}@media(min-width:768px){.bootstrap .dropdown-menu-md-left{left:0;right:auto}.bootstrap .dropdown-menu-md-right{left:auto;right:0}}@media(min-width:992px){.bootstrap .dropdown-menu-lg-left{left:0;right:auto}.bootstrap .dropdown-menu-lg-right{left:auto;right:0}}@media(min-width:1200px){.bootstrap .dropdown-menu-xl-left{left:0;right:auto}.bootstrap .dropdown-menu-xl-right{left:auto;right:0}}.bootstrap .dropup .dropdown-menu{bottom:100%;margin-bottom:.125rem;margin-top:0;top:auto}.bootstrap .dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid #0000;border-right:.3em solid #0000;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap .dropup .dropdown-toggle:empty:after{margin-left:0}.bootstrap .dropright .dropdown-menu{left:100%;margin-left:.125rem;margin-top:0;right:auto;top:0}.bootstrap .dropright .dropdown-toggle:after{border-bottom:.3em solid #0000;border-left:.3em solid;border-right:0;border-top:.3em solid #0000;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap .dropright .dropdown-toggle:empty:after{margin-left:0}.bootstrap .dropright .dropdown-toggle:after{vertical-align:0}.bootstrap .dropleft .dropdown-menu{left:auto;margin-right:.125rem;margin-top:0;right:100%;top:0}.bootstrap .dropleft .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.bootstrap .dropleft .dropdown-toggle:before{border-bottom:.3em solid #0000;border-right:.3em solid;border-top:.3em solid #0000;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.bootstrap .dropleft .dropdown-toggle:empty:after{margin-left:0}.bootstrap .dropleft .dropdown-toggle:before{vertical-align:0}.bootstrap .dropdown-menu[x-placement^=bottom],.bootstrap .dropdown-menu[x-placement^=left],.bootstrap .dropdown-menu[x-placement^=right],.bootstrap .dropdown-menu[x-placement^=top]{bottom:auto;right:auto}.bootstrap .dropdown-divider{border-top:1px solid #e9ecef;height:0;margin:.5rem 0;overflow:hidden}.bootstrap .dropdown-item{background-color:initial;border:0;clear:both;color:#212529;display:block;font-weight:400;padding:.25rem 1.5rem;text-align:inherit;white-space:nowrap;width:100%}.bootstrap .dropdown-item:focus,.bootstrap .dropdown-item:hover{background-color:#e9ecef;color:#16181b;text-decoration:none}.bootstrap .dropdown-item.active,.bootstrap .dropdown-item:active{background-color:#007bff;color:#fff;text-decoration:none}.bootstrap .dropdown-item.disabled,.bootstrap .dropdown-item:disabled{background-color:initial;color:#adb5bd;pointer-events:none}.bootstrap .dropdown-menu.show{display:block}.bootstrap .dropdown-header{color:#6c757d;display:block;font-size:.875rem;margin-bottom:0;padding:.5rem 1.5rem;white-space:nowrap}.bootstrap .dropdown-item-text{color:#212529;display:block;padding:.25rem 1.5rem}.bootstrap .btn-group,.bootstrap .btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.bootstrap .btn-group-vertical>.btn,.bootstrap .btn-group>.btn{flex:1 1 auto;position:relative}.bootstrap .btn-group-vertical>.btn.active,.bootstrap .btn-group-vertical>.btn:active,.bootstrap .btn-group-vertical>.btn:focus,.bootstrap .btn-group-vertical>.btn:hover,.bootstrap .btn-group>.btn.active,.bootstrap .btn-group>.btn:active,.bootstrap .btn-group>.btn:focus,.bootstrap .btn-group>.btn:hover{z-index:1}.bootstrap .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.bootstrap .btn-toolbar .input-group{width:auto}.bootstrap .btn-group>.btn-group:not(:first-child),.bootstrap .btn-group>.btn:not(:first-child){margin-left:-1px}.bootstrap .btn-group>.btn-group:not(:last-child)>.btn,.bootstrap .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap .btn-group>.btn-group:not(:first-child)>.btn,.bootstrap .btn-group>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap .dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.bootstrap .dropdown-toggle-split:after,.dropright .bootstrap .dropdown-toggle-split:after,.dropup .bootstrap .dropdown-toggle-split:after{margin-left:0}.dropleft .bootstrap .dropdown-toggle-split:before{margin-right:0}.bootstrap .btn-group-sm>.btn+.dropdown-toggle-split,.bootstrap .btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.bootstrap .btn-group-lg>.btn+.dropdown-toggle-split,.bootstrap .btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.bootstrap .btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.bootstrap .btn-group-vertical>.btn,.bootstrap .btn-group-vertical>.btn-group{width:100%}.bootstrap .btn-group-vertical>.btn-group:not(:first-child),.bootstrap .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.bootstrap .btn-group-vertical>.btn-group:not(:last-child)>.btn,.bootstrap .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap .btn-group-vertical>.btn-group:not(:first-child)>.btn,.bootstrap .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.bootstrap .btn-group-toggle>.btn,.bootstrap .btn-group-toggle>.btn-group>.btn{margin-bottom:0}.bootstrap .btn-group-toggle>.btn input[type=checkbox],.bootstrap .btn-group-toggle>.btn input[type=radio],.bootstrap .btn-group-toggle>.btn-group>.btn input[type=checkbox],.bootstrap .btn-group-toggle>.btn-group>.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.bootstrap .input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.bootstrap .input-group>.custom-file,.bootstrap .input-group>.custom-select,.bootstrap .input-group>.form-control,.bootstrap .input-group>.form-control-plaintext{flex:1 1 auto;margin-bottom:0;min-width:0;position:relative;width:1%}.bootstrap .input-group>.custom-file+.custom-file,.bootstrap .input-group>.custom-file+.custom-select,.bootstrap .input-group>.custom-file+.form-control,.bootstrap .input-group>.custom-select+.custom-file,.bootstrap .input-group>.custom-select+.custom-select,.bootstrap .input-group>.custom-select+.form-control,.bootstrap .input-group>.form-control+.custom-file,.bootstrap .input-group>.form-control+.custom-select,.bootstrap .input-group>.form-control+.form-control,.bootstrap .input-group>.form-control-plaintext+.custom-file,.bootstrap .input-group>.form-control-plaintext+.custom-select,.bootstrap .input-group>.form-control-plaintext+.form-control{margin-left:-1px}.bootstrap .input-group>.custom-file .custom-file-input:focus~.custom-file-label,.bootstrap .input-group>.custom-select:focus,.bootstrap .input-group>.form-control:focus{z-index:3}.bootstrap .input-group>.custom-file .custom-file-input:focus{z-index:4}.bootstrap .input-group>.custom-select:not(:first-child),.bootstrap .input-group>.form-control:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap .input-group>.custom-file{align-items:center;display:flex}.bootstrap .input-group>.custom-file:not(:last-child) .custom-file-label,.bootstrap .input-group>.custom-file:not(:last-child) .custom-file-label:after{border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap .input-group>.custom-file:not(:first-child) .custom-file-label{border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.bootstrap .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.bootstrap .input-group.has-validation>.custom-select:nth-last-child(n+3),.bootstrap .input-group.has-validation>.form-control:nth-last-child(n+3),.bootstrap .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.bootstrap .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.bootstrap .input-group:not(.has-validation)>.custom-select:not(:last-child),.bootstrap .input-group:not(.has-validation)>.form-control:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap .input-group-append,.bootstrap .input-group-prepend{display:flex}.bootstrap .input-group-append .btn,.bootstrap .input-group-prepend .btn{position:relative;z-index:2}.bootstrap .input-group-append .btn:focus,.bootstrap .input-group-prepend .btn:focus{z-index:3}.bootstrap .input-group-append .btn+.btn,.bootstrap .input-group-append .btn+.input-group-text,.bootstrap .input-group-append .input-group-text+.btn,.bootstrap .input-group-append .input-group-text+.input-group-text,.bootstrap .input-group-prepend .btn+.btn,.bootstrap .input-group-prepend .btn+.input-group-text,.bootstrap .input-group-prepend .input-group-text+.btn,.bootstrap .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.bootstrap .input-group-prepend{margin-right:-1px}.bootstrap .input-group-append{margin-left:-1px}.bootstrap .input-group-text{align-items:center;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem;color:#495057;display:flex;font-size:1rem;font-weight:400;line-height:1.5;margin-bottom:0;padding:.375rem .75rem;text-align:center;white-space:nowrap}.bootstrap .input-group-text input[type=checkbox],.bootstrap .input-group-text input[type=radio]{margin-top:0}.bootstrap .input-group-lg>.custom-select,.bootstrap .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.bootstrap .input-group-lg>.custom-select,.bootstrap .input-group-lg>.form-control,.bootstrap .input-group-lg>.input-group-append>.btn,.bootstrap .input-group-lg>.input-group-append>.input-group-text,.bootstrap .input-group-lg>.input-group-prepend>.btn,.bootstrap .input-group-lg>.input-group-prepend>.input-group-text{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.bootstrap .input-group-sm>.custom-select,.bootstrap .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.bootstrap .input-group-sm>.custom-select,.bootstrap .input-group-sm>.form-control,.bootstrap .input-group-sm>.input-group-append>.btn,.bootstrap .input-group-sm>.input-group-append>.input-group-text,.bootstrap .input-group-sm>.input-group-prepend>.btn,.bootstrap .input-group-sm>.input-group-prepend>.input-group-text{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap .input-group-lg>.custom-select,.bootstrap .input-group-sm>.custom-select{padding-right:1.75rem}.bootstrap .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.bootstrap .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.bootstrap .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.bootstrap .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.bootstrap .input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.bootstrap .input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.bootstrap .input-group>.input-group-prepend>.btn,.bootstrap .input-group>.input-group-prepend>.input-group-text{border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap .input-group>.input-group-append>.btn,.bootstrap .input-group>.input-group-append>.input-group-text,.bootstrap .input-group>.input-group-prepend:first-child>.btn:not(:first-child),.bootstrap .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.bootstrap .input-group>.input-group-prepend:not(:first-child)>.btn,.bootstrap .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap .custom-control{-webkit-print-color-adjust:exact;color-adjust:exact;display:block;min-height:1.5rem;padding-left:1.5rem;position:relative;z-index:1}.bootstrap .custom-control-inline{display:inline-flex;margin-right:1rem}.bootstrap .custom-control-input{height:1.25rem;left:0;opacity:0;position:absolute;width:1rem;z-index:-1}.bootstrap .custom-control-input:checked~.custom-control-label:before{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #007bff40}.bootstrap .custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#80bdff}.bootstrap .custom-control-input:not(:disabled):active~.custom-control-label:before{background-color:#b3d7ff;border-color:#b3d7ff;color:#fff}.bootstrap .custom-control-input:disabled~.custom-control-label,.bootstrap .custom-control-input[disabled]~.custom-control-label{color:#6c757d}.bootstrap .custom-control-input:disabled~.custom-control-label:before,.bootstrap .custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.bootstrap .custom-control-label{margin-bottom:0;position:relative;vertical-align:top}.bootstrap .custom-control-label:before{background-color:#fff;border:1px solid #adb5bd;pointer-events:none}.bootstrap .custom-control-label:after,.bootstrap .custom-control-label:before{content:"";display:block;height:1rem;left:-1.5rem;position:absolute;top:.25rem;width:1rem}.bootstrap .custom-control-label:after{background:50%/50% 50% no-repeat}.bootstrap .custom-checkbox .custom-control-label:before{border-radius:.25rem}.bootstrap .custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='m6.564.75-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.bootstrap .custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{background-color:#007bff;border-color:#007bff}.bootstrap .custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.bootstrap .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before,.bootstrap .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:#007bff80}.bootstrap .custom-radio .custom-control-label:before{border-radius:50%}.bootstrap .custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.bootstrap .custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#007bff80}.bootstrap .custom-switch{padding-left:2.25rem}.bootstrap .custom-switch .custom-control-label:before{border-radius:.5rem;left:-2.25rem;pointer-events:all;width:1.75rem}.bootstrap .custom-switch .custom-control-label:after{background-color:#adb5bd;border-radius:.5rem;height:calc(1rem - 4px);left:calc(-2.25rem + 2px);top:calc(.25rem + 2px);transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:calc(1rem - 4px)}@media(prefers-reduced-motion:reduce){.bootstrap .custom-switch .custom-control-label:after{transition:none}}.bootstrap .custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.bootstrap .custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#007bff80}.bootstrap .custom-select{-webkit-appearance:none;appearance:none;background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;color:#495057;display:inline-block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem 1.75rem .375rem .75rem;vertical-align:middle;width:100%}.bootstrap .custom-select:focus{border-color:#80bdff;box-shadow:0 0 0 .2rem #007bff40;outline:0}.bootstrap .custom-select:focus::-ms-value{background-color:#fff;color:#495057}.bootstrap .custom-select[multiple],.bootstrap .custom-select[size]:not([size="1"]){background-image:none;height:auto;padding-right:.75rem}.bootstrap .custom-select:disabled{background-color:#e9ecef;color:#6c757d}.bootstrap .custom-select::-ms-expand{display:none}.bootstrap .custom-select:-moz-focusring{color:#0000;text-shadow:0 0 0 #495057}.bootstrap .custom-select-sm{font-size:.875rem;height:calc(1.5em + .5rem + 2px);padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.bootstrap .custom-select-lg{font-size:1.25rem;height:calc(1.5em + 1rem + 2px);padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.bootstrap .custom-file{display:inline-block;margin-bottom:0}.bootstrap .custom-file,.bootstrap .custom-file-input{height:calc(1.5em + .75rem + 2px);position:relative;width:100%}.bootstrap .custom-file-input{margin:0;opacity:0;overflow:hidden;z-index:2}.bootstrap .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem #007bff40}.bootstrap .custom-file-input:disabled~.custom-file-label,.bootstrap .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.bootstrap .custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.bootstrap .custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.bootstrap .custom-file-label{background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;font-weight:400;height:calc(1.5em + .75rem + 2px);left:0;overflow:hidden;z-index:1}.bootstrap .custom-file-label,.bootstrap .custom-file-label:after{color:#495057;line-height:1.5;padding:.375rem .75rem;position:absolute;right:0;top:0}.bootstrap .custom-file-label:after{background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0;bottom:0;content:"Browse";display:block;height:calc(1.5em + .75rem);z-index:3}.bootstrap .custom-range{-webkit-appearance:none;appearance:none;background-color:initial;height:1.4rem;padding:0;width:100%}.bootstrap .custom-range:focus{outline:0}.bootstrap .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap .custom-range::-moz-focus-outer{border:0}.bootstrap .custom-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.bootstrap .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.bootstrap .custom-range::-webkit-slider-runnable-track{background-color:#dee2e6;border-color:#0000;border-radius:1rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap .custom-range::-moz-range-thumb{appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.bootstrap .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.bootstrap .custom-range::-moz-range-track{background-color:#dee2e6;border-color:#0000;border-radius:1rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap .custom-range::-ms-thumb{appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;margin-left:.2rem;margin-right:.2rem;margin-top:0;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap .custom-range::-ms-thumb{-ms-transition:none;transition:none}}.bootstrap .custom-range::-ms-thumb:active{background-color:#b3d7ff}.bootstrap .custom-range::-ms-track{background-color:initial;border-color:#0000;border-width:.5rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap .custom-range::-ms-fill-lower,.bootstrap .custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.bootstrap .custom-range::-ms-fill-upper{margin-right:15px}.bootstrap .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.bootstrap .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.bootstrap .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.bootstrap .custom-range:disabled::-moz-range-track{cursor:default}.bootstrap .custom-range:disabled::-ms-thumb{background-color:#adb5bd}.bootstrap .custom-control-label:before,.bootstrap .custom-file-label,.bootstrap .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.bootstrap .custom-control-label:before,.bootstrap .custom-file-label,.bootstrap .custom-select{transition:none}}.bootstrap .nav{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.bootstrap .nav-link{display:block;padding:.5rem 1rem}.bootstrap .nav-link:focus,.bootstrap .nav-link:hover{text-decoration:none}.bootstrap .nav-link.disabled{color:#6c757d;cursor:default;pointer-events:none}.bootstrap .nav-tabs{border-bottom:1px solid #dee2e6}.bootstrap .nav-tabs .nav-link{border:1px solid #0000;border-top-left-radius:.25rem;border-top-right-radius:.25rem;margin-bottom:-1px}.bootstrap .nav-tabs .nav-link:focus,.bootstrap .nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.bootstrap .nav-tabs .nav-link.disabled{background-color:initial;border-color:#0000;color:#6c757d}.bootstrap .nav-tabs .nav-item.show .nav-link,.bootstrap .nav-tabs .nav-link.active{background-color:#fff;border-color:#dee2e6 #dee2e6 #fff;color:#495057}.bootstrap .nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.bootstrap .nav-pills .nav-link{border-radius:.25rem}.bootstrap .nav-pills .nav-link.active,.bootstrap .nav-pills .show>.nav-link{background-color:#007bff;color:#fff}.bootstrap .nav-fill .nav-item,.bootstrap .nav-fill>.nav-link{flex:1 1 auto;text-align:center}.bootstrap .nav-justified .nav-item,.bootstrap .nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.bootstrap .tab-content>.tab-pane{display:none}.bootstrap .tab-content>.active{display:block}.bootstrap .navbar{padding:.5rem 1rem;position:relative}.bootstrap .navbar,.bootstrap .navbar .container,.bootstrap .navbar .container-fluid,.bootstrap .navbar .container-lg,.bootstrap .navbar .container-md,.bootstrap .navbar .container-sm,.bootstrap .navbar .container-xl{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.bootstrap .navbar-brand{display:inline-block;font-size:1.25rem;line-height:inherit;margin-right:1rem;padding-bottom:.3125rem;padding-top:.3125rem;white-space:nowrap}.bootstrap .navbar-brand:focus,.bootstrap .navbar-brand:hover{text-decoration:none}.bootstrap .navbar-nav{display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.bootstrap .navbar-nav .nav-link{padding-left:0;padding-right:0}.bootstrap .navbar-nav .dropdown-menu{float:none;position:static}.bootstrap .navbar-text{display:inline-block;padding-bottom:.5rem;padding-top:.5rem}.bootstrap .navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.bootstrap .navbar-toggler{background-color:initial;border:1px solid #0000;border-radius:.25rem;font-size:1.25rem;line-height:1;padding:.25rem .75rem}.bootstrap .navbar-toggler:focus,.bootstrap .navbar-toggler:hover{text-decoration:none}.bootstrap .navbar-toggler-icon{background:50%/100% 100% no-repeat;content:"";display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.bootstrap .navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media(max-width:575.98px){.bootstrap .navbar-expand-sm>.container,.bootstrap .navbar-expand-sm>.container-fluid,.bootstrap .navbar-expand-sm>.container-lg,.bootstrap .navbar-expand-sm>.container-md,.bootstrap .navbar-expand-sm>.container-sm,.bootstrap .navbar-expand-sm>.container-xl{padding-left:0;padding-right:0}}@media(min-width:576px){.bootstrap .navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.bootstrap .navbar-expand-sm .navbar-nav{flex-direction:row}.bootstrap .navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.bootstrap .navbar-expand-sm .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap .navbar-expand-sm>.container,.bootstrap .navbar-expand-sm>.container-fluid,.bootstrap .navbar-expand-sm>.container-lg,.bootstrap .navbar-expand-sm>.container-md,.bootstrap .navbar-expand-sm>.container-sm,.bootstrap .navbar-expand-sm>.container-xl{flex-wrap:nowrap}.bootstrap .navbar-expand-sm .navbar-nav-scroll{overflow:visible}.bootstrap .navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap .navbar-expand-sm .navbar-toggler{display:none}}@media(max-width:767.98px){.bootstrap .navbar-expand-md>.container,.bootstrap .navbar-expand-md>.container-fluid,.bootstrap .navbar-expand-md>.container-lg,.bootstrap .navbar-expand-md>.container-md,.bootstrap .navbar-expand-md>.container-sm,.bootstrap .navbar-expand-md>.container-xl{padding-left:0;padding-right:0}}@media(min-width:768px){.bootstrap .navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.bootstrap .navbar-expand-md .navbar-nav{flex-direction:row}.bootstrap .navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.bootstrap .navbar-expand-md .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap .navbar-expand-md>.container,.bootstrap .navbar-expand-md>.container-fluid,.bootstrap .navbar-expand-md>.container-lg,.bootstrap .navbar-expand-md>.container-md,.bootstrap .navbar-expand-md>.container-sm,.bootstrap .navbar-expand-md>.container-xl{flex-wrap:nowrap}.bootstrap .navbar-expand-md .navbar-nav-scroll{overflow:visible}.bootstrap .navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap .navbar-expand-md .navbar-toggler{display:none}}@media(max-width:991.98px){.bootstrap .navbar-expand-lg>.container,.bootstrap .navbar-expand-lg>.container-fluid,.bootstrap .navbar-expand-lg>.container-lg,.bootstrap .navbar-expand-lg>.container-md,.bootstrap .navbar-expand-lg>.container-sm,.bootstrap .navbar-expand-lg>.container-xl{padding-left:0;padding-right:0}}@media(min-width:992px){.bootstrap .navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.bootstrap .navbar-expand-lg .navbar-nav{flex-direction:row}.bootstrap .navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.bootstrap .navbar-expand-lg .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap .navbar-expand-lg>.container,.bootstrap .navbar-expand-lg>.container-fluid,.bootstrap .navbar-expand-lg>.container-lg,.bootstrap .navbar-expand-lg>.container-md,.bootstrap .navbar-expand-lg>.container-sm,.bootstrap .navbar-expand-lg>.container-xl{flex-wrap:nowrap}.bootstrap .navbar-expand-lg .navbar-nav-scroll{overflow:visible}.bootstrap .navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap .navbar-expand-lg .navbar-toggler{display:none}}@media(max-width:1199.98px){.bootstrap .navbar-expand-xl>.container,.bootstrap .navbar-expand-xl>.container-fluid,.bootstrap .navbar-expand-xl>.container-lg,.bootstrap .navbar-expand-xl>.container-md,.bootstrap .navbar-expand-xl>.container-sm,.bootstrap .navbar-expand-xl>.container-xl{padding-left:0;padding-right:0}}@media(min-width:1200px){.bootstrap .navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.bootstrap .navbar-expand-xl .navbar-nav{flex-direction:row}.bootstrap .navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.bootstrap .navbar-expand-xl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap .navbar-expand-xl>.container,.bootstrap .navbar-expand-xl>.container-fluid,.bootstrap .navbar-expand-xl>.container-lg,.bootstrap .navbar-expand-xl>.container-md,.bootstrap .navbar-expand-xl>.container-sm,.bootstrap .navbar-expand-xl>.container-xl{flex-wrap:nowrap}.bootstrap .navbar-expand-xl .navbar-nav-scroll{overflow:visible}.bootstrap .navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap .navbar-expand-xl .navbar-toggler{display:none}}.bootstrap .navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.bootstrap .navbar-expand>.container,.bootstrap .navbar-expand>.container-fluid,.bootstrap .navbar-expand>.container-lg,.bootstrap .navbar-expand>.container-md,.bootstrap .navbar-expand>.container-sm,.bootstrap .navbar-expand>.container-xl{padding-left:0;padding-right:0}.bootstrap .navbar-expand .navbar-nav{flex-direction:row}.bootstrap .navbar-expand .navbar-nav .dropdown-menu{position:absolute}.bootstrap .navbar-expand .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap .navbar-expand>.container,.bootstrap .navbar-expand>.container-fluid,.bootstrap .navbar-expand>.container-lg,.bootstrap .navbar-expand>.container-md,.bootstrap .navbar-expand>.container-sm,.bootstrap .navbar-expand>.container-xl{flex-wrap:nowrap}.bootstrap .navbar-expand .navbar-nav-scroll{overflow:visible}.bootstrap .navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap .navbar-expand .navbar-toggler{display:none}.bootstrap .navbar-light .navbar-brand,.bootstrap .navbar-light .navbar-brand:focus,.bootstrap .navbar-light .navbar-brand:hover,.bootstrap .navbar-themed .navbar-brand,.bootstrap .navbar-themed .navbar-brand:focus,.bootstrap .navbar-themed .navbar-brand:hover{color:#000000e6}.bootstrap .navbar-light .navbar-nav .nav-link,.bootstrap .navbar-themed .navbar-nav .nav-link{color:#00000080}.bootstrap .navbar-light .navbar-nav .nav-link:focus,.bootstrap .navbar-light .navbar-nav .nav-link:hover,.bootstrap .navbar-themed .navbar-nav .nav-link:focus,.bootstrap .navbar-themed .navbar-nav .nav-link:hover{color:#000000b3}.bootstrap .navbar-light .navbar-nav .nav-link.disabled,.bootstrap .navbar-themed .navbar-nav .nav-link.disabled{color:#0000004d}.bootstrap .navbar-light .navbar-nav .active>.nav-link,.bootstrap .navbar-light .navbar-nav .nav-link.active,.bootstrap .navbar-light .navbar-nav .nav-link.show,.bootstrap .navbar-light .navbar-nav .show>.nav-link,.bootstrap .navbar-themed .navbar-nav .active>.nav-link,.bootstrap .navbar-themed .navbar-nav .nav-link.active,.bootstrap .navbar-themed .navbar-nav .nav-link.show,.bootstrap .navbar-themed .navbar-nav .show>.nav-link{color:#000000e6}.bootstrap .navbar-light .navbar-toggler,.bootstrap .navbar-themed .navbar-toggler{border-color:#0000001a;color:#00000080}.bootstrap .navbar-light .navbar-toggler-icon,.bootstrap .navbar-themed .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.bootstrap .navbar-light .navbar-text,.bootstrap .navbar-themed .navbar-text{color:#00000080}.bootstrap .navbar-light .navbar-text a,.bootstrap .navbar-light .navbar-text a:focus,.bootstrap .navbar-light .navbar-text a:hover,.bootstrap .navbar-themed .navbar-text a,.bootstrap .navbar-themed .navbar-text a:focus,.bootstrap .navbar-themed .navbar-text a:hover{color:#000000e6}.bootstrap .navbar-dark .navbar-brand,.bootstrap .navbar-dark .navbar-brand:focus,.bootstrap .navbar-dark .navbar-brand:hover{color:#fff}.bootstrap .navbar-dark .navbar-nav .nav-link{color:#ffffff80}.bootstrap .navbar-dark .navbar-nav .nav-link:focus,.bootstrap .navbar-dark .navbar-nav .nav-link:hover{color:#ffffffbf}.bootstrap .navbar-dark .navbar-nav .nav-link.disabled{color:#ffffff40}.bootstrap .navbar-dark .navbar-nav .active>.nav-link,.bootstrap .navbar-dark .navbar-nav .nav-link.active,.bootstrap .navbar-dark .navbar-nav .nav-link.show,.bootstrap .navbar-dark .navbar-nav .show>.nav-link{color:#fff}.bootstrap .navbar-dark .navbar-toggler{border-color:#ffffff1a;color:#ffffff80}.bootstrap .navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.bootstrap .navbar-dark .navbar-text{color:#ffffff80}.bootstrap .navbar-dark .navbar-text a,.bootstrap .navbar-dark .navbar-text a:focus,.bootstrap .navbar-dark .navbar-text a:hover{color:#fff}.bootstrap .card{word-wrap:break-word;background-clip:initial;background-color:#fff;border:1px solid rgba(0,0,0,.125);border-radius:.25rem;display:flex;flex-direction:column;min-width:0;position:relative}.bootstrap .card>hr{margin-left:0;margin-right:0}.bootstrap .card>.list-group{border-bottom:inherit;border-top:inherit}.bootstrap .card>.list-group:first-child{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);border-top-width:0}.bootstrap .card>.list-group:last-child{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px);border-bottom-width:0}.bootstrap .card>.card-header+.list-group,.bootstrap .card>.list-group+.card-footer{border-top:0}.bootstrap .card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.bootstrap .card-title{margin-bottom:.75rem}.bootstrap .card-subtitle{margin-bottom:0;margin-top:-.375rem}.bootstrap .card-text:last-child{margin-bottom:0}.bootstrap .card-link:hover{text-decoration:none}.bootstrap .card-link+.card-link{margin-left:1.25rem}.bootstrap .card-header{background-color:#00000008;border-bottom:1px solid rgba(0,0,0,.125);margin-bottom:0;padding:.75rem 1.25rem}.bootstrap .card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.bootstrap .card-footer{background-color:#00000008;border-top:1px solid rgba(0,0,0,.125);padding:.75rem 1.25rem}.bootstrap .card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.bootstrap .card-header-tabs{border-bottom:0;margin-bottom:-.75rem}.bootstrap .card-header-pills,.bootstrap .card-header-tabs{margin-left:-.625rem;margin-right:-.625rem}.bootstrap .card-img-overlay{border-radius:calc(.25rem - 1px);bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.bootstrap .card-img,.bootstrap .card-img-bottom,.bootstrap .card-img-top{flex-shrink:0;width:100%}.bootstrap .card-img,.bootstrap .card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.bootstrap .card-img,.bootstrap .card-img-bottom{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.bootstrap .card-deck .card{margin-bottom:15px}@media(min-width:576px){.bootstrap .card-deck{display:flex;flex-flow:row wrap;margin-left:-15px;margin-right:-15px}.bootstrap .card-deck .card{flex:1 0;margin-bottom:0;margin-left:15px;margin-right:15px}}.bootstrap .card-group>.card{margin-bottom:15px}@media(min-width:576px){.bootstrap .card-group{display:flex;flex-flow:row wrap}.bootstrap .card-group>.card{flex:1 0;margin-bottom:0}.bootstrap .card-group>.card+.card{border-left:0;margin-left:0}.bootstrap .card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap .card-group>.card:not(:last-child) .card-header,.bootstrap .card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.bootstrap .card-group>.card:not(:last-child) .card-footer,.bootstrap .card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.bootstrap .card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap .card-group>.card:not(:first-child) .card-header,.bootstrap .card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.bootstrap .card-group>.card:not(:first-child) .card-footer,.bootstrap .card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.bootstrap .card-columns .card{margin-bottom:.75rem}@media(min-width:576px){.bootstrap .card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.bootstrap .card-columns .card{display:inline-block;width:100%}}.bootstrap .accordion{overflow-anchor:none}.bootstrap .accordion>.card{overflow:hidden}.bootstrap .accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap .accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.bootstrap .accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.bootstrap .breadcrumb{background-color:#e9ecef;border-radius:.25rem;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:1rem;padding:.75rem 1rem}.bootstrap .breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.bootstrap .breadcrumb-item+.breadcrumb-item:before{color:#6c757d;content:"/";float:left;padding-right:.5rem}.bootstrap .breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.bootstrap .breadcrumb-item.active{color:#6c757d}.bootstrap .pagination{border-radius:.25rem;display:flex;list-style:none;padding-left:0}.bootstrap .page-link{background-color:#fff;border:1px solid #dee2e6;color:#007bff;display:block;line-height:1.25;margin-left:-1px;padding:.5rem .75rem;position:relative}.bootstrap .page-link:hover{background-color:#e9ecef;border-color:#dee2e6;color:#0056b3;text-decoration:none;z-index:2}.bootstrap .page-link:focus{box-shadow:0 0 0 .2rem #007bff40;outline:0;z-index:3}.bootstrap .page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem;margin-left:0}.bootstrap .page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.bootstrap .page-item.active .page-link{background-color:#007bff;border-color:#007bff;color:#fff;z-index:3}.bootstrap .page-item.disabled .page-link{background-color:#fff;border-color:#dee2e6;color:#6c757d;cursor:auto;pointer-events:none}.bootstrap .pagination-lg .page-link{font-size:1.25rem;line-height:1.5;padding:.75rem 1.5rem}.bootstrap .pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.bootstrap .pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.bootstrap .pagination-sm .page-link{font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap .pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.bootstrap .pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.bootstrap .badge{border-radius:.25rem;display:inline-block;font-size:75%;font-weight:700;line-height:1;padding:.25em .4em;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:initial;white-space:nowrap}@media(prefers-reduced-motion:reduce){.bootstrap .badge{transition:none}}a.bootstrap .badge:focus,a.bootstrap .badge:hover{text-decoration:none}.bootstrap .badge:empty{display:none}.bootstrap .btn .badge{position:relative;top:-1px}.bootstrap .badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.bootstrap .badge-primary{background-color:#007bff;color:#fff}a.bootstrap .badge-primary:focus,a.bootstrap .badge-primary:hover{background-color:#0062cc;color:#fff}a.bootstrap .badge-primary.focus,a.bootstrap .badge-primary:focus{box-shadow:0 0 0 .2rem #007bff80;outline:0}.bootstrap .badge-secondary{background-color:#6c757d;color:#fff}a.bootstrap .badge-secondary:focus,a.bootstrap .badge-secondary:hover{background-color:#545b62;color:#fff}a.bootstrap .badge-secondary.focus,a.bootstrap .badge-secondary:focus{box-shadow:0 0 0 .2rem #6c757d80;outline:0}.bootstrap .badge-success{background-color:#28a745;color:#fff}a.bootstrap .badge-success:focus,a.bootstrap .badge-success:hover{background-color:#1e7e34;color:#fff}a.bootstrap .badge-success.focus,a.bootstrap .badge-success:focus{box-shadow:0 0 0 .2rem #28a74580;outline:0}.bootstrap .badge-info{background-color:#17a2b8;color:#fff}a.bootstrap .badge-info:focus,a.bootstrap .badge-info:hover{background-color:#117a8b;color:#fff}a.bootstrap .badge-info.focus,a.bootstrap .badge-info:focus{box-shadow:0 0 0 .2rem #17a2b880;outline:0}.bootstrap .badge-warning{background-color:#ffc107;color:#212529}a.bootstrap .badge-warning:focus,a.bootstrap .badge-warning:hover{background-color:#d39e00;color:#212529}a.bootstrap .badge-warning.focus,a.bootstrap .badge-warning:focus{box-shadow:0 0 0 .2rem #ffc10780;outline:0}.bootstrap .badge-danger{background-color:#dc3545;color:#fff}a.bootstrap .badge-danger:focus,a.bootstrap .badge-danger:hover{background-color:#bd2130;color:#fff}a.bootstrap .badge-danger.focus,a.bootstrap .badge-danger:focus{box-shadow:0 0 0 .2rem #dc354580;outline:0}.bootstrap .badge-light{background-color:#f8f9fa;color:#212529}a.bootstrap .badge-light:focus,a.bootstrap .badge-light:hover{background-color:#dae0e5;color:#212529}a.bootstrap .badge-light.focus,a.bootstrap .badge-light:focus{box-shadow:0 0 0 .2rem #f8f9fa80;outline:0}.bootstrap .badge-dark{background-color:#343a40;color:#fff}a.bootstrap .badge-dark:focus,a.bootstrap .badge-dark:hover{background-color:#1d2124;color:#fff}a.bootstrap .badge-dark.focus,a.bootstrap .badge-dark:focus{box-shadow:0 0 0 .2rem #343a4080;outline:0}.bootstrap .jumbotron{background-color:#e9ecef;border-radius:.3rem;margin-bottom:2rem;padding:2rem 1rem}@media(min-width:576px){.bootstrap .jumbotron{padding:4rem 2rem}}.bootstrap .jumbotron-fluid{border-radius:0;padding-left:0;padding-right:0}.bootstrap .alert{border:1px solid #0000;border-radius:.25rem;margin-bottom:1rem;padding:.75rem 1.25rem;position:relative}.bootstrap .alert-heading{color:inherit}.bootstrap .alert-link{font-weight:700}.bootstrap .alert-dismissible{padding-right:4rem}.bootstrap .alert-dismissible .close{color:inherit;padding:.75rem 1.25rem;position:absolute;right:0;top:0;z-index:2}.bootstrap .alert-primary{background-color:#cce5ff;border-color:#b8daff;color:#004085}.bootstrap .alert-primary hr{border-top-color:#9fcdff}.bootstrap .alert-primary .alert-link{color:#002752}.bootstrap .alert-secondary{background-color:#e2e3e5;border-color:#d6d8db;color:#383d41}.bootstrap .alert-secondary hr{border-top-color:#c8cbcf}.bootstrap .alert-secondary .alert-link{color:#202326}.bootstrap .alert-success{background-color:#d4edda;border-color:#c3e6cb;color:#155724}.bootstrap .alert-success hr{border-top-color:#b1dfbb}.bootstrap .alert-success .alert-link{color:#0b2e13}.bootstrap .alert-info{background-color:#d1ecf1;border-color:#bee5eb;color:#0c5460}.bootstrap .alert-info hr{border-top-color:#abdde5}.bootstrap .alert-info .alert-link{color:#062c33}.bootstrap .alert-warning{background-color:#fff3cd;border-color:#ffeeba;color:#856404}.bootstrap .alert-warning hr{border-top-color:#ffe8a1}.bootstrap .alert-warning .alert-link{color:#533f03}.bootstrap .alert-danger{background-color:#f8d7da;border-color:#f5c6cb;color:#721c24}.bootstrap .alert-danger hr{border-top-color:#f1b0b7}.bootstrap .alert-danger .alert-link{color:#491217}.bootstrap .alert-light{background-color:#fefefe;border-color:#fdfdfe;color:#818182}.bootstrap .alert-light hr{border-top-color:#ececf6}.bootstrap .alert-light .alert-link{color:#686868}.bootstrap .alert-dark{background-color:#d6d8d9;border-color:#c6c8ca;color:#1b1e21}.bootstrap .alert-dark hr{border-top-color:#b9bbbe}.bootstrap .alert-dark .alert-link{color:#040505}.bootstrap .progress{background-color:#e9ecef;border-radius:.25rem;display:flex;font-size:.75rem;height:1rem;line-height:0;overflow:hidden}.bootstrap .progress-bar{background-color:#007bff;color:#fff;display:flex;flex-direction:column;justify-content:center;overflow:hidden;text-align:center;transition:width .6s ease;white-space:nowrap}@media(prefers-reduced-motion:reduce){.bootstrap .progress-bar{transition:none}}.bootstrap .progress-bar-striped{background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-size:1rem 1rem}.bootstrap .progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media(prefers-reduced-motion:reduce){.bootstrap .progress-bar-animated{animation:none}}.bootstrap .media{align-items:flex-start;display:flex}.bootstrap .media-body{flex:1 1}.bootstrap .list-group{border-radius:.25rem;display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.bootstrap .list-group-item-action{color:#495057;text-align:inherit;width:100%}.bootstrap .list-group-item-action:focus,.bootstrap .list-group-item-action:hover{background-color:#f8f9fa;color:#495057;text-decoration:none;z-index:1}.bootstrap .list-group-item-action:active{background-color:#e9ecef;color:#212529}.bootstrap .list-group-item{background-color:#fff;border:1px solid rgba(0,0,0,.125);display:block;padding:.75rem 1.25rem;position:relative}.bootstrap .list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.bootstrap .list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.bootstrap .list-group-item.disabled,.bootstrap .list-group-item:disabled{background-color:#fff;color:#6c757d;pointer-events:none}.bootstrap .list-group-item.active{background-color:#007bff;border-color:#007bff;color:#fff;z-index:2}.bootstrap .list-group-item+.bootstrap .list-group-item{border-top-width:0}.bootstrap .list-group-item+.bootstrap .list-group-item.active{border-top-width:1px;margin-top:-1px}.bootstrap .list-group-horizontal{flex-direction:row}.bootstrap .list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap .list-group-horizontal>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap .list-group-horizontal>.list-group-item.active{margin-top:0}.bootstrap .list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap .list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}@media(min-width:576px){.bootstrap .list-group-horizontal-sm{flex-direction:row}.bootstrap .list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap .list-group-horizontal-sm>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap .list-group-horizontal-sm>.list-group-item.active{margin-top:0}.bootstrap .list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap .list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:768px){.bootstrap .list-group-horizontal-md{flex-direction:row}.bootstrap .list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap .list-group-horizontal-md>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap .list-group-horizontal-md>.list-group-item.active{margin-top:0}.bootstrap .list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap .list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:992px){.bootstrap .list-group-horizontal-lg{flex-direction:row}.bootstrap .list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap .list-group-horizontal-lg>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap .list-group-horizontal-lg>.list-group-item.active{margin-top:0}.bootstrap .list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap .list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:1200px){.bootstrap .list-group-horizontal-xl{flex-direction:row}.bootstrap .list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap .list-group-horizontal-xl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap .list-group-horizontal-xl>.list-group-item.active{margin-top:0}.bootstrap .list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap .list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}.bootstrap .list-group-flush{border-radius:0}.bootstrap .list-group-flush>.list-group-item{border-width:0 0 1px}.bootstrap .list-group-flush>.list-group-item:last-child{border-bottom-width:0}.bootstrap .list-group-item-primary{background-color:#b8daff;color:#004085}.bootstrap .list-group-item-primary.list-group-item-action:focus,.bootstrap .list-group-item-primary.list-group-item-action:hover{background-color:#9fcdff;color:#004085}.bootstrap .list-group-item-primary.list-group-item-action.active{background-color:#004085;border-color:#004085;color:#fff}.bootstrap .list-group-item-secondary{background-color:#d6d8db;color:#383d41}.bootstrap .list-group-item-secondary.list-group-item-action:focus,.bootstrap .list-group-item-secondary.list-group-item-action:hover{background-color:#c8cbcf;color:#383d41}.bootstrap .list-group-item-secondary.list-group-item-action.active{background-color:#383d41;border-color:#383d41;color:#fff}.bootstrap .list-group-item-success{background-color:#c3e6cb;color:#155724}.bootstrap .list-group-item-success.list-group-item-action:focus,.bootstrap .list-group-item-success.list-group-item-action:hover{background-color:#b1dfbb;color:#155724}.bootstrap .list-group-item-success.list-group-item-action.active{background-color:#155724;border-color:#155724;color:#fff}.bootstrap .list-group-item-info{background-color:#bee5eb;color:#0c5460}.bootstrap .list-group-item-info.list-group-item-action:focus,.bootstrap .list-group-item-info.list-group-item-action:hover{background-color:#abdde5;color:#0c5460}.bootstrap .list-group-item-info.list-group-item-action.active{background-color:#0c5460;border-color:#0c5460;color:#fff}.bootstrap .list-group-item-warning{background-color:#ffeeba;color:#856404}.bootstrap .list-group-item-warning.list-group-item-action:focus,.bootstrap .list-group-item-warning.list-group-item-action:hover{background-color:#ffe8a1;color:#856404}.bootstrap .list-group-item-warning.list-group-item-action.active{background-color:#856404;border-color:#856404;color:#fff}.bootstrap .list-group-item-danger{background-color:#f5c6cb;color:#721c24}.bootstrap .list-group-item-danger.list-group-item-action:focus,.bootstrap .list-group-item-danger.list-group-item-action:hover{background-color:#f1b0b7;color:#721c24}.bootstrap .list-group-item-danger.list-group-item-action.active{background-color:#721c24;border-color:#721c24;color:#fff}.bootstrap .list-group-item-light{background-color:#fdfdfe;color:#818182}.bootstrap .list-group-item-light.list-group-item-action:focus,.bootstrap .list-group-item-light.list-group-item-action:hover{background-color:#ececf6;color:#818182}.bootstrap .list-group-item-light.list-group-item-action.active{background-color:#818182;border-color:#818182;color:#fff}.bootstrap .list-group-item-dark{background-color:#c6c8ca;color:#1b1e21}.bootstrap .list-group-item-dark.list-group-item-action:focus,.bootstrap .list-group-item-dark.list-group-item-action:hover{background-color:#b9bbbe;color:#1b1e21}.bootstrap .list-group-item-dark.list-group-item-action.active{background-color:#1b1e21;border-color:#1b1e21;color:#fff}.bootstrap .close{color:#000;float:right;font-size:1.5rem;font-weight:700;line-height:1;opacity:.5;text-shadow:0 1px 0 #fff}.bootstrap .close:hover{color:#000;text-decoration:none}.bootstrap .close:not(:disabled):not(.disabled):focus,.bootstrap .close:not(:disabled):not(.disabled):hover{opacity:.75}.bootstrap button.close{background-color:initial;border:0;padding:0}.bootstrap a.close.disabled{pointer-events:none}.bootstrap .toast{background-clip:padding-box;background-color:#ffffffd9;border:1px solid #0000001a;border-radius:.25rem;box-shadow:0 .25rem .75rem #0000001a;flex-basis:350px;font-size:.875rem;max-width:350px;opacity:0}.bootstrap .toast:not(:last-child){margin-bottom:.75rem}.bootstrap .toast.showing{opacity:1}.bootstrap .toast.show{display:block;opacity:1}.bootstrap .toast.hide{display:none}.bootstrap .toast-header{align-items:center;background-clip:padding-box;background-color:#ffffffd9;border-bottom:1px solid #0000000d;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);color:#6c757d;display:flex;padding:.25rem .75rem}.bootstrap .toast-body{padding:.75rem}.bootstrap .modal-open{overflow:hidden}.bootstrap .modal-open .modal{overflow-x:hidden;overflow-y:auto}.bootstrap .modal{display:none;height:100%;left:0;outline:0;overflow:hidden;position:fixed;top:0;width:100%;z-index:1050}.bootstrap .modal-dialog{margin:.5rem;pointer-events:none;position:relative;width:auto}.modal.fade .bootstrap .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media(prefers-reduced-motion:reduce){.modal.fade .bootstrap .modal-dialog{transition:none}}.modal.show .bootstrap .modal-dialog{transform:none}.modal.modal-static .bootstrap .modal-dialog{transform:scale(1.02)}.bootstrap .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.bootstrap .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.bootstrap .modal-dialog-scrollable .modal-footer,.bootstrap .modal-dialog-scrollable .modal-header{flex-shrink:0}.bootstrap .modal-dialog-scrollable .modal-body{overflow-y:auto}.bootstrap .modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - 1rem)}.bootstrap .modal-dialog-centered:before{content:"";display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:min-content}.bootstrap .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;height:100%;justify-content:center}.bootstrap .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.bootstrap .modal-dialog-centered.modal-dialog-scrollable:before{content:none}.bootstrap .modal-content{background-clip:padding-box;background-color:#fff;border:1px solid #0003;border-radius:.3rem;display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.bootstrap .modal-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.bootstrap .modal-backdrop.fade{opacity:0}.bootstrap .modal-backdrop.show{opacity:.5}.bootstrap .modal-header{align-items:flex-start;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);display:flex;justify-content:space-between;padding:1rem}.bootstrap .modal-header .close{margin:-1rem -1rem -1rem auto;padding:1rem}.bootstrap .modal-title{line-height:1.5;margin-bottom:0}.bootstrap .modal-body{flex:1 1 auto;padding:1rem;position:relative}.bootstrap .modal-footer{align-items:center;border-bottom-left-radius:calc(.3rem - 1px);border-bottom-right-radius:calc(.3rem - 1px);border-top:1px solid #dee2e6;display:flex;flex-wrap:wrap;justify-content:flex-end;padding:.75rem}.bootstrap .modal-footer>*{margin:.25rem}.bootstrap .modal-scrollbar-measure{height:50px;overflow:scroll;position:absolute;top:-9999px;width:50px}@media(min-width:576px){.bootstrap .modal-dialog{margin:1.75rem auto;max-width:500px}.bootstrap .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.bootstrap .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.bootstrap .modal-dialog-centered{min-height:calc(100% - 3.5rem)}.bootstrap .modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:min-content}.bootstrap .modal-sm{max-width:300px}}@media(min-width:992px){.bootstrap .modal-lg,.bootstrap .modal-xl{max-width:800px}}@media(min-width:1200px){.bootstrap .modal-xl{max-width:1140px}}.bootstrap .tooltip{word-wrap:break-word;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.875rem;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:0;opacity:0;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:1070}.bootstrap .tooltip.show{opacity:.9}.bootstrap .tooltip .arrow{display:block;height:.4rem;position:absolute;width:.8rem}.bootstrap .tooltip .arrow:before{border-color:#0000;border-style:solid;content:"";position:absolute}.bootstrap .bs-tooltip-auto[x-placement^=top],.bootstrap .bs-tooltip-top{padding:.4rem 0}.bootstrap .bs-tooltip-auto[x-placement^=top] .arrow,.bootstrap .bs-tooltip-top .arrow{bottom:0}.bootstrap .bs-tooltip-auto[x-placement^=top] .arrow:before,.bootstrap .bs-tooltip-top .arrow:before{border-top-color:#000;border-width:.4rem .4rem 0;top:0}.bootstrap .bs-tooltip-auto[x-placement^=right],.bootstrap .bs-tooltip-right{padding:0 .4rem}.bootstrap .bs-tooltip-auto[x-placement^=right] .arrow,.bootstrap .bs-tooltip-right .arrow{height:.8rem;left:0;width:.4rem}.bootstrap .bs-tooltip-auto[x-placement^=right] .arrow:before,.bootstrap .bs-tooltip-right .arrow:before{border-right-color:#000;border-width:.4rem .4rem .4rem 0;right:0}.bootstrap .bs-tooltip-auto[x-placement^=bottom],.bootstrap .bs-tooltip-bottom{padding:.4rem 0}.bootstrap .bs-tooltip-auto[x-placement^=bottom] .arrow,.bootstrap .bs-tooltip-bottom .arrow{top:0}.bootstrap .bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bootstrap .bs-tooltip-bottom .arrow:before{border-bottom-color:#000;border-width:0 .4rem .4rem;bottom:0}.bootstrap .bs-tooltip-auto[x-placement^=left],.bootstrap .bs-tooltip-left{padding:0 .4rem}.bootstrap .bs-tooltip-auto[x-placement^=left] .arrow,.bootstrap .bs-tooltip-left .arrow{height:.8rem;right:0;width:.4rem}.bootstrap .bs-tooltip-auto[x-placement^=left] .arrow:before,.bootstrap .bs-tooltip-left .arrow:before{border-left-color:#000;border-width:.4rem 0 .4rem .4rem;left:0}.bootstrap .tooltip-inner{background-color:#000;border-radius:.25rem;color:#fff;max-width:200px;padding:.25rem .5rem;text-align:center}.bootstrap .popover{word-wrap:break-word;background-clip:padding-box;background-color:#fff;border:1px solid #0003;border-radius:.3rem;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.875rem;font-style:normal;font-weight:400;left:0;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:276px;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;top:0;white-space:normal;word-break:normal;word-spacing:normal;z-index:1060}.bootstrap .popover .arrow{display:block;height:.5rem;margin:0 .3rem;position:absolute;width:1rem}.bootstrap .popover .arrow:after,.bootstrap .popover .arrow:before{border-color:#0000;border-style:solid;content:"";display:block;position:absolute}.bootstrap .bs-popover-auto[x-placement^=top],.bootstrap .bs-popover-top{margin-bottom:.5rem}.bootstrap .bs-popover-auto[x-placement^=top]>.arrow,.bootstrap .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bootstrap .bs-popover-auto[x-placement^=top]>.arrow:before,.bootstrap .bs-popover-top>.arrow:before{border-top-color:#00000040;border-width:.5rem .5rem 0;bottom:0}.bootstrap .bs-popover-auto[x-placement^=top]>.arrow:after,.bootstrap .bs-popover-top>.arrow:after{border-top-color:#fff;border-width:.5rem .5rem 0;bottom:1px}.bootstrap .bs-popover-auto[x-placement^=right],.bootstrap .bs-popover-right{margin-left:.5rem}.bootstrap .bs-popover-auto[x-placement^=right]>.arrow,.bootstrap .bs-popover-right>.arrow{height:1rem;left:calc(-.5rem - 1px);margin:.3rem 0;width:.5rem}.bootstrap .bs-popover-auto[x-placement^=right]>.arrow:before,.bootstrap .bs-popover-right>.arrow:before{border-right-color:#00000040;border-width:.5rem .5rem .5rem 0;left:0}.bootstrap .bs-popover-auto[x-placement^=right]>.arrow:after,.bootstrap .bs-popover-right>.arrow:after{border-right-color:#fff;border-width:.5rem .5rem .5rem 0;left:1px}.bootstrap .bs-popover-auto[x-placement^=bottom],.bootstrap .bs-popover-bottom{margin-top:.5rem}.bootstrap .bs-popover-auto[x-placement^=bottom]>.arrow,.bootstrap .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bootstrap .bs-popover-auto[x-placement^=bottom]>.arrow:before,.bootstrap .bs-popover-bottom>.arrow:before{border-bottom-color:#00000040;border-width:0 .5rem .5rem;top:0}.bootstrap .bs-popover-auto[x-placement^=bottom]>.arrow:after,.bootstrap .bs-popover-bottom>.arrow:after{border-bottom-color:#fff;border-width:0 .5rem .5rem;top:1px}.bootstrap .bs-popover-auto[x-placement^=bottom] .popover-header:before,.bootstrap .bs-popover-bottom .popover-header:before{border-bottom:1px solid #f7f7f7;content:"";display:block;left:50%;margin-left:-.5rem;position:absolute;top:0;width:1rem}.bootstrap .bs-popover-auto[x-placement^=left],.bootstrap .bs-popover-left{margin-right:.5rem}.bootstrap .bs-popover-auto[x-placement^=left]>.arrow,.bootstrap .bs-popover-left>.arrow{height:1rem;margin:.3rem 0;right:calc(-.5rem - 1px);width:.5rem}.bootstrap .bs-popover-auto[x-placement^=left]>.arrow:before,.bootstrap .bs-popover-left>.arrow:before{border-left-color:#00000040;border-width:.5rem 0 .5rem .5rem;right:0}.bootstrap .bs-popover-auto[x-placement^=left]>.arrow:after,.bootstrap .bs-popover-left>.arrow:after{border-left-color:#fff;border-width:.5rem 0 .5rem .5rem;right:1px}.bootstrap .popover-header{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);font-size:1rem;margin-bottom:0;padding:.5rem .75rem}.bootstrap .popover-header:empty{display:none}.bootstrap .popover-body{color:#212529;padding:.5rem .75rem}.bootstrap .carousel{position:relative}.bootstrap .carousel.pointer-event{touch-action:pan-y}.bootstrap .carousel-inner{overflow:hidden;position:relative;width:100%}.bootstrap .carousel-inner:after{clear:both;content:"";display:block}.bootstrap .carousel-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.bootstrap .carousel-item{transition:none}}.bootstrap .carousel-item-next,.bootstrap .carousel-item-prev,.bootstrap .carousel-item.active{display:block}.bootstrap .active.carousel-item-right,.bootstrap .carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.bootstrap .active.carousel-item-left,.bootstrap .carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.bootstrap .carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.bootstrap .carousel-fade .carousel-item-next.carousel-item-left,.bootstrap .carousel-fade .carousel-item-prev.carousel-item-right,.bootstrap .carousel-fade .carousel-item.active{opacity:1;z-index:1}.bootstrap .carousel-fade .active.carousel-item-left,.bootstrap .carousel-fade .active.carousel-item-right{opacity:0;transition:opacity 0s .6s;z-index:0}@media(prefers-reduced-motion:reduce){.bootstrap .carousel-fade .active.carousel-item-left,.bootstrap .carousel-fade .active.carousel-item-right{transition:none}}.bootstrap .carousel-control-next,.bootstrap .carousel-control-prev{align-items:center;background:none;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media(prefers-reduced-motion:reduce){.bootstrap .carousel-control-next,.bootstrap .carousel-control-prev{transition:none}}.bootstrap .carousel-control-next:focus,.bootstrap .carousel-control-next:hover,.bootstrap .carousel-control-prev:focus,.bootstrap .carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.bootstrap .carousel-control-prev{left:0}.bootstrap .carousel-control-next{right:0}.bootstrap .carousel-control-next-icon,.bootstrap .carousel-control-prev-icon{background:50%/100% 100% no-repeat;display:inline-block;height:20px;width:20px}.bootstrap .carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m5.25 0-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.bootstrap .carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m2.75 0-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.bootstrap .carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-left:15%;margin-right:15%;padding-left:0;position:absolute;right:0;z-index:15}.bootstrap .carousel-indicators li{background-clip:padding-box;background-color:#fff;border-bottom:10px solid #0000;border-top:10px solid #0000;box-sizing:initial;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;text-indent:-999px;transition:opacity .6s ease;width:30px}@media(prefers-reduced-motion:reduce){.bootstrap .carousel-indicators li{transition:none}}.bootstrap .carousel-indicators .active{opacity:1}.bootstrap .carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;z-index:10}.bootstrap .spinner-border{animation:spinner-border .75s linear infinite;border:.25em solid;border-radius:50%;border-right:.25em solid #0000;display:inline-block;height:2rem;vertical-align:-.125em;width:2rem}.bootstrap .spinner-border-sm{border-width:.2em;height:1rem;width:1rem}.bootstrap .spinner-grow{animation:spinner-grow .75s linear infinite;background-color:currentColor;border-radius:50%;display:inline-block;height:2rem;opacity:0;vertical-align:-.125em;width:2rem}.bootstrap .spinner-grow-sm{height:1rem;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap .spinner-border,.bootstrap .spinner-grow{animation-duration:1.5s}}.bootstrap .align-baseline{vertical-align:initial!important}.bootstrap .align-top{vertical-align:top!important}.bootstrap .align-middle{vertical-align:middle!important}.bootstrap .align-bottom{vertical-align:bottom!important}.bootstrap .align-text-bottom{vertical-align:text-bottom!important}.bootstrap .align-text-top{vertical-align:text-top!important}.bootstrap .bg-primary{background-color:#007bff!important}.bootstrap a.bg-primary:focus,.bootstrap a.bg-primary:hover,.bootstrap button.bg-primary:focus,.bootstrap button.bg-primary:hover{background-color:#0062cc!important}.bootstrap .bg-secondary{background-color:#6c757d!important}.bootstrap a.bg-secondary:focus,.bootstrap a.bg-secondary:hover,.bootstrap button.bg-secondary:focus,.bootstrap button.bg-secondary:hover{background-color:#545b62!important}.bootstrap .bg-success{background-color:#28a745!important}.bootstrap a.bg-success:focus,.bootstrap a.bg-success:hover,.bootstrap button.bg-success:focus,.bootstrap button.bg-success:hover{background-color:#1e7e34!important}.bootstrap .bg-info{background-color:#17a2b8!important}.bootstrap a.bg-info:focus,.bootstrap a.bg-info:hover,.bootstrap button.bg-info:focus,.bootstrap button.bg-info:hover{background-color:#117a8b!important}.bootstrap .bg-warning{background-color:#ffc107!important}.bootstrap a.bg-warning:focus,.bootstrap a.bg-warning:hover,.bootstrap button.bg-warning:focus,.bootstrap button.bg-warning:hover{background-color:#d39e00!important}.bootstrap .bg-danger{background-color:#dc3545!important}.bootstrap a.bg-danger:focus,.bootstrap a.bg-danger:hover,.bootstrap button.bg-danger:focus,.bootstrap button.bg-danger:hover{background-color:#bd2130!important}.bootstrap .bg-light,.bootstrap .navbar-themed{background-color:#f8f9fa!important}.bootstrap a.bg-light:focus,.bootstrap a.bg-light:hover,.bootstrap a.navbar-themed:focus,.bootstrap a.navbar-themed:hover,.bootstrap button.bg-light:focus,.bootstrap button.bg-light:hover,.bootstrap button.navbar-themed:focus,.bootstrap button.navbar-themed:hover{background-color:#dae0e5!important}.bootstrap .bg-dark{background-color:#343a40!important}.bootstrap a.bg-dark:focus,.bootstrap a.bg-dark:hover,.bootstrap button.bg-dark:focus,.bootstrap button.bg-dark:hover{background-color:#1d2124!important}.bootstrap .bg-white{background-color:#fff!important}.bootstrap .bg-transparent{background-color:initial!important}.bootstrap .border{border:1px solid #dee2e6!important}.bootstrap .border-top{border-top:1px solid #dee2e6!important}.bootstrap .border-right{border-right:1px solid #dee2e6!important}.bootstrap .border-bottom{border-bottom:1px solid #dee2e6!important}.bootstrap .border-left{border-left:1px solid #dee2e6!important}.bootstrap .border-0{border:0!important}.bootstrap .border-top-0{border-top:0!important}.bootstrap .border-right-0{border-right:0!important}.bootstrap .border-bottom-0{border-bottom:0!important}.bootstrap .border-left-0{border-left:0!important}.bootstrap .border-primary{border-color:#007bff!important}.bootstrap .border-secondary{border-color:#6c757d!important}.bootstrap .border-success{border-color:#28a745!important}.bootstrap .border-info{border-color:#17a2b8!important}.bootstrap .border-warning{border-color:#ffc107!important}.bootstrap .border-danger{border-color:#dc3545!important}.bootstrap .border-light{border-color:#f8f9fa!important}.bootstrap .border-dark{border-color:#343a40!important}.bootstrap .border-white{border-color:#fff!important}.bootstrap .rounded-sm{border-radius:.2rem!important}.bootstrap .rounded{border-radius:.25rem!important}.bootstrap .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.bootstrap .rounded-right{border-bottom-right-radius:.25rem!important;border-top-right-radius:.25rem!important}.bootstrap .rounded-bottom{border-bottom-left-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.bootstrap .rounded-left{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.bootstrap .rounded-lg{border-radius:.3rem!important}.bootstrap .rounded-circle{border-radius:50%!important}.bootstrap .rounded-pill{border-radius:50rem!important}.bootstrap .rounded-0{border-radius:0!important}.bootstrap .clearfix:after{clear:both;content:"";display:block}.bootstrap .d-none{display:none!important}.bootstrap .d-inline{display:inline!important}.bootstrap .d-inline-block{display:inline-block!important}.bootstrap .d-block{display:block!important}.bootstrap .d-table{display:table!important}.bootstrap .d-table-row{display:table-row!important}.bootstrap .d-table-cell{display:table-cell!important}.bootstrap .d-flex{display:flex!important}.bootstrap .d-inline-flex{display:inline-flex!important}@media(min-width:576px){.bootstrap .d-sm-none{display:none!important}.bootstrap .d-sm-inline{display:inline!important}.bootstrap .d-sm-inline-block{display:inline-block!important}.bootstrap .d-sm-block{display:block!important}.bootstrap .d-sm-table{display:table!important}.bootstrap .d-sm-table-row{display:table-row!important}.bootstrap .d-sm-table-cell{display:table-cell!important}.bootstrap .d-sm-flex{display:flex!important}.bootstrap .d-sm-inline-flex{display:inline-flex!important}}@media(min-width:768px){.bootstrap .d-md-none{display:none!important}.bootstrap .d-md-inline{display:inline!important}.bootstrap .d-md-inline-block{display:inline-block!important}.bootstrap .d-md-block{display:block!important}.bootstrap .d-md-table{display:table!important}.bootstrap .d-md-table-row{display:table-row!important}.bootstrap .d-md-table-cell{display:table-cell!important}.bootstrap .d-md-flex{display:flex!important}.bootstrap .d-md-inline-flex{display:inline-flex!important}}@media(min-width:992px){.bootstrap .d-lg-none{display:none!important}.bootstrap .d-lg-inline{display:inline!important}.bootstrap .d-lg-inline-block{display:inline-block!important}.bootstrap .d-lg-block{display:block!important}.bootstrap .d-lg-table{display:table!important}.bootstrap .d-lg-table-row{display:table-row!important}.bootstrap .d-lg-table-cell{display:table-cell!important}.bootstrap .d-lg-flex{display:flex!important}.bootstrap .d-lg-inline-flex{display:inline-flex!important}}@media(min-width:1200px){.bootstrap .d-xl-none{display:none!important}.bootstrap .d-xl-inline{display:inline!important}.bootstrap .d-xl-inline-block{display:inline-block!important}.bootstrap .d-xl-block{display:block!important}.bootstrap .d-xl-table{display:table!important}.bootstrap .d-xl-table-row{display:table-row!important}.bootstrap .d-xl-table-cell{display:table-cell!important}.bootstrap .d-xl-flex{display:flex!important}.bootstrap .d-xl-inline-flex{display:inline-flex!important}}@media print{.bootstrap .d-print-none{display:none!important}.bootstrap .d-print-inline{display:inline!important}.bootstrap .d-print-inline-block{display:inline-block!important}.bootstrap .d-print-block{display:block!important}.bootstrap .d-print-table{display:table!important}.bootstrap .d-print-table-row{display:table-row!important}.bootstrap .d-print-table-cell{display:table-cell!important}.bootstrap .d-print-flex{display:flex!important}.bootstrap .d-print-inline-flex{display:inline-flex!important}}.bootstrap .embed-responsive{display:block;overflow:hidden;padding:0;position:relative;width:100%}.bootstrap .embed-responsive:before{content:"";display:block}.bootstrap .embed-responsive .embed-responsive-item,.bootstrap .embed-responsive embed,.bootstrap .embed-responsive iframe,.bootstrap .embed-responsive object,.bootstrap .embed-responsive video{border:0;bottom:0;height:100%;left:0;position:absolute;top:0;width:100%}.bootstrap .embed-responsive-21by9:before{padding-top:42.85714286%}.bootstrap .embed-responsive-16by9:before{padding-top:56.25%}.bootstrap .embed-responsive-4by3:before{padding-top:75%}.bootstrap .embed-responsive-1by1:before{padding-top:100%}.bootstrap .flex-row{flex-direction:row!important}.bootstrap .flex-column{flex-direction:column!important}.bootstrap .flex-row-reverse{flex-direction:row-reverse!important}.bootstrap .flex-column-reverse{flex-direction:column-reverse!important}.bootstrap .flex-wrap{flex-wrap:wrap!important}.bootstrap .flex-nowrap{flex-wrap:nowrap!important}.bootstrap .flex-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap .flex-fill{flex:1 1 auto!important}.bootstrap .flex-grow-0{flex-grow:0!important}.bootstrap .flex-grow-1{flex-grow:1!important}.bootstrap .flex-shrink-0{flex-shrink:0!important}.bootstrap .flex-shrink-1{flex-shrink:1!important}.bootstrap .justify-content-start{justify-content:flex-start!important}.bootstrap .justify-content-end{justify-content:flex-end!important}.bootstrap .justify-content-center{justify-content:center!important}.bootstrap .justify-content-between{justify-content:space-between!important}.bootstrap .justify-content-around{justify-content:space-around!important}.bootstrap .align-items-start{align-items:flex-start!important}.bootstrap .align-items-end{align-items:flex-end!important}.bootstrap .align-items-center{align-items:center!important}.bootstrap .align-items-baseline{align-items:baseline!important}.bootstrap .align-items-stretch{align-items:stretch!important}.bootstrap .align-content-start{align-content:flex-start!important}.bootstrap .align-content-end{align-content:flex-end!important}.bootstrap .align-content-center{align-content:center!important}.bootstrap .align-content-between{align-content:space-between!important}.bootstrap .align-content-around{align-content:space-around!important}.bootstrap .align-content-stretch{align-content:stretch!important}.bootstrap .align-self-auto{align-self:auto!important}.bootstrap .align-self-start{align-self:flex-start!important}.bootstrap .align-self-end{align-self:flex-end!important}.bootstrap .align-self-center{align-self:center!important}.bootstrap .align-self-baseline{align-self:baseline!important}.bootstrap .align-self-stretch{align-self:stretch!important}@media(min-width:576px){.bootstrap .flex-sm-row{flex-direction:row!important}.bootstrap .flex-sm-column{flex-direction:column!important}.bootstrap .flex-sm-row-reverse{flex-direction:row-reverse!important}.bootstrap .flex-sm-column-reverse{flex-direction:column-reverse!important}.bootstrap .flex-sm-wrap{flex-wrap:wrap!important}.bootstrap .flex-sm-nowrap{flex-wrap:nowrap!important}.bootstrap .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap .flex-sm-fill{flex:1 1 auto!important}.bootstrap .flex-sm-grow-0{flex-grow:0!important}.bootstrap .flex-sm-grow-1{flex-grow:1!important}.bootstrap .flex-sm-shrink-0{flex-shrink:0!important}.bootstrap .flex-sm-shrink-1{flex-shrink:1!important}.bootstrap .justify-content-sm-start{justify-content:flex-start!important}.bootstrap .justify-content-sm-end{justify-content:flex-end!important}.bootstrap .justify-content-sm-center{justify-content:center!important}.bootstrap .justify-content-sm-between{justify-content:space-between!important}.bootstrap .justify-content-sm-around{justify-content:space-around!important}.bootstrap .align-items-sm-start{align-items:flex-start!important}.bootstrap .align-items-sm-end{align-items:flex-end!important}.bootstrap .align-items-sm-center{align-items:center!important}.bootstrap .align-items-sm-baseline{align-items:baseline!important}.bootstrap .align-items-sm-stretch{align-items:stretch!important}.bootstrap .align-content-sm-start{align-content:flex-start!important}.bootstrap .align-content-sm-end{align-content:flex-end!important}.bootstrap .align-content-sm-center{align-content:center!important}.bootstrap .align-content-sm-between{align-content:space-between!important}.bootstrap .align-content-sm-around{align-content:space-around!important}.bootstrap .align-content-sm-stretch{align-content:stretch!important}.bootstrap .align-self-sm-auto{align-self:auto!important}.bootstrap .align-self-sm-start{align-self:flex-start!important}.bootstrap .align-self-sm-end{align-self:flex-end!important}.bootstrap .align-self-sm-center{align-self:center!important}.bootstrap .align-self-sm-baseline{align-self:baseline!important}.bootstrap .align-self-sm-stretch{align-self:stretch!important}}@media(min-width:768px){.bootstrap .flex-md-row{flex-direction:row!important}.bootstrap .flex-md-column{flex-direction:column!important}.bootstrap .flex-md-row-reverse{flex-direction:row-reverse!important}.bootstrap .flex-md-column-reverse{flex-direction:column-reverse!important}.bootstrap .flex-md-wrap{flex-wrap:wrap!important}.bootstrap .flex-md-nowrap{flex-wrap:nowrap!important}.bootstrap .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap .flex-md-fill{flex:1 1 auto!important}.bootstrap .flex-md-grow-0{flex-grow:0!important}.bootstrap .flex-md-grow-1{flex-grow:1!important}.bootstrap .flex-md-shrink-0{flex-shrink:0!important}.bootstrap .flex-md-shrink-1{flex-shrink:1!important}.bootstrap .justify-content-md-start{justify-content:flex-start!important}.bootstrap .justify-content-md-end{justify-content:flex-end!important}.bootstrap .justify-content-md-center{justify-content:center!important}.bootstrap .justify-content-md-between{justify-content:space-between!important}.bootstrap .justify-content-md-around{justify-content:space-around!important}.bootstrap .align-items-md-start{align-items:flex-start!important}.bootstrap .align-items-md-end{align-items:flex-end!important}.bootstrap .align-items-md-center{align-items:center!important}.bootstrap .align-items-md-baseline{align-items:baseline!important}.bootstrap .align-items-md-stretch{align-items:stretch!important}.bootstrap .align-content-md-start{align-content:flex-start!important}.bootstrap .align-content-md-end{align-content:flex-end!important}.bootstrap .align-content-md-center{align-content:center!important}.bootstrap .align-content-md-between{align-content:space-between!important}.bootstrap .align-content-md-around{align-content:space-around!important}.bootstrap .align-content-md-stretch{align-content:stretch!important}.bootstrap .align-self-md-auto{align-self:auto!important}.bootstrap .align-self-md-start{align-self:flex-start!important}.bootstrap .align-self-md-end{align-self:flex-end!important}.bootstrap .align-self-md-center{align-self:center!important}.bootstrap .align-self-md-baseline{align-self:baseline!important}.bootstrap .align-self-md-stretch{align-self:stretch!important}}@media(min-width:992px){.bootstrap .flex-lg-row{flex-direction:row!important}.bootstrap .flex-lg-column{flex-direction:column!important}.bootstrap .flex-lg-row-reverse{flex-direction:row-reverse!important}.bootstrap .flex-lg-column-reverse{flex-direction:column-reverse!important}.bootstrap .flex-lg-wrap{flex-wrap:wrap!important}.bootstrap .flex-lg-nowrap{flex-wrap:nowrap!important}.bootstrap .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap .flex-lg-fill{flex:1 1 auto!important}.bootstrap .flex-lg-grow-0{flex-grow:0!important}.bootstrap .flex-lg-grow-1{flex-grow:1!important}.bootstrap .flex-lg-shrink-0{flex-shrink:0!important}.bootstrap .flex-lg-shrink-1{flex-shrink:1!important}.bootstrap .justify-content-lg-start{justify-content:flex-start!important}.bootstrap .justify-content-lg-end{justify-content:flex-end!important}.bootstrap .justify-content-lg-center{justify-content:center!important}.bootstrap .justify-content-lg-between{justify-content:space-between!important}.bootstrap .justify-content-lg-around{justify-content:space-around!important}.bootstrap .align-items-lg-start{align-items:flex-start!important}.bootstrap .align-items-lg-end{align-items:flex-end!important}.bootstrap .align-items-lg-center{align-items:center!important}.bootstrap .align-items-lg-baseline{align-items:baseline!important}.bootstrap .align-items-lg-stretch{align-items:stretch!important}.bootstrap .align-content-lg-start{align-content:flex-start!important}.bootstrap .align-content-lg-end{align-content:flex-end!important}.bootstrap .align-content-lg-center{align-content:center!important}.bootstrap .align-content-lg-between{align-content:space-between!important}.bootstrap .align-content-lg-around{align-content:space-around!important}.bootstrap .align-content-lg-stretch{align-content:stretch!important}.bootstrap .align-self-lg-auto{align-self:auto!important}.bootstrap .align-self-lg-start{align-self:flex-start!important}.bootstrap .align-self-lg-end{align-self:flex-end!important}.bootstrap .align-self-lg-center{align-self:center!important}.bootstrap .align-self-lg-baseline{align-self:baseline!important}.bootstrap .align-self-lg-stretch{align-self:stretch!important}}@media(min-width:1200px){.bootstrap .flex-xl-row{flex-direction:row!important}.bootstrap .flex-xl-column{flex-direction:column!important}.bootstrap .flex-xl-row-reverse{flex-direction:row-reverse!important}.bootstrap .flex-xl-column-reverse{flex-direction:column-reverse!important}.bootstrap .flex-xl-wrap{flex-wrap:wrap!important}.bootstrap .flex-xl-nowrap{flex-wrap:nowrap!important}.bootstrap .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap .flex-xl-fill{flex:1 1 auto!important}.bootstrap .flex-xl-grow-0{flex-grow:0!important}.bootstrap .flex-xl-grow-1{flex-grow:1!important}.bootstrap .flex-xl-shrink-0{flex-shrink:0!important}.bootstrap .flex-xl-shrink-1{flex-shrink:1!important}.bootstrap .justify-content-xl-start{justify-content:flex-start!important}.bootstrap .justify-content-xl-end{justify-content:flex-end!important}.bootstrap .justify-content-xl-center{justify-content:center!important}.bootstrap .justify-content-xl-between{justify-content:space-between!important}.bootstrap .justify-content-xl-around{justify-content:space-around!important}.bootstrap .align-items-xl-start{align-items:flex-start!important}.bootstrap .align-items-xl-end{align-items:flex-end!important}.bootstrap .align-items-xl-center{align-items:center!important}.bootstrap .align-items-xl-baseline{align-items:baseline!important}.bootstrap .align-items-xl-stretch{align-items:stretch!important}.bootstrap .align-content-xl-start{align-content:flex-start!important}.bootstrap .align-content-xl-end{align-content:flex-end!important}.bootstrap .align-content-xl-center{align-content:center!important}.bootstrap .align-content-xl-between{align-content:space-between!important}.bootstrap .align-content-xl-around{align-content:space-around!important}.bootstrap .align-content-xl-stretch{align-content:stretch!important}.bootstrap .align-self-xl-auto{align-self:auto!important}.bootstrap .align-self-xl-start{align-self:flex-start!important}.bootstrap .align-self-xl-end{align-self:flex-end!important}.bootstrap .align-self-xl-center{align-self:center!important}.bootstrap .align-self-xl-baseline{align-self:baseline!important}.bootstrap .align-self-xl-stretch{align-self:stretch!important}}.bootstrap .float-left{float:left!important}.bootstrap .float-right{float:right!important}.bootstrap .float-none{float:none!important}@media(min-width:576px){.bootstrap .float-sm-left{float:left!important}.bootstrap .float-sm-right{float:right!important}.bootstrap .float-sm-none{float:none!important}}@media(min-width:768px){.bootstrap .float-md-left{float:left!important}.bootstrap .float-md-right{float:right!important}.bootstrap .float-md-none{float:none!important}}@media(min-width:992px){.bootstrap .float-lg-left{float:left!important}.bootstrap .float-lg-right{float:right!important}.bootstrap .float-lg-none{float:none!important}}@media(min-width:1200px){.bootstrap .float-xl-left{float:left!important}.bootstrap .float-xl-right{float:right!important}.bootstrap .float-xl-none{float:none!important}}.bootstrap .user-select-all{-webkit-user-select:all!important;user-select:all!important}.bootstrap .user-select-auto{-webkit-user-select:auto!important;user-select:auto!important}.bootstrap .user-select-none{-webkit-user-select:none!important;user-select:none!important}.bootstrap .overflow-auto{overflow:auto!important}.bootstrap .overflow-hidden{overflow:hidden!important}.bootstrap .position-static{position:static!important}.bootstrap .position-relative{position:relative!important}.bootstrap .position-absolute{position:absolute!important}.bootstrap .position-fixed{position:fixed!important}.bootstrap .position-sticky{position:-webkit-sticky!important;position:sticky!important}.bootstrap .fixed-top{left:0;position:fixed;right:0;top:0;z-index:1030}.bootstrap .fixed-bottom{bottom:0;left:0;position:fixed;right:0;z-index:1030}@supports((position:-webkit-sticky) or (position:sticky)){.bootstrap .sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.bootstrap .sr-only{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.bootstrap .sr-only-focusable:active,.bootstrap .sr-only-focusable:focus{clip:auto;height:auto;overflow:visible;position:static;white-space:normal;width:auto}.bootstrap .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.bootstrap .shadow{box-shadow:0 .5rem 1rem #00000026!important}.bootstrap .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.bootstrap .shadow-none{box-shadow:none!important}.bootstrap .w-25{width:25%!important}.bootstrap .w-50{width:50%!important}.bootstrap .w-75{width:75%!important}.bootstrap .w-100{width:100%!important}.bootstrap .w-auto{width:auto!important}.bootstrap .h-25{height:25%!important}.bootstrap .h-50{height:50%!important}.bootstrap .h-75{height:75%!important}.bootstrap .h-100{height:100%!important}.bootstrap .h-auto{height:auto!important}.bootstrap .mw-100{max-width:100%!important}.bootstrap .mh-100{max-height:100%!important}.bootstrap .min-vw-100{min-width:100vw!important}.bootstrap .min-vh-100{min-height:100vh!important}.bootstrap .vw-100{width:100vw!important}.bootstrap .vh-100{height:100vh!important}.bootstrap .m-0{margin:0!important}.bootstrap .mt-0,.bootstrap .my-0{margin-top:0!important}.bootstrap .mr-0,.bootstrap .mx-0{margin-right:0!important}.bootstrap .mb-0,.bootstrap .my-0{margin-bottom:0!important}.bootstrap .ml-0,.bootstrap .mx-0{margin-left:0!important}.bootstrap .m-1{margin:.25rem!important}.bootstrap .mt-1,.bootstrap .my-1{margin-top:.25rem!important}.bootstrap .mr-1,.bootstrap .mx-1{margin-right:.25rem!important}.bootstrap .mb-1,.bootstrap .my-1{margin-bottom:.25rem!important}.bootstrap .ml-1,.bootstrap .mx-1{margin-left:.25rem!important}.bootstrap .m-2{margin:.5rem!important}.bootstrap .mt-2,.bootstrap .my-2{margin-top:.5rem!important}.bootstrap .mr-2,.bootstrap .mx-2{margin-right:.5rem!important}.bootstrap .mb-2,.bootstrap .my-2{margin-bottom:.5rem!important}.bootstrap .ml-2,.bootstrap .mx-2{margin-left:.5rem!important}.bootstrap .m-3{margin:1rem!important}.bootstrap .mt-3,.bootstrap .my-3{margin-top:1rem!important}.bootstrap .mr-3,.bootstrap .mx-3{margin-right:1rem!important}.bootstrap .mb-3,.bootstrap .my-3{margin-bottom:1rem!important}.bootstrap .ml-3,.bootstrap .mx-3{margin-left:1rem!important}.bootstrap .m-4{margin:1.5rem!important}.bootstrap .mt-4,.bootstrap .my-4{margin-top:1.5rem!important}.bootstrap .mr-4,.bootstrap .mx-4{margin-right:1.5rem!important}.bootstrap .mb-4,.bootstrap .my-4{margin-bottom:1.5rem!important}.bootstrap .ml-4,.bootstrap .mx-4{margin-left:1.5rem!important}.bootstrap .m-5{margin:3rem!important}.bootstrap .mt-5,.bootstrap .my-5{margin-top:3rem!important}.bootstrap .mr-5,.bootstrap .mx-5{margin-right:3rem!important}.bootstrap .mb-5,.bootstrap .my-5{margin-bottom:3rem!important}.bootstrap .ml-5,.bootstrap .mx-5{margin-left:3rem!important}.bootstrap .p-0{padding:0!important}.bootstrap .pt-0,.bootstrap .py-0{padding-top:0!important}.bootstrap .pr-0,.bootstrap .px-0{padding-right:0!important}.bootstrap .pb-0,.bootstrap .py-0{padding-bottom:0!important}.bootstrap .pl-0,.bootstrap .px-0{padding-left:0!important}.bootstrap .p-1{padding:.25rem!important}.bootstrap .pt-1,.bootstrap .py-1{padding-top:.25rem!important}.bootstrap .pr-1,.bootstrap .px-1{padding-right:.25rem!important}.bootstrap .pb-1,.bootstrap .py-1{padding-bottom:.25rem!important}.bootstrap .pl-1,.bootstrap .px-1{padding-left:.25rem!important}.bootstrap .p-2{padding:.5rem!important}.bootstrap .pt-2,.bootstrap .py-2{padding-top:.5rem!important}.bootstrap .pr-2,.bootstrap .px-2{padding-right:.5rem!important}.bootstrap .pb-2,.bootstrap .py-2{padding-bottom:.5rem!important}.bootstrap .pl-2,.bootstrap .px-2{padding-left:.5rem!important}.bootstrap .p-3{padding:1rem!important}.bootstrap .pt-3,.bootstrap .py-3{padding-top:1rem!important}.bootstrap .pr-3,.bootstrap .px-3{padding-right:1rem!important}.bootstrap .pb-3,.bootstrap .py-3{padding-bottom:1rem!important}.bootstrap .pl-3,.bootstrap .px-3{padding-left:1rem!important}.bootstrap .p-4{padding:1.5rem!important}.bootstrap .pt-4,.bootstrap .py-4{padding-top:1.5rem!important}.bootstrap .pr-4,.bootstrap .px-4{padding-right:1.5rem!important}.bootstrap .pb-4,.bootstrap .py-4{padding-bottom:1.5rem!important}.bootstrap .pl-4,.bootstrap .px-4{padding-left:1.5rem!important}.bootstrap .p-5{padding:3rem!important}.bootstrap .pt-5,.bootstrap .py-5{padding-top:3rem!important}.bootstrap .pr-5,.bootstrap .px-5{padding-right:3rem!important}.bootstrap .pb-5,.bootstrap .py-5{padding-bottom:3rem!important}.bootstrap .pl-5,.bootstrap .px-5{padding-left:3rem!important}.bootstrap .m-n1{margin:-.25rem!important}.bootstrap .mt-n1,.bootstrap .my-n1{margin-top:-.25rem!important}.bootstrap .mr-n1,.bootstrap .mx-n1{margin-right:-.25rem!important}.bootstrap .mb-n1,.bootstrap .my-n1{margin-bottom:-.25rem!important}.bootstrap .ml-n1,.bootstrap .mx-n1{margin-left:-.25rem!important}.bootstrap .m-n2{margin:-.5rem!important}.bootstrap .mt-n2,.bootstrap .my-n2{margin-top:-.5rem!important}.bootstrap .mr-n2,.bootstrap .mx-n2{margin-right:-.5rem!important}.bootstrap .mb-n2,.bootstrap .my-n2{margin-bottom:-.5rem!important}.bootstrap .ml-n2,.bootstrap .mx-n2{margin-left:-.5rem!important}.bootstrap .m-n3{margin:-1rem!important}.bootstrap .mt-n3,.bootstrap .my-n3{margin-top:-1rem!important}.bootstrap .mr-n3,.bootstrap .mx-n3{margin-right:-1rem!important}.bootstrap .mb-n3,.bootstrap .my-n3{margin-bottom:-1rem!important}.bootstrap .ml-n3,.bootstrap .mx-n3{margin-left:-1rem!important}.bootstrap .m-n4{margin:-1.5rem!important}.bootstrap .mt-n4,.bootstrap .my-n4{margin-top:-1.5rem!important}.bootstrap .mr-n4,.bootstrap .mx-n4{margin-right:-1.5rem!important}.bootstrap .mb-n4,.bootstrap .my-n4{margin-bottom:-1.5rem!important}.bootstrap .ml-n4,.bootstrap .mx-n4{margin-left:-1.5rem!important}.bootstrap .m-n5{margin:-3rem!important}.bootstrap .mt-n5,.bootstrap .my-n5{margin-top:-3rem!important}.bootstrap .mr-n5,.bootstrap .mx-n5{margin-right:-3rem!important}.bootstrap .mb-n5,.bootstrap .my-n5{margin-bottom:-3rem!important}.bootstrap .ml-n5,.bootstrap .mx-n5{margin-left:-3rem!important}.bootstrap .m-auto{margin:auto!important}.bootstrap .mt-auto,.bootstrap .my-auto{margin-top:auto!important}.bootstrap .mr-auto,.bootstrap .mx-auto{margin-right:auto!important}.bootstrap .mb-auto,.bootstrap .my-auto{margin-bottom:auto!important}.bootstrap .ml-auto,.bootstrap .mx-auto{margin-left:auto!important}@media(min-width:576px){.bootstrap .m-sm-0{margin:0!important}.bootstrap .mt-sm-0,.bootstrap .my-sm-0{margin-top:0!important}.bootstrap .mr-sm-0,.bootstrap .mx-sm-0{margin-right:0!important}.bootstrap .mb-sm-0,.bootstrap .my-sm-0{margin-bottom:0!important}.bootstrap .ml-sm-0,.bootstrap .mx-sm-0{margin-left:0!important}.bootstrap .m-sm-1{margin:.25rem!important}.bootstrap .mt-sm-1,.bootstrap .my-sm-1{margin-top:.25rem!important}.bootstrap .mr-sm-1,.bootstrap .mx-sm-1{margin-right:.25rem!important}.bootstrap .mb-sm-1,.bootstrap .my-sm-1{margin-bottom:.25rem!important}.bootstrap .ml-sm-1,.bootstrap .mx-sm-1{margin-left:.25rem!important}.bootstrap .m-sm-2{margin:.5rem!important}.bootstrap .mt-sm-2,.bootstrap .my-sm-2{margin-top:.5rem!important}.bootstrap .mr-sm-2,.bootstrap .mx-sm-2{margin-right:.5rem!important}.bootstrap .mb-sm-2,.bootstrap .my-sm-2{margin-bottom:.5rem!important}.bootstrap .ml-sm-2,.bootstrap .mx-sm-2{margin-left:.5rem!important}.bootstrap .m-sm-3{margin:1rem!important}.bootstrap .mt-sm-3,.bootstrap .my-sm-3{margin-top:1rem!important}.bootstrap .mr-sm-3,.bootstrap .mx-sm-3{margin-right:1rem!important}.bootstrap .mb-sm-3,.bootstrap .my-sm-3{margin-bottom:1rem!important}.bootstrap .ml-sm-3,.bootstrap .mx-sm-3{margin-left:1rem!important}.bootstrap .m-sm-4{margin:1.5rem!important}.bootstrap .mt-sm-4,.bootstrap .my-sm-4{margin-top:1.5rem!important}.bootstrap .mr-sm-4,.bootstrap .mx-sm-4{margin-right:1.5rem!important}.bootstrap .mb-sm-4,.bootstrap .my-sm-4{margin-bottom:1.5rem!important}.bootstrap .ml-sm-4,.bootstrap .mx-sm-4{margin-left:1.5rem!important}.bootstrap .m-sm-5{margin:3rem!important}.bootstrap .mt-sm-5,.bootstrap .my-sm-5{margin-top:3rem!important}.bootstrap .mr-sm-5,.bootstrap .mx-sm-5{margin-right:3rem!important}.bootstrap .mb-sm-5,.bootstrap .my-sm-5{margin-bottom:3rem!important}.bootstrap .ml-sm-5,.bootstrap .mx-sm-5{margin-left:3rem!important}.bootstrap .p-sm-0{padding:0!important}.bootstrap .pt-sm-0,.bootstrap .py-sm-0{padding-top:0!important}.bootstrap .pr-sm-0,.bootstrap .px-sm-0{padding-right:0!important}.bootstrap .pb-sm-0,.bootstrap .py-sm-0{padding-bottom:0!important}.bootstrap .pl-sm-0,.bootstrap .px-sm-0{padding-left:0!important}.bootstrap .p-sm-1{padding:.25rem!important}.bootstrap .pt-sm-1,.bootstrap .py-sm-1{padding-top:.25rem!important}.bootstrap .pr-sm-1,.bootstrap .px-sm-1{padding-right:.25rem!important}.bootstrap .pb-sm-1,.bootstrap .py-sm-1{padding-bottom:.25rem!important}.bootstrap .pl-sm-1,.bootstrap .px-sm-1{padding-left:.25rem!important}.bootstrap .p-sm-2{padding:.5rem!important}.bootstrap .pt-sm-2,.bootstrap .py-sm-2{padding-top:.5rem!important}.bootstrap .pr-sm-2,.bootstrap .px-sm-2{padding-right:.5rem!important}.bootstrap .pb-sm-2,.bootstrap .py-sm-2{padding-bottom:.5rem!important}.bootstrap .pl-sm-2,.bootstrap .px-sm-2{padding-left:.5rem!important}.bootstrap .p-sm-3{padding:1rem!important}.bootstrap .pt-sm-3,.bootstrap .py-sm-3{padding-top:1rem!important}.bootstrap .pr-sm-3,.bootstrap .px-sm-3{padding-right:1rem!important}.bootstrap .pb-sm-3,.bootstrap .py-sm-3{padding-bottom:1rem!important}.bootstrap .pl-sm-3,.bootstrap .px-sm-3{padding-left:1rem!important}.bootstrap .p-sm-4{padding:1.5rem!important}.bootstrap .pt-sm-4,.bootstrap .py-sm-4{padding-top:1.5rem!important}.bootstrap .pr-sm-4,.bootstrap .px-sm-4{padding-right:1.5rem!important}.bootstrap .pb-sm-4,.bootstrap .py-sm-4{padding-bottom:1.5rem!important}.bootstrap .pl-sm-4,.bootstrap .px-sm-4{padding-left:1.5rem!important}.bootstrap .p-sm-5{padding:3rem!important}.bootstrap .pt-sm-5,.bootstrap .py-sm-5{padding-top:3rem!important}.bootstrap .pr-sm-5,.bootstrap .px-sm-5{padding-right:3rem!important}.bootstrap .pb-sm-5,.bootstrap .py-sm-5{padding-bottom:3rem!important}.bootstrap .pl-sm-5,.bootstrap .px-sm-5{padding-left:3rem!important}.bootstrap .m-sm-n1{margin:-.25rem!important}.bootstrap .mt-sm-n1,.bootstrap .my-sm-n1{margin-top:-.25rem!important}.bootstrap .mr-sm-n1,.bootstrap .mx-sm-n1{margin-right:-.25rem!important}.bootstrap .mb-sm-n1,.bootstrap .my-sm-n1{margin-bottom:-.25rem!important}.bootstrap .ml-sm-n1,.bootstrap .mx-sm-n1{margin-left:-.25rem!important}.bootstrap .m-sm-n2{margin:-.5rem!important}.bootstrap .mt-sm-n2,.bootstrap .my-sm-n2{margin-top:-.5rem!important}.bootstrap .mr-sm-n2,.bootstrap .mx-sm-n2{margin-right:-.5rem!important}.bootstrap .mb-sm-n2,.bootstrap .my-sm-n2{margin-bottom:-.5rem!important}.bootstrap .ml-sm-n2,.bootstrap .mx-sm-n2{margin-left:-.5rem!important}.bootstrap .m-sm-n3{margin:-1rem!important}.bootstrap .mt-sm-n3,.bootstrap .my-sm-n3{margin-top:-1rem!important}.bootstrap .mr-sm-n3,.bootstrap .mx-sm-n3{margin-right:-1rem!important}.bootstrap .mb-sm-n3,.bootstrap .my-sm-n3{margin-bottom:-1rem!important}.bootstrap .ml-sm-n3,.bootstrap .mx-sm-n3{margin-left:-1rem!important}.bootstrap .m-sm-n4{margin:-1.5rem!important}.bootstrap .mt-sm-n4,.bootstrap .my-sm-n4{margin-top:-1.5rem!important}.bootstrap .mr-sm-n4,.bootstrap .mx-sm-n4{margin-right:-1.5rem!important}.bootstrap .mb-sm-n4,.bootstrap .my-sm-n4{margin-bottom:-1.5rem!important}.bootstrap .ml-sm-n4,.bootstrap .mx-sm-n4{margin-left:-1.5rem!important}.bootstrap .m-sm-n5{margin:-3rem!important}.bootstrap .mt-sm-n5,.bootstrap .my-sm-n5{margin-top:-3rem!important}.bootstrap .mr-sm-n5,.bootstrap .mx-sm-n5{margin-right:-3rem!important}.bootstrap .mb-sm-n5,.bootstrap .my-sm-n5{margin-bottom:-3rem!important}.bootstrap .ml-sm-n5,.bootstrap .mx-sm-n5{margin-left:-3rem!important}.bootstrap .m-sm-auto{margin:auto!important}.bootstrap .mt-sm-auto,.bootstrap .my-sm-auto{margin-top:auto!important}.bootstrap .mr-sm-auto,.bootstrap .mx-sm-auto{margin-right:auto!important}.bootstrap .mb-sm-auto,.bootstrap .my-sm-auto{margin-bottom:auto!important}.bootstrap .ml-sm-auto,.bootstrap .mx-sm-auto{margin-left:auto!important}}@media(min-width:768px){.bootstrap .m-md-0{margin:0!important}.bootstrap .mt-md-0,.bootstrap .my-md-0{margin-top:0!important}.bootstrap .mr-md-0,.bootstrap .mx-md-0{margin-right:0!important}.bootstrap .mb-md-0,.bootstrap .my-md-0{margin-bottom:0!important}.bootstrap .ml-md-0,.bootstrap .mx-md-0{margin-left:0!important}.bootstrap .m-md-1{margin:.25rem!important}.bootstrap .mt-md-1,.bootstrap .my-md-1{margin-top:.25rem!important}.bootstrap .mr-md-1,.bootstrap .mx-md-1{margin-right:.25rem!important}.bootstrap .mb-md-1,.bootstrap .my-md-1{margin-bottom:.25rem!important}.bootstrap .ml-md-1,.bootstrap .mx-md-1{margin-left:.25rem!important}.bootstrap .m-md-2{margin:.5rem!important}.bootstrap .mt-md-2,.bootstrap .my-md-2{margin-top:.5rem!important}.bootstrap .mr-md-2,.bootstrap .mx-md-2{margin-right:.5rem!important}.bootstrap .mb-md-2,.bootstrap .my-md-2{margin-bottom:.5rem!important}.bootstrap .ml-md-2,.bootstrap .mx-md-2{margin-left:.5rem!important}.bootstrap .m-md-3{margin:1rem!important}.bootstrap .mt-md-3,.bootstrap .my-md-3{margin-top:1rem!important}.bootstrap .mr-md-3,.bootstrap .mx-md-3{margin-right:1rem!important}.bootstrap .mb-md-3,.bootstrap .my-md-3{margin-bottom:1rem!important}.bootstrap .ml-md-3,.bootstrap .mx-md-3{margin-left:1rem!important}.bootstrap .m-md-4{margin:1.5rem!important}.bootstrap .mt-md-4,.bootstrap .my-md-4{margin-top:1.5rem!important}.bootstrap .mr-md-4,.bootstrap .mx-md-4{margin-right:1.5rem!important}.bootstrap .mb-md-4,.bootstrap .my-md-4{margin-bottom:1.5rem!important}.bootstrap .ml-md-4,.bootstrap .mx-md-4{margin-left:1.5rem!important}.bootstrap .m-md-5{margin:3rem!important}.bootstrap .mt-md-5,.bootstrap .my-md-5{margin-top:3rem!important}.bootstrap .mr-md-5,.bootstrap .mx-md-5{margin-right:3rem!important}.bootstrap .mb-md-5,.bootstrap .my-md-5{margin-bottom:3rem!important}.bootstrap .ml-md-5,.bootstrap .mx-md-5{margin-left:3rem!important}.bootstrap .p-md-0{padding:0!important}.bootstrap .pt-md-0,.bootstrap .py-md-0{padding-top:0!important}.bootstrap .pr-md-0,.bootstrap .px-md-0{padding-right:0!important}.bootstrap .pb-md-0,.bootstrap .py-md-0{padding-bottom:0!important}.bootstrap .pl-md-0,.bootstrap .px-md-0{padding-left:0!important}.bootstrap .p-md-1{padding:.25rem!important}.bootstrap .pt-md-1,.bootstrap .py-md-1{padding-top:.25rem!important}.bootstrap .pr-md-1,.bootstrap .px-md-1{padding-right:.25rem!important}.bootstrap .pb-md-1,.bootstrap .py-md-1{padding-bottom:.25rem!important}.bootstrap .pl-md-1,.bootstrap .px-md-1{padding-left:.25rem!important}.bootstrap .p-md-2{padding:.5rem!important}.bootstrap .pt-md-2,.bootstrap .py-md-2{padding-top:.5rem!important}.bootstrap .pr-md-2,.bootstrap .px-md-2{padding-right:.5rem!important}.bootstrap .pb-md-2,.bootstrap .py-md-2{padding-bottom:.5rem!important}.bootstrap .pl-md-2,.bootstrap .px-md-2{padding-left:.5rem!important}.bootstrap .p-md-3{padding:1rem!important}.bootstrap .pt-md-3,.bootstrap .py-md-3{padding-top:1rem!important}.bootstrap .pr-md-3,.bootstrap .px-md-3{padding-right:1rem!important}.bootstrap .pb-md-3,.bootstrap .py-md-3{padding-bottom:1rem!important}.bootstrap .pl-md-3,.bootstrap .px-md-3{padding-left:1rem!important}.bootstrap .p-md-4{padding:1.5rem!important}.bootstrap .pt-md-4,.bootstrap .py-md-4{padding-top:1.5rem!important}.bootstrap .pr-md-4,.bootstrap .px-md-4{padding-right:1.5rem!important}.bootstrap .pb-md-4,.bootstrap .py-md-4{padding-bottom:1.5rem!important}.bootstrap .pl-md-4,.bootstrap .px-md-4{padding-left:1.5rem!important}.bootstrap .p-md-5{padding:3rem!important}.bootstrap .pt-md-5,.bootstrap .py-md-5{padding-top:3rem!important}.bootstrap .pr-md-5,.bootstrap .px-md-5{padding-right:3rem!important}.bootstrap .pb-md-5,.bootstrap .py-md-5{padding-bottom:3rem!important}.bootstrap .pl-md-5,.bootstrap .px-md-5{padding-left:3rem!important}.bootstrap .m-md-n1{margin:-.25rem!important}.bootstrap .mt-md-n1,.bootstrap .my-md-n1{margin-top:-.25rem!important}.bootstrap .mr-md-n1,.bootstrap .mx-md-n1{margin-right:-.25rem!important}.bootstrap .mb-md-n1,.bootstrap .my-md-n1{margin-bottom:-.25rem!important}.bootstrap .ml-md-n1,.bootstrap .mx-md-n1{margin-left:-.25rem!important}.bootstrap .m-md-n2{margin:-.5rem!important}.bootstrap .mt-md-n2,.bootstrap .my-md-n2{margin-top:-.5rem!important}.bootstrap .mr-md-n2,.bootstrap .mx-md-n2{margin-right:-.5rem!important}.bootstrap .mb-md-n2,.bootstrap .my-md-n2{margin-bottom:-.5rem!important}.bootstrap .ml-md-n2,.bootstrap .mx-md-n2{margin-left:-.5rem!important}.bootstrap .m-md-n3{margin:-1rem!important}.bootstrap .mt-md-n3,.bootstrap .my-md-n3{margin-top:-1rem!important}.bootstrap .mr-md-n3,.bootstrap .mx-md-n3{margin-right:-1rem!important}.bootstrap .mb-md-n3,.bootstrap .my-md-n3{margin-bottom:-1rem!important}.bootstrap .ml-md-n3,.bootstrap .mx-md-n3{margin-left:-1rem!important}.bootstrap .m-md-n4{margin:-1.5rem!important}.bootstrap .mt-md-n4,.bootstrap .my-md-n4{margin-top:-1.5rem!important}.bootstrap .mr-md-n4,.bootstrap .mx-md-n4{margin-right:-1.5rem!important}.bootstrap .mb-md-n4,.bootstrap .my-md-n4{margin-bottom:-1.5rem!important}.bootstrap .ml-md-n4,.bootstrap .mx-md-n4{margin-left:-1.5rem!important}.bootstrap .m-md-n5{margin:-3rem!important}.bootstrap .mt-md-n5,.bootstrap .my-md-n5{margin-top:-3rem!important}.bootstrap .mr-md-n5,.bootstrap .mx-md-n5{margin-right:-3rem!important}.bootstrap .mb-md-n5,.bootstrap .my-md-n5{margin-bottom:-3rem!important}.bootstrap .ml-md-n5,.bootstrap .mx-md-n5{margin-left:-3rem!important}.bootstrap .m-md-auto{margin:auto!important}.bootstrap .mt-md-auto,.bootstrap .my-md-auto{margin-top:auto!important}.bootstrap .mr-md-auto,.bootstrap .mx-md-auto{margin-right:auto!important}.bootstrap .mb-md-auto,.bootstrap .my-md-auto{margin-bottom:auto!important}.bootstrap .ml-md-auto,.bootstrap .mx-md-auto{margin-left:auto!important}}@media(min-width:992px){.bootstrap .m-lg-0{margin:0!important}.bootstrap .mt-lg-0,.bootstrap .my-lg-0{margin-top:0!important}.bootstrap .mr-lg-0,.bootstrap .mx-lg-0{margin-right:0!important}.bootstrap .mb-lg-0,.bootstrap .my-lg-0{margin-bottom:0!important}.bootstrap .ml-lg-0,.bootstrap .mx-lg-0{margin-left:0!important}.bootstrap .m-lg-1{margin:.25rem!important}.bootstrap .mt-lg-1,.bootstrap .my-lg-1{margin-top:.25rem!important}.bootstrap .mr-lg-1,.bootstrap .mx-lg-1{margin-right:.25rem!important}.bootstrap .mb-lg-1,.bootstrap .my-lg-1{margin-bottom:.25rem!important}.bootstrap .ml-lg-1,.bootstrap .mx-lg-1{margin-left:.25rem!important}.bootstrap .m-lg-2{margin:.5rem!important}.bootstrap .mt-lg-2,.bootstrap .my-lg-2{margin-top:.5rem!important}.bootstrap .mr-lg-2,.bootstrap .mx-lg-2{margin-right:.5rem!important}.bootstrap .mb-lg-2,.bootstrap .my-lg-2{margin-bottom:.5rem!important}.bootstrap .ml-lg-2,.bootstrap .mx-lg-2{margin-left:.5rem!important}.bootstrap .m-lg-3{margin:1rem!important}.bootstrap .mt-lg-3,.bootstrap .my-lg-3{margin-top:1rem!important}.bootstrap .mr-lg-3,.bootstrap .mx-lg-3{margin-right:1rem!important}.bootstrap .mb-lg-3,.bootstrap .my-lg-3{margin-bottom:1rem!important}.bootstrap .ml-lg-3,.bootstrap .mx-lg-3{margin-left:1rem!important}.bootstrap .m-lg-4{margin:1.5rem!important}.bootstrap .mt-lg-4,.bootstrap .my-lg-4{margin-top:1.5rem!important}.bootstrap .mr-lg-4,.bootstrap .mx-lg-4{margin-right:1.5rem!important}.bootstrap .mb-lg-4,.bootstrap .my-lg-4{margin-bottom:1.5rem!important}.bootstrap .ml-lg-4,.bootstrap .mx-lg-4{margin-left:1.5rem!important}.bootstrap .m-lg-5{margin:3rem!important}.bootstrap .mt-lg-5,.bootstrap .my-lg-5{margin-top:3rem!important}.bootstrap .mr-lg-5,.bootstrap .mx-lg-5{margin-right:3rem!important}.bootstrap .mb-lg-5,.bootstrap .my-lg-5{margin-bottom:3rem!important}.bootstrap .ml-lg-5,.bootstrap .mx-lg-5{margin-left:3rem!important}.bootstrap .p-lg-0{padding:0!important}.bootstrap .pt-lg-0,.bootstrap .py-lg-0{padding-top:0!important}.bootstrap .pr-lg-0,.bootstrap .px-lg-0{padding-right:0!important}.bootstrap .pb-lg-0,.bootstrap .py-lg-0{padding-bottom:0!important}.bootstrap .pl-lg-0,.bootstrap .px-lg-0{padding-left:0!important}.bootstrap .p-lg-1{padding:.25rem!important}.bootstrap .pt-lg-1,.bootstrap .py-lg-1{padding-top:.25rem!important}.bootstrap .pr-lg-1,.bootstrap .px-lg-1{padding-right:.25rem!important}.bootstrap .pb-lg-1,.bootstrap .py-lg-1{padding-bottom:.25rem!important}.bootstrap .pl-lg-1,.bootstrap .px-lg-1{padding-left:.25rem!important}.bootstrap .p-lg-2{padding:.5rem!important}.bootstrap .pt-lg-2,.bootstrap .py-lg-2{padding-top:.5rem!important}.bootstrap .pr-lg-2,.bootstrap .px-lg-2{padding-right:.5rem!important}.bootstrap .pb-lg-2,.bootstrap .py-lg-2{padding-bottom:.5rem!important}.bootstrap .pl-lg-2,.bootstrap .px-lg-2{padding-left:.5rem!important}.bootstrap .p-lg-3{padding:1rem!important}.bootstrap .pt-lg-3,.bootstrap .py-lg-3{padding-top:1rem!important}.bootstrap .pr-lg-3,.bootstrap .px-lg-3{padding-right:1rem!important}.bootstrap .pb-lg-3,.bootstrap .py-lg-3{padding-bottom:1rem!important}.bootstrap .pl-lg-3,.bootstrap .px-lg-3{padding-left:1rem!important}.bootstrap .p-lg-4{padding:1.5rem!important}.bootstrap .pt-lg-4,.bootstrap .py-lg-4{padding-top:1.5rem!important}.bootstrap .pr-lg-4,.bootstrap .px-lg-4{padding-right:1.5rem!important}.bootstrap .pb-lg-4,.bootstrap .py-lg-4{padding-bottom:1.5rem!important}.bootstrap .pl-lg-4,.bootstrap .px-lg-4{padding-left:1.5rem!important}.bootstrap .p-lg-5{padding:3rem!important}.bootstrap .pt-lg-5,.bootstrap .py-lg-5{padding-top:3rem!important}.bootstrap .pr-lg-5,.bootstrap .px-lg-5{padding-right:3rem!important}.bootstrap .pb-lg-5,.bootstrap .py-lg-5{padding-bottom:3rem!important}.bootstrap .pl-lg-5,.bootstrap .px-lg-5{padding-left:3rem!important}.bootstrap .m-lg-n1{margin:-.25rem!important}.bootstrap .mt-lg-n1,.bootstrap .my-lg-n1{margin-top:-.25rem!important}.bootstrap .mr-lg-n1,.bootstrap .mx-lg-n1{margin-right:-.25rem!important}.bootstrap .mb-lg-n1,.bootstrap .my-lg-n1{margin-bottom:-.25rem!important}.bootstrap .ml-lg-n1,.bootstrap .mx-lg-n1{margin-left:-.25rem!important}.bootstrap .m-lg-n2{margin:-.5rem!important}.bootstrap .mt-lg-n2,.bootstrap .my-lg-n2{margin-top:-.5rem!important}.bootstrap .mr-lg-n2,.bootstrap .mx-lg-n2{margin-right:-.5rem!important}.bootstrap .mb-lg-n2,.bootstrap .my-lg-n2{margin-bottom:-.5rem!important}.bootstrap .ml-lg-n2,.bootstrap .mx-lg-n2{margin-left:-.5rem!important}.bootstrap .m-lg-n3{margin:-1rem!important}.bootstrap .mt-lg-n3,.bootstrap .my-lg-n3{margin-top:-1rem!important}.bootstrap .mr-lg-n3,.bootstrap .mx-lg-n3{margin-right:-1rem!important}.bootstrap .mb-lg-n3,.bootstrap .my-lg-n3{margin-bottom:-1rem!important}.bootstrap .ml-lg-n3,.bootstrap .mx-lg-n3{margin-left:-1rem!important}.bootstrap .m-lg-n4{margin:-1.5rem!important}.bootstrap .mt-lg-n4,.bootstrap .my-lg-n4{margin-top:-1.5rem!important}.bootstrap .mr-lg-n4,.bootstrap .mx-lg-n4{margin-right:-1.5rem!important}.bootstrap .mb-lg-n4,.bootstrap .my-lg-n4{margin-bottom:-1.5rem!important}.bootstrap .ml-lg-n4,.bootstrap .mx-lg-n4{margin-left:-1.5rem!important}.bootstrap .m-lg-n5{margin:-3rem!important}.bootstrap .mt-lg-n5,.bootstrap .my-lg-n5{margin-top:-3rem!important}.bootstrap .mr-lg-n5,.bootstrap .mx-lg-n5{margin-right:-3rem!important}.bootstrap .mb-lg-n5,.bootstrap .my-lg-n5{margin-bottom:-3rem!important}.bootstrap .ml-lg-n5,.bootstrap .mx-lg-n5{margin-left:-3rem!important}.bootstrap .m-lg-auto{margin:auto!important}.bootstrap .mt-lg-auto,.bootstrap .my-lg-auto{margin-top:auto!important}.bootstrap .mr-lg-auto,.bootstrap .mx-lg-auto{margin-right:auto!important}.bootstrap .mb-lg-auto,.bootstrap .my-lg-auto{margin-bottom:auto!important}.bootstrap .ml-lg-auto,.bootstrap .mx-lg-auto{margin-left:auto!important}}@media(min-width:1200px){.bootstrap .m-xl-0{margin:0!important}.bootstrap .mt-xl-0,.bootstrap .my-xl-0{margin-top:0!important}.bootstrap .mr-xl-0,.bootstrap .mx-xl-0{margin-right:0!important}.bootstrap .mb-xl-0,.bootstrap .my-xl-0{margin-bottom:0!important}.bootstrap .ml-xl-0,.bootstrap .mx-xl-0{margin-left:0!important}.bootstrap .m-xl-1{margin:.25rem!important}.bootstrap .mt-xl-1,.bootstrap .my-xl-1{margin-top:.25rem!important}.bootstrap .mr-xl-1,.bootstrap .mx-xl-1{margin-right:.25rem!important}.bootstrap .mb-xl-1,.bootstrap .my-xl-1{margin-bottom:.25rem!important}.bootstrap .ml-xl-1,.bootstrap .mx-xl-1{margin-left:.25rem!important}.bootstrap .m-xl-2{margin:.5rem!important}.bootstrap .mt-xl-2,.bootstrap .my-xl-2{margin-top:.5rem!important}.bootstrap .mr-xl-2,.bootstrap .mx-xl-2{margin-right:.5rem!important}.bootstrap .mb-xl-2,.bootstrap .my-xl-2{margin-bottom:.5rem!important}.bootstrap .ml-xl-2,.bootstrap .mx-xl-2{margin-left:.5rem!important}.bootstrap .m-xl-3{margin:1rem!important}.bootstrap .mt-xl-3,.bootstrap .my-xl-3{margin-top:1rem!important}.bootstrap .mr-xl-3,.bootstrap .mx-xl-3{margin-right:1rem!important}.bootstrap .mb-xl-3,.bootstrap .my-xl-3{margin-bottom:1rem!important}.bootstrap .ml-xl-3,.bootstrap .mx-xl-3{margin-left:1rem!important}.bootstrap .m-xl-4{margin:1.5rem!important}.bootstrap .mt-xl-4,.bootstrap .my-xl-4{margin-top:1.5rem!important}.bootstrap .mr-xl-4,.bootstrap .mx-xl-4{margin-right:1.5rem!important}.bootstrap .mb-xl-4,.bootstrap .my-xl-4{margin-bottom:1.5rem!important}.bootstrap .ml-xl-4,.bootstrap .mx-xl-4{margin-left:1.5rem!important}.bootstrap .m-xl-5{margin:3rem!important}.bootstrap .mt-xl-5,.bootstrap .my-xl-5{margin-top:3rem!important}.bootstrap .mr-xl-5,.bootstrap .mx-xl-5{margin-right:3rem!important}.bootstrap .mb-xl-5,.bootstrap .my-xl-5{margin-bottom:3rem!important}.bootstrap .ml-xl-5,.bootstrap .mx-xl-5{margin-left:3rem!important}.bootstrap .p-xl-0{padding:0!important}.bootstrap .pt-xl-0,.bootstrap .py-xl-0{padding-top:0!important}.bootstrap .pr-xl-0,.bootstrap .px-xl-0{padding-right:0!important}.bootstrap .pb-xl-0,.bootstrap .py-xl-0{padding-bottom:0!important}.bootstrap .pl-xl-0,.bootstrap .px-xl-0{padding-left:0!important}.bootstrap .p-xl-1{padding:.25rem!important}.bootstrap .pt-xl-1,.bootstrap .py-xl-1{padding-top:.25rem!important}.bootstrap .pr-xl-1,.bootstrap .px-xl-1{padding-right:.25rem!important}.bootstrap .pb-xl-1,.bootstrap .py-xl-1{padding-bottom:.25rem!important}.bootstrap .pl-xl-1,.bootstrap .px-xl-1{padding-left:.25rem!important}.bootstrap .p-xl-2{padding:.5rem!important}.bootstrap .pt-xl-2,.bootstrap .py-xl-2{padding-top:.5rem!important}.bootstrap .pr-xl-2,.bootstrap .px-xl-2{padding-right:.5rem!important}.bootstrap .pb-xl-2,.bootstrap .py-xl-2{padding-bottom:.5rem!important}.bootstrap .pl-xl-2,.bootstrap .px-xl-2{padding-left:.5rem!important}.bootstrap .p-xl-3{padding:1rem!important}.bootstrap .pt-xl-3,.bootstrap .py-xl-3{padding-top:1rem!important}.bootstrap .pr-xl-3,.bootstrap .px-xl-3{padding-right:1rem!important}.bootstrap .pb-xl-3,.bootstrap .py-xl-3{padding-bottom:1rem!important}.bootstrap .pl-xl-3,.bootstrap .px-xl-3{padding-left:1rem!important}.bootstrap .p-xl-4{padding:1.5rem!important}.bootstrap .pt-xl-4,.bootstrap .py-xl-4{padding-top:1.5rem!important}.bootstrap .pr-xl-4,.bootstrap .px-xl-4{padding-right:1.5rem!important}.bootstrap .pb-xl-4,.bootstrap .py-xl-4{padding-bottom:1.5rem!important}.bootstrap .pl-xl-4,.bootstrap .px-xl-4{padding-left:1.5rem!important}.bootstrap .p-xl-5{padding:3rem!important}.bootstrap .pt-xl-5,.bootstrap .py-xl-5{padding-top:3rem!important}.bootstrap .pr-xl-5,.bootstrap .px-xl-5{padding-right:3rem!important}.bootstrap .pb-xl-5,.bootstrap .py-xl-5{padding-bottom:3rem!important}.bootstrap .pl-xl-5,.bootstrap .px-xl-5{padding-left:3rem!important}.bootstrap .m-xl-n1{margin:-.25rem!important}.bootstrap .mt-xl-n1,.bootstrap .my-xl-n1{margin-top:-.25rem!important}.bootstrap .mr-xl-n1,.bootstrap .mx-xl-n1{margin-right:-.25rem!important}.bootstrap .mb-xl-n1,.bootstrap .my-xl-n1{margin-bottom:-.25rem!important}.bootstrap .ml-xl-n1,.bootstrap .mx-xl-n1{margin-left:-.25rem!important}.bootstrap .m-xl-n2{margin:-.5rem!important}.bootstrap .mt-xl-n2,.bootstrap .my-xl-n2{margin-top:-.5rem!important}.bootstrap .mr-xl-n2,.bootstrap .mx-xl-n2{margin-right:-.5rem!important}.bootstrap .mb-xl-n2,.bootstrap .my-xl-n2{margin-bottom:-.5rem!important}.bootstrap .ml-xl-n2,.bootstrap .mx-xl-n2{margin-left:-.5rem!important}.bootstrap .m-xl-n3{margin:-1rem!important}.bootstrap .mt-xl-n3,.bootstrap .my-xl-n3{margin-top:-1rem!important}.bootstrap .mr-xl-n3,.bootstrap .mx-xl-n3{margin-right:-1rem!important}.bootstrap .mb-xl-n3,.bootstrap .my-xl-n3{margin-bottom:-1rem!important}.bootstrap .ml-xl-n3,.bootstrap .mx-xl-n3{margin-left:-1rem!important}.bootstrap .m-xl-n4{margin:-1.5rem!important}.bootstrap .mt-xl-n4,.bootstrap .my-xl-n4{margin-top:-1.5rem!important}.bootstrap .mr-xl-n4,.bootstrap .mx-xl-n4{margin-right:-1.5rem!important}.bootstrap .mb-xl-n4,.bootstrap .my-xl-n4{margin-bottom:-1.5rem!important}.bootstrap .ml-xl-n4,.bootstrap .mx-xl-n4{margin-left:-1.5rem!important}.bootstrap .m-xl-n5{margin:-3rem!important}.bootstrap .mt-xl-n5,.bootstrap .my-xl-n5{margin-top:-3rem!important}.bootstrap .mr-xl-n5,.bootstrap .mx-xl-n5{margin-right:-3rem!important}.bootstrap .mb-xl-n5,.bootstrap .my-xl-n5{margin-bottom:-3rem!important}.bootstrap .ml-xl-n5,.bootstrap .mx-xl-n5{margin-left:-3rem!important}.bootstrap .m-xl-auto{margin:auto!important}.bootstrap .mt-xl-auto,.bootstrap .my-xl-auto{margin-top:auto!important}.bootstrap .mr-xl-auto,.bootstrap .mx-xl-auto{margin-right:auto!important}.bootstrap .mb-xl-auto,.bootstrap .my-xl-auto{margin-bottom:auto!important}.bootstrap .ml-xl-auto,.bootstrap .mx-xl-auto{margin-left:auto!important}}.bootstrap .stretched-link:after{background-color:#0000;bottom:0;content:"";left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.bootstrap .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.bootstrap .text-justify{text-align:justify!important}.bootstrap .text-wrap{white-space:normal!important}.bootstrap .text-nowrap{white-space:nowrap!important}.bootstrap .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap .text-left{text-align:left!important}.bootstrap .text-right{text-align:right!important}.bootstrap .text-center{text-align:center!important}@media(min-width:576px){.bootstrap .text-sm-left{text-align:left!important}.bootstrap .text-sm-right{text-align:right!important}.bootstrap .text-sm-center{text-align:center!important}}@media(min-width:768px){.bootstrap .text-md-left{text-align:left!important}.bootstrap .text-md-right{text-align:right!important}.bootstrap .text-md-center{text-align:center!important}}@media(min-width:992px){.bootstrap .text-lg-left{text-align:left!important}.bootstrap .text-lg-right{text-align:right!important}.bootstrap .text-lg-center{text-align:center!important}}@media(min-width:1200px){.bootstrap .text-xl-left{text-align:left!important}.bootstrap .text-xl-right{text-align:right!important}.bootstrap .text-xl-center{text-align:center!important}}.bootstrap .text-lowercase{text-transform:lowercase!important}.bootstrap .text-uppercase{text-transform:uppercase!important}.bootstrap .text-capitalize{text-transform:capitalize!important}.bootstrap .font-weight-light{font-weight:300!important}.bootstrap .font-weight-lighter{font-weight:lighter!important}.bootstrap .font-weight-normal{font-weight:400!important}.bootstrap .font-weight-bold{font-weight:700!important}.bootstrap .font-weight-bolder{font-weight:bolder!important}.bootstrap .font-italic{font-style:italic!important}.bootstrap .text-white{color:#fff!important}.bootstrap .text-primary{color:#007bff!important}.bootstrap a.text-primary:focus,.bootstrap a.text-primary:hover{color:#0056b3!important}.bootstrap .text-secondary{color:#6c757d!important}.bootstrap a.text-secondary:focus,.bootstrap a.text-secondary:hover{color:#494f54!important}.bootstrap .text-success{color:#28a745!important}.bootstrap a.text-success:focus,.bootstrap a.text-success:hover{color:#19692c!important}.bootstrap .text-info{color:#17a2b8!important}.bootstrap a.text-info:focus,.bootstrap a.text-info:hover{color:#0f6674!important}.bootstrap .text-warning{color:#ffc107!important}.bootstrap a.text-warning:focus,.bootstrap a.text-warning:hover{color:#ba8b00!important}.bootstrap .text-danger{color:#dc3545!important}.bootstrap a.text-danger:focus,.bootstrap a.text-danger:hover{color:#a71d2a!important}.bootstrap .text-light{color:#f8f9fa!important}.bootstrap a.text-light:focus,.bootstrap a.text-light:hover{color:#cbd3da!important}.bootstrap .text-dark{color:#343a40!important}.bootstrap a.text-dark:focus,.bootstrap a.text-dark:hover{color:#121416!important}.bootstrap .text-body{color:#212529!important}.bootstrap .text-muted{color:#6c757d!important}.bootstrap .text-black-50{color:#00000080!important}.bootstrap .text-white-50{color:#ffffff80!important}.bootstrap .text-hide{background-color:initial;border:0;color:#0000;font:0/0 a;text-shadow:none}.bootstrap .text-decoration-none{text-decoration:none!important}.bootstrap .text-break{word-wrap:break-word!important;word-break:break-word!important}.bootstrap .text-reset{color:inherit!important}.bootstrap .visible{visibility:visible!important}.bootstrap .invisible{visibility:hidden!important}.bootstrap .alert-cell{background:#f5f5f5;color:inherit}.bootstrap .config-yaml,.bootstrap .rule-cell{background-color:#f5f5f5}.bootstrap .config-yaml{border:1px solid #ccc;border-radius:4px;color:#333;display:block;font-size:13px;padding:10px;word-break:break-all}.bootstrap .query-stats{color:#71808e;flex-grow:1;font-size:.7rem}.bootstrap .metrics-explorer.modal-dialog{max-width:750px;overflow-wrap:break-word}.bootstrap .metrics-explorer .metric{cursor:pointer;margin:0;padding:5px}.bootstrap .metrics-explorer .metric:hover{background:#efefef}.bootstrap button.metrics-explorer-btn{background-color:#e9ecef;border:1px solid #ced4da;color:#495057}.bootstrap .graph-controls button.clear-time-btn,.bootstrap .table-controls button.clear-time-btn{background-color:#fff;border:1px solid #ced4da;border-left:none}.bootstrap .graph-controls button.clear-time-btn:hover,.bootstrap .table-controls button.clear-time-btn:hover{color:#545b62}.bootstrap button.execute-btn{border:1px solid #006fe6;width:84px}.bootstrap .expression-input .cm-expression-input{border:1px solid #ced4da;flex:1 1 auto;font-size:15px;padding:4px 0 0 8px}.bootstrap .tab-content{border-bottom:1px solid #dee2e6;border-left:1px solid #dee2e6;border-right:1px solid #dee2e6;padding:10px}.bootstrap .modal.show{overflow-y:auto}.bootstrap .panel{margin-bottom:20px}.bootstrap input[type=checkbox]:checked+label{color:#286090}.bootstrap .custom-control-label{cursor:pointer}.bootstrap .togglers-wrapper .form-group{margin-bottom:.5rem}.bootstrap [for$=-toggler].custom-control-label:after,.bootstrap [for$=-toggler].custom-control-label:before{height:1.12rem;left:-1.3rem;top:.28rem;width:1.12rem}.bootstrap .capitalize-title:first-letter{text-transform:capitalize}.bootstrap .input-group.expression-input{flex-wrap:nowrap;margin-bottom:10px}.bootstrap .alert.alert-danger{margin-bottom:10px}.bootstrap .nav-tabs .nav-link{cursor:pointer}.bootstrap .tab-content .alert{margin-bottom:0}.bootstrap .data-table.table{margin:10px 0 2px}.bootstrap .data-table>tbody>tr>td{font-size:.8em;overflow:hidden;padding:5px 0 5px 8px}.bootstrap .autosuggest-dropdown{background-color:#fff;border:1px solid #ced4da;color:#495057;font-size:1rem;left:56px;margin-top:-6px;position:absolute;z-index:1000}.bootstrap .autosuggest-dropdown-list{list-style:none;margin:0;padding:0}.bootstrap .autosuggest-dropdown-list li{background-color:initial;border:0;clear:both;display:block;padding:.25rem 1.5rem;white-space:nowrap;width:100%}.bootstrap .autosuggest-dropdown-list li.autosuggest-dropdown-header{background-color:#bfdeff;font-size:10px;line-height:1.5;text-align:center;text-transform:uppercase}.bootstrap .graph-controls,.bootstrap .table-controls{margin-bottom:10px}.bootstrap .graph-controls input,.bootstrap .table-controls input{text-align:center}.bootstrap .graph-controls .range-input input{width:50px}.bootstrap .time-input input{border-right:none}.bootstrap .time-input{width:270px!important}.bootstrap .graph-controls input.resolution-input{width:90px}.bootstrap .graph-controls>:not(:first-child){margin-left:20px}.bootstrap .graph-legend{display:inline-block;font-size:.75em;margin:15px 0 15px 55px;padding:10px 5px}.bootstrap .legend-item{border-radius:3px;cursor:pointer;display:flex;line-height:1.7;padding:0 5px}.bootstrap .legend-item div{flex-wrap:wrap}.bootstrap .legend-swatch{display:inline-block;height:7px;margin:6px 8px 2px 0;min-width:7px;outline:1.5px solid #ccc;outline-offset:1px}.bootstrap .legend-item:hover{background:#0000002e}.bootstrap .legend-metric-name{margin-right:1px}.bootstrap .legend-label-name{font-weight:700}.bootstrap .graph{margin:0 5px}.bootstrap .graph-chart{fill:#495057;font-size:.8em;height:500px;width:100%}.bootstrap .graph-chart .flot-overlay{cursor:crosshair}.bootstrap .graph-tooltip{background:#000c;border-radius:3px;color:#fff;font-family:Arial,Helvetica,sans-serif;font-size:12px;padding:8px;white-space:nowrap}.bootstrap .graph-tooltip .labels{font-size:11px;line-height:11px}.bootstrap .graph-tooltip .detail-swatch{display:inline-block;height:10px;width:10px}.bootstrap .add-panel-btn{margin-bottom:20px}.bootstrap .target-head{font-size:large;font-weight:700}.bootstrap .group-info{display:flex;justify-content:space-between;margin-bottom:10px;padding:10px}.bootstrap .badges-wrapper>span{margin-right:5px;max-height:20px}.bootstrap .rules-head{font-weight:600}.bootstrap .rule_cell{background-color:#f5f5f5;display:block;font-family:monospace;white-space:pre-wrap}.bootstrap .popup-message{background-color:#000000b3;border-radius:4px;color:#fff;display:none;font-size:14px;margin-right:15px;max-width:250px;min-width:120px;padding:8px 12px;position:absolute;right:100%;top:50%;transform:translateY(-50%);white-space:normal;width:-webkit-max-content;width:max-content}.bootstrap .custom-control-label:hover .popup-message{display:block}html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);font-family:sans-serif;line-height:1.15}body.bootstrap-dark{background-color:#191d21;color:#d3d3d3;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;line-height:1.5;margin:0;text-align:left}body.bootstrap-dark button{color:#d3d3d3}.bootstrap-dark :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.bootstrap-dark .h1,.bootstrap-dark .h2,.bootstrap-dark .h3,.bootstrap-dark .h4,.bootstrap-dark .h5,.bootstrap-dark .h6,.bootstrap-dark h1,.bootstrap-dark h2,.bootstrap-dark h3,.bootstrap-dark h4,.bootstrap-dark h5,.bootstrap-dark h6{font-weight:500;line-height:1.2;margin-bottom:.5rem}.bootstrap-dark .h1,.bootstrap-dark h1{font-size:2.5rem}.bootstrap-dark .h2,.bootstrap-dark h2{font-size:2rem}.bootstrap-dark .h3,.bootstrap-dark h3{font-size:1.75rem}.bootstrap-dark .h4,.bootstrap-dark h4{font-size:1.5rem}.bootstrap-dark .h5,.bootstrap-dark h5{font-size:1.25rem}.bootstrap-dark .h6,.bootstrap-dark h6{font-size:1rem}.bootstrap-dark .lead{font-size:1.25rem;font-weight:300}.bootstrap-dark .display-1{font-size:6rem;font-weight:300;line-height:1.2}.bootstrap-dark .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.bootstrap-dark .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.bootstrap-dark .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}.bootstrap-dark hr{border:0;border-top:1px solid #ffffff1a;margin-bottom:1rem;margin-top:1rem}.bootstrap-dark .small,.bootstrap-dark small{font-size:80%;font-weight:400}.bootstrap-dark .mark,.bootstrap-dark mark{background-color:#fcf8e3;padding:.2em}.bootstrap-dark .list-inline,.bootstrap-dark .list-unstyled{list-style:none;padding-left:0}.bootstrap-dark .list-inline-item{display:inline-block}.bootstrap-dark .list-inline-item:not(:last-child){margin-right:.5rem}.bootstrap-dark .initialism{font-size:90%;text-transform:uppercase}.bootstrap-dark .blockquote{font-size:1.25rem;margin-bottom:1rem}.bootstrap-dark .blockquote-footer{color:#6c757d;display:block;font-size:80%}.bootstrap-dark .blockquote-footer:before{content:"— "}.bootstrap-dark .img-fluid{height:auto;max-width:100%}.bootstrap-dark .img-thumbnail{background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;height:auto;max-width:100%;padding:.25rem}.bootstrap-dark .figure{display:inline-block}.bootstrap-dark .figure-img{line-height:1;margin-bottom:.5rem}.bootstrap-dark .figure-caption{color:#6c757d;font-size:90%}.bootstrap-dark code{word-wrap:break-word;color:#e83e8c;font-size:87.5%}a>.bootstrap-dark code{color:inherit}.bootstrap-dark kbd{background-color:#212529;border-radius:.2rem;color:#fff;font-size:87.5%;padding:.2rem .4rem}.bootstrap-dark kbd kbd{font-size:100%;font-weight:700;padding:0}.bootstrap-dark pre{color:#212529;display:block;font-size:87.5%}.bootstrap-dark pre code{color:inherit;font-size:inherit;word-break:normal}.bootstrap-dark .pre-scrollable{max-height:340px;overflow-y:scroll}.bootstrap-dark .container,.bootstrap-dark .container-fluid,.bootstrap-dark .container-lg,.bootstrap-dark .container-md,.bootstrap-dark .container-sm,.bootstrap-dark .container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media(min-width:576px){.bootstrap-dark .container,.bootstrap-dark .container-sm{max-width:540px}}@media(min-width:768px){.bootstrap-dark .container,.bootstrap-dark .container-md,.bootstrap-dark .container-sm{max-width:720px}}@media(min-width:992px){.bootstrap-dark .container,.bootstrap-dark .container-lg,.bootstrap-dark .container-md,.bootstrap-dark .container-sm{max-width:960px}}@media(min-width:1200px){.bootstrap-dark .container,.bootstrap-dark .container-lg,.bootstrap-dark .container-md,.bootstrap-dark .container-sm,.bootstrap-dark .container-xl{max-width:1140px}}.bootstrap-dark .row{display:flex;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.bootstrap-dark .no-gutters{margin-left:0;margin-right:0}.bootstrap-dark .no-gutters>.col,.bootstrap-dark .no-gutters>[class*=col-]{padding-left:0;padding-right:0}.bootstrap-dark .col,.bootstrap-dark .col-1,.bootstrap-dark .col-10,.bootstrap-dark .col-11,.bootstrap-dark .col-12,.bootstrap-dark .col-2,.bootstrap-dark .col-3,.bootstrap-dark .col-4,.bootstrap-dark .col-5,.bootstrap-dark .col-6,.bootstrap-dark .col-7,.bootstrap-dark .col-8,.bootstrap-dark .col-9,.bootstrap-dark .col-auto,.bootstrap-dark .col-lg,.bootstrap-dark .col-lg-1,.bootstrap-dark .col-lg-10,.bootstrap-dark .col-lg-11,.bootstrap-dark .col-lg-12,.bootstrap-dark .col-lg-2,.bootstrap-dark .col-lg-3,.bootstrap-dark .col-lg-4,.bootstrap-dark .col-lg-5,.bootstrap-dark .col-lg-6,.bootstrap-dark .col-lg-7,.bootstrap-dark .col-lg-8,.bootstrap-dark .col-lg-9,.bootstrap-dark .col-lg-auto,.bootstrap-dark .col-md,.bootstrap-dark .col-md-1,.bootstrap-dark .col-md-10,.bootstrap-dark .col-md-11,.bootstrap-dark .col-md-12,.bootstrap-dark .col-md-2,.bootstrap-dark .col-md-3,.bootstrap-dark .col-md-4,.bootstrap-dark .col-md-5,.bootstrap-dark .col-md-6,.bootstrap-dark .col-md-7,.bootstrap-dark .col-md-8,.bootstrap-dark .col-md-9,.bootstrap-dark .col-md-auto,.bootstrap-dark .col-sm,.bootstrap-dark .col-sm-1,.bootstrap-dark .col-sm-10,.bootstrap-dark .col-sm-11,.bootstrap-dark .col-sm-12,.bootstrap-dark .col-sm-2,.bootstrap-dark .col-sm-3,.bootstrap-dark .col-sm-4,.bootstrap-dark .col-sm-5,.bootstrap-dark .col-sm-6,.bootstrap-dark .col-sm-7,.bootstrap-dark .col-sm-8,.bootstrap-dark .col-sm-9,.bootstrap-dark .col-sm-auto,.bootstrap-dark .col-xl,.bootstrap-dark .col-xl-1,.bootstrap-dark .col-xl-10,.bootstrap-dark .col-xl-11,.bootstrap-dark .col-xl-12,.bootstrap-dark .col-xl-2,.bootstrap-dark .col-xl-3,.bootstrap-dark .col-xl-4,.bootstrap-dark .col-xl-5,.bootstrap-dark .col-xl-6,.bootstrap-dark .col-xl-7,.bootstrap-dark .col-xl-8,.bootstrap-dark .col-xl-9,.bootstrap-dark .col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}.bootstrap-dark .col{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap-dark .row-cols-1>*{flex:0 0 100%;max-width:100%}.bootstrap-dark .row-cols-2>*{flex:0 0 50%;max-width:50%}.bootstrap-dark .row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap-dark .row-cols-4>*{flex:0 0 25%;max-width:25%}.bootstrap-dark .row-cols-5>*{flex:0 0 20%;max-width:20%}.bootstrap-dark .row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap-dark .col-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap-dark .col-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap-dark .col-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap-dark .col-3{flex:0 0 25%;max-width:25%}.bootstrap-dark .col-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap-dark .col-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap-dark .col-6{flex:0 0 50%;max-width:50%}.bootstrap-dark .col-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap-dark .col-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap-dark .col-9{flex:0 0 75%;max-width:75%}.bootstrap-dark .col-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap-dark .col-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap-dark .col-12{flex:0 0 100%;max-width:100%}.bootstrap-dark .order-first{order:-1}.bootstrap-dark .order-last{order:13}.bootstrap-dark .order-0{order:0}.bootstrap-dark .order-1{order:1}.bootstrap-dark .order-2{order:2}.bootstrap-dark .order-3{order:3}.bootstrap-dark .order-4{order:4}.bootstrap-dark .order-5{order:5}.bootstrap-dark .order-6{order:6}.bootstrap-dark .order-7{order:7}.bootstrap-dark .order-8{order:8}.bootstrap-dark .order-9{order:9}.bootstrap-dark .order-10{order:10}.bootstrap-dark .order-11{order:11}.bootstrap-dark .order-12{order:12}.bootstrap-dark .offset-1{margin-left:8.33333333%}.bootstrap-dark .offset-2{margin-left:16.66666667%}.bootstrap-dark .offset-3{margin-left:25%}.bootstrap-dark .offset-4{margin-left:33.33333333%}.bootstrap-dark .offset-5{margin-left:41.66666667%}.bootstrap-dark .offset-6{margin-left:50%}.bootstrap-dark .offset-7{margin-left:58.33333333%}.bootstrap-dark .offset-8{margin-left:66.66666667%}.bootstrap-dark .offset-9{margin-left:75%}.bootstrap-dark .offset-10{margin-left:83.33333333%}.bootstrap-dark .offset-11{margin-left:91.66666667%}@media(min-width:576px){.bootstrap-dark .col-sm{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap-dark .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.bootstrap-dark .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.bootstrap-dark .row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap-dark .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.bootstrap-dark .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.bootstrap-dark .row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap-dark .col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap-dark .col-sm-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap-dark .col-sm-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap-dark .col-sm-3{flex:0 0 25%;max-width:25%}.bootstrap-dark .col-sm-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap-dark .col-sm-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap-dark .col-sm-6{flex:0 0 50%;max-width:50%}.bootstrap-dark .col-sm-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap-dark .col-sm-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap-dark .col-sm-9{flex:0 0 75%;max-width:75%}.bootstrap-dark .col-sm-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap-dark .col-sm-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap-dark .col-sm-12{flex:0 0 100%;max-width:100%}.bootstrap-dark .order-sm-first{order:-1}.bootstrap-dark .order-sm-last{order:13}.bootstrap-dark .order-sm-0{order:0}.bootstrap-dark .order-sm-1{order:1}.bootstrap-dark .order-sm-2{order:2}.bootstrap-dark .order-sm-3{order:3}.bootstrap-dark .order-sm-4{order:4}.bootstrap-dark .order-sm-5{order:5}.bootstrap-dark .order-sm-6{order:6}.bootstrap-dark .order-sm-7{order:7}.bootstrap-dark .order-sm-8{order:8}.bootstrap-dark .order-sm-9{order:9}.bootstrap-dark .order-sm-10{order:10}.bootstrap-dark .order-sm-11{order:11}.bootstrap-dark .order-sm-12{order:12}.bootstrap-dark .offset-sm-0{margin-left:0}.bootstrap-dark .offset-sm-1{margin-left:8.33333333%}.bootstrap-dark .offset-sm-2{margin-left:16.66666667%}.bootstrap-dark .offset-sm-3{margin-left:25%}.bootstrap-dark .offset-sm-4{margin-left:33.33333333%}.bootstrap-dark .offset-sm-5{margin-left:41.66666667%}.bootstrap-dark .offset-sm-6{margin-left:50%}.bootstrap-dark .offset-sm-7{margin-left:58.33333333%}.bootstrap-dark .offset-sm-8{margin-left:66.66666667%}.bootstrap-dark .offset-sm-9{margin-left:75%}.bootstrap-dark .offset-sm-10{margin-left:83.33333333%}.bootstrap-dark .offset-sm-11{margin-left:91.66666667%}}@media(min-width:768px){.bootstrap-dark .col-md{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap-dark .row-cols-md-1>*{flex:0 0 100%;max-width:100%}.bootstrap-dark .row-cols-md-2>*{flex:0 0 50%;max-width:50%}.bootstrap-dark .row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap-dark .row-cols-md-4>*{flex:0 0 25%;max-width:25%}.bootstrap-dark .row-cols-md-5>*{flex:0 0 20%;max-width:20%}.bootstrap-dark .row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap-dark .col-md-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap-dark .col-md-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap-dark .col-md-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap-dark .col-md-3{flex:0 0 25%;max-width:25%}.bootstrap-dark .col-md-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap-dark .col-md-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap-dark .col-md-6{flex:0 0 50%;max-width:50%}.bootstrap-dark .col-md-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap-dark .col-md-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap-dark .col-md-9{flex:0 0 75%;max-width:75%}.bootstrap-dark .col-md-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap-dark .col-md-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap-dark .col-md-12{flex:0 0 100%;max-width:100%}.bootstrap-dark .order-md-first{order:-1}.bootstrap-dark .order-md-last{order:13}.bootstrap-dark .order-md-0{order:0}.bootstrap-dark .order-md-1{order:1}.bootstrap-dark .order-md-2{order:2}.bootstrap-dark .order-md-3{order:3}.bootstrap-dark .order-md-4{order:4}.bootstrap-dark .order-md-5{order:5}.bootstrap-dark .order-md-6{order:6}.bootstrap-dark .order-md-7{order:7}.bootstrap-dark .order-md-8{order:8}.bootstrap-dark .order-md-9{order:9}.bootstrap-dark .order-md-10{order:10}.bootstrap-dark .order-md-11{order:11}.bootstrap-dark .order-md-12{order:12}.bootstrap-dark .offset-md-0{margin-left:0}.bootstrap-dark .offset-md-1{margin-left:8.33333333%}.bootstrap-dark .offset-md-2{margin-left:16.66666667%}.bootstrap-dark .offset-md-3{margin-left:25%}.bootstrap-dark .offset-md-4{margin-left:33.33333333%}.bootstrap-dark .offset-md-5{margin-left:41.66666667%}.bootstrap-dark .offset-md-6{margin-left:50%}.bootstrap-dark .offset-md-7{margin-left:58.33333333%}.bootstrap-dark .offset-md-8{margin-left:66.66666667%}.bootstrap-dark .offset-md-9{margin-left:75%}.bootstrap-dark .offset-md-10{margin-left:83.33333333%}.bootstrap-dark .offset-md-11{margin-left:91.66666667%}}@media(min-width:992px){.bootstrap-dark .col-lg{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap-dark .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.bootstrap-dark .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.bootstrap-dark .row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap-dark .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.bootstrap-dark .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.bootstrap-dark .row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap-dark .col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap-dark .col-lg-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap-dark .col-lg-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap-dark .col-lg-3{flex:0 0 25%;max-width:25%}.bootstrap-dark .col-lg-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap-dark .col-lg-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap-dark .col-lg-6{flex:0 0 50%;max-width:50%}.bootstrap-dark .col-lg-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap-dark .col-lg-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap-dark .col-lg-9{flex:0 0 75%;max-width:75%}.bootstrap-dark .col-lg-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap-dark .col-lg-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap-dark .col-lg-12{flex:0 0 100%;max-width:100%}.bootstrap-dark .order-lg-first{order:-1}.bootstrap-dark .order-lg-last{order:13}.bootstrap-dark .order-lg-0{order:0}.bootstrap-dark .order-lg-1{order:1}.bootstrap-dark .order-lg-2{order:2}.bootstrap-dark .order-lg-3{order:3}.bootstrap-dark .order-lg-4{order:4}.bootstrap-dark .order-lg-5{order:5}.bootstrap-dark .order-lg-6{order:6}.bootstrap-dark .order-lg-7{order:7}.bootstrap-dark .order-lg-8{order:8}.bootstrap-dark .order-lg-9{order:9}.bootstrap-dark .order-lg-10{order:10}.bootstrap-dark .order-lg-11{order:11}.bootstrap-dark .order-lg-12{order:12}.bootstrap-dark .offset-lg-0{margin-left:0}.bootstrap-dark .offset-lg-1{margin-left:8.33333333%}.bootstrap-dark .offset-lg-2{margin-left:16.66666667%}.bootstrap-dark .offset-lg-3{margin-left:25%}.bootstrap-dark .offset-lg-4{margin-left:33.33333333%}.bootstrap-dark .offset-lg-5{margin-left:41.66666667%}.bootstrap-dark .offset-lg-6{margin-left:50%}.bootstrap-dark .offset-lg-7{margin-left:58.33333333%}.bootstrap-dark .offset-lg-8{margin-left:66.66666667%}.bootstrap-dark .offset-lg-9{margin-left:75%}.bootstrap-dark .offset-lg-10{margin-left:83.33333333%}.bootstrap-dark .offset-lg-11{margin-left:91.66666667%}}@media(min-width:1200px){.bootstrap-dark .col-xl{flex-basis:0;flex-grow:1;max-width:100%}.bootstrap-dark .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.bootstrap-dark .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.bootstrap-dark .row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.bootstrap-dark .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.bootstrap-dark .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.bootstrap-dark .row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.bootstrap-dark .col-xl-auto{flex:0 0 auto;max-width:100%;width:auto}.bootstrap-dark .col-xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.bootstrap-dark .col-xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.bootstrap-dark .col-xl-3{flex:0 0 25%;max-width:25%}.bootstrap-dark .col-xl-4{flex:0 0 33.33333333%;max-width:33.33333333%}.bootstrap-dark .col-xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.bootstrap-dark .col-xl-6{flex:0 0 50%;max-width:50%}.bootstrap-dark .col-xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.bootstrap-dark .col-xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.bootstrap-dark .col-xl-9{flex:0 0 75%;max-width:75%}.bootstrap-dark .col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.bootstrap-dark .col-xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.bootstrap-dark .col-xl-12{flex:0 0 100%;max-width:100%}.bootstrap-dark .order-xl-first{order:-1}.bootstrap-dark .order-xl-last{order:13}.bootstrap-dark .order-xl-0{order:0}.bootstrap-dark .order-xl-1{order:1}.bootstrap-dark .order-xl-2{order:2}.bootstrap-dark .order-xl-3{order:3}.bootstrap-dark .order-xl-4{order:4}.bootstrap-dark .order-xl-5{order:5}.bootstrap-dark .order-xl-6{order:6}.bootstrap-dark .order-xl-7{order:7}.bootstrap-dark .order-xl-8{order:8}.bootstrap-dark .order-xl-9{order:9}.bootstrap-dark .order-xl-10{order:10}.bootstrap-dark .order-xl-11{order:11}.bootstrap-dark .order-xl-12{order:12}.bootstrap-dark .offset-xl-0{margin-left:0}.bootstrap-dark .offset-xl-1{margin-left:8.33333333%}.bootstrap-dark .offset-xl-2{margin-left:16.66666667%}.bootstrap-dark .offset-xl-3{margin-left:25%}.bootstrap-dark .offset-xl-4{margin-left:33.33333333%}.bootstrap-dark .offset-xl-5{margin-left:41.66666667%}.bootstrap-dark .offset-xl-6{margin-left:50%}.bootstrap-dark .offset-xl-7{margin-left:58.33333333%}.bootstrap-dark .offset-xl-8{margin-left:66.66666667%}.bootstrap-dark .offset-xl-9{margin-left:75%}.bootstrap-dark .offset-xl-10{margin-left:83.33333333%}.bootstrap-dark .offset-xl-11{margin-left:91.66666667%}}.bootstrap-dark .table{color:#d3d3d3;margin-bottom:1rem;width:100%}.bootstrap-dark .table td,.bootstrap-dark .table th{border-top:1px solid #343a40;padding:.75rem;vertical-align:top}.bootstrap-dark .table thead th{border-bottom:2px solid #343a40;vertical-align:bottom}.bootstrap-dark .table tbody+tbody{border-top:2px solid #343a40}.bootstrap-dark .table-sm td,.bootstrap-dark .table-sm th{padding:.3rem}.bootstrap-dark .table-bordered,.bootstrap-dark .table-bordered td,.bootstrap-dark .table-bordered th{border:1px solid #343a40}.bootstrap-dark .table-bordered thead td,.bootstrap-dark .table-bordered thead th{border-bottom-width:2px}.bootstrap-dark .table-borderless tbody+tbody,.bootstrap-dark .table-borderless td,.bootstrap-dark .table-borderless th,.bootstrap-dark .table-borderless thead th{border:0}.bootstrap-dark .table-striped tbody tr:nth-of-type(odd){background-color:#0000000d}.bootstrap-dark .table-hover tbody tr:hover{background-color:rgba(0,0,0,.075);color:#d3d3d3}.bootstrap-dark .table-primary,.bootstrap-dark .table-primary>td,.bootstrap-dark .table-primary>th{background-color:#b8daff}.bootstrap-dark .table-primary tbody+tbody,.bootstrap-dark .table-primary td,.bootstrap-dark .table-primary th,.bootstrap-dark .table-primary thead th{border-color:#7abaff}.bootstrap-dark .table-hover .table-primary:hover,.bootstrap-dark .table-hover .table-primary:hover>td,.bootstrap-dark .table-hover .table-primary:hover>th{background-color:#9fcdff}.bootstrap-dark .table-secondary,.bootstrap-dark .table-secondary>td,.bootstrap-dark .table-secondary>th{background-color:#d6d8db}.bootstrap-dark .table-secondary tbody+tbody,.bootstrap-dark .table-secondary td,.bootstrap-dark .table-secondary th,.bootstrap-dark .table-secondary thead th{border-color:#b3b7bb}.bootstrap-dark .table-hover .table-secondary:hover,.bootstrap-dark .table-hover .table-secondary:hover>td,.bootstrap-dark .table-hover .table-secondary:hover>th{background-color:#c8cbcf}.bootstrap-dark .table-success,.bootstrap-dark .table-success>td,.bootstrap-dark .table-success>th{background-color:#c3e6cb}.bootstrap-dark .table-success tbody+tbody,.bootstrap-dark .table-success td,.bootstrap-dark .table-success th,.bootstrap-dark .table-success thead th{border-color:#8fd19e}.bootstrap-dark .table-hover .table-success:hover,.bootstrap-dark .table-hover .table-success:hover>td,.bootstrap-dark .table-hover .table-success:hover>th{background-color:#b1dfbb}.bootstrap-dark .table-info,.bootstrap-dark .table-info>td,.bootstrap-dark .table-info>th{background-color:#bee5eb}.bootstrap-dark .table-info tbody+tbody,.bootstrap-dark .table-info td,.bootstrap-dark .table-info th,.bootstrap-dark .table-info thead th{border-color:#86cfda}.bootstrap-dark .table-hover .table-info:hover,.bootstrap-dark .table-hover .table-info:hover>td,.bootstrap-dark .table-hover .table-info:hover>th{background-color:#abdde5}.bootstrap-dark .table-warning,.bootstrap-dark .table-warning>td,.bootstrap-dark .table-warning>th{background-color:#ffeeba}.bootstrap-dark .table-warning tbody+tbody,.bootstrap-dark .table-warning td,.bootstrap-dark .table-warning th,.bootstrap-dark .table-warning thead th{border-color:#ffdf7e}.bootstrap-dark .table-hover .table-warning:hover,.bootstrap-dark .table-hover .table-warning:hover>td,.bootstrap-dark .table-hover .table-warning:hover>th{background-color:#ffe8a1}.bootstrap-dark .table-danger,.bootstrap-dark .table-danger>td,.bootstrap-dark .table-danger>th{background-color:#f5c6cb}.bootstrap-dark .table-danger tbody+tbody,.bootstrap-dark .table-danger td,.bootstrap-dark .table-danger th,.bootstrap-dark .table-danger thead th{border-color:#ed969e}.bootstrap-dark .table-hover .table-danger:hover,.bootstrap-dark .table-hover .table-danger:hover>td,.bootstrap-dark .table-hover .table-danger:hover>th{background-color:#f1b0b7}.bootstrap-dark .table-light,.bootstrap-dark .table-light>td,.bootstrap-dark .table-light>th{background-color:#fdfdfe}.bootstrap-dark .table-light tbody+tbody,.bootstrap-dark .table-light td,.bootstrap-dark .table-light th,.bootstrap-dark .table-light thead th{border-color:#fbfcfc}.bootstrap-dark .table-hover .table-light:hover,.bootstrap-dark .table-hover .table-light:hover>td,.bootstrap-dark .table-hover .table-light:hover>th{background-color:#ececf6}.bootstrap-dark .table-dark,.bootstrap-dark .table-dark>td,.bootstrap-dark .table-dark>th{background-color:#c6c8ca}.bootstrap-dark .table-dark tbody+tbody,.bootstrap-dark .table-dark td,.bootstrap-dark .table-dark th,.bootstrap-dark .table-dark thead th{border-color:#95999c}.bootstrap-dark .table-hover .table-dark:hover,.bootstrap-dark .table-hover .table-dark:hover>td,.bootstrap-dark .table-hover .table-dark:hover>th{background-color:#b9bbbe}.bootstrap-dark .table-active,.bootstrap-dark .table-active>td,.bootstrap-dark .table-active>th,.bootstrap-dark .table-hover .table-active:hover,.bootstrap-dark .table-hover .table-active:hover>td,.bootstrap-dark .table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.bootstrap-dark .table .thead-dark th{background-color:#343a40;border-color:#454d55;color:#dee2e6}.bootstrap-dark .table .thead-light th{background-color:#e9ecef;border-color:#343a40;color:#495057}.bootstrap-dark .table-dark{background-color:#343a40}.bootstrap-dark .table-dark td,.bootstrap-dark .table-dark th,.bootstrap-dark .table-dark thead th{border-color:#454d55}.bootstrap-dark .table-dark.table-bordered{border:0}.bootstrap-dark .table-dark.table-striped tbody tr:nth-of-type(odd){background-color:#ffffff0d}.bootstrap-dark .table-dark.table-hover tbody tr:hover{background-color:hsla(0,0%,100%,.075);color:#fff}@media(max-width:575.98px){.bootstrap-dark .table-responsive-sm{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap-dark .table-responsive-sm>.table-bordered{border:0}}@media(max-width:767.98px){.bootstrap-dark .table-responsive-md{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap-dark .table-responsive-md>.table-bordered{border:0}}@media(max-width:991.98px){.bootstrap-dark .table-responsive-lg{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap-dark .table-responsive-lg>.table-bordered{border:0}}@media(max-width:1199.98px){.bootstrap-dark .table-responsive-xl{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap-dark .table-responsive-xl>.table-bordered{border:0}}.bootstrap-dark .table-responsive{-webkit-overflow-scrolling:touch;display:block;overflow-x:auto;width:100%}.bootstrap-dark .table-responsive>.table-bordered{border:0}.bootstrap-dark .table-danger,.bootstrap-dark .table-danger>td,.bootstrap-dark .table-danger>th,.bootstrap-dark .table-dark,.bootstrap-dark .table-dark>td,.bootstrap-dark .table-dark>th,.bootstrap-dark .table-hover .table-danger:hover,.bootstrap-dark .table-hover .table-danger:hover>td,.bootstrap-dark .table-hover .table-danger:hover>th,.bootstrap-dark .table-hover .table-dark:hover,.bootstrap-dark .table-hover .table-dark:hover>td,.bootstrap-dark .table-hover .table-dark:hover>th,.bootstrap-dark .table-hover .table-info:hover,.bootstrap-dark .table-hover .table-info:hover>td,.bootstrap-dark .table-hover .table-info:hover>th,.bootstrap-dark .table-hover .table-light:hover,.bootstrap-dark .table-hover .table-light:hover>td,.bootstrap-dark .table-hover .table-light:hover>th,.bootstrap-dark .table-hover .table-primary:hover,.bootstrap-dark .table-hover .table-primary:hover>td,.bootstrap-dark .table-hover .table-primary:hover>th,.bootstrap-dark .table-hover .table-secondary:hover,.bootstrap-dark .table-hover .table-secondary:hover>td,.bootstrap-dark .table-hover .table-secondary:hover>th,.bootstrap-dark .table-hover .table-success:hover,.bootstrap-dark .table-hover .table-success:hover>td,.bootstrap-dark .table-hover .table-success:hover>th,.bootstrap-dark .table-hover .table-warning:hover,.bootstrap-dark .table-hover .table-warning:hover>td,.bootstrap-dark .table-hover .table-warning:hover>th,.bootstrap-dark .table-info,.bootstrap-dark .table-info>td,.bootstrap-dark .table-info>th,.bootstrap-dark .table-light,.bootstrap-dark .table-light>td,.bootstrap-dark .table-light>th,.bootstrap-dark .table-primary,.bootstrap-dark .table-primary>td,.bootstrap-dark .table-primary>th,.bootstrap-dark .table-secondary,.bootstrap-dark .table-secondary>td,.bootstrap-dark .table-secondary>th,.bootstrap-dark .table-success,.bootstrap-dark .table-success>td,.bootstrap-dark .table-success>th,.bootstrap-dark .table-warning,.bootstrap-dark .table-warning>td,.bootstrap-dark .table-warning>th{color:#212529}.bootstrap-dark .table-active,.bootstrap-dark .table-active>td,.bootstrap-dark .table-active>th,.bootstrap-dark .table-hover .table-active:hover,.bootstrap-dark .table-hover .table-active:hover>td,.bootstrap-dark .table-hover .table-active:hover>th{color:#ced4da}.bootstrap-dark .table-dark{color:#dee2e6}.bootstrap-dark .form-control{background-clip:padding-box;background-color:#000;border:1px solid #6c757d;border-radius:.25rem;color:#dee2e6;display:block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.bootstrap-dark .form-control{transition:none}}.bootstrap-dark .form-control::-ms-expand{background-color:initial;border:0}.bootstrap-dark .form-control:focus{background-color:#191d21;border-color:#b3d7ff;box-shadow:0 0 0 .2rem #007bff40;color:#dee2e6;outline:0}.bootstrap-dark .form-control::placeholder{color:#6c757d;opacity:1}.bootstrap-dark .form-control:disabled,.bootstrap-dark .form-control[readonly]{background-color:#343a40;opacity:1}.bootstrap-dark input[type=date].form-control,.bootstrap-dark input[type=datetime-local].form-control,.bootstrap-dark input[type=month].form-control,.bootstrap-dark input[type=time].form-control{-webkit-appearance:none;appearance:none}.bootstrap-dark select.form-control:-moz-focusring{color:#0000;text-shadow:0 0 0 #dee2e6}.bootstrap-dark select.form-control:focus::-ms-value{background-color:#000;color:#dee2e6}.bootstrap-dark .form-control-file,.bootstrap-dark .form-control-range{display:block;width:100%}.bootstrap-dark .col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.bootstrap-dark .col-form-label-lg{font-size:1.25rem;line-height:1.5;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.bootstrap-dark .col-form-label-sm{font-size:.875rem;line-height:1.5;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.bootstrap-dark .form-control-plaintext{background-color:initial;border:solid #0000;border-width:1px 0;color:#212529;display:block;font-size:1rem;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.bootstrap-dark .form-control-plaintext.form-control-lg,.bootstrap-dark .form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.bootstrap-dark .form-control-sm{border-radius:.2rem;font-size:.875rem;height:calc(1.5em + .5rem + 2px);line-height:1.5;padding:.25rem .5rem}.bootstrap-dark .form-control-lg{border-radius:.3rem;font-size:1.25rem;height:calc(1.5em + 1rem + 2px);line-height:1.5;padding:.5rem 1rem}.bootstrap-dark select.form-control[multiple],.bootstrap-dark select.form-control[size],.bootstrap-dark textarea.form-control{height:auto}.bootstrap-dark .form-group{margin-bottom:1rem}.bootstrap-dark .form-text{display:block;margin-top:.25rem}.bootstrap-dark .form-row{display:flex;flex-wrap:wrap;margin-left:-5px;margin-right:-5px}.bootstrap-dark .form-row>.col,.bootstrap-dark .form-row>[class*=col-]{padding-left:5px;padding-right:5px}.bootstrap-dark .form-check{display:block;padding-left:1.25rem;position:relative}.bootstrap-dark .form-check-input{margin-left:-1.25rem;margin-top:.3rem;position:absolute}.bootstrap-dark .form-check-input:disabled~.form-check-label,.bootstrap-dark .form-check-input[disabled]~.form-check-label{color:#6c757d}.bootstrap-dark .form-check-label{margin-bottom:0}.bootstrap-dark .form-check-inline{align-items:center;display:inline-flex;margin-right:.75rem;padding-left:0}.bootstrap-dark .form-check-inline .form-check-input{margin-left:0;margin-right:.3125rem;margin-top:0;position:static}.bootstrap-dark .valid-feedback{color:#28a745;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap-dark .valid-tooltip{background-color:#28a745e6;border-radius:.25rem;color:#ced4da;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap-dark .valid-tooltip,.form-row>[class*=col-]>.bootstrap-dark .valid-tooltip{left:5px}.bootstrap-dark .is-valid~.valid-feedback,.bootstrap-dark .is-valid~.valid-tooltip{display:block}.bootstrap-dark .form-control.is-valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#28a745;padding-right:calc(1.5em + .75rem)!important}.bootstrap-dark .form-control.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark select.form-control.is-valid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap-dark textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap-dark .custom-select.is-valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap-dark .custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .form-check-input.is-valid~.form-check-label{color:#28a745}.bootstrap-dark .form-check-input.is-valid~.valid-feedback,.bootstrap-dark .form-check-input.is-valid~.valid-tooltip{display:block}.bootstrap-dark .custom-control-input.is-valid~.custom-control-label{color:#28a745}.bootstrap-dark .custom-control-input.is-valid~.custom-control-label:before{border-color:#28a745}.bootstrap-dark .custom-control-input.is-valid:checked~.custom-control-label:before{background-color:#34ce57;border-color:#34ce57}.bootstrap-dark .custom-control-input.is-valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .custom-file-input.is-valid~.custom-file-label{border-color:#28a745}.bootstrap-dark .custom-file-input.is-valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .invalid-feedback{color:#dc3545;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap-dark .invalid-tooltip{background-color:#dc3545e6;border-radius:.25rem;color:#ced4da;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap-dark .invalid-tooltip,.form-row>[class*=col-]>.bootstrap-dark .invalid-tooltip{left:5px}.bootstrap-dark .is-invalid~.invalid-feedback,.bootstrap-dark .is-invalid~.invalid-tooltip{display:block}.bootstrap-dark .form-control.is-invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important}.bootstrap-dark .form-control.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark select.form-control.is-invalid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap-dark textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap-dark .custom-select.is-invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap-dark .custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .form-check-input.is-invalid~.form-check-label{color:#dc3545}.bootstrap-dark .form-check-input.is-invalid~.invalid-feedback,.bootstrap-dark .form-check-input.is-invalid~.invalid-tooltip{display:block}.bootstrap-dark .custom-control-input.is-invalid~.custom-control-label{color:#dc3545}.bootstrap-dark .custom-control-input.is-invalid~.custom-control-label:before{border-color:#dc3545}.bootstrap-dark .custom-control-input.is-invalid:checked~.custom-control-label:before{background-color:#e4606d;border-color:#e4606d}.bootstrap-dark .custom-control-input.is-invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .custom-file-input.is-invalid~.custom-file-label{border-color:#dc3545}.bootstrap-dark .custom-file-input.is-invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .form-inline{align-items:center;display:flex;flex-flow:row wrap}.bootstrap-dark .form-inline .form-check{width:100%}@media(min-width:576px){.bootstrap-dark .form-inline label{align-items:center;display:flex;justify-content:center;margin-bottom:0}.bootstrap-dark .form-inline .form-group{align-items:center;display:flex;flex:0 0 auto;flex-flow:row wrap;margin-bottom:0}.bootstrap-dark .form-inline .form-control{display:inline-block;vertical-align:middle;width:auto}.bootstrap-dark .form-inline .form-control-plaintext{display:inline-block}.bootstrap-dark .form-inline .custom-select,.bootstrap-dark .form-inline .input-group{width:auto}.bootstrap-dark .form-inline .form-check{align-items:center;display:flex;justify-content:center;padding-left:0;width:auto}.bootstrap-dark .form-inline .form-check-input{flex-shrink:0;margin-left:0;margin-right:.25rem;margin-top:0;position:relative}.bootstrap-dark .form-inline .custom-control{align-items:center;justify-content:center}.bootstrap-dark .form-inline .custom-control-label{margin-bottom:0}}.bootstrap-dark .was-validated .valid-feedback{color:#28a745;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap-dark .was-validated .valid-tooltip{background-color:#28a745e6;border-radius:.25rem;color:#ced4da;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap-dark .was-validated .valid-tooltip,.form-row>[class*=col-]>.bootstrap-dark .was-validated .valid-tooltip{left:5px}.bootstrap-dark .was-validated.is-valid~.valid-feedback,.bootstrap-dark .was-validated.is-valid~.valid-tooltip,.bootstrap-dark .was-validated:valid~.valid-feedback,.bootstrap-dark .was-validated:valid~.valid-tooltip{display:block}.bootstrap-dark .was-validated .form-control.is-valid,.bootstrap-dark .was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#28a745;padding-right:calc(1.5em + .75rem)!important}.bootstrap-dark .was-validated .form-control.is-valid:focus,.bootstrap-dark .was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .was-validated select.form-control.is-valid,.bootstrap-dark .was-validated select.form-control:valid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap-dark .was-validated textarea.form-control.is-valid,.bootstrap-dark .was-validated textarea.form-control:valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap-dark .was-validated .custom-select.is-valid,.bootstrap-dark .was-validated .custom-select:valid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap-dark .was-validated .custom-select.is-valid:focus,.bootstrap-dark .was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .was-validated .form-check-input.is-valid~.form-check-label,.bootstrap-dark .was-validated .form-check-input:valid~.form-check-label{color:#28a745}.bootstrap-dark .was-validated .form-check-input.is-valid~.valid-feedback,.bootstrap-dark .was-validated .form-check-input.is-valid~.valid-tooltip,.bootstrap-dark .was-validated .form-check-input:valid~.valid-feedback,.bootstrap-dark .was-validated .form-check-input:valid~.valid-tooltip{display:block}.bootstrap-dark .was-validated .custom-control-input.is-valid~.custom-control-label,.bootstrap-dark .was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.bootstrap-dark .was-validated .custom-control-input.is-valid~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.bootstrap-dark .was-validated .custom-control-input.is-valid:checked~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:valid:checked~.custom-control-label:before{background-color:#34ce57;border-color:#34ce57}.bootstrap-dark .was-validated .custom-control-input.is-valid:focus~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .was-validated .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .was-validated .custom-file-input.is-valid~.custom-file-label,.bootstrap-dark .was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.bootstrap-dark .was-validated .custom-file-input.is-valid:focus~.custom-file-label,.bootstrap-dark .was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem #28a74540}.bootstrap-dark .was-validated .is-valid~.valid-feedback,.bootstrap-dark .was-validated .is-valid~.valid-tooltip,.bootstrap-dark .was-validated :valid~.valid-feedback,.bootstrap-dark .was-validated :valid~.valid-tooltip{display:block}.bootstrap-dark .was-validated .invalid-feedback{color:#dc3545;display:none;font-size:80%;margin-top:.25rem;width:100%}.bootstrap-dark .was-validated .invalid-tooltip{background-color:#dc3545e6;border-radius:.25rem;color:#ced4da;display:none;font-size:.875rem;left:0;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-row>.col>.bootstrap-dark .was-validated .invalid-tooltip,.form-row>[class*=col-]>.bootstrap-dark .was-validated .invalid-tooltip{left:5px}.bootstrap-dark .was-validated.is-invalid~.invalid-feedback,.bootstrap-dark .was-validated.is-invalid~.invalid-tooltip,.bootstrap-dark .was-validated:invalid~.invalid-feedback,.bootstrap-dark .was-validated:invalid~.invalid-tooltip{display:block}.bootstrap-dark .was-validated .form-control.is-invalid,.bootstrap-dark .was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important}.bootstrap-dark .was-validated .form-control.is-invalid:focus,.bootstrap-dark .was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .was-validated select.form-control.is-invalid,.bootstrap-dark .was-validated select.form-control:invalid{background-position:right 1.5rem center;padding-right:3rem!important}.bootstrap-dark .was-validated textarea.form-control.is-invalid,.bootstrap-dark .was-validated textarea.form-control:invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.bootstrap-dark .was-validated .custom-select.is-invalid,.bootstrap-dark .was-validated .custom-select:invalid{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat;border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important}.bootstrap-dark .was-validated .custom-select.is-invalid:focus,.bootstrap-dark .was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .was-validated .form-check-input.is-invalid~.form-check-label,.bootstrap-dark .was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.bootstrap-dark .was-validated .form-check-input.is-invalid~.invalid-feedback,.bootstrap-dark .was-validated .form-check-input.is-invalid~.invalid-tooltip,.bootstrap-dark .was-validated .form-check-input:invalid~.invalid-feedback,.bootstrap-dark .was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.bootstrap-dark .was-validated .custom-control-input.is-invalid~.custom-control-label,.bootstrap-dark .was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.bootstrap-dark .was-validated .custom-control-input.is-invalid~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.bootstrap-dark .was-validated .custom-control-input.is-invalid:checked~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:invalid:checked~.custom-control-label:before{background-color:#e4606d;border-color:#e4606d}.bootstrap-dark .was-validated .custom-control-input.is-invalid:focus~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .was-validated .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.bootstrap-dark .was-validated .custom-file-input.is-invalid~.custom-file-label,.bootstrap-dark .was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.bootstrap-dark .was-validated .custom-file-input.is-invalid:focus~.custom-file-label,.bootstrap-dark .was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem #dc354540}.bootstrap-dark .was-validated .is-invalid~.invalid-feedback,.bootstrap-dark .was-validated .is-invalid~.invalid-tooltip,.bootstrap-dark .was-validated :invalid~.invalid-feedback,.bootstrap-dark .was-validated :invalid~.invalid-tooltip{display:block}.bootstrap-dark .btn{background-color:initial;border:1px solid #0000;border-radius:.25rem;color:#d3d3d3;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;user-select:none;vertical-align:middle}@media(prefers-reduced-motion:reduce){.bootstrap-dark .btn{transition:none}}.bootstrap-dark .btn:hover{color:#d3d3d3;text-decoration:none}.bootstrap-dark .btn.focus,.bootstrap-dark .btn:focus{box-shadow:0 0 0 .2rem #007bff40;outline:0}.bootstrap-dark .btn.disabled,.bootstrap-dark .btn:disabled{opacity:.65}.bootstrap-dark .btn:not(:disabled):not(.disabled){cursor:pointer}.bootstrap-dark a.btn.disabled,.bootstrap-dark fieldset:disabled a.btn{pointer-events:none}.bootstrap-dark .btn-primary{background-color:#007bff;border-color:#007bff;color:#ced4da}.bootstrap-dark .btn-primary:hover{background-color:#0069d9;border-color:#0062cc;color:#ced4da}.bootstrap-dark .btn-primary.focus,.bootstrap-dark .btn-primary:focus{background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem #1f88f980;color:#ced4da}.bootstrap-dark .btn-primary.disabled,.bootstrap-dark .btn-primary:disabled{background-color:#007bff;border-color:#007bff;color:#ced4da}.bootstrap-dark .btn-primary:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-primary:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-primary.dropdown-toggle{background-color:#0062cc;border-color:#005cbf;color:#ced4da}.bootstrap-dark .btn-primary:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-primary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #1f88f980}.bootstrap-dark .btn-secondary{background-color:#6c757d;border-color:#6c757d;color:#ced4da}.bootstrap-dark .btn-secondary:hover{background-color:#5a6268;border-color:#545b62;color:#ced4da}.bootstrap-dark .btn-secondary.focus,.bootstrap-dark .btn-secondary:focus{background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem #7b838b80;color:#ced4da}.bootstrap-dark .btn-secondary.disabled,.bootstrap-dark .btn-secondary:disabled{background-color:#6c757d;border-color:#6c757d;color:#ced4da}.bootstrap-dark .btn-secondary:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-secondary:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-secondary.dropdown-toggle{background-color:#545b62;border-color:#4e555b;color:#ced4da}.bootstrap-dark .btn-secondary:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #7b838b80}.bootstrap-dark .btn-success{background-color:#28a745;border-color:#28a745;color:#ced4da}.bootstrap-dark .btn-success:hover{background-color:#218838;border-color:#1e7e34;color:#ced4da}.bootstrap-dark .btn-success.focus,.bootstrap-dark .btn-success:focus{background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem #41ae5b80;color:#ced4da}.bootstrap-dark .btn-success.disabled,.bootstrap-dark .btn-success:disabled{background-color:#28a745;border-color:#28a745;color:#ced4da}.bootstrap-dark .btn-success:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-success:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-success.dropdown-toggle{background-color:#1e7e34;border-color:#1c7430;color:#ced4da}.bootstrap-dark .btn-success:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-success:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #41ae5b80}.bootstrap-dark .btn-info{background-color:#17a2b8;border-color:#17a2b8;color:#ced4da}.bootstrap-dark .btn-info:hover{background-color:#138496;border-color:#117a8b;color:#ced4da}.bootstrap-dark .btn-info.focus,.bootstrap-dark .btn-info:focus{background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem #32aabd80;color:#ced4da}.bootstrap-dark .btn-info.disabled,.bootstrap-dark .btn-info:disabled{background-color:#17a2b8;border-color:#17a2b8;color:#ced4da}.bootstrap-dark .btn-info:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-info:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-info.dropdown-toggle{background-color:#117a8b;border-color:#10707f;color:#ced4da}.bootstrap-dark .btn-info:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-info:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #32aabd80}.bootstrap-dark .btn-warning{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap-dark .btn-warning:hover{background-color:#e0a800;border-color:#d39e00;color:#212529}.bootstrap-dark .btn-warning.focus,.bootstrap-dark .btn-warning:focus{background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem #deaa0c80;color:#212529}.bootstrap-dark .btn-warning.disabled,.bootstrap-dark .btn-warning:disabled{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap-dark .btn-warning:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-warning:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-warning.dropdown-toggle{background-color:#d39e00;border-color:#c69500;color:#212529}.bootstrap-dark .btn-warning:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-warning:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #deaa0c80}.bootstrap-dark .btn-danger{background-color:#dc3545;border-color:#dc3545;color:#ced4da}.bootstrap-dark .btn-danger:hover{background-color:#c82333;border-color:#bd2130;color:#ced4da}.bootstrap-dark .btn-danger.focus,.bootstrap-dark .btn-danger:focus{background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem #da4d5b80;color:#ced4da}.bootstrap-dark .btn-danger.disabled,.bootstrap-dark .btn-danger:disabled{background-color:#dc3545;border-color:#dc3545;color:#ced4da}.bootstrap-dark .btn-danger:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-danger:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-danger.dropdown-toggle{background-color:#bd2130;border-color:#b21f2d;color:#ced4da}.bootstrap-dark .btn-danger:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-danger:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #da4d5b80}.bootstrap-dark .btn-light{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap-dark .btn-light:hover{background-color:#e2e6ea;border-color:#dae0e5;color:#212529}.bootstrap-dark .btn-light.focus,.bootstrap-dark .btn-light:focus{background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem #d8d9db80;color:#212529}.bootstrap-dark .btn-light.disabled,.bootstrap-dark .btn-light:disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap-dark .btn-light:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-light:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-light.dropdown-toggle{background-color:#dae0e5;border-color:#d3d9df;color:#212529}.bootstrap-dark .btn-light:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-light:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #d8d9db80}.bootstrap-dark .btn-dark{background-color:#343a40;border-color:#343a40;color:#ced4da}.bootstrap-dark .btn-dark:hover{background-color:#23272b;border-color:#1d2124;color:#ced4da}.bootstrap-dark .btn-dark.focus,.bootstrap-dark .btn-dark:focus{background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem #4b515780;color:#ced4da}.bootstrap-dark .btn-dark.disabled,.bootstrap-dark .btn-dark:disabled{background-color:#343a40;border-color:#343a40;color:#ced4da}.bootstrap-dark .btn-dark:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-dark:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-dark.dropdown-toggle{background-color:#1d2124;border-color:#171a1d;color:#ced4da}.bootstrap-dark .btn-dark:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-dark:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #4b515780}.bootstrap-dark .btn-outline-primary{border-color:#007bff;color:#007bff}.bootstrap-dark .btn-outline-primary:hover{background-color:#007bff;border-color:#007bff;color:#ced4da}.bootstrap-dark .btn-outline-primary.focus,.bootstrap-dark .btn-outline-primary:focus{box-shadow:0 0 0 .2rem #007bff80}.bootstrap-dark .btn-outline-primary.disabled,.bootstrap-dark .btn-outline-primary:disabled{background-color:initial;color:#007bff}.bootstrap-dark .btn-outline-primary:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-primary:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-primary.dropdown-toggle{background-color:#007bff;border-color:#007bff;color:#ced4da}.bootstrap-dark .btn-outline-primary:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #007bff80}.bootstrap-dark .btn-outline-secondary{border-color:#6c757d;color:#6c757d}.bootstrap-dark .btn-outline-secondary:hover{background-color:#6c757d;border-color:#6c757d;color:#ced4da}.bootstrap-dark .btn-outline-secondary.focus,.bootstrap-dark .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem #6c757d80}.bootstrap-dark .btn-outline-secondary.disabled,.bootstrap-dark .btn-outline-secondary:disabled{background-color:initial;color:#6c757d}.bootstrap-dark .btn-outline-secondary:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-secondary.dropdown-toggle{background-color:#6c757d;border-color:#6c757d;color:#ced4da}.bootstrap-dark .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #6c757d80}.bootstrap-dark .btn-outline-success{border-color:#28a745;color:#28a745}.bootstrap-dark .btn-outline-success:hover{background-color:#28a745;border-color:#28a745;color:#ced4da}.bootstrap-dark .btn-outline-success.focus,.bootstrap-dark .btn-outline-success:focus{box-shadow:0 0 0 .2rem #28a74580}.bootstrap-dark .btn-outline-success.disabled,.bootstrap-dark .btn-outline-success:disabled{background-color:initial;color:#28a745}.bootstrap-dark .btn-outline-success:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-success:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-success.dropdown-toggle{background-color:#28a745;border-color:#28a745;color:#ced4da}.bootstrap-dark .btn-outline-success:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #28a74580}.bootstrap-dark .btn-outline-info{border-color:#17a2b8;color:#17a2b8}.bootstrap-dark .btn-outline-info:hover{background-color:#17a2b8;border-color:#17a2b8;color:#ced4da}.bootstrap-dark .btn-outline-info.focus,.bootstrap-dark .btn-outline-info:focus{box-shadow:0 0 0 .2rem #17a2b880}.bootstrap-dark .btn-outline-info.disabled,.bootstrap-dark .btn-outline-info:disabled{background-color:initial;color:#17a2b8}.bootstrap-dark .btn-outline-info:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-info:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-info.dropdown-toggle{background-color:#17a2b8;border-color:#17a2b8;color:#ced4da}.bootstrap-dark .btn-outline-info:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #17a2b880}.bootstrap-dark .btn-outline-warning{border-color:#ffc107;color:#ffc107}.bootstrap-dark .btn-outline-warning:hover{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap-dark .btn-outline-warning.focus,.bootstrap-dark .btn-outline-warning:focus{box-shadow:0 0 0 .2rem #ffc10780}.bootstrap-dark .btn-outline-warning.disabled,.bootstrap-dark .btn-outline-warning:disabled{background-color:initial;color:#ffc107}.bootstrap-dark .btn-outline-warning:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-warning:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-warning.dropdown-toggle{background-color:#ffc107;border-color:#ffc107;color:#212529}.bootstrap-dark .btn-outline-warning:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #ffc10780}.bootstrap-dark .btn-outline-danger{border-color:#dc3545;color:#dc3545}.bootstrap-dark .btn-outline-danger:hover{background-color:#dc3545;border-color:#dc3545;color:#ced4da}.bootstrap-dark .btn-outline-danger.focus,.bootstrap-dark .btn-outline-danger:focus{box-shadow:0 0 0 .2rem #dc354580}.bootstrap-dark .btn-outline-danger.disabled,.bootstrap-dark .btn-outline-danger:disabled{background-color:initial;color:#dc3545}.bootstrap-dark .btn-outline-danger:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-danger:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-danger.dropdown-toggle{background-color:#dc3545;border-color:#dc3545;color:#ced4da}.bootstrap-dark .btn-outline-danger:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #dc354580}.bootstrap-dark .btn-outline-light{border-color:#f8f9fa;color:#f8f9fa}.bootstrap-dark .btn-outline-light:hover{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap-dark .btn-outline-light.focus,.bootstrap-dark .btn-outline-light:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.bootstrap-dark .btn-outline-light.disabled,.bootstrap-dark .btn-outline-light:disabled{background-color:initial;color:#f8f9fa}.bootstrap-dark .btn-outline-light:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-light:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-light.dropdown-toggle{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.bootstrap-dark .btn-outline-light:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #f8f9fa80}.bootstrap-dark .btn-outline-dark{border-color:#343a40;color:#343a40}.bootstrap-dark .btn-outline-dark:hover{background-color:#343a40;border-color:#343a40;color:#ced4da}.bootstrap-dark .btn-outline-dark.focus,.bootstrap-dark .btn-outline-dark:focus{box-shadow:0 0 0 .2rem #343a4080}.bootstrap-dark .btn-outline-dark.disabled,.bootstrap-dark .btn-outline-dark:disabled{background-color:initial;color:#343a40}.bootstrap-dark .btn-outline-dark:not(:disabled):not(.disabled).active,.bootstrap-dark .btn-outline-dark:not(:disabled):not(.disabled):active,.show>.bootstrap-dark .btn-outline-dark.dropdown-toggle{background-color:#343a40;border-color:#343a40;color:#ced4da}.bootstrap-dark .btn-outline-dark:not(:disabled):not(.disabled).active:focus,.bootstrap-dark .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.bootstrap-dark .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem #343a4080}.bootstrap-dark .btn-link{color:#adadad;font-weight:400;text-decoration:none}.bootstrap-dark .btn-link:hover{color:#878787;text-decoration:underline}.bootstrap-dark .btn-link.focus,.bootstrap-dark .btn-link:focus{text-decoration:underline}.bootstrap-dark .btn-link.disabled,.bootstrap-dark .btn-link:disabled{color:#6c757d;pointer-events:none}.bootstrap-dark .btn-group-lg>.btn,.bootstrap-dark .btn-lg{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.bootstrap-dark .btn-group-sm>.btn,.bootstrap-dark .btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap-dark .btn-block{display:block;width:100%}.bootstrap-dark .btn-block+.btn-block{margin-top:.5rem}.bootstrap-dark input[type=button].btn-block,.bootstrap-dark input[type=reset].btn-block,.bootstrap-dark input[type=submit].btn-block{width:100%}.bootstrap-dark .fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.bootstrap-dark .fade{transition:none}}.bootstrap-dark .fade:not(.show){opacity:0}.bootstrap-dark .collapse:not(.show){display:none}.bootstrap-dark .collapsing{height:0;overflow:hidden;position:relative;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.bootstrap-dark .collapsing{transition:none}}.bootstrap-dark .dropdown,.bootstrap-dark .dropleft,.bootstrap-dark .dropright,.bootstrap-dark .dropup{position:relative}.bootstrap-dark .dropdown-toggle{white-space:nowrap}.bootstrap-dark .dropdown-toggle:after{border-bottom:0;border-left:.3em solid #0000;border-right:.3em solid #0000;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap-dark .dropdown-toggle:empty:after{margin-left:0}.bootstrap-dark .dropdown-menu{background-clip:padding-box;background-color:#000;border:1px solid #ffffff26;border-radius:.25rem;color:#d3d3d3;display:none;float:left;font-size:1rem;left:0;list-style:none;margin:.125rem 0 0;min-width:10rem;padding:.5rem 0;position:absolute;text-align:left;top:100%;z-index:1000}.bootstrap-dark .dropdown-menu-left{left:0;right:auto}.bootstrap-dark .dropdown-menu-right{left:auto;right:0}@media(min-width:576px){.bootstrap-dark .dropdown-menu-sm-left{left:0;right:auto}.bootstrap-dark .dropdown-menu-sm-right{left:auto;right:0}}@media(min-width:768px){.bootstrap-dark .dropdown-menu-md-left{left:0;right:auto}.bootstrap-dark .dropdown-menu-md-right{left:auto;right:0}}@media(min-width:992px){.bootstrap-dark .dropdown-menu-lg-left{left:0;right:auto}.bootstrap-dark .dropdown-menu-lg-right{left:auto;right:0}}@media(min-width:1200px){.bootstrap-dark .dropdown-menu-xl-left{left:0;right:auto}.bootstrap-dark .dropdown-menu-xl-right{left:auto;right:0}}.bootstrap-dark .dropup .dropdown-menu{bottom:100%;margin-bottom:.125rem;margin-top:0;top:auto}.bootstrap-dark .dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid #0000;border-right:.3em solid #0000;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap-dark .dropup .dropdown-toggle:empty:after{margin-left:0}.bootstrap-dark .dropright .dropdown-menu{left:100%;margin-left:.125rem;margin-top:0;right:auto;top:0}.bootstrap-dark .dropright .dropdown-toggle:after{border-bottom:.3em solid #0000;border-left:.3em solid;border-right:0;border-top:.3em solid #0000;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.bootstrap-dark .dropright .dropdown-toggle:empty:after{margin-left:0}.bootstrap-dark .dropright .dropdown-toggle:after{vertical-align:0}.bootstrap-dark .dropleft .dropdown-menu{left:auto;margin-right:.125rem;margin-top:0;right:100%;top:0}.bootstrap-dark .dropleft .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.bootstrap-dark .dropleft .dropdown-toggle:before{border-bottom:.3em solid #0000;border-right:.3em solid;border-top:.3em solid #0000;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.bootstrap-dark .dropleft .dropdown-toggle:empty:after{margin-left:0}.bootstrap-dark .dropleft .dropdown-toggle:before{vertical-align:0}.bootstrap-dark .dropdown-menu[x-placement^=bottom],.bootstrap-dark .dropdown-menu[x-placement^=left],.bootstrap-dark .dropdown-menu[x-placement^=right],.bootstrap-dark .dropdown-menu[x-placement^=top]{bottom:auto;right:auto}.bootstrap-dark .dropdown-divider{border-top:1px solid #343a40;height:0;margin:.5rem 0;overflow:hidden}.bootstrap-dark .dropdown-item{background-color:initial;border:0;clear:both;color:#f8f9fa;display:block;font-weight:400;padding:.25rem 1.5rem;text-align:inherit;white-space:nowrap;width:100%}.bootstrap-dark .dropdown-item:focus,.bootstrap-dark .dropdown-item:hover{background-color:#212529;color:#fff;text-decoration:none}.bootstrap-dark .dropdown-item.active,.bootstrap-dark .dropdown-item:active{background-color:#3395ff;color:#000;text-decoration:none}.bootstrap-dark .dropdown-item.disabled,.bootstrap-dark .dropdown-item:disabled{background-color:initial;color:#ced4da;pointer-events:none}.bootstrap-dark .dropdown-menu.show{display:block}.bootstrap-dark .dropdown-header{color:#ced4da;display:block;font-size:.875rem;margin-bottom:0;padding:.5rem 1.5rem;white-space:nowrap}.bootstrap-dark .dropdown-item-text{color:#f8f9fa;display:block;padding:.25rem 1.5rem}.bootstrap-dark .btn-group,.bootstrap-dark .btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.bootstrap-dark .btn-group-vertical>.btn,.bootstrap-dark .btn-group>.btn{flex:1 1 auto;position:relative}.bootstrap-dark .btn-group-vertical>.btn.active,.bootstrap-dark .btn-group-vertical>.btn:active,.bootstrap-dark .btn-group-vertical>.btn:focus,.bootstrap-dark .btn-group-vertical>.btn:hover,.bootstrap-dark .btn-group>.btn.active,.bootstrap-dark .btn-group>.btn:active,.bootstrap-dark .btn-group>.btn:focus,.bootstrap-dark .btn-group>.btn:hover{z-index:1}.bootstrap-dark .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.bootstrap-dark .btn-toolbar .input-group{width:auto}.bootstrap-dark .btn-group>.btn-group:not(:first-child),.bootstrap-dark .btn-group>.btn:not(:first-child){margin-left:-1px}.bootstrap-dark .btn-group>.btn-group:not(:last-child)>.btn,.bootstrap-dark .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .btn-group>.btn-group:not(:first-child)>.btn,.bootstrap-dark .btn-group>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap-dark .dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.bootstrap-dark .dropdown-toggle-split:after,.dropright .bootstrap-dark .dropdown-toggle-split:after,.dropup .bootstrap-dark .dropdown-toggle-split:after{margin-left:0}.dropleft .bootstrap-dark .dropdown-toggle-split:before{margin-right:0}.bootstrap-dark .btn-group-sm>.btn+.dropdown-toggle-split,.bootstrap-dark .btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.bootstrap-dark .btn-group-lg>.btn+.dropdown-toggle-split,.bootstrap-dark .btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.bootstrap-dark .btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.bootstrap-dark .btn-group-vertical>.btn,.bootstrap-dark .btn-group-vertical>.btn-group{width:100%}.bootstrap-dark .btn-group-vertical>.btn-group:not(:first-child),.bootstrap-dark .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.bootstrap-dark .btn-group-vertical>.btn-group:not(:last-child)>.btn,.bootstrap-dark .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap-dark .btn-group-vertical>.btn-group:not(:first-child)>.btn,.bootstrap-dark .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.bootstrap-dark .btn-group-toggle>.btn,.bootstrap-dark .btn-group-toggle>.btn-group>.btn{margin-bottom:0}.bootstrap-dark .btn-group-toggle>.btn input[type=checkbox],.bootstrap-dark .btn-group-toggle>.btn input[type=radio],.bootstrap-dark .btn-group-toggle>.btn-group>.btn input[type=checkbox],.bootstrap-dark .btn-group-toggle>.btn-group>.btn input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.bootstrap-dark .input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.bootstrap-dark .input-group>.custom-file,.bootstrap-dark .input-group>.custom-select,.bootstrap-dark .input-group>.form-control,.bootstrap-dark .input-group>.form-control-plaintext{flex:1 1 auto;margin-bottom:0;min-width:0;position:relative;width:1%}.bootstrap-dark .input-group>.custom-file+.custom-file,.bootstrap-dark .input-group>.custom-file+.custom-select,.bootstrap-dark .input-group>.custom-file+.form-control,.bootstrap-dark .input-group>.custom-select+.custom-file,.bootstrap-dark .input-group>.custom-select+.custom-select,.bootstrap-dark .input-group>.custom-select+.form-control,.bootstrap-dark .input-group>.form-control+.custom-file,.bootstrap-dark .input-group>.form-control+.custom-select,.bootstrap-dark .input-group>.form-control+.form-control,.bootstrap-dark .input-group>.form-control-plaintext+.custom-file,.bootstrap-dark .input-group>.form-control-plaintext+.custom-select,.bootstrap-dark .input-group>.form-control-plaintext+.form-control{margin-left:-1px}.bootstrap-dark .input-group>.custom-file .custom-file-input:focus~.custom-file-label,.bootstrap-dark .input-group>.custom-select:focus,.bootstrap-dark .input-group>.form-control:focus{z-index:3}.bootstrap-dark .input-group>.custom-file .custom-file-input:focus{z-index:4}.bootstrap-dark .input-group>.custom-select:not(:first-child),.bootstrap-dark .input-group>.form-control:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap-dark .input-group>.custom-file{align-items:center;display:flex}.bootstrap-dark .input-group>.custom-file:not(:last-child) .custom-file-label,.bootstrap-dark .input-group>.custom-file:not(:last-child) .custom-file-label:after{border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .input-group>.custom-file:not(:first-child) .custom-file-label{border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap-dark .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.bootstrap-dark .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.bootstrap-dark .input-group.has-validation>.custom-select:nth-last-child(n+3),.bootstrap-dark .input-group.has-validation>.form-control:nth-last-child(n+3),.bootstrap-dark .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.bootstrap-dark .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.bootstrap-dark .input-group:not(.has-validation)>.custom-select:not(:last-child),.bootstrap-dark .input-group:not(.has-validation)>.form-control:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .input-group-append,.bootstrap-dark .input-group-prepend{display:flex}.bootstrap-dark .input-group-append .btn,.bootstrap-dark .input-group-prepend .btn{position:relative;z-index:2}.bootstrap-dark .input-group-append .btn:focus,.bootstrap-dark .input-group-prepend .btn:focus{z-index:3}.bootstrap-dark .input-group-append .btn+.btn,.bootstrap-dark .input-group-append .btn+.input-group-text,.bootstrap-dark .input-group-append .input-group-text+.btn,.bootstrap-dark .input-group-append .input-group-text+.input-group-text,.bootstrap-dark .input-group-prepend .btn+.btn,.bootstrap-dark .input-group-prepend .btn+.input-group-text,.bootstrap-dark .input-group-prepend .input-group-text+.btn,.bootstrap-dark .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.bootstrap-dark .input-group-prepend{margin-right:-1px}.bootstrap-dark .input-group-append{margin-left:-1px}.bootstrap-dark .input-group-text{align-items:center;background-color:#343a40;border:1px solid #6c757d;border-radius:.25rem;color:#dee2e6;display:flex;font-size:1rem;font-weight:400;line-height:1.5;margin-bottom:0;padding:.375rem .75rem;text-align:center;white-space:nowrap}.bootstrap-dark .input-group-text input[type=checkbox],.bootstrap-dark .input-group-text input[type=radio]{margin-top:0}.bootstrap-dark .input-group-lg>.custom-select,.bootstrap-dark .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.bootstrap-dark .input-group-lg>.custom-select,.bootstrap-dark .input-group-lg>.form-control,.bootstrap-dark .input-group-lg>.input-group-append>.btn,.bootstrap-dark .input-group-lg>.input-group-append>.input-group-text,.bootstrap-dark .input-group-lg>.input-group-prepend>.btn,.bootstrap-dark .input-group-lg>.input-group-prepend>.input-group-text{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.bootstrap-dark .input-group-sm>.custom-select,.bootstrap-dark .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.bootstrap-dark .input-group-sm>.custom-select,.bootstrap-dark .input-group-sm>.form-control,.bootstrap-dark .input-group-sm>.input-group-append>.btn,.bootstrap-dark .input-group-sm>.input-group-append>.input-group-text,.bootstrap-dark .input-group-sm>.input-group-prepend>.btn,.bootstrap-dark .input-group-sm>.input-group-prepend>.input-group-text{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap-dark .input-group-lg>.custom-select,.bootstrap-dark .input-group-sm>.custom-select{padding-right:1.75rem}.bootstrap-dark .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.bootstrap-dark .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.bootstrap-dark .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.bootstrap-dark .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.bootstrap-dark .input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.bootstrap-dark .input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.bootstrap-dark .input-group>.input-group-prepend>.btn,.bootstrap-dark .input-group>.input-group-prepend>.input-group-text{border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .input-group>.input-group-append>.btn,.bootstrap-dark .input-group>.input-group-append>.custom-select,.bootstrap-dark .input-group>.input-group-append>.input-group-text,.bootstrap-dark .input-group>.input-group-prepend:first-child>.btn:not(:first-child),.bootstrap-dark .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.bootstrap-dark .input-group>.input-group-prepend:not(:first-child)>.btn,.bootstrap-dark .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap-dark .input-group>.input-group-prepend>.custom-select{border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .custom-control{-webkit-print-color-adjust:exact;color-adjust:exact;display:block;min-height:1.5rem;padding-left:1.5rem;position:relative;z-index:1}.bootstrap-dark .custom-control-inline{display:inline-flex;margin-right:1rem}.bootstrap-dark .custom-control-input{height:1.25rem;left:0;opacity:0;position:absolute;width:1rem;z-index:-1}.bootstrap-dark .custom-control-input:checked~.custom-control-label:before{background-color:#007bff;border-color:#007bff;color:#fff}.bootstrap-dark .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem #007bff40}.bootstrap-dark .custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#80bdff}.bootstrap-dark .custom-control-input:not(:disabled):active~.custom-control-label:before{background-color:#b3d7ff;border-color:#b3d7ff;color:#fff}.bootstrap-dark .custom-control-input:disabled~.custom-control-label,.bootstrap-dark .custom-control-input[disabled]~.custom-control-label{color:#6c757d}.bootstrap-dark .custom-control-input:disabled~.custom-control-label:before,.bootstrap-dark .custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.bootstrap-dark .custom-control-label{margin-bottom:0;position:relative;vertical-align:top}.bootstrap-dark .custom-control-label:before{background-color:#fff;border:1px solid #adb5bd;pointer-events:none}.bootstrap-dark .custom-control-label:after,.bootstrap-dark .custom-control-label:before{content:"";display:block;height:1rem;left:-1.5rem;position:absolute;top:.25rem;width:1rem}.bootstrap-dark .custom-control-label:after{background:50%/50% 50% no-repeat}.bootstrap-dark .custom-checkbox .custom-control-label:before{border-radius:.25rem}.bootstrap-dark .custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='m6.564.75-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.bootstrap-dark .custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{background-color:#007bff;border-color:#007bff}.bootstrap-dark .custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.bootstrap-dark .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before,.bootstrap-dark .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:#007bff80}.bootstrap-dark .custom-radio .custom-control-label:before{border-radius:50%}.bootstrap-dark .custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.bootstrap-dark .custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#007bff80}.bootstrap-dark .custom-switch{padding-left:2.25rem}.bootstrap-dark .custom-switch .custom-control-label:before{border-radius:.5rem;left:-2.25rem;pointer-events:all;width:1.75rem}.bootstrap-dark .custom-switch .custom-control-label:after{background-color:#adb5bd;border-radius:.5rem;height:calc(1rem - 4px);left:calc(-2.25rem + 2px);top:calc(.25rem + 2px);transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:calc(1rem - 4px)}@media(prefers-reduced-motion:reduce){.bootstrap-dark .custom-switch .custom-control-label:after{transition:none}}.bootstrap-dark .custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.bootstrap-dark .custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:#007bff80}.bootstrap-dark .custom-select{-webkit-appearance:none;appearance:none;background:#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0 0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat;border:1px solid #6c757d;border-radius:.25rem;color:#dee2e6;display:inline-block;font-size:1rem;font-weight:400;height:calc(1.5em + .75rem + 2px);line-height:1.5;padding:.375rem 1.75rem .375rem .75rem;vertical-align:middle;width:100%}.bootstrap-dark .custom-select:focus{border-color:#80bdff;box-shadow:0 0 0 .2rem #007bff40;outline:0}.bootstrap-dark .custom-select:focus::-ms-value{background-color:#000;color:#dee2e6}.bootstrap-dark .custom-select[multiple],.bootstrap-dark .custom-select[size]:not([size="1"]){background-image:none;height:auto;padding-right:.75rem}.bootstrap-dark .custom-select:disabled{background-color:#343a40;color:#ced4da}.bootstrap-dark .custom-select::-ms-expand{display:none}.bootstrap-dark .custom-select:-moz-focusring{color:#0000;text-shadow:0 0 0 #dee2e6}.bootstrap-dark .custom-select-sm{font-size:.875rem;height:calc(1.5em + .5rem + 2px);padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.bootstrap-dark .custom-select-lg{font-size:1.25rem;height:calc(1.5em + 1rem + 2px);padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.bootstrap-dark .custom-file{display:inline-block;height:calc(1.5em + .75rem + 2px);margin-bottom:0;position:relative;width:100%}.bootstrap-dark .custom-file-input{height:calc(1.5em + .75rem + 2px);margin:0;opacity:0;overflow:hidden;position:relative;width:100%;z-index:2}.bootstrap-dark .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem #007bff40}.bootstrap-dark .custom-file-input:disabled~.custom-file-label,.bootstrap-dark .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.bootstrap-dark .custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.bootstrap-dark .custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.bootstrap-dark .custom-file-label{background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;font-weight:400;height:calc(1.5em + .75rem + 2px);left:0;overflow:hidden;z-index:1}.bootstrap-dark .custom-file-label,.bootstrap-dark .custom-file-label:after{color:#495057;line-height:1.5;padding:.375rem .75rem;position:absolute;right:0;top:0}.bootstrap-dark .custom-file-label:after{background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0;bottom:0;content:"Browse";display:block;height:calc(1.5em + .75rem);z-index:3}.bootstrap-dark .custom-range{-webkit-appearance:none;appearance:none;background-color:initial;height:1.4rem;padding:0;width:100%}.bootstrap-dark .custom-range:focus{outline:0}.bootstrap-dark .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap-dark .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap-dark .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem #007bff40}.bootstrap-dark .custom-range::-moz-focus-outer{border:0}.bootstrap-dark .custom-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap-dark .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.bootstrap-dark .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.bootstrap-dark .custom-range::-webkit-slider-runnable-track{background-color:#dee2e6;border-color:#0000;border-radius:1rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap-dark .custom-range::-moz-range-thumb{appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap-dark .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.bootstrap-dark .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.bootstrap-dark .custom-range::-moz-range-track{background-color:#dee2e6;border-color:#0000;border-radius:1rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap-dark .custom-range::-ms-thumb{appearance:none;background-color:#007bff;border:0;border-radius:1rem;height:1rem;margin-left:.2rem;margin-right:.2rem;margin-top:0;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap-dark .custom-range::-ms-thumb{-ms-transition:none;transition:none}}.bootstrap-dark .custom-range::-ms-thumb:active{background-color:#b3d7ff}.bootstrap-dark .custom-range::-ms-track{background-color:initial;border-color:#0000;border-width:.5rem;color:#0000;cursor:pointer;height:.5rem;width:100%}.bootstrap-dark .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.bootstrap-dark .custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem;margin-right:15px}.bootstrap-dark .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.bootstrap-dark .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.bootstrap-dark .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.bootstrap-dark .custom-range:disabled::-moz-range-track{cursor:default}.bootstrap-dark .custom-range:disabled::-ms-thumb{background-color:#adb5bd}.bootstrap-dark .custom-control-label:before,.bootstrap-dark .custom-file-label,.bootstrap-dark .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.bootstrap-dark .custom-control-label:before,.bootstrap-dark .custom-file-label,.bootstrap-dark .custom-select{transition:none}}.bootstrap-dark .nav{display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.bootstrap-dark .nav-link{display:block;padding:.5rem 1rem}.bootstrap-dark .nav-link:focus,.bootstrap-dark .nav-link:hover{text-decoration:none}.bootstrap-dark .nav-link.disabled{color:#6c757d;cursor:default;pointer-events:none}.bootstrap-dark .nav-tabs{border-bottom:1px solid hsla(0,0%,100%,.125)}.bootstrap-dark .nav-tabs .nav-link{border:1px solid #0000;border-top-left-radius:.25rem;border-top-right-radius:.25rem;margin-bottom:-1px}.bootstrap-dark .nav-tabs .nav-link:focus,.bootstrap-dark .nav-tabs .nav-link:hover{border-color:#495057 #495057 hsla(0,0%,100%,.125)}.bootstrap-dark .nav-tabs .nav-link.disabled{background-color:initial;border-color:#0000;color:#6c757d}.bootstrap-dark .nav-tabs .nav-item.show .nav-link,.bootstrap-dark .nav-tabs .nav-link.active{background-color:#191d21;border-color:#495057 #495057 #191d21;color:#f8f9fa}.bootstrap-dark .nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:-1px}.bootstrap-dark .nav-pills .nav-link{border-radius:.25rem}.bootstrap-dark .nav-pills .nav-link.active,.bootstrap-dark .nav-pills .show>.nav-link{background-color:#007bff;color:#fff}.bootstrap-dark .nav-fill .nav-item,.bootstrap-dark .nav-fill>.nav-link{flex:1 1 auto;text-align:center}.bootstrap-dark .nav-justified .nav-item,.bootstrap-dark .nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.bootstrap-dark .tab-content>.tab-pane{display:none}.bootstrap-dark .tab-content>.active{display:block}.bootstrap-dark .navbar{padding:.5rem 1rem;position:relative}.bootstrap-dark .navbar,.bootstrap-dark .navbar .container,.bootstrap-dark .navbar .container-fluid,.bootstrap-dark .navbar .container-lg,.bootstrap-dark .navbar .container-md,.bootstrap-dark .navbar .container-sm,.bootstrap-dark .navbar .container-xl{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.bootstrap-dark .navbar-brand{display:inline-block;font-size:1.25rem;line-height:inherit;margin-right:1rem;padding-bottom:.3125rem;padding-top:.3125rem;white-space:nowrap}.bootstrap-dark .navbar-brand:focus,.bootstrap-dark .navbar-brand:hover{text-decoration:none}.bootstrap-dark .navbar-nav{display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.bootstrap-dark .navbar-nav .nav-link{padding-left:0;padding-right:0}.bootstrap-dark .navbar-nav .dropdown-menu{float:none;position:static}.bootstrap-dark .navbar-text{display:inline-block;padding-bottom:.5rem;padding-top:.5rem}.bootstrap-dark .navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.bootstrap-dark .navbar-toggler{background-color:initial;border:1px solid #0000;border-radius:.25rem;font-size:1.25rem;line-height:1;padding:.25rem .75rem}.bootstrap-dark .navbar-toggler:focus,.bootstrap-dark .navbar-toggler:hover{text-decoration:none}.bootstrap-dark .navbar-toggler-icon{background:50%/100% 100% no-repeat;content:"";display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.bootstrap-dark .navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media(max-width:575.98px){.bootstrap-dark .navbar-expand-sm>.container,.bootstrap-dark .navbar-expand-sm>.container-fluid,.bootstrap-dark .navbar-expand-sm>.container-lg,.bootstrap-dark .navbar-expand-sm>.container-md,.bootstrap-dark .navbar-expand-sm>.container-sm,.bootstrap-dark .navbar-expand-sm>.container-xl{padding-left:0;padding-right:0}}@media(min-width:576px){.bootstrap-dark .navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.bootstrap-dark .navbar-expand-sm .navbar-nav{flex-direction:row}.bootstrap-dark .navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.bootstrap-dark .navbar-expand-sm .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap-dark .navbar-expand-sm>.container,.bootstrap-dark .navbar-expand-sm>.container-fluid,.bootstrap-dark .navbar-expand-sm>.container-lg,.bootstrap-dark .navbar-expand-sm>.container-md,.bootstrap-dark .navbar-expand-sm>.container-sm,.bootstrap-dark .navbar-expand-sm>.container-xl{flex-wrap:nowrap}.bootstrap-dark .navbar-expand-sm .navbar-nav-scroll{overflow:visible}.bootstrap-dark .navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap-dark .navbar-expand-sm .navbar-toggler{display:none}}@media(max-width:767.98px){.bootstrap-dark .navbar-expand-md>.container,.bootstrap-dark .navbar-expand-md>.container-fluid,.bootstrap-dark .navbar-expand-md>.container-lg,.bootstrap-dark .navbar-expand-md>.container-md,.bootstrap-dark .navbar-expand-md>.container-sm,.bootstrap-dark .navbar-expand-md>.container-xl{padding-left:0;padding-right:0}}@media(min-width:768px){.bootstrap-dark .navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.bootstrap-dark .navbar-expand-md .navbar-nav{flex-direction:row}.bootstrap-dark .navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.bootstrap-dark .navbar-expand-md .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap-dark .navbar-expand-md>.container,.bootstrap-dark .navbar-expand-md>.container-fluid,.bootstrap-dark .navbar-expand-md>.container-lg,.bootstrap-dark .navbar-expand-md>.container-md,.bootstrap-dark .navbar-expand-md>.container-sm,.bootstrap-dark .navbar-expand-md>.container-xl{flex-wrap:nowrap}.bootstrap-dark .navbar-expand-md .navbar-nav-scroll{overflow:visible}.bootstrap-dark .navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap-dark .navbar-expand-md .navbar-toggler{display:none}}@media(max-width:991.98px){.bootstrap-dark .navbar-expand-lg>.container,.bootstrap-dark .navbar-expand-lg>.container-fluid,.bootstrap-dark .navbar-expand-lg>.container-lg,.bootstrap-dark .navbar-expand-lg>.container-md,.bootstrap-dark .navbar-expand-lg>.container-sm,.bootstrap-dark .navbar-expand-lg>.container-xl{padding-left:0;padding-right:0}}@media(min-width:992px){.bootstrap-dark .navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.bootstrap-dark .navbar-expand-lg .navbar-nav{flex-direction:row}.bootstrap-dark .navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.bootstrap-dark .navbar-expand-lg .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap-dark .navbar-expand-lg>.container,.bootstrap-dark .navbar-expand-lg>.container-fluid,.bootstrap-dark .navbar-expand-lg>.container-lg,.bootstrap-dark .navbar-expand-lg>.container-md,.bootstrap-dark .navbar-expand-lg>.container-sm,.bootstrap-dark .navbar-expand-lg>.container-xl{flex-wrap:nowrap}.bootstrap-dark .navbar-expand-lg .navbar-nav-scroll{overflow:visible}.bootstrap-dark .navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap-dark .navbar-expand-lg .navbar-toggler{display:none}}@media(max-width:1199.98px){.bootstrap-dark .navbar-expand-xl>.container,.bootstrap-dark .navbar-expand-xl>.container-fluid,.bootstrap-dark .navbar-expand-xl>.container-lg,.bootstrap-dark .navbar-expand-xl>.container-md,.bootstrap-dark .navbar-expand-xl>.container-sm,.bootstrap-dark .navbar-expand-xl>.container-xl{padding-left:0;padding-right:0}}@media(min-width:1200px){.bootstrap-dark .navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.bootstrap-dark .navbar-expand-xl .navbar-nav{flex-direction:row}.bootstrap-dark .navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.bootstrap-dark .navbar-expand-xl .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap-dark .navbar-expand-xl>.container,.bootstrap-dark .navbar-expand-xl>.container-fluid,.bootstrap-dark .navbar-expand-xl>.container-lg,.bootstrap-dark .navbar-expand-xl>.container-md,.bootstrap-dark .navbar-expand-xl>.container-sm,.bootstrap-dark .navbar-expand-xl>.container-xl{flex-wrap:nowrap}.bootstrap-dark .navbar-expand-xl .navbar-nav-scroll{overflow:visible}.bootstrap-dark .navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap-dark .navbar-expand-xl .navbar-toggler{display:none}}.bootstrap-dark .navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.bootstrap-dark .navbar-expand>.container,.bootstrap-dark .navbar-expand>.container-fluid,.bootstrap-dark .navbar-expand>.container-lg,.bootstrap-dark .navbar-expand>.container-md,.bootstrap-dark .navbar-expand>.container-sm,.bootstrap-dark .navbar-expand>.container-xl{padding-left:0;padding-right:0}.bootstrap-dark .navbar-expand .navbar-nav{flex-direction:row}.bootstrap-dark .navbar-expand .navbar-nav .dropdown-menu{position:absolute}.bootstrap-dark .navbar-expand .navbar-nav .nav-link{padding-left:.5rem;padding-right:.5rem}.bootstrap-dark .navbar-expand>.container,.bootstrap-dark .navbar-expand>.container-fluid,.bootstrap-dark .navbar-expand>.container-lg,.bootstrap-dark .navbar-expand>.container-md,.bootstrap-dark .navbar-expand>.container-sm,.bootstrap-dark .navbar-expand>.container-xl{flex-wrap:nowrap}.bootstrap-dark .navbar-expand .navbar-nav-scroll{overflow:visible}.bootstrap-dark .navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.bootstrap-dark .navbar-expand .navbar-toggler{display:none}.bootstrap-dark .navbar-light .navbar-brand,.bootstrap-dark .navbar-light .navbar-brand:focus,.bootstrap-dark .navbar-light .navbar-brand:hover{color:#000000e6}.bootstrap-dark .navbar-light .navbar-nav .nav-link{color:#00000080}.bootstrap-dark .navbar-light .navbar-nav .nav-link:focus,.bootstrap-dark .navbar-light .navbar-nav .nav-link:hover{color:#000000b3}.bootstrap-dark .navbar-light .navbar-nav .nav-link.disabled{color:#0000004d}.bootstrap-dark .navbar-light .navbar-nav .active>.nav-link,.bootstrap-dark .navbar-light .navbar-nav .nav-link.active,.bootstrap-dark .navbar-light .navbar-nav .nav-link.show,.bootstrap-dark .navbar-light .navbar-nav .show>.nav-link{color:#000000e6}.bootstrap-dark .navbar-light .navbar-toggler{border-color:#0000001a;color:#00000080}.bootstrap-dark .navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.bootstrap-dark .navbar-light .navbar-text{color:#00000080}.bootstrap-dark .navbar-light .navbar-text a,.bootstrap-dark .navbar-light .navbar-text a:focus,.bootstrap-dark .navbar-light .navbar-text a:hover{color:#000000e6}.bootstrap-dark .navbar-dark .navbar-brand,.bootstrap-dark .navbar-dark .navbar-brand:focus,.bootstrap-dark .navbar-dark .navbar-brand:hover,.bootstrap-dark .navbar-themed .navbar-brand,.bootstrap-dark .navbar-themed .navbar-brand:focus,.bootstrap-dark .navbar-themed .navbar-brand:hover{color:#fff}.bootstrap-dark .navbar-dark .navbar-nav .nav-link,.bootstrap-dark .navbar-themed .navbar-nav .nav-link{color:#ffffff80}.bootstrap-dark .navbar-dark .navbar-nav .nav-link:focus,.bootstrap-dark .navbar-dark .navbar-nav .nav-link:hover,.bootstrap-dark .navbar-themed .navbar-nav .nav-link:focus,.bootstrap-dark .navbar-themed .navbar-nav .nav-link:hover{color:#ffffffbf}.bootstrap-dark .navbar-dark .navbar-nav .nav-link.disabled,.bootstrap-dark .navbar-themed .navbar-nav .nav-link.disabled{color:#ffffff40}.bootstrap-dark .navbar-dark .navbar-nav .active>.nav-link,.bootstrap-dark .navbar-dark .navbar-nav .nav-link.active,.bootstrap-dark .navbar-dark .navbar-nav .nav-link.show,.bootstrap-dark .navbar-dark .navbar-nav .show>.nav-link,.bootstrap-dark .navbar-themed .navbar-nav .active>.nav-link,.bootstrap-dark .navbar-themed .navbar-nav .nav-link.active,.bootstrap-dark .navbar-themed .navbar-nav .nav-link.show,.bootstrap-dark .navbar-themed .navbar-nav .show>.nav-link{color:#fff}.bootstrap-dark .navbar-dark .navbar-toggler,.bootstrap-dark .navbar-themed .navbar-toggler{border-color:#ffffff1a;color:#ffffff80}.bootstrap-dark .navbar-dark .navbar-toggler-icon,.bootstrap-dark .navbar-themed .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.bootstrap-dark .navbar-dark .navbar-text,.bootstrap-dark .navbar-themed .navbar-text{color:#ffffff80}.bootstrap-dark .navbar-dark .navbar-text a,.bootstrap-dark .navbar-dark .navbar-text a:focus,.bootstrap-dark .navbar-dark .navbar-text a:hover,.bootstrap-dark .navbar-themed .navbar-text a,.bootstrap-dark .navbar-themed .navbar-text a:focus,.bootstrap-dark .navbar-themed .navbar-text a:hover{color:#fff}.bootstrap-dark .card{word-wrap:break-word;background-clip:initial;background-color:#212529;border:1px solid hsla(0,0%,100%,.125);border-radius:.25rem;display:flex;flex-direction:column;min-width:0;position:relative}.bootstrap-dark .card>hr{margin-left:0;margin-right:0}.bootstrap-dark .card>.list-group{border-bottom:inherit;border-top:inherit}.bootstrap-dark .card>.list-group:first-child{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);border-top-width:0}.bootstrap-dark .card>.list-group:last-child{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px);border-bottom-width:0}.bootstrap-dark .card>.card-header+.list-group,.bootstrap-dark .card>.list-group+.card-footer{border-top:0}.bootstrap-dark .card-body{color:#e9ecef;flex:1 1 auto;min-height:1px;padding:1.25rem}.bootstrap-dark .card-title{margin-bottom:.75rem}.bootstrap-dark .card-subtitle{margin-bottom:0;margin-top:-.375rem}.bootstrap-dark .card-text:last-child{margin-bottom:0}.bootstrap-dark .card-link:hover{text-decoration:none}.bootstrap-dark .card-link+.card-link{margin-left:1.25rem}.bootstrap-dark .card-header{background-color:#ffffff08;border-bottom:1px solid hsla(0,0%,100%,.125);margin-bottom:0;padding:.75rem 1.25rem}.bootstrap-dark .card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.bootstrap-dark .card-footer{background-color:#ffffff08;border-top:1px solid hsla(0,0%,100%,.125);padding:.75rem 1.25rem}.bootstrap-dark .card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.bootstrap-dark .card-header-tabs{border-bottom:0;margin-bottom:-.75rem}.bootstrap-dark .card-header-pills,.bootstrap-dark .card-header-tabs{margin-left:-.625rem;margin-right:-.625rem}.bootstrap-dark .card-img-overlay{border-radius:calc(.25rem - 1px);bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.bootstrap-dark .card-img,.bootstrap-dark .card-img-bottom,.bootstrap-dark .card-img-top{flex-shrink:0;width:100%}.bootstrap-dark .card-img,.bootstrap-dark .card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.bootstrap-dark .card-img,.bootstrap-dark .card-img-bottom{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.bootstrap-dark .card-deck .card{margin-bottom:15px}@media(min-width:576px){.bootstrap-dark .card-deck{display:flex;flex-flow:row wrap;margin-left:-15px;margin-right:-15px}.bootstrap-dark .card-deck .card{flex:1 0;margin-bottom:0;margin-left:15px;margin-right:15px}}.bootstrap-dark .card-group>.card{margin-bottom:15px}@media(min-width:576px){.bootstrap-dark .card-group{display:flex;flex-flow:row wrap}.bootstrap-dark .card-group>.card{flex:1 0;margin-bottom:0}.bootstrap-dark .card-group>.card+.card{border-left:0;margin-left:0}.bootstrap-dark .card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.bootstrap-dark .card-group>.card:not(:last-child) .card-header,.bootstrap-dark .card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.bootstrap-dark .card-group>.card:not(:last-child) .card-footer,.bootstrap-dark .card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.bootstrap-dark .card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bootstrap-dark .card-group>.card:not(:first-child) .card-header,.bootstrap-dark .card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.bootstrap-dark .card-group>.card:not(:first-child) .card-footer,.bootstrap-dark .card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.bootstrap-dark .card-columns .card{margin-bottom:.75rem}@media(min-width:576px){.bootstrap-dark .card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.bootstrap-dark .card-columns .card{display:inline-block;width:100%}}.bootstrap-dark .accordion{overflow-anchor:none}.bootstrap-dark .accordion>.card{overflow:hidden}.bootstrap-dark .accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap-dark .accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.bootstrap-dark .accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.bootstrap-dark .breadcrumb{background-color:#343a40;border-radius:.25rem;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:1rem;padding:.75rem 1rem}.bootstrap-dark .breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.bootstrap-dark .breadcrumb-item+.breadcrumb-item:before{color:#ced4da;content:"/";float:left;padding-right:.5rem}.bootstrap-dark .breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.bootstrap-dark .breadcrumb-item.active{color:#ced4da}.bootstrap-dark .pagination{border-radius:.25rem;display:flex;list-style:none;padding-left:0}.bootstrap-dark .page-link{background-color:#000;border:1px solid #495057;color:#adadad;display:block;line-height:1.25;margin-left:-1px;padding:.5rem .75rem;position:relative}.bootstrap-dark .page-link:hover{background-color:#343a40;border-color:#495057;color:#878787;text-decoration:none;z-index:2}.bootstrap-dark .page-link:focus{box-shadow:0 0 0 .2rem #007bff40;outline:0;z-index:3}.bootstrap-dark .page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem;margin-left:0}.bootstrap-dark .page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.bootstrap-dark .page-item.active .page-link{background-color:#3395ff;border-color:#3395ff;color:#000;z-index:3}.bootstrap-dark .page-item.disabled .page-link{background-color:#000;border-color:#495057;color:#ced4da;cursor:auto;pointer-events:none}.bootstrap-dark .pagination-lg .page-link{font-size:1.25rem;line-height:1.5;padding:.75rem 1.5rem}.bootstrap-dark .pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.bootstrap-dark .pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.bootstrap-dark .pagination-sm .page-link{font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.bootstrap-dark .pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.bootstrap-dark .pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.bootstrap-dark .badge{border-radius:.25rem;display:inline-block;font-size:75%;font-weight:700;line-height:1;padding:.25em .4em;text-align:center;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:initial;white-space:nowrap}@media(prefers-reduced-motion:reduce){.bootstrap-dark .badge{transition:none}}a.bootstrap-dark .badge:focus,a.bootstrap-dark .badge:hover{text-decoration:none}.bootstrap-dark .badge:empty{display:none}.bootstrap-dark .btn .badge{position:relative;top:-1px}.bootstrap-dark .badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.bootstrap-dark .badge-primary{background-color:#007bff;color:#ced4da}a.bootstrap-dark .badge-primary:focus,a.bootstrap-dark .badge-primary:hover{background-color:#0062cc;color:#ced4da}a.bootstrap-dark .badge-primary.focus,a.bootstrap-dark .badge-primary:focus{box-shadow:0 0 0 .2rem #007bff80;outline:0}.bootstrap-dark .badge-secondary{background-color:#6c757d;color:#ced4da}a.bootstrap-dark .badge-secondary:focus,a.bootstrap-dark .badge-secondary:hover{background-color:#545b62;color:#ced4da}a.bootstrap-dark .badge-secondary.focus,a.bootstrap-dark .badge-secondary:focus{box-shadow:0 0 0 .2rem #6c757d80;outline:0}.bootstrap-dark .badge-success{background-color:#28a745;color:#ced4da}a.bootstrap-dark .badge-success:focus,a.bootstrap-dark .badge-success:hover{background-color:#1e7e34;color:#ced4da}a.bootstrap-dark .badge-success.focus,a.bootstrap-dark .badge-success:focus{box-shadow:0 0 0 .2rem #28a74580;outline:0}.bootstrap-dark .badge-info{background-color:#17a2b8;color:#ced4da}a.bootstrap-dark .badge-info:focus,a.bootstrap-dark .badge-info:hover{background-color:#117a8b;color:#ced4da}a.bootstrap-dark .badge-info.focus,a.bootstrap-dark .badge-info:focus{box-shadow:0 0 0 .2rem #17a2b880;outline:0}.bootstrap-dark .badge-warning{background-color:#ffc107;color:#212529}a.bootstrap-dark .badge-warning:focus,a.bootstrap-dark .badge-warning:hover{background-color:#d39e00;color:#212529}a.bootstrap-dark .badge-warning.focus,a.bootstrap-dark .badge-warning:focus{box-shadow:0 0 0 .2rem #ffc10780;outline:0}.bootstrap-dark .badge-danger{background-color:#dc3545;color:#ced4da}a.bootstrap-dark .badge-danger:focus,a.bootstrap-dark .badge-danger:hover{background-color:#bd2130;color:#ced4da}a.bootstrap-dark .badge-danger.focus,a.bootstrap-dark .badge-danger:focus{box-shadow:0 0 0 .2rem #dc354580;outline:0}.bootstrap-dark .badge-light{background-color:#f8f9fa;color:#212529}a.bootstrap-dark .badge-light:focus,a.bootstrap-dark .badge-light:hover{background-color:#dae0e5;color:#212529}a.bootstrap-dark .badge-light.focus,a.bootstrap-dark .badge-light:focus{box-shadow:0 0 0 .2rem #f8f9fa80;outline:0}.bootstrap-dark .badge-dark{background-color:#343a40;color:#ced4da}a.bootstrap-dark .badge-dark:focus,a.bootstrap-dark .badge-dark:hover{background-color:#1d2124;color:#ced4da}a.bootstrap-dark .badge-dark.focus,a.bootstrap-dark .badge-dark:focus{box-shadow:0 0 0 .2rem #343a4080;outline:0}.bootstrap-dark .jumbotron{background-color:#343a40;border-radius:.3rem;margin-bottom:2rem;padding:2rem 1rem}@media(min-width:576px){.bootstrap-dark .jumbotron{padding:4rem 2rem}}.bootstrap-dark .jumbotron-fluid{border-radius:0;padding-left:0;padding-right:0}.bootstrap-dark .alert{border:1px solid #0000;border-radius:.25rem;margin-bottom:1rem;padding:.75rem 1.25rem;position:relative}.bootstrap-dark .alert-heading{color:inherit}.bootstrap-dark .alert-link{font-weight:700}.bootstrap-dark .alert-dismissible{padding-right:4rem}.bootstrap-dark .alert-dismissible .close{color:inherit;padding:.75rem 1.25rem;position:absolute;right:0;top:0;z-index:2}.bootstrap-dark .alert-primary{background-color:#cce5ff;border-color:#b8daff;color:#004085}.bootstrap-dark .alert-primary hr{border-top-color:#9fcdff}.bootstrap-dark .alert-primary .alert-link{color:#002752}.bootstrap-dark .alert-secondary{background-color:#e2e3e5;border-color:#d6d8db;color:#383d41}.bootstrap-dark .alert-secondary hr{border-top-color:#c8cbcf}.bootstrap-dark .alert-secondary .alert-link{color:#202326}.bootstrap-dark .alert-success{background-color:#d4edda;border-color:#c3e6cb;color:#155724}.bootstrap-dark .alert-success hr{border-top-color:#b1dfbb}.bootstrap-dark .alert-success .alert-link{color:#0b2e13}.bootstrap-dark .alert-info{background-color:#d1ecf1;border-color:#bee5eb;color:#0c5460}.bootstrap-dark .alert-info hr{border-top-color:#abdde5}.bootstrap-dark .alert-info .alert-link{color:#062c33}.bootstrap-dark .alert-warning{background-color:#fff3cd;border-color:#ffeeba;color:#856404}.bootstrap-dark .alert-warning hr{border-top-color:#ffe8a1}.bootstrap-dark .alert-warning .alert-link{color:#533f03}.bootstrap-dark .alert-danger{background-color:#f8d7da;border-color:#f5c6cb;color:#721c24}.bootstrap-dark .alert-danger hr{border-top-color:#f1b0b7}.bootstrap-dark .alert-danger .alert-link{color:#491217}.bootstrap-dark .alert-light{background-color:#fefefe;border-color:#fdfdfe;color:#818182}.bootstrap-dark .alert-light hr{border-top-color:#ececf6}.bootstrap-dark .alert-light .alert-link{color:#686868}.bootstrap-dark .alert-dark{background-color:#d6d8d9;border-color:#c6c8ca;color:#1b1e21}.bootstrap-dark .alert-dark hr{border-top-color:#b9bbbe}.bootstrap-dark .alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.bootstrap-dark .progress{background-color:#e9ecef;border-radius:.25rem;display:flex;font-size:.75rem;height:1rem;line-height:0;overflow:hidden}.bootstrap-dark .progress-bar{background-color:#007bff;color:#fff;display:flex;flex-direction:column;justify-content:center;overflow:hidden;text-align:center;transition:width .6s ease;white-space:nowrap}@media(prefers-reduced-motion:reduce){.bootstrap-dark .progress-bar{transition:none}}.bootstrap-dark .progress-bar-striped{background-image:linear-gradient(45deg,#ffffff26 25%,#0000 0,#0000 50%,#ffffff26 0,#ffffff26 75%,#0000 0,#0000);background-size:1rem 1rem}.bootstrap-dark .progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media(prefers-reduced-motion:reduce){.bootstrap-dark .progress-bar-animated{animation:none}}.bootstrap-dark .media{align-items:flex-start;display:flex}.bootstrap-dark .media-body{flex:1 1}.bootstrap-dark .list-group{border-radius:.25rem;display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.bootstrap-dark .list-group-item-action{color:#dee2e6;text-align:inherit;width:100%}.bootstrap-dark .list-group-item-action:focus,.bootstrap-dark .list-group-item-action:hover{background-color:#212529;color:#dee2e6;text-decoration:none;z-index:1}.bootstrap-dark .list-group-item-action:active{background-color:#343a40;color:#d3d3d3}.bootstrap-dark .list-group-item{background-color:#191d210d;border:1px solid hsla(0,0%,100%,.125);display:block;padding:.75rem 1.25rem;position:relative}.bootstrap-dark .list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.bootstrap-dark .list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.bootstrap-dark .list-group-item.disabled,.bootstrap-dark .list-group-item:disabled{background-color:#191d210d;color:#ced4da;pointer-events:none}.bootstrap-dark .list-group-item.active{background-color:#3395ff;border-color:#3395ff;color:#000;z-index:2}.bootstrap-dark .list-group-item+.bootstrap-dark .list-group-item{border-top-width:0}.bootstrap-dark .list-group-item+.bootstrap-dark .list-group-item.active{border-top-width:1px;margin-top:-1px}.bootstrap-dark .list-group-horizontal{flex-direction:row}.bootstrap-dark .list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap-dark .list-group-horizontal>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap-dark .list-group-horizontal>.list-group-item.active{margin-top:0}.bootstrap-dark .list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap-dark .list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}@media(min-width:576px){.bootstrap-dark .list-group-horizontal-sm{flex-direction:row}.bootstrap-dark .list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap-dark .list-group-horizontal-sm>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap-dark .list-group-horizontal-sm>.list-group-item.active{margin-top:0}.bootstrap-dark .list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap-dark .list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:768px){.bootstrap-dark .list-group-horizontal-md{flex-direction:row}.bootstrap-dark .list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap-dark .list-group-horizontal-md>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap-dark .list-group-horizontal-md>.list-group-item.active{margin-top:0}.bootstrap-dark .list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap-dark .list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:992px){.bootstrap-dark .list-group-horizontal-lg{flex-direction:row}.bootstrap-dark .list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap-dark .list-group-horizontal-lg>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap-dark .list-group-horizontal-lg>.list-group-item.active{margin-top:0}.bootstrap-dark .list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap-dark .list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}@media(min-width:1200px){.bootstrap-dark .list-group-horizontal-xl{flex-direction:row}.bootstrap-dark .list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.bootstrap-dark .list-group-horizontal-xl>.list-group-item:last-child{border-bottom-left-radius:0;border-top-right-radius:.25rem}.bootstrap-dark .list-group-horizontal-xl>.list-group-item.active{margin-top:0}.bootstrap-dark .list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:1px}.bootstrap-dark .list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:1px;margin-left:-1px}}.bootstrap-dark .list-group-flush{border-radius:0}.bootstrap-dark .list-group-flush>.list-group-item{border-width:0 0 1px}.bootstrap-dark .list-group-flush>.list-group-item:last-child{border-bottom-width:0}.bootstrap-dark .list-group-item-primary{background-color:#b8daff;color:#004085}.bootstrap-dark .list-group-item-primary.list-group-item-action:focus,.bootstrap-dark .list-group-item-primary.list-group-item-action:hover{background-color:#9fcdff;color:#004085}.bootstrap-dark .list-group-item-primary.list-group-item-action.active{background-color:#004085;border-color:#004085;color:#fff}.bootstrap-dark .list-group-item-secondary{background-color:#d6d8db;color:#383d41}.bootstrap-dark .list-group-item-secondary.list-group-item-action:focus,.bootstrap-dark .list-group-item-secondary.list-group-item-action:hover{background-color:#c8cbcf;color:#383d41}.bootstrap-dark .list-group-item-secondary.list-group-item-action.active{background-color:#383d41;border-color:#383d41;color:#fff}.bootstrap-dark .list-group-item-success{background-color:#c3e6cb;color:#155724}.bootstrap-dark .list-group-item-success.list-group-item-action:focus,.bootstrap-dark .list-group-item-success.list-group-item-action:hover{background-color:#b1dfbb;color:#155724}.bootstrap-dark .list-group-item-success.list-group-item-action.active{background-color:#155724;border-color:#155724;color:#fff}.bootstrap-dark .list-group-item-info{background-color:#bee5eb;color:#0c5460}.bootstrap-dark .list-group-item-info.list-group-item-action:focus,.bootstrap-dark .list-group-item-info.list-group-item-action:hover{background-color:#abdde5;color:#0c5460}.bootstrap-dark .list-group-item-info.list-group-item-action.active{background-color:#0c5460;border-color:#0c5460;color:#fff}.bootstrap-dark .list-group-item-warning{background-color:#ffeeba;color:#856404}.bootstrap-dark .list-group-item-warning.list-group-item-action:focus,.bootstrap-dark .list-group-item-warning.list-group-item-action:hover{background-color:#ffe8a1;color:#856404}.bootstrap-dark .list-group-item-warning.list-group-item-action.active{background-color:#856404;border-color:#856404;color:#fff}.bootstrap-dark .list-group-item-danger{background-color:#f5c6cb;color:#721c24}.bootstrap-dark .list-group-item-danger.list-group-item-action:focus,.bootstrap-dark .list-group-item-danger.list-group-item-action:hover{background-color:#f1b0b7;color:#721c24}.bootstrap-dark .list-group-item-danger.list-group-item-action.active{background-color:#721c24;border-color:#721c24;color:#fff}.bootstrap-dark .list-group-item-light{background-color:#fdfdfe;color:#818182}.bootstrap-dark .list-group-item-light.list-group-item-action:focus,.bootstrap-dark .list-group-item-light.list-group-item-action:hover{background-color:#ececf6;color:#818182}.bootstrap-dark .list-group-item-light.list-group-item-action.active{background-color:#818182;border-color:#818182;color:#fff}.bootstrap-dark .list-group-item-dark{background-color:#c6c8ca;color:#1b1e21}.bootstrap-dark .list-group-item-dark.list-group-item-action:focus,.bootstrap-dark .list-group-item-dark.list-group-item-action:hover{background-color:#b9bbbe;color:#1b1e21}.bootstrap-dark .list-group-item-dark.list-group-item-action.active{background-color:#1b1e21;border-color:#1b1e21;color:#fff}.bootstrap-dark .close{color:#fff;float:right;font-size:1.5rem;font-weight:700;line-height:1;opacity:.5;text-shadow:0 1px 0 #000}.bootstrap-dark .close:hover{color:#fff;text-decoration:none}.bootstrap-dark .close:not(:disabled):not(.disabled):focus,.bootstrap-dark .close:not(:disabled):not(.disabled):hover{opacity:.75}.bootstrap-dark button.close{background-color:initial;border:0;padding:0}.bootstrap-dark a.close.disabled{pointer-events:none}.bootstrap-dark .toast{background-clip:padding-box;background-color:#000000d9;border:1px solid #ffffff1a;border-radius:.25rem;box-shadow:0 .25rem .75rem #ffffff1a;flex-basis:350px;font-size:.875rem;max-width:350px;opacity:0}.bootstrap-dark .toast:not(:last-child){margin-bottom:.75rem}.bootstrap-dark .toast.showing{opacity:1}.bootstrap-dark .toast.show{display:block;opacity:1}.bootstrap-dark .toast.hide{display:none}.bootstrap-dark .toast-header{align-items:center;background-clip:padding-box;background-color:#000000d9;border-bottom:1px solid #ffffff0d;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px);color:#ced4da;display:flex;padding:.25rem .75rem}.bootstrap-dark .toast-body{padding:.75rem}.bootstrap-dark .modal-open{overflow:hidden}.bootstrap-dark .modal-open .modal{overflow-x:hidden;overflow-y:auto}.bootstrap-dark .modal{display:none;height:100%;left:0;outline:0;overflow:hidden;position:fixed;top:0;width:100%;z-index:1050}.bootstrap-dark .modal-dialog{margin:.5rem;pointer-events:none;position:relative;width:auto}.modal.fade .bootstrap-dark .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media(prefers-reduced-motion:reduce){.modal.fade .bootstrap-dark .modal-dialog{transition:none}}.modal.show .bootstrap-dark .modal-dialog{transform:none}.modal.modal-static .bootstrap-dark .modal-dialog{transform:scale(1.02)}.bootstrap-dark .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.bootstrap-dark .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.bootstrap-dark .modal-dialog-scrollable .modal-footer,.bootstrap-dark .modal-dialog-scrollable .modal-header{flex-shrink:0}.bootstrap-dark .modal-dialog-scrollable .modal-body{overflow-y:auto}.bootstrap-dark .modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - 1rem)}.bootstrap-dark .modal-dialog-centered:before{content:"";display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:min-content}.bootstrap-dark .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;height:100%;justify-content:center}.bootstrap-dark .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.bootstrap-dark .modal-dialog-centered.modal-dialog-scrollable:before{content:none}.bootstrap-dark .modal-content{background-clip:padding-box;background-color:#191d21;border:1px solid #fff3;border-radius:.3rem;display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.bootstrap-dark .modal-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.bootstrap-dark .modal-backdrop.fade{opacity:0}.bootstrap-dark .modal-backdrop.show{opacity:.5}.bootstrap-dark .modal-header{align-items:flex-start;border-bottom:1px solid #343a40;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);display:flex;justify-content:space-between;padding:1rem}.bootstrap-dark .modal-header .close{margin:-1rem -1rem -1rem auto;padding:1rem}.bootstrap-dark .modal-title{line-height:1.5;margin-bottom:0}.bootstrap-dark .modal-body{flex:1 1 auto;padding:1rem;position:relative}.bootstrap-dark .modal-footer{align-items:center;border-bottom-left-radius:calc(.3rem - 1px);border-bottom-right-radius:calc(.3rem - 1px);border-top:1px solid #343a40;display:flex;flex-wrap:wrap;justify-content:flex-end;padding:.75rem}.bootstrap-dark .modal-footer>*{margin:.25rem}.bootstrap-dark .modal-scrollbar-measure{height:50px;overflow:scroll;position:absolute;top:-9999px;width:50px}@media(min-width:576px){.bootstrap-dark .modal-dialog{margin:1.75rem auto;max-width:500px}.bootstrap-dark .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.bootstrap-dark .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.bootstrap-dark .modal-dialog-centered{min-height:calc(100% - 3.5rem)}.bootstrap-dark .modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:min-content}.bootstrap-dark .modal-sm{max-width:300px}}@media(min-width:992px){.bootstrap-dark .modal-lg,.bootstrap-dark .modal-xl{max-width:800px}}@media(min-width:1200px){.bootstrap-dark .modal-xl{max-width:1140px}}.bootstrap-dark .tooltip{word-wrap:break-word;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.875rem;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:0;opacity:0;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:1070}.bootstrap-dark .tooltip.show{opacity:.9}.bootstrap-dark .tooltip .arrow{display:block;height:.4rem;position:absolute;width:.8rem}.bootstrap-dark .tooltip .arrow:before{border-color:#0000;border-style:solid;content:"";position:absolute}.bootstrap-dark .bs-tooltip-auto[x-placement^=top],.bootstrap-dark .bs-tooltip-top{padding:.4rem 0}.bootstrap-dark .bs-tooltip-auto[x-placement^=top] .arrow,.bootstrap-dark .bs-tooltip-top .arrow{bottom:0}.bootstrap-dark .bs-tooltip-auto[x-placement^=top] .arrow:before,.bootstrap-dark .bs-tooltip-top .arrow:before{border-top-color:#000;border-width:.4rem .4rem 0;top:0}.bootstrap-dark .bs-tooltip-auto[x-placement^=right],.bootstrap-dark .bs-tooltip-right{padding:0 .4rem}.bootstrap-dark .bs-tooltip-auto[x-placement^=right] .arrow,.bootstrap-dark .bs-tooltip-right .arrow{height:.8rem;left:0;width:.4rem}.bootstrap-dark .bs-tooltip-auto[x-placement^=right] .arrow:before,.bootstrap-dark .bs-tooltip-right .arrow:before{border-right-color:#000;border-width:.4rem .4rem .4rem 0;right:0}.bootstrap-dark .bs-tooltip-auto[x-placement^=bottom],.bootstrap-dark .bs-tooltip-bottom{padding:.4rem 0}.bootstrap-dark .bs-tooltip-auto[x-placement^=bottom] .arrow,.bootstrap-dark .bs-tooltip-bottom .arrow{top:0}.bootstrap-dark .bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bootstrap-dark .bs-tooltip-bottom .arrow:before{border-bottom-color:#000;border-width:0 .4rem .4rem;bottom:0}.bootstrap-dark .bs-tooltip-auto[x-placement^=left],.bootstrap-dark .bs-tooltip-left{padding:0 .4rem}.bootstrap-dark .bs-tooltip-auto[x-placement^=left] .arrow,.bootstrap-dark .bs-tooltip-left .arrow{height:.8rem;right:0;width:.4rem}.bootstrap-dark .bs-tooltip-auto[x-placement^=left] .arrow:before,.bootstrap-dark .bs-tooltip-left .arrow:before{border-left-color:#000;border-width:.4rem 0 .4rem .4rem;left:0}.bootstrap-dark .tooltip-inner{background-color:#000;border-radius:.25rem;color:#fff;max-width:200px;padding:.25rem .5rem;text-align:center}.bootstrap-dark .popover{word-wrap:break-word;background-clip:padding-box;background-color:#fff;border:1px solid #0003;border-radius:.3rem;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.875rem;font-style:normal;font-weight:400;left:0;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:276px;position:absolute;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;top:0;white-space:normal;word-break:normal;word-spacing:normal;z-index:1060}.bootstrap-dark .popover .arrow{display:block;height:.5rem;margin:0 .3rem;position:absolute;width:1rem}.bootstrap-dark .popover .arrow:after,.bootstrap-dark .popover .arrow:before{border-color:#0000;border-style:solid;content:"";display:block;position:absolute}.bootstrap-dark .bs-popover-auto[x-placement^=top],.bootstrap-dark .bs-popover-top{margin-bottom:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=top]>.arrow,.bootstrap-dark .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bootstrap-dark .bs-popover-auto[x-placement^=top]>.arrow:before,.bootstrap-dark .bs-popover-top>.arrow:before{border-top-color:#00000040;border-width:.5rem .5rem 0;bottom:0}.bootstrap-dark .bs-popover-auto[x-placement^=top]>.arrow:after,.bootstrap-dark .bs-popover-top>.arrow:after{border-top-color:#fff;border-width:.5rem .5rem 0;bottom:1px}.bootstrap-dark .bs-popover-auto[x-placement^=right],.bootstrap-dark .bs-popover-right{margin-left:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=right]>.arrow,.bootstrap-dark .bs-popover-right>.arrow{height:1rem;left:calc(-.5rem - 1px);margin:.3rem 0;width:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=right]>.arrow:before,.bootstrap-dark .bs-popover-right>.arrow:before{border-right-color:#00000040;border-width:.5rem .5rem .5rem 0;left:0}.bootstrap-dark .bs-popover-auto[x-placement^=right]>.arrow:after,.bootstrap-dark .bs-popover-right>.arrow:after{border-right-color:#fff;border-width:.5rem .5rem .5rem 0;left:1px}.bootstrap-dark .bs-popover-auto[x-placement^=bottom],.bootstrap-dark .bs-popover-bottom{margin-top:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=bottom]>.arrow,.bootstrap-dark .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bootstrap-dark .bs-popover-auto[x-placement^=bottom]>.arrow:before,.bootstrap-dark .bs-popover-bottom>.arrow:before{border-bottom-color:#00000040;border-width:0 .5rem .5rem;top:0}.bootstrap-dark .bs-popover-auto[x-placement^=bottom]>.arrow:after,.bootstrap-dark .bs-popover-bottom>.arrow:after{border-bottom-color:#fff;border-width:0 .5rem .5rem;top:1px}.bootstrap-dark .bs-popover-auto[x-placement^=bottom] .popover-header:before,.bootstrap-dark .bs-popover-bottom .popover-header:before{border-bottom:1px solid #f7f7f7;content:"";display:block;left:50%;margin-left:-.5rem;position:absolute;top:0;width:1rem}.bootstrap-dark .bs-popover-auto[x-placement^=left],.bootstrap-dark .bs-popover-left{margin-right:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=left]>.arrow,.bootstrap-dark .bs-popover-left>.arrow{height:1rem;margin:.3rem 0;right:calc(-.5rem - 1px);width:.5rem}.bootstrap-dark .bs-popover-auto[x-placement^=left]>.arrow:before,.bootstrap-dark .bs-popover-left>.arrow:before{border-left-color:#00000040;border-width:.5rem 0 .5rem .5rem;right:0}.bootstrap-dark .bs-popover-auto[x-placement^=left]>.arrow:after,.bootstrap-dark .bs-popover-left>.arrow:after{border-left-color:#fff;border-width:.5rem 0 .5rem .5rem;right:1px}.bootstrap-dark .popover-header{background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px);font-size:1rem;margin-bottom:0;padding:.5rem .75rem}.bootstrap-dark .popover-header:empty{display:none}.bootstrap-dark .popover-body{color:#212529;padding:.5rem .75rem}.bootstrap-dark .carousel{position:relative}.bootstrap-dark .carousel.pointer-event{touch-action:pan-y}.bootstrap-dark .carousel-inner{overflow:hidden;position:relative;width:100%}.bootstrap-dark .carousel-inner:after{clear:both;content:"";display:block}.bootstrap-dark .carousel-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.bootstrap-dark .carousel-item{transition:none}}.bootstrap-dark .carousel-item-next,.bootstrap-dark .carousel-item-prev,.bootstrap-dark .carousel-item.active{display:block}.bootstrap-dark .active.carousel-item-right,.bootstrap-dark .carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.bootstrap-dark .active.carousel-item-left,.bootstrap-dark .carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.bootstrap-dark .carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.bootstrap-dark .carousel-fade .carousel-item-next.carousel-item-left,.bootstrap-dark .carousel-fade .carousel-item-prev.carousel-item-right,.bootstrap-dark .carousel-fade .carousel-item.active{opacity:1;z-index:1}.bootstrap-dark .carousel-fade .active.carousel-item-left,.bootstrap-dark .carousel-fade .active.carousel-item-right{opacity:0;transition:opacity 0s .6s;z-index:0}@media(prefers-reduced-motion:reduce){.bootstrap-dark .carousel-fade .active.carousel-item-left,.bootstrap-dark .carousel-fade .active.carousel-item-right{transition:none}}.bootstrap-dark .carousel-control-next,.bootstrap-dark .carousel-control-prev{align-items:center;background:none;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media(prefers-reduced-motion:reduce){.bootstrap-dark .carousel-control-next,.bootstrap-dark .carousel-control-prev{transition:none}}.bootstrap-dark .carousel-control-next:focus,.bootstrap-dark .carousel-control-next:hover,.bootstrap-dark .carousel-control-prev:focus,.bootstrap-dark .carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.bootstrap-dark .carousel-control-prev{left:0}.bootstrap-dark .carousel-control-next{right:0}.bootstrap-dark .carousel-control-next-icon,.bootstrap-dark .carousel-control-prev-icon{background:50%/100% 100% no-repeat;display:inline-block;height:20px;width:20px}.bootstrap-dark .carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m5.25 0-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.bootstrap-dark .carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='m2.75 0-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.bootstrap-dark .carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-left:15%;margin-right:15%;padding-left:0;position:absolute;right:0;z-index:15}.bootstrap-dark .carousel-indicators li{background-clip:padding-box;background-color:#fff;border-bottom:10px solid #0000;border-top:10px solid #0000;box-sizing:initial;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;text-indent:-999px;transition:opacity .6s ease;width:30px}@media(prefers-reduced-motion:reduce){.bootstrap-dark .carousel-indicators li{transition:none}}.bootstrap-dark .carousel-indicators .active{opacity:1}.bootstrap-dark .carousel-caption{bottom:20px;color:#fff;left:15%;padding-bottom:20px;padding-top:20px;position:absolute;right:15%;text-align:center;z-index:10}@keyframes spinner-border{to{transform:rotate(1turn)}}.bootstrap-dark .spinner-border{animation:spinner-border .75s linear infinite;border:.25em solid;border-radius:50%;border-right:.25em solid #0000;display:inline-block;height:2rem;vertical-align:-.125em;width:2rem}.bootstrap-dark .spinner-border-sm{border-width:.2em;height:1rem;width:1rem}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.bootstrap-dark .spinner-grow{animation:spinner-grow .75s linear infinite;background-color:currentColor;border-radius:50%;display:inline-block;height:2rem;opacity:0;vertical-align:-.125em;width:2rem}.bootstrap-dark .spinner-grow-sm{height:1rem;width:1rem}@media(prefers-reduced-motion:reduce){.bootstrap-dark .spinner-border,.bootstrap-dark .spinner-grow{animation-duration:1.5s}}.bootstrap-dark .align-baseline{vertical-align:initial!important}.bootstrap-dark .align-top{vertical-align:top!important}.bootstrap-dark .align-middle{vertical-align:middle!important}.bootstrap-dark .align-bottom{vertical-align:bottom!important}.bootstrap-dark .align-text-bottom{vertical-align:text-bottom!important}.bootstrap-dark .align-text-top{vertical-align:text-top!important}.bootstrap-dark .bg-primary{background-color:#007bff!important}.bootstrap-dark a.bg-primary:focus,.bootstrap-dark a.bg-primary:hover,.bootstrap-dark button.bg-primary:focus,.bootstrap-dark button.bg-primary:hover{background-color:#0062cc!important}.bootstrap-dark .bg-secondary{background-color:#6c757d!important}.bootstrap-dark a.bg-secondary:focus,.bootstrap-dark a.bg-secondary:hover,.bootstrap-dark button.bg-secondary:focus,.bootstrap-dark button.bg-secondary:hover{background-color:#545b62!important}.bootstrap-dark .bg-success{background-color:#28a745!important}.bootstrap-dark a.bg-success:focus,.bootstrap-dark a.bg-success:hover,.bootstrap-dark button.bg-success:focus,.bootstrap-dark button.bg-success:hover{background-color:#1e7e34!important}.bootstrap-dark .bg-info{background-color:#17a2b8!important}.bootstrap-dark a.bg-info:focus,.bootstrap-dark a.bg-info:hover,.bootstrap-dark button.bg-info:focus,.bootstrap-dark button.bg-info:hover{background-color:#117a8b!important}.bootstrap-dark .bg-warning{background-color:#ffc107!important}.bootstrap-dark a.bg-warning:focus,.bootstrap-dark a.bg-warning:hover,.bootstrap-dark button.bg-warning:focus,.bootstrap-dark button.bg-warning:hover{background-color:#d39e00!important}.bootstrap-dark .bg-danger{background-color:#dc3545!important}.bootstrap-dark a.bg-danger:focus,.bootstrap-dark a.bg-danger:hover,.bootstrap-dark button.bg-danger:focus,.bootstrap-dark button.bg-danger:hover{background-color:#bd2130!important}.bootstrap-dark .bg-light{background-color:#f8f9fa!important}.bootstrap-dark a.bg-light:focus,.bootstrap-dark a.bg-light:hover,.bootstrap-dark button.bg-light:focus,.bootstrap-dark button.bg-light:hover{background-color:#dae0e5!important}.bootstrap-dark .bg-dark,.bootstrap-dark .navbar-themed{background-color:#343a40!important}.bootstrap-dark a.bg-dark:focus,.bootstrap-dark a.bg-dark:hover,.bootstrap-dark a.navbar-themed:focus,.bootstrap-dark a.navbar-themed:hover,.bootstrap-dark button.bg-dark:focus,.bootstrap-dark button.bg-dark:hover,.bootstrap-dark button.navbar-themed:focus,.bootstrap-dark button.navbar-themed:hover{background-color:#1d2124!important}.bootstrap-dark .bg-white{background-color:#fff!important}.bootstrap-dark .bg-transparent{background-color:initial!important}.bootstrap-dark .border{border:1px solid #343a40!important}.bootstrap-dark .border-top{border-top:1px solid #343a40!important}.bootstrap-dark .border-right{border-right:1px solid #343a40!important}.bootstrap-dark .border-bottom{border-bottom:1px solid #343a40!important}.bootstrap-dark .border-left{border-left:1px solid #343a40!important}.bootstrap-dark .border-0{border:0!important}.bootstrap-dark .border-top-0{border-top:0!important}.bootstrap-dark .border-right-0{border-right:0!important}.bootstrap-dark .border-bottom-0{border-bottom:0!important}.bootstrap-dark .border-left-0{border-left:0!important}.bootstrap-dark .border-primary{border-color:#007bff!important}.bootstrap-dark .border-secondary{border-color:#6c757d!important}.bootstrap-dark .border-success{border-color:#28a745!important}.bootstrap-dark .border-info{border-color:#17a2b8!important}.bootstrap-dark .border-warning{border-color:#ffc107!important}.bootstrap-dark .border-danger{border-color:#dc3545!important}.bootstrap-dark .border-light{border-color:#f8f9fa!important}.bootstrap-dark .border-dark{border-color:#343a40!important}.bootstrap-dark .border-white{border-color:#fff!important}.bootstrap-dark .rounded-sm{border-radius:.2rem!important}.bootstrap-dark .rounded{border-radius:.25rem!important}.bootstrap-dark .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.bootstrap-dark .rounded-right{border-bottom-right-radius:.25rem!important;border-top-right-radius:.25rem!important}.bootstrap-dark .rounded-bottom{border-bottom-left-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.bootstrap-dark .rounded-left{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.bootstrap-dark .rounded-lg{border-radius:.3rem!important}.bootstrap-dark .rounded-circle{border-radius:50%!important}.bootstrap-dark .rounded-pill{border-radius:50rem!important}.bootstrap-dark .rounded-0{border-radius:0!important}.bootstrap-dark .clearfix:after{clear:both;content:"";display:block}.bootstrap-dark .d-none{display:none!important}.bootstrap-dark .d-inline{display:inline!important}.bootstrap-dark .d-inline-block{display:inline-block!important}.bootstrap-dark .d-block{display:block!important}.bootstrap-dark .d-table{display:table!important}.bootstrap-dark .d-table-row{display:table-row!important}.bootstrap-dark .d-table-cell{display:table-cell!important}.bootstrap-dark .d-flex{display:flex!important}.bootstrap-dark .d-inline-flex{display:inline-flex!important}@media(min-width:576px){.bootstrap-dark .d-sm-none{display:none!important}.bootstrap-dark .d-sm-inline{display:inline!important}.bootstrap-dark .d-sm-inline-block{display:inline-block!important}.bootstrap-dark .d-sm-block{display:block!important}.bootstrap-dark .d-sm-table{display:table!important}.bootstrap-dark .d-sm-table-row{display:table-row!important}.bootstrap-dark .d-sm-table-cell{display:table-cell!important}.bootstrap-dark .d-sm-flex{display:flex!important}.bootstrap-dark .d-sm-inline-flex{display:inline-flex!important}}@media(min-width:768px){.bootstrap-dark .d-md-none{display:none!important}.bootstrap-dark .d-md-inline{display:inline!important}.bootstrap-dark .d-md-inline-block{display:inline-block!important}.bootstrap-dark .d-md-block{display:block!important}.bootstrap-dark .d-md-table{display:table!important}.bootstrap-dark .d-md-table-row{display:table-row!important}.bootstrap-dark .d-md-table-cell{display:table-cell!important}.bootstrap-dark .d-md-flex{display:flex!important}.bootstrap-dark .d-md-inline-flex{display:inline-flex!important}}@media(min-width:992px){.bootstrap-dark .d-lg-none{display:none!important}.bootstrap-dark .d-lg-inline{display:inline!important}.bootstrap-dark .d-lg-inline-block{display:inline-block!important}.bootstrap-dark .d-lg-block{display:block!important}.bootstrap-dark .d-lg-table{display:table!important}.bootstrap-dark .d-lg-table-row{display:table-row!important}.bootstrap-dark .d-lg-table-cell{display:table-cell!important}.bootstrap-dark .d-lg-flex{display:flex!important}.bootstrap-dark .d-lg-inline-flex{display:inline-flex!important}}@media(min-width:1200px){.bootstrap-dark .d-xl-none{display:none!important}.bootstrap-dark .d-xl-inline{display:inline!important}.bootstrap-dark .d-xl-inline-block{display:inline-block!important}.bootstrap-dark .d-xl-block{display:block!important}.bootstrap-dark .d-xl-table{display:table!important}.bootstrap-dark .d-xl-table-row{display:table-row!important}.bootstrap-dark .d-xl-table-cell{display:table-cell!important}.bootstrap-dark .d-xl-flex{display:flex!important}.bootstrap-dark .d-xl-inline-flex{display:inline-flex!important}}@media print{.bootstrap-dark .d-print-none{display:none!important}.bootstrap-dark .d-print-inline{display:inline!important}.bootstrap-dark .d-print-inline-block{display:inline-block!important}.bootstrap-dark .d-print-block{display:block!important}.bootstrap-dark .d-print-table{display:table!important}.bootstrap-dark .d-print-table-row{display:table-row!important}.bootstrap-dark .d-print-table-cell{display:table-cell!important}.bootstrap-dark .d-print-flex{display:flex!important}.bootstrap-dark .d-print-inline-flex{display:inline-flex!important}}.bootstrap-dark .embed-responsive{display:block;overflow:hidden;padding:0;position:relative;width:100%}.bootstrap-dark .embed-responsive:before{content:"";display:block}.bootstrap-dark .embed-responsive .embed-responsive-item,.bootstrap-dark .embed-responsive embed,.bootstrap-dark .embed-responsive iframe,.bootstrap-dark .embed-responsive object,.bootstrap-dark .embed-responsive video{border:0;bottom:0;height:100%;left:0;position:absolute;top:0;width:100%}.bootstrap-dark .embed-responsive-21by9:before{padding-top:42.85714286%}.bootstrap-dark .embed-responsive-16by9:before{padding-top:56.25%}.bootstrap-dark .embed-responsive-4by3:before{padding-top:75%}.bootstrap-dark .embed-responsive-1by1:before{padding-top:100%}.bootstrap-dark .flex-row{flex-direction:row!important}.bootstrap-dark .flex-column{flex-direction:column!important}.bootstrap-dark .flex-row-reverse{flex-direction:row-reverse!important}.bootstrap-dark .flex-column-reverse{flex-direction:column-reverse!important}.bootstrap-dark .flex-wrap{flex-wrap:wrap!important}.bootstrap-dark .flex-nowrap{flex-wrap:nowrap!important}.bootstrap-dark .flex-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap-dark .flex-fill{flex:1 1 auto!important}.bootstrap-dark .flex-grow-0{flex-grow:0!important}.bootstrap-dark .flex-grow-1{flex-grow:1!important}.bootstrap-dark .flex-shrink-0{flex-shrink:0!important}.bootstrap-dark .flex-shrink-1{flex-shrink:1!important}.bootstrap-dark .justify-content-start{justify-content:flex-start!important}.bootstrap-dark .justify-content-end{justify-content:flex-end!important}.bootstrap-dark .justify-content-center{justify-content:center!important}.bootstrap-dark .justify-content-between{justify-content:space-between!important}.bootstrap-dark .justify-content-around{justify-content:space-around!important}.bootstrap-dark .align-items-start{align-items:flex-start!important}.bootstrap-dark .align-items-end{align-items:flex-end!important}.bootstrap-dark .align-items-center{align-items:center!important}.bootstrap-dark .align-items-baseline{align-items:baseline!important}.bootstrap-dark .align-items-stretch{align-items:stretch!important}.bootstrap-dark .align-content-start{align-content:flex-start!important}.bootstrap-dark .align-content-end{align-content:flex-end!important}.bootstrap-dark .align-content-center{align-content:center!important}.bootstrap-dark .align-content-between{align-content:space-between!important}.bootstrap-dark .align-content-around{align-content:space-around!important}.bootstrap-dark .align-content-stretch{align-content:stretch!important}.bootstrap-dark .align-self-auto{align-self:auto!important}.bootstrap-dark .align-self-start{align-self:flex-start!important}.bootstrap-dark .align-self-end{align-self:flex-end!important}.bootstrap-dark .align-self-center{align-self:center!important}.bootstrap-dark .align-self-baseline{align-self:baseline!important}.bootstrap-dark .align-self-stretch{align-self:stretch!important}@media(min-width:576px){.bootstrap-dark .flex-sm-row{flex-direction:row!important}.bootstrap-dark .flex-sm-column{flex-direction:column!important}.bootstrap-dark .flex-sm-row-reverse{flex-direction:row-reverse!important}.bootstrap-dark .flex-sm-column-reverse{flex-direction:column-reverse!important}.bootstrap-dark .flex-sm-wrap{flex-wrap:wrap!important}.bootstrap-dark .flex-sm-nowrap{flex-wrap:nowrap!important}.bootstrap-dark .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap-dark .flex-sm-fill{flex:1 1 auto!important}.bootstrap-dark .flex-sm-grow-0{flex-grow:0!important}.bootstrap-dark .flex-sm-grow-1{flex-grow:1!important}.bootstrap-dark .flex-sm-shrink-0{flex-shrink:0!important}.bootstrap-dark .flex-sm-shrink-1{flex-shrink:1!important}.bootstrap-dark .justify-content-sm-start{justify-content:flex-start!important}.bootstrap-dark .justify-content-sm-end{justify-content:flex-end!important}.bootstrap-dark .justify-content-sm-center{justify-content:center!important}.bootstrap-dark .justify-content-sm-between{justify-content:space-between!important}.bootstrap-dark .justify-content-sm-around{justify-content:space-around!important}.bootstrap-dark .align-items-sm-start{align-items:flex-start!important}.bootstrap-dark .align-items-sm-end{align-items:flex-end!important}.bootstrap-dark .align-items-sm-center{align-items:center!important}.bootstrap-dark .align-items-sm-baseline{align-items:baseline!important}.bootstrap-dark .align-items-sm-stretch{align-items:stretch!important}.bootstrap-dark .align-content-sm-start{align-content:flex-start!important}.bootstrap-dark .align-content-sm-end{align-content:flex-end!important}.bootstrap-dark .align-content-sm-center{align-content:center!important}.bootstrap-dark .align-content-sm-between{align-content:space-between!important}.bootstrap-dark .align-content-sm-around{align-content:space-around!important}.bootstrap-dark .align-content-sm-stretch{align-content:stretch!important}.bootstrap-dark .align-self-sm-auto{align-self:auto!important}.bootstrap-dark .align-self-sm-start{align-self:flex-start!important}.bootstrap-dark .align-self-sm-end{align-self:flex-end!important}.bootstrap-dark .align-self-sm-center{align-self:center!important}.bootstrap-dark .align-self-sm-baseline{align-self:baseline!important}.bootstrap-dark .align-self-sm-stretch{align-self:stretch!important}}@media(min-width:768px){.bootstrap-dark .flex-md-row{flex-direction:row!important}.bootstrap-dark .flex-md-column{flex-direction:column!important}.bootstrap-dark .flex-md-row-reverse{flex-direction:row-reverse!important}.bootstrap-dark .flex-md-column-reverse{flex-direction:column-reverse!important}.bootstrap-dark .flex-md-wrap{flex-wrap:wrap!important}.bootstrap-dark .flex-md-nowrap{flex-wrap:nowrap!important}.bootstrap-dark .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap-dark .flex-md-fill{flex:1 1 auto!important}.bootstrap-dark .flex-md-grow-0{flex-grow:0!important}.bootstrap-dark .flex-md-grow-1{flex-grow:1!important}.bootstrap-dark .flex-md-shrink-0{flex-shrink:0!important}.bootstrap-dark .flex-md-shrink-1{flex-shrink:1!important}.bootstrap-dark .justify-content-md-start{justify-content:flex-start!important}.bootstrap-dark .justify-content-md-end{justify-content:flex-end!important}.bootstrap-dark .justify-content-md-center{justify-content:center!important}.bootstrap-dark .justify-content-md-between{justify-content:space-between!important}.bootstrap-dark .justify-content-md-around{justify-content:space-around!important}.bootstrap-dark .align-items-md-start{align-items:flex-start!important}.bootstrap-dark .align-items-md-end{align-items:flex-end!important}.bootstrap-dark .align-items-md-center{align-items:center!important}.bootstrap-dark .align-items-md-baseline{align-items:baseline!important}.bootstrap-dark .align-items-md-stretch{align-items:stretch!important}.bootstrap-dark .align-content-md-start{align-content:flex-start!important}.bootstrap-dark .align-content-md-end{align-content:flex-end!important}.bootstrap-dark .align-content-md-center{align-content:center!important}.bootstrap-dark .align-content-md-between{align-content:space-between!important}.bootstrap-dark .align-content-md-around{align-content:space-around!important}.bootstrap-dark .align-content-md-stretch{align-content:stretch!important}.bootstrap-dark .align-self-md-auto{align-self:auto!important}.bootstrap-dark .align-self-md-start{align-self:flex-start!important}.bootstrap-dark .align-self-md-end{align-self:flex-end!important}.bootstrap-dark .align-self-md-center{align-self:center!important}.bootstrap-dark .align-self-md-baseline{align-self:baseline!important}.bootstrap-dark .align-self-md-stretch{align-self:stretch!important}}@media(min-width:992px){.bootstrap-dark .flex-lg-row{flex-direction:row!important}.bootstrap-dark .flex-lg-column{flex-direction:column!important}.bootstrap-dark .flex-lg-row-reverse{flex-direction:row-reverse!important}.bootstrap-dark .flex-lg-column-reverse{flex-direction:column-reverse!important}.bootstrap-dark .flex-lg-wrap{flex-wrap:wrap!important}.bootstrap-dark .flex-lg-nowrap{flex-wrap:nowrap!important}.bootstrap-dark .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap-dark .flex-lg-fill{flex:1 1 auto!important}.bootstrap-dark .flex-lg-grow-0{flex-grow:0!important}.bootstrap-dark .flex-lg-grow-1{flex-grow:1!important}.bootstrap-dark .flex-lg-shrink-0{flex-shrink:0!important}.bootstrap-dark .flex-lg-shrink-1{flex-shrink:1!important}.bootstrap-dark .justify-content-lg-start{justify-content:flex-start!important}.bootstrap-dark .justify-content-lg-end{justify-content:flex-end!important}.bootstrap-dark .justify-content-lg-center{justify-content:center!important}.bootstrap-dark .justify-content-lg-between{justify-content:space-between!important}.bootstrap-dark .justify-content-lg-around{justify-content:space-around!important}.bootstrap-dark .align-items-lg-start{align-items:flex-start!important}.bootstrap-dark .align-items-lg-end{align-items:flex-end!important}.bootstrap-dark .align-items-lg-center{align-items:center!important}.bootstrap-dark .align-items-lg-baseline{align-items:baseline!important}.bootstrap-dark .align-items-lg-stretch{align-items:stretch!important}.bootstrap-dark .align-content-lg-start{align-content:flex-start!important}.bootstrap-dark .align-content-lg-end{align-content:flex-end!important}.bootstrap-dark .align-content-lg-center{align-content:center!important}.bootstrap-dark .align-content-lg-between{align-content:space-between!important}.bootstrap-dark .align-content-lg-around{align-content:space-around!important}.bootstrap-dark .align-content-lg-stretch{align-content:stretch!important}.bootstrap-dark .align-self-lg-auto{align-self:auto!important}.bootstrap-dark .align-self-lg-start{align-self:flex-start!important}.bootstrap-dark .align-self-lg-end{align-self:flex-end!important}.bootstrap-dark .align-self-lg-center{align-self:center!important}.bootstrap-dark .align-self-lg-baseline{align-self:baseline!important}.bootstrap-dark .align-self-lg-stretch{align-self:stretch!important}}@media(min-width:1200px){.bootstrap-dark .flex-xl-row{flex-direction:row!important}.bootstrap-dark .flex-xl-column{flex-direction:column!important}.bootstrap-dark .flex-xl-row-reverse{flex-direction:row-reverse!important}.bootstrap-dark .flex-xl-column-reverse{flex-direction:column-reverse!important}.bootstrap-dark .flex-xl-wrap{flex-wrap:wrap!important}.bootstrap-dark .flex-xl-nowrap{flex-wrap:nowrap!important}.bootstrap-dark .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.bootstrap-dark .flex-xl-fill{flex:1 1 auto!important}.bootstrap-dark .flex-xl-grow-0{flex-grow:0!important}.bootstrap-dark .flex-xl-grow-1{flex-grow:1!important}.bootstrap-dark .flex-xl-shrink-0{flex-shrink:0!important}.bootstrap-dark .flex-xl-shrink-1{flex-shrink:1!important}.bootstrap-dark .justify-content-xl-start{justify-content:flex-start!important}.bootstrap-dark .justify-content-xl-end{justify-content:flex-end!important}.bootstrap-dark .justify-content-xl-center{justify-content:center!important}.bootstrap-dark .justify-content-xl-between{justify-content:space-between!important}.bootstrap-dark .justify-content-xl-around{justify-content:space-around!important}.bootstrap-dark .align-items-xl-start{align-items:flex-start!important}.bootstrap-dark .align-items-xl-end{align-items:flex-end!important}.bootstrap-dark .align-items-xl-center{align-items:center!important}.bootstrap-dark .align-items-xl-baseline{align-items:baseline!important}.bootstrap-dark .align-items-xl-stretch{align-items:stretch!important}.bootstrap-dark .align-content-xl-start{align-content:flex-start!important}.bootstrap-dark .align-content-xl-end{align-content:flex-end!important}.bootstrap-dark .align-content-xl-center{align-content:center!important}.bootstrap-dark .align-content-xl-between{align-content:space-between!important}.bootstrap-dark .align-content-xl-around{align-content:space-around!important}.bootstrap-dark .align-content-xl-stretch{align-content:stretch!important}.bootstrap-dark .align-self-xl-auto{align-self:auto!important}.bootstrap-dark .align-self-xl-start{align-self:flex-start!important}.bootstrap-dark .align-self-xl-end{align-self:flex-end!important}.bootstrap-dark .align-self-xl-center{align-self:center!important}.bootstrap-dark .align-self-xl-baseline{align-self:baseline!important}.bootstrap-dark .align-self-xl-stretch{align-self:stretch!important}}.bootstrap-dark .float-left{float:left!important}.bootstrap-dark .float-right{float:right!important}.bootstrap-dark .float-none{float:none!important}@media(min-width:576px){.bootstrap-dark .float-sm-left{float:left!important}.bootstrap-dark .float-sm-right{float:right!important}.bootstrap-dark .float-sm-none{float:none!important}}@media(min-width:768px){.bootstrap-dark .float-md-left{float:left!important}.bootstrap-dark .float-md-right{float:right!important}.bootstrap-dark .float-md-none{float:none!important}}@media(min-width:992px){.bootstrap-dark .float-lg-left{float:left!important}.bootstrap-dark .float-lg-right{float:right!important}.bootstrap-dark .float-lg-none{float:none!important}}@media(min-width:1200px){.bootstrap-dark .float-xl-left{float:left!important}.bootstrap-dark .float-xl-right{float:right!important}.bootstrap-dark .float-xl-none{float:none!important}}.bootstrap-dark .user-select-all{-webkit-user-select:all!important;user-select:all!important}.bootstrap-dark .user-select-auto{-webkit-user-select:auto!important;user-select:auto!important}.bootstrap-dark .user-select-none{-webkit-user-select:none!important;user-select:none!important}.bootstrap-dark .overflow-auto{overflow:auto!important}.bootstrap-dark .overflow-hidden{overflow:hidden!important}.bootstrap-dark .position-static{position:static!important}.bootstrap-dark .position-relative{position:relative!important}.bootstrap-dark .position-absolute{position:absolute!important}.bootstrap-dark .position-fixed{position:fixed!important}.bootstrap-dark .position-sticky{position:-webkit-sticky!important;position:sticky!important}.bootstrap-dark .fixed-top{left:0;position:fixed;right:0;top:0;z-index:1030}.bootstrap-dark .fixed-bottom{bottom:0;left:0;position:fixed;right:0;z-index:1030}@supports((position:-webkit-sticky) or (position:sticky)){.bootstrap-dark .sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.bootstrap-dark .sr-only{clip:rect(0,0,0,0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.bootstrap-dark .sr-only-focusable:active,.bootstrap-dark .sr-only-focusable:focus{clip:auto;height:auto;overflow:visible;position:static;white-space:normal;width:auto}.bootstrap-dark .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.bootstrap-dark .shadow{box-shadow:0 .5rem 1rem #00000026!important}.bootstrap-dark .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.bootstrap-dark .shadow-none{box-shadow:none!important}.bootstrap-dark .w-25{width:25%!important}.bootstrap-dark .w-50{width:50%!important}.bootstrap-dark .w-75{width:75%!important}.bootstrap-dark .w-100{width:100%!important}.bootstrap-dark .w-auto{width:auto!important}.bootstrap-dark .h-25{height:25%!important}.bootstrap-dark .h-50{height:50%!important}.bootstrap-dark .h-75{height:75%!important}.bootstrap-dark .h-100{height:100%!important}.bootstrap-dark .h-auto{height:auto!important}.bootstrap-dark .mw-100{max-width:100%!important}.bootstrap-dark .mh-100{max-height:100%!important}.bootstrap-dark .min-vw-100{min-width:100vw!important}.bootstrap-dark .min-vh-100{min-height:100vh!important}.bootstrap-dark .vw-100{width:100vw!important}.bootstrap-dark .vh-100{height:100vh!important}.bootstrap-dark .m-0{margin:0!important}.bootstrap-dark .mt-0,.bootstrap-dark .my-0{margin-top:0!important}.bootstrap-dark .mr-0,.bootstrap-dark .mx-0{margin-right:0!important}.bootstrap-dark .mb-0,.bootstrap-dark .my-0{margin-bottom:0!important}.bootstrap-dark .ml-0,.bootstrap-dark .mx-0{margin-left:0!important}.bootstrap-dark .m-1{margin:.25rem!important}.bootstrap-dark .mt-1,.bootstrap-dark .my-1{margin-top:.25rem!important}.bootstrap-dark .mr-1,.bootstrap-dark .mx-1{margin-right:.25rem!important}.bootstrap-dark .mb-1,.bootstrap-dark .my-1{margin-bottom:.25rem!important}.bootstrap-dark .ml-1,.bootstrap-dark .mx-1{margin-left:.25rem!important}.bootstrap-dark .m-2{margin:.5rem!important}.bootstrap-dark .mt-2,.bootstrap-dark .my-2{margin-top:.5rem!important}.bootstrap-dark .mr-2,.bootstrap-dark .mx-2{margin-right:.5rem!important}.bootstrap-dark .mb-2,.bootstrap-dark .my-2{margin-bottom:.5rem!important}.bootstrap-dark .ml-2,.bootstrap-dark .mx-2{margin-left:.5rem!important}.bootstrap-dark .m-3{margin:1rem!important}.bootstrap-dark .mt-3,.bootstrap-dark .my-3{margin-top:1rem!important}.bootstrap-dark .mr-3,.bootstrap-dark .mx-3{margin-right:1rem!important}.bootstrap-dark .mb-3,.bootstrap-dark .my-3{margin-bottom:1rem!important}.bootstrap-dark .ml-3,.bootstrap-dark .mx-3{margin-left:1rem!important}.bootstrap-dark .m-4{margin:1.5rem!important}.bootstrap-dark .mt-4,.bootstrap-dark .my-4{margin-top:1.5rem!important}.bootstrap-dark .mr-4,.bootstrap-dark .mx-4{margin-right:1.5rem!important}.bootstrap-dark .mb-4,.bootstrap-dark .my-4{margin-bottom:1.5rem!important}.bootstrap-dark .ml-4,.bootstrap-dark .mx-4{margin-left:1.5rem!important}.bootstrap-dark .m-5{margin:3rem!important}.bootstrap-dark .mt-5,.bootstrap-dark .my-5{margin-top:3rem!important}.bootstrap-dark .mr-5,.bootstrap-dark .mx-5{margin-right:3rem!important}.bootstrap-dark .mb-5,.bootstrap-dark .my-5{margin-bottom:3rem!important}.bootstrap-dark .ml-5,.bootstrap-dark .mx-5{margin-left:3rem!important}.bootstrap-dark .p-0{padding:0!important}.bootstrap-dark .pt-0,.bootstrap-dark .py-0{padding-top:0!important}.bootstrap-dark .pr-0,.bootstrap-dark .px-0{padding-right:0!important}.bootstrap-dark .pb-0,.bootstrap-dark .py-0{padding-bottom:0!important}.bootstrap-dark .pl-0,.bootstrap-dark .px-0{padding-left:0!important}.bootstrap-dark .p-1{padding:.25rem!important}.bootstrap-dark .pt-1,.bootstrap-dark .py-1{padding-top:.25rem!important}.bootstrap-dark .pr-1,.bootstrap-dark .px-1{padding-right:.25rem!important}.bootstrap-dark .pb-1,.bootstrap-dark .py-1{padding-bottom:.25rem!important}.bootstrap-dark .pl-1,.bootstrap-dark .px-1{padding-left:.25rem!important}.bootstrap-dark .p-2{padding:.5rem!important}.bootstrap-dark .pt-2,.bootstrap-dark .py-2{padding-top:.5rem!important}.bootstrap-dark .pr-2,.bootstrap-dark .px-2{padding-right:.5rem!important}.bootstrap-dark .pb-2,.bootstrap-dark .py-2{padding-bottom:.5rem!important}.bootstrap-dark .pl-2,.bootstrap-dark .px-2{padding-left:.5rem!important}.bootstrap-dark .p-3{padding:1rem!important}.bootstrap-dark .pt-3,.bootstrap-dark .py-3{padding-top:1rem!important}.bootstrap-dark .pr-3,.bootstrap-dark .px-3{padding-right:1rem!important}.bootstrap-dark .pb-3,.bootstrap-dark .py-3{padding-bottom:1rem!important}.bootstrap-dark .pl-3,.bootstrap-dark .px-3{padding-left:1rem!important}.bootstrap-dark .p-4{padding:1.5rem!important}.bootstrap-dark .pt-4,.bootstrap-dark .py-4{padding-top:1.5rem!important}.bootstrap-dark .pr-4,.bootstrap-dark .px-4{padding-right:1.5rem!important}.bootstrap-dark .pb-4,.bootstrap-dark .py-4{padding-bottom:1.5rem!important}.bootstrap-dark .pl-4,.bootstrap-dark .px-4{padding-left:1.5rem!important}.bootstrap-dark .p-5{padding:3rem!important}.bootstrap-dark .pt-5,.bootstrap-dark .py-5{padding-top:3rem!important}.bootstrap-dark .pr-5,.bootstrap-dark .px-5{padding-right:3rem!important}.bootstrap-dark .pb-5,.bootstrap-dark .py-5{padding-bottom:3rem!important}.bootstrap-dark .pl-5,.bootstrap-dark .px-5{padding-left:3rem!important}.bootstrap-dark .m-n1{margin:-.25rem!important}.bootstrap-dark .mt-n1,.bootstrap-dark .my-n1{margin-top:-.25rem!important}.bootstrap-dark .mr-n1,.bootstrap-dark .mx-n1{margin-right:-.25rem!important}.bootstrap-dark .mb-n1,.bootstrap-dark .my-n1{margin-bottom:-.25rem!important}.bootstrap-dark .ml-n1,.bootstrap-dark .mx-n1{margin-left:-.25rem!important}.bootstrap-dark .m-n2{margin:-.5rem!important}.bootstrap-dark .mt-n2,.bootstrap-dark .my-n2{margin-top:-.5rem!important}.bootstrap-dark .mr-n2,.bootstrap-dark .mx-n2{margin-right:-.5rem!important}.bootstrap-dark .mb-n2,.bootstrap-dark .my-n2{margin-bottom:-.5rem!important}.bootstrap-dark .ml-n2,.bootstrap-dark .mx-n2{margin-left:-.5rem!important}.bootstrap-dark .m-n3{margin:-1rem!important}.bootstrap-dark .mt-n3,.bootstrap-dark .my-n3{margin-top:-1rem!important}.bootstrap-dark .mr-n3,.bootstrap-dark .mx-n3{margin-right:-1rem!important}.bootstrap-dark .mb-n3,.bootstrap-dark .my-n3{margin-bottom:-1rem!important}.bootstrap-dark .ml-n3,.bootstrap-dark .mx-n3{margin-left:-1rem!important}.bootstrap-dark .m-n4{margin:-1.5rem!important}.bootstrap-dark .mt-n4,.bootstrap-dark .my-n4{margin-top:-1.5rem!important}.bootstrap-dark .mr-n4,.bootstrap-dark .mx-n4{margin-right:-1.5rem!important}.bootstrap-dark .mb-n4,.bootstrap-dark .my-n4{margin-bottom:-1.5rem!important}.bootstrap-dark .ml-n4,.bootstrap-dark .mx-n4{margin-left:-1.5rem!important}.bootstrap-dark .m-n5{margin:-3rem!important}.bootstrap-dark .mt-n5,.bootstrap-dark .my-n5{margin-top:-3rem!important}.bootstrap-dark .mr-n5,.bootstrap-dark .mx-n5{margin-right:-3rem!important}.bootstrap-dark .mb-n5,.bootstrap-dark .my-n5{margin-bottom:-3rem!important}.bootstrap-dark .ml-n5,.bootstrap-dark .mx-n5{margin-left:-3rem!important}.bootstrap-dark .m-auto{margin:auto!important}.bootstrap-dark .mt-auto,.bootstrap-dark .my-auto{margin-top:auto!important}.bootstrap-dark .mr-auto,.bootstrap-dark .mx-auto{margin-right:auto!important}.bootstrap-dark .mb-auto,.bootstrap-dark .my-auto{margin-bottom:auto!important}.bootstrap-dark .ml-auto,.bootstrap-dark .mx-auto{margin-left:auto!important}@media(min-width:576px){.bootstrap-dark .m-sm-0{margin:0!important}.bootstrap-dark .mt-sm-0,.bootstrap-dark .my-sm-0{margin-top:0!important}.bootstrap-dark .mr-sm-0,.bootstrap-dark .mx-sm-0{margin-right:0!important}.bootstrap-dark .mb-sm-0,.bootstrap-dark .my-sm-0{margin-bottom:0!important}.bootstrap-dark .ml-sm-0,.bootstrap-dark .mx-sm-0{margin-left:0!important}.bootstrap-dark .m-sm-1{margin:.25rem!important}.bootstrap-dark .mt-sm-1,.bootstrap-dark .my-sm-1{margin-top:.25rem!important}.bootstrap-dark .mr-sm-1,.bootstrap-dark .mx-sm-1{margin-right:.25rem!important}.bootstrap-dark .mb-sm-1,.bootstrap-dark .my-sm-1{margin-bottom:.25rem!important}.bootstrap-dark .ml-sm-1,.bootstrap-dark .mx-sm-1{margin-left:.25rem!important}.bootstrap-dark .m-sm-2{margin:.5rem!important}.bootstrap-dark .mt-sm-2,.bootstrap-dark .my-sm-2{margin-top:.5rem!important}.bootstrap-dark .mr-sm-2,.bootstrap-dark .mx-sm-2{margin-right:.5rem!important}.bootstrap-dark .mb-sm-2,.bootstrap-dark .my-sm-2{margin-bottom:.5rem!important}.bootstrap-dark .ml-sm-2,.bootstrap-dark .mx-sm-2{margin-left:.5rem!important}.bootstrap-dark .m-sm-3{margin:1rem!important}.bootstrap-dark .mt-sm-3,.bootstrap-dark .my-sm-3{margin-top:1rem!important}.bootstrap-dark .mr-sm-3,.bootstrap-dark .mx-sm-3{margin-right:1rem!important}.bootstrap-dark .mb-sm-3,.bootstrap-dark .my-sm-3{margin-bottom:1rem!important}.bootstrap-dark .ml-sm-3,.bootstrap-dark .mx-sm-3{margin-left:1rem!important}.bootstrap-dark .m-sm-4{margin:1.5rem!important}.bootstrap-dark .mt-sm-4,.bootstrap-dark .my-sm-4{margin-top:1.5rem!important}.bootstrap-dark .mr-sm-4,.bootstrap-dark .mx-sm-4{margin-right:1.5rem!important}.bootstrap-dark .mb-sm-4,.bootstrap-dark .my-sm-4{margin-bottom:1.5rem!important}.bootstrap-dark .ml-sm-4,.bootstrap-dark .mx-sm-4{margin-left:1.5rem!important}.bootstrap-dark .m-sm-5{margin:3rem!important}.bootstrap-dark .mt-sm-5,.bootstrap-dark .my-sm-5{margin-top:3rem!important}.bootstrap-dark .mr-sm-5,.bootstrap-dark .mx-sm-5{margin-right:3rem!important}.bootstrap-dark .mb-sm-5,.bootstrap-dark .my-sm-5{margin-bottom:3rem!important}.bootstrap-dark .ml-sm-5,.bootstrap-dark .mx-sm-5{margin-left:3rem!important}.bootstrap-dark .p-sm-0{padding:0!important}.bootstrap-dark .pt-sm-0,.bootstrap-dark .py-sm-0{padding-top:0!important}.bootstrap-dark .pr-sm-0,.bootstrap-dark .px-sm-0{padding-right:0!important}.bootstrap-dark .pb-sm-0,.bootstrap-dark .py-sm-0{padding-bottom:0!important}.bootstrap-dark .pl-sm-0,.bootstrap-dark .px-sm-0{padding-left:0!important}.bootstrap-dark .p-sm-1{padding:.25rem!important}.bootstrap-dark .pt-sm-1,.bootstrap-dark .py-sm-1{padding-top:.25rem!important}.bootstrap-dark .pr-sm-1,.bootstrap-dark .px-sm-1{padding-right:.25rem!important}.bootstrap-dark .pb-sm-1,.bootstrap-dark .py-sm-1{padding-bottom:.25rem!important}.bootstrap-dark .pl-sm-1,.bootstrap-dark .px-sm-1{padding-left:.25rem!important}.bootstrap-dark .p-sm-2{padding:.5rem!important}.bootstrap-dark .pt-sm-2,.bootstrap-dark .py-sm-2{padding-top:.5rem!important}.bootstrap-dark .pr-sm-2,.bootstrap-dark .px-sm-2{padding-right:.5rem!important}.bootstrap-dark .pb-sm-2,.bootstrap-dark .py-sm-2{padding-bottom:.5rem!important}.bootstrap-dark .pl-sm-2,.bootstrap-dark .px-sm-2{padding-left:.5rem!important}.bootstrap-dark .p-sm-3{padding:1rem!important}.bootstrap-dark .pt-sm-3,.bootstrap-dark .py-sm-3{padding-top:1rem!important}.bootstrap-dark .pr-sm-3,.bootstrap-dark .px-sm-3{padding-right:1rem!important}.bootstrap-dark .pb-sm-3,.bootstrap-dark .py-sm-3{padding-bottom:1rem!important}.bootstrap-dark .pl-sm-3,.bootstrap-dark .px-sm-3{padding-left:1rem!important}.bootstrap-dark .p-sm-4{padding:1.5rem!important}.bootstrap-dark .pt-sm-4,.bootstrap-dark .py-sm-4{padding-top:1.5rem!important}.bootstrap-dark .pr-sm-4,.bootstrap-dark .px-sm-4{padding-right:1.5rem!important}.bootstrap-dark .pb-sm-4,.bootstrap-dark .py-sm-4{padding-bottom:1.5rem!important}.bootstrap-dark .pl-sm-4,.bootstrap-dark .px-sm-4{padding-left:1.5rem!important}.bootstrap-dark .p-sm-5{padding:3rem!important}.bootstrap-dark .pt-sm-5,.bootstrap-dark .py-sm-5{padding-top:3rem!important}.bootstrap-dark .pr-sm-5,.bootstrap-dark .px-sm-5{padding-right:3rem!important}.bootstrap-dark .pb-sm-5,.bootstrap-dark .py-sm-5{padding-bottom:3rem!important}.bootstrap-dark .pl-sm-5,.bootstrap-dark .px-sm-5{padding-left:3rem!important}.bootstrap-dark .m-sm-n1{margin:-.25rem!important}.bootstrap-dark .mt-sm-n1,.bootstrap-dark .my-sm-n1{margin-top:-.25rem!important}.bootstrap-dark .mr-sm-n1,.bootstrap-dark .mx-sm-n1{margin-right:-.25rem!important}.bootstrap-dark .mb-sm-n1,.bootstrap-dark .my-sm-n1{margin-bottom:-.25rem!important}.bootstrap-dark .ml-sm-n1,.bootstrap-dark .mx-sm-n1{margin-left:-.25rem!important}.bootstrap-dark .m-sm-n2{margin:-.5rem!important}.bootstrap-dark .mt-sm-n2,.bootstrap-dark .my-sm-n2{margin-top:-.5rem!important}.bootstrap-dark .mr-sm-n2,.bootstrap-dark .mx-sm-n2{margin-right:-.5rem!important}.bootstrap-dark .mb-sm-n2,.bootstrap-dark .my-sm-n2{margin-bottom:-.5rem!important}.bootstrap-dark .ml-sm-n2,.bootstrap-dark .mx-sm-n2{margin-left:-.5rem!important}.bootstrap-dark .m-sm-n3{margin:-1rem!important}.bootstrap-dark .mt-sm-n3,.bootstrap-dark .my-sm-n3{margin-top:-1rem!important}.bootstrap-dark .mr-sm-n3,.bootstrap-dark .mx-sm-n3{margin-right:-1rem!important}.bootstrap-dark .mb-sm-n3,.bootstrap-dark .my-sm-n3{margin-bottom:-1rem!important}.bootstrap-dark .ml-sm-n3,.bootstrap-dark .mx-sm-n3{margin-left:-1rem!important}.bootstrap-dark .m-sm-n4{margin:-1.5rem!important}.bootstrap-dark .mt-sm-n4,.bootstrap-dark .my-sm-n4{margin-top:-1.5rem!important}.bootstrap-dark .mr-sm-n4,.bootstrap-dark .mx-sm-n4{margin-right:-1.5rem!important}.bootstrap-dark .mb-sm-n4,.bootstrap-dark .my-sm-n4{margin-bottom:-1.5rem!important}.bootstrap-dark .ml-sm-n4,.bootstrap-dark .mx-sm-n4{margin-left:-1.5rem!important}.bootstrap-dark .m-sm-n5{margin:-3rem!important}.bootstrap-dark .mt-sm-n5,.bootstrap-dark .my-sm-n5{margin-top:-3rem!important}.bootstrap-dark .mr-sm-n5,.bootstrap-dark .mx-sm-n5{margin-right:-3rem!important}.bootstrap-dark .mb-sm-n5,.bootstrap-dark .my-sm-n5{margin-bottom:-3rem!important}.bootstrap-dark .ml-sm-n5,.bootstrap-dark .mx-sm-n5{margin-left:-3rem!important}.bootstrap-dark .m-sm-auto{margin:auto!important}.bootstrap-dark .mt-sm-auto,.bootstrap-dark .my-sm-auto{margin-top:auto!important}.bootstrap-dark .mr-sm-auto,.bootstrap-dark .mx-sm-auto{margin-right:auto!important}.bootstrap-dark .mb-sm-auto,.bootstrap-dark .my-sm-auto{margin-bottom:auto!important}.bootstrap-dark .ml-sm-auto,.bootstrap-dark .mx-sm-auto{margin-left:auto!important}}@media(min-width:768px){.bootstrap-dark .m-md-0{margin:0!important}.bootstrap-dark .mt-md-0,.bootstrap-dark .my-md-0{margin-top:0!important}.bootstrap-dark .mr-md-0,.bootstrap-dark .mx-md-0{margin-right:0!important}.bootstrap-dark .mb-md-0,.bootstrap-dark .my-md-0{margin-bottom:0!important}.bootstrap-dark .ml-md-0,.bootstrap-dark .mx-md-0{margin-left:0!important}.bootstrap-dark .m-md-1{margin:.25rem!important}.bootstrap-dark .mt-md-1,.bootstrap-dark .my-md-1{margin-top:.25rem!important}.bootstrap-dark .mr-md-1,.bootstrap-dark .mx-md-1{margin-right:.25rem!important}.bootstrap-dark .mb-md-1,.bootstrap-dark .my-md-1{margin-bottom:.25rem!important}.bootstrap-dark .ml-md-1,.bootstrap-dark .mx-md-1{margin-left:.25rem!important}.bootstrap-dark .m-md-2{margin:.5rem!important}.bootstrap-dark .mt-md-2,.bootstrap-dark .my-md-2{margin-top:.5rem!important}.bootstrap-dark .mr-md-2,.bootstrap-dark .mx-md-2{margin-right:.5rem!important}.bootstrap-dark .mb-md-2,.bootstrap-dark .my-md-2{margin-bottom:.5rem!important}.bootstrap-dark .ml-md-2,.bootstrap-dark .mx-md-2{margin-left:.5rem!important}.bootstrap-dark .m-md-3{margin:1rem!important}.bootstrap-dark .mt-md-3,.bootstrap-dark .my-md-3{margin-top:1rem!important}.bootstrap-dark .mr-md-3,.bootstrap-dark .mx-md-3{margin-right:1rem!important}.bootstrap-dark .mb-md-3,.bootstrap-dark .my-md-3{margin-bottom:1rem!important}.bootstrap-dark .ml-md-3,.bootstrap-dark .mx-md-3{margin-left:1rem!important}.bootstrap-dark .m-md-4{margin:1.5rem!important}.bootstrap-dark .mt-md-4,.bootstrap-dark .my-md-4{margin-top:1.5rem!important}.bootstrap-dark .mr-md-4,.bootstrap-dark .mx-md-4{margin-right:1.5rem!important}.bootstrap-dark .mb-md-4,.bootstrap-dark .my-md-4{margin-bottom:1.5rem!important}.bootstrap-dark .ml-md-4,.bootstrap-dark .mx-md-4{margin-left:1.5rem!important}.bootstrap-dark .m-md-5{margin:3rem!important}.bootstrap-dark .mt-md-5,.bootstrap-dark .my-md-5{margin-top:3rem!important}.bootstrap-dark .mr-md-5,.bootstrap-dark .mx-md-5{margin-right:3rem!important}.bootstrap-dark .mb-md-5,.bootstrap-dark .my-md-5{margin-bottom:3rem!important}.bootstrap-dark .ml-md-5,.bootstrap-dark .mx-md-5{margin-left:3rem!important}.bootstrap-dark .p-md-0{padding:0!important}.bootstrap-dark .pt-md-0,.bootstrap-dark .py-md-0{padding-top:0!important}.bootstrap-dark .pr-md-0,.bootstrap-dark .px-md-0{padding-right:0!important}.bootstrap-dark .pb-md-0,.bootstrap-dark .py-md-0{padding-bottom:0!important}.bootstrap-dark .pl-md-0,.bootstrap-dark .px-md-0{padding-left:0!important}.bootstrap-dark .p-md-1{padding:.25rem!important}.bootstrap-dark .pt-md-1,.bootstrap-dark .py-md-1{padding-top:.25rem!important}.bootstrap-dark .pr-md-1,.bootstrap-dark .px-md-1{padding-right:.25rem!important}.bootstrap-dark .pb-md-1,.bootstrap-dark .py-md-1{padding-bottom:.25rem!important}.bootstrap-dark .pl-md-1,.bootstrap-dark .px-md-1{padding-left:.25rem!important}.bootstrap-dark .p-md-2{padding:.5rem!important}.bootstrap-dark .pt-md-2,.bootstrap-dark .py-md-2{padding-top:.5rem!important}.bootstrap-dark .pr-md-2,.bootstrap-dark .px-md-2{padding-right:.5rem!important}.bootstrap-dark .pb-md-2,.bootstrap-dark .py-md-2{padding-bottom:.5rem!important}.bootstrap-dark .pl-md-2,.bootstrap-dark .px-md-2{padding-left:.5rem!important}.bootstrap-dark .p-md-3{padding:1rem!important}.bootstrap-dark .pt-md-3,.bootstrap-dark .py-md-3{padding-top:1rem!important}.bootstrap-dark .pr-md-3,.bootstrap-dark .px-md-3{padding-right:1rem!important}.bootstrap-dark .pb-md-3,.bootstrap-dark .py-md-3{padding-bottom:1rem!important}.bootstrap-dark .pl-md-3,.bootstrap-dark .px-md-3{padding-left:1rem!important}.bootstrap-dark .p-md-4{padding:1.5rem!important}.bootstrap-dark .pt-md-4,.bootstrap-dark .py-md-4{padding-top:1.5rem!important}.bootstrap-dark .pr-md-4,.bootstrap-dark .px-md-4{padding-right:1.5rem!important}.bootstrap-dark .pb-md-4,.bootstrap-dark .py-md-4{padding-bottom:1.5rem!important}.bootstrap-dark .pl-md-4,.bootstrap-dark .px-md-4{padding-left:1.5rem!important}.bootstrap-dark .p-md-5{padding:3rem!important}.bootstrap-dark .pt-md-5,.bootstrap-dark .py-md-5{padding-top:3rem!important}.bootstrap-dark .pr-md-5,.bootstrap-dark .px-md-5{padding-right:3rem!important}.bootstrap-dark .pb-md-5,.bootstrap-dark .py-md-5{padding-bottom:3rem!important}.bootstrap-dark .pl-md-5,.bootstrap-dark .px-md-5{padding-left:3rem!important}.bootstrap-dark .m-md-n1{margin:-.25rem!important}.bootstrap-dark .mt-md-n1,.bootstrap-dark .my-md-n1{margin-top:-.25rem!important}.bootstrap-dark .mr-md-n1,.bootstrap-dark .mx-md-n1{margin-right:-.25rem!important}.bootstrap-dark .mb-md-n1,.bootstrap-dark .my-md-n1{margin-bottom:-.25rem!important}.bootstrap-dark .ml-md-n1,.bootstrap-dark .mx-md-n1{margin-left:-.25rem!important}.bootstrap-dark .m-md-n2{margin:-.5rem!important}.bootstrap-dark .mt-md-n2,.bootstrap-dark .my-md-n2{margin-top:-.5rem!important}.bootstrap-dark .mr-md-n2,.bootstrap-dark .mx-md-n2{margin-right:-.5rem!important}.bootstrap-dark .mb-md-n2,.bootstrap-dark .my-md-n2{margin-bottom:-.5rem!important}.bootstrap-dark .ml-md-n2,.bootstrap-dark .mx-md-n2{margin-left:-.5rem!important}.bootstrap-dark .m-md-n3{margin:-1rem!important}.bootstrap-dark .mt-md-n3,.bootstrap-dark .my-md-n3{margin-top:-1rem!important}.bootstrap-dark .mr-md-n3,.bootstrap-dark .mx-md-n3{margin-right:-1rem!important}.bootstrap-dark .mb-md-n3,.bootstrap-dark .my-md-n3{margin-bottom:-1rem!important}.bootstrap-dark .ml-md-n3,.bootstrap-dark .mx-md-n3{margin-left:-1rem!important}.bootstrap-dark .m-md-n4{margin:-1.5rem!important}.bootstrap-dark .mt-md-n4,.bootstrap-dark .my-md-n4{margin-top:-1.5rem!important}.bootstrap-dark .mr-md-n4,.bootstrap-dark .mx-md-n4{margin-right:-1.5rem!important}.bootstrap-dark .mb-md-n4,.bootstrap-dark .my-md-n4{margin-bottom:-1.5rem!important}.bootstrap-dark .ml-md-n4,.bootstrap-dark .mx-md-n4{margin-left:-1.5rem!important}.bootstrap-dark .m-md-n5{margin:-3rem!important}.bootstrap-dark .mt-md-n5,.bootstrap-dark .my-md-n5{margin-top:-3rem!important}.bootstrap-dark .mr-md-n5,.bootstrap-dark .mx-md-n5{margin-right:-3rem!important}.bootstrap-dark .mb-md-n5,.bootstrap-dark .my-md-n5{margin-bottom:-3rem!important}.bootstrap-dark .ml-md-n5,.bootstrap-dark .mx-md-n5{margin-left:-3rem!important}.bootstrap-dark .m-md-auto{margin:auto!important}.bootstrap-dark .mt-md-auto,.bootstrap-dark .my-md-auto{margin-top:auto!important}.bootstrap-dark .mr-md-auto,.bootstrap-dark .mx-md-auto{margin-right:auto!important}.bootstrap-dark .mb-md-auto,.bootstrap-dark .my-md-auto{margin-bottom:auto!important}.bootstrap-dark .ml-md-auto,.bootstrap-dark .mx-md-auto{margin-left:auto!important}}@media(min-width:992px){.bootstrap-dark .m-lg-0{margin:0!important}.bootstrap-dark .mt-lg-0,.bootstrap-dark .my-lg-0{margin-top:0!important}.bootstrap-dark .mr-lg-0,.bootstrap-dark .mx-lg-0{margin-right:0!important}.bootstrap-dark .mb-lg-0,.bootstrap-dark .my-lg-0{margin-bottom:0!important}.bootstrap-dark .ml-lg-0,.bootstrap-dark .mx-lg-0{margin-left:0!important}.bootstrap-dark .m-lg-1{margin:.25rem!important}.bootstrap-dark .mt-lg-1,.bootstrap-dark .my-lg-1{margin-top:.25rem!important}.bootstrap-dark .mr-lg-1,.bootstrap-dark .mx-lg-1{margin-right:.25rem!important}.bootstrap-dark .mb-lg-1,.bootstrap-dark .my-lg-1{margin-bottom:.25rem!important}.bootstrap-dark .ml-lg-1,.bootstrap-dark .mx-lg-1{margin-left:.25rem!important}.bootstrap-dark .m-lg-2{margin:.5rem!important}.bootstrap-dark .mt-lg-2,.bootstrap-dark .my-lg-2{margin-top:.5rem!important}.bootstrap-dark .mr-lg-2,.bootstrap-dark .mx-lg-2{margin-right:.5rem!important}.bootstrap-dark .mb-lg-2,.bootstrap-dark .my-lg-2{margin-bottom:.5rem!important}.bootstrap-dark .ml-lg-2,.bootstrap-dark .mx-lg-2{margin-left:.5rem!important}.bootstrap-dark .m-lg-3{margin:1rem!important}.bootstrap-dark .mt-lg-3,.bootstrap-dark .my-lg-3{margin-top:1rem!important}.bootstrap-dark .mr-lg-3,.bootstrap-dark .mx-lg-3{margin-right:1rem!important}.bootstrap-dark .mb-lg-3,.bootstrap-dark .my-lg-3{margin-bottom:1rem!important}.bootstrap-dark .ml-lg-3,.bootstrap-dark .mx-lg-3{margin-left:1rem!important}.bootstrap-dark .m-lg-4{margin:1.5rem!important}.bootstrap-dark .mt-lg-4,.bootstrap-dark .my-lg-4{margin-top:1.5rem!important}.bootstrap-dark .mr-lg-4,.bootstrap-dark .mx-lg-4{margin-right:1.5rem!important}.bootstrap-dark .mb-lg-4,.bootstrap-dark .my-lg-4{margin-bottom:1.5rem!important}.bootstrap-dark .ml-lg-4,.bootstrap-dark .mx-lg-4{margin-left:1.5rem!important}.bootstrap-dark .m-lg-5{margin:3rem!important}.bootstrap-dark .mt-lg-5,.bootstrap-dark .my-lg-5{margin-top:3rem!important}.bootstrap-dark .mr-lg-5,.bootstrap-dark .mx-lg-5{margin-right:3rem!important}.bootstrap-dark .mb-lg-5,.bootstrap-dark .my-lg-5{margin-bottom:3rem!important}.bootstrap-dark .ml-lg-5,.bootstrap-dark .mx-lg-5{margin-left:3rem!important}.bootstrap-dark .p-lg-0{padding:0!important}.bootstrap-dark .pt-lg-0,.bootstrap-dark .py-lg-0{padding-top:0!important}.bootstrap-dark .pr-lg-0,.bootstrap-dark .px-lg-0{padding-right:0!important}.bootstrap-dark .pb-lg-0,.bootstrap-dark .py-lg-0{padding-bottom:0!important}.bootstrap-dark .pl-lg-0,.bootstrap-dark .px-lg-0{padding-left:0!important}.bootstrap-dark .p-lg-1{padding:.25rem!important}.bootstrap-dark .pt-lg-1,.bootstrap-dark .py-lg-1{padding-top:.25rem!important}.bootstrap-dark .pr-lg-1,.bootstrap-dark .px-lg-1{padding-right:.25rem!important}.bootstrap-dark .pb-lg-1,.bootstrap-dark .py-lg-1{padding-bottom:.25rem!important}.bootstrap-dark .pl-lg-1,.bootstrap-dark .px-lg-1{padding-left:.25rem!important}.bootstrap-dark .p-lg-2{padding:.5rem!important}.bootstrap-dark .pt-lg-2,.bootstrap-dark .py-lg-2{padding-top:.5rem!important}.bootstrap-dark .pr-lg-2,.bootstrap-dark .px-lg-2{padding-right:.5rem!important}.bootstrap-dark .pb-lg-2,.bootstrap-dark .py-lg-2{padding-bottom:.5rem!important}.bootstrap-dark .pl-lg-2,.bootstrap-dark .px-lg-2{padding-left:.5rem!important}.bootstrap-dark .p-lg-3{padding:1rem!important}.bootstrap-dark .pt-lg-3,.bootstrap-dark .py-lg-3{padding-top:1rem!important}.bootstrap-dark .pr-lg-3,.bootstrap-dark .px-lg-3{padding-right:1rem!important}.bootstrap-dark .pb-lg-3,.bootstrap-dark .py-lg-3{padding-bottom:1rem!important}.bootstrap-dark .pl-lg-3,.bootstrap-dark .px-lg-3{padding-left:1rem!important}.bootstrap-dark .p-lg-4{padding:1.5rem!important}.bootstrap-dark .pt-lg-4,.bootstrap-dark .py-lg-4{padding-top:1.5rem!important}.bootstrap-dark .pr-lg-4,.bootstrap-dark .px-lg-4{padding-right:1.5rem!important}.bootstrap-dark .pb-lg-4,.bootstrap-dark .py-lg-4{padding-bottom:1.5rem!important}.bootstrap-dark .pl-lg-4,.bootstrap-dark .px-lg-4{padding-left:1.5rem!important}.bootstrap-dark .p-lg-5{padding:3rem!important}.bootstrap-dark .pt-lg-5,.bootstrap-dark .py-lg-5{padding-top:3rem!important}.bootstrap-dark .pr-lg-5,.bootstrap-dark .px-lg-5{padding-right:3rem!important}.bootstrap-dark .pb-lg-5,.bootstrap-dark .py-lg-5{padding-bottom:3rem!important}.bootstrap-dark .pl-lg-5,.bootstrap-dark .px-lg-5{padding-left:3rem!important}.bootstrap-dark .m-lg-n1{margin:-.25rem!important}.bootstrap-dark .mt-lg-n1,.bootstrap-dark .my-lg-n1{margin-top:-.25rem!important}.bootstrap-dark .mr-lg-n1,.bootstrap-dark .mx-lg-n1{margin-right:-.25rem!important}.bootstrap-dark .mb-lg-n1,.bootstrap-dark .my-lg-n1{margin-bottom:-.25rem!important}.bootstrap-dark .ml-lg-n1,.bootstrap-dark .mx-lg-n1{margin-left:-.25rem!important}.bootstrap-dark .m-lg-n2{margin:-.5rem!important}.bootstrap-dark .mt-lg-n2,.bootstrap-dark .my-lg-n2{margin-top:-.5rem!important}.bootstrap-dark .mr-lg-n2,.bootstrap-dark .mx-lg-n2{margin-right:-.5rem!important}.bootstrap-dark .mb-lg-n2,.bootstrap-dark .my-lg-n2{margin-bottom:-.5rem!important}.bootstrap-dark .ml-lg-n2,.bootstrap-dark .mx-lg-n2{margin-left:-.5rem!important}.bootstrap-dark .m-lg-n3{margin:-1rem!important}.bootstrap-dark .mt-lg-n3,.bootstrap-dark .my-lg-n3{margin-top:-1rem!important}.bootstrap-dark .mr-lg-n3,.bootstrap-dark .mx-lg-n3{margin-right:-1rem!important}.bootstrap-dark .mb-lg-n3,.bootstrap-dark .my-lg-n3{margin-bottom:-1rem!important}.bootstrap-dark .ml-lg-n3,.bootstrap-dark .mx-lg-n3{margin-left:-1rem!important}.bootstrap-dark .m-lg-n4{margin:-1.5rem!important}.bootstrap-dark .mt-lg-n4,.bootstrap-dark .my-lg-n4{margin-top:-1.5rem!important}.bootstrap-dark .mr-lg-n4,.bootstrap-dark .mx-lg-n4{margin-right:-1.5rem!important}.bootstrap-dark .mb-lg-n4,.bootstrap-dark .my-lg-n4{margin-bottom:-1.5rem!important}.bootstrap-dark .ml-lg-n4,.bootstrap-dark .mx-lg-n4{margin-left:-1.5rem!important}.bootstrap-dark .m-lg-n5{margin:-3rem!important}.bootstrap-dark .mt-lg-n5,.bootstrap-dark .my-lg-n5{margin-top:-3rem!important}.bootstrap-dark .mr-lg-n5,.bootstrap-dark .mx-lg-n5{margin-right:-3rem!important}.bootstrap-dark .mb-lg-n5,.bootstrap-dark .my-lg-n5{margin-bottom:-3rem!important}.bootstrap-dark .ml-lg-n5,.bootstrap-dark .mx-lg-n5{margin-left:-3rem!important}.bootstrap-dark .m-lg-auto{margin:auto!important}.bootstrap-dark .mt-lg-auto,.bootstrap-dark .my-lg-auto{margin-top:auto!important}.bootstrap-dark .mr-lg-auto,.bootstrap-dark .mx-lg-auto{margin-right:auto!important}.bootstrap-dark .mb-lg-auto,.bootstrap-dark .my-lg-auto{margin-bottom:auto!important}.bootstrap-dark .ml-lg-auto,.bootstrap-dark .mx-lg-auto{margin-left:auto!important}}@media(min-width:1200px){.bootstrap-dark .m-xl-0{margin:0!important}.bootstrap-dark .mt-xl-0,.bootstrap-dark .my-xl-0{margin-top:0!important}.bootstrap-dark .mr-xl-0,.bootstrap-dark .mx-xl-0{margin-right:0!important}.bootstrap-dark .mb-xl-0,.bootstrap-dark .my-xl-0{margin-bottom:0!important}.bootstrap-dark .ml-xl-0,.bootstrap-dark .mx-xl-0{margin-left:0!important}.bootstrap-dark .m-xl-1{margin:.25rem!important}.bootstrap-dark .mt-xl-1,.bootstrap-dark .my-xl-1{margin-top:.25rem!important}.bootstrap-dark .mr-xl-1,.bootstrap-dark .mx-xl-1{margin-right:.25rem!important}.bootstrap-dark .mb-xl-1,.bootstrap-dark .my-xl-1{margin-bottom:.25rem!important}.bootstrap-dark .ml-xl-1,.bootstrap-dark .mx-xl-1{margin-left:.25rem!important}.bootstrap-dark .m-xl-2{margin:.5rem!important}.bootstrap-dark .mt-xl-2,.bootstrap-dark .my-xl-2{margin-top:.5rem!important}.bootstrap-dark .mr-xl-2,.bootstrap-dark .mx-xl-2{margin-right:.5rem!important}.bootstrap-dark .mb-xl-2,.bootstrap-dark .my-xl-2{margin-bottom:.5rem!important}.bootstrap-dark .ml-xl-2,.bootstrap-dark .mx-xl-2{margin-left:.5rem!important}.bootstrap-dark .m-xl-3{margin:1rem!important}.bootstrap-dark .mt-xl-3,.bootstrap-dark .my-xl-3{margin-top:1rem!important}.bootstrap-dark .mr-xl-3,.bootstrap-dark .mx-xl-3{margin-right:1rem!important}.bootstrap-dark .mb-xl-3,.bootstrap-dark .my-xl-3{margin-bottom:1rem!important}.bootstrap-dark .ml-xl-3,.bootstrap-dark .mx-xl-3{margin-left:1rem!important}.bootstrap-dark .m-xl-4{margin:1.5rem!important}.bootstrap-dark .mt-xl-4,.bootstrap-dark .my-xl-4{margin-top:1.5rem!important}.bootstrap-dark .mr-xl-4,.bootstrap-dark .mx-xl-4{margin-right:1.5rem!important}.bootstrap-dark .mb-xl-4,.bootstrap-dark .my-xl-4{margin-bottom:1.5rem!important}.bootstrap-dark .ml-xl-4,.bootstrap-dark .mx-xl-4{margin-left:1.5rem!important}.bootstrap-dark .m-xl-5{margin:3rem!important}.bootstrap-dark .mt-xl-5,.bootstrap-dark .my-xl-5{margin-top:3rem!important}.bootstrap-dark .mr-xl-5,.bootstrap-dark .mx-xl-5{margin-right:3rem!important}.bootstrap-dark .mb-xl-5,.bootstrap-dark .my-xl-5{margin-bottom:3rem!important}.bootstrap-dark .ml-xl-5,.bootstrap-dark .mx-xl-5{margin-left:3rem!important}.bootstrap-dark .p-xl-0{padding:0!important}.bootstrap-dark .pt-xl-0,.bootstrap-dark .py-xl-0{padding-top:0!important}.bootstrap-dark .pr-xl-0,.bootstrap-dark .px-xl-0{padding-right:0!important}.bootstrap-dark .pb-xl-0,.bootstrap-dark .py-xl-0{padding-bottom:0!important}.bootstrap-dark .pl-xl-0,.bootstrap-dark .px-xl-0{padding-left:0!important}.bootstrap-dark .p-xl-1{padding:.25rem!important}.bootstrap-dark .pt-xl-1,.bootstrap-dark .py-xl-1{padding-top:.25rem!important}.bootstrap-dark .pr-xl-1,.bootstrap-dark .px-xl-1{padding-right:.25rem!important}.bootstrap-dark .pb-xl-1,.bootstrap-dark .py-xl-1{padding-bottom:.25rem!important}.bootstrap-dark .pl-xl-1,.bootstrap-dark .px-xl-1{padding-left:.25rem!important}.bootstrap-dark .p-xl-2{padding:.5rem!important}.bootstrap-dark .pt-xl-2,.bootstrap-dark .py-xl-2{padding-top:.5rem!important}.bootstrap-dark .pr-xl-2,.bootstrap-dark .px-xl-2{padding-right:.5rem!important}.bootstrap-dark .pb-xl-2,.bootstrap-dark .py-xl-2{padding-bottom:.5rem!important}.bootstrap-dark .pl-xl-2,.bootstrap-dark .px-xl-2{padding-left:.5rem!important}.bootstrap-dark .p-xl-3{padding:1rem!important}.bootstrap-dark .pt-xl-3,.bootstrap-dark .py-xl-3{padding-top:1rem!important}.bootstrap-dark .pr-xl-3,.bootstrap-dark .px-xl-3{padding-right:1rem!important}.bootstrap-dark .pb-xl-3,.bootstrap-dark .py-xl-3{padding-bottom:1rem!important}.bootstrap-dark .pl-xl-3,.bootstrap-dark .px-xl-3{padding-left:1rem!important}.bootstrap-dark .p-xl-4{padding:1.5rem!important}.bootstrap-dark .pt-xl-4,.bootstrap-dark .py-xl-4{padding-top:1.5rem!important}.bootstrap-dark .pr-xl-4,.bootstrap-dark .px-xl-4{padding-right:1.5rem!important}.bootstrap-dark .pb-xl-4,.bootstrap-dark .py-xl-4{padding-bottom:1.5rem!important}.bootstrap-dark .pl-xl-4,.bootstrap-dark .px-xl-4{padding-left:1.5rem!important}.bootstrap-dark .p-xl-5{padding:3rem!important}.bootstrap-dark .pt-xl-5,.bootstrap-dark .py-xl-5{padding-top:3rem!important}.bootstrap-dark .pr-xl-5,.bootstrap-dark .px-xl-5{padding-right:3rem!important}.bootstrap-dark .pb-xl-5,.bootstrap-dark .py-xl-5{padding-bottom:3rem!important}.bootstrap-dark .pl-xl-5,.bootstrap-dark .px-xl-5{padding-left:3rem!important}.bootstrap-dark .m-xl-n1{margin:-.25rem!important}.bootstrap-dark .mt-xl-n1,.bootstrap-dark .my-xl-n1{margin-top:-.25rem!important}.bootstrap-dark .mr-xl-n1,.bootstrap-dark .mx-xl-n1{margin-right:-.25rem!important}.bootstrap-dark .mb-xl-n1,.bootstrap-dark .my-xl-n1{margin-bottom:-.25rem!important}.bootstrap-dark .ml-xl-n1,.bootstrap-dark .mx-xl-n1{margin-left:-.25rem!important}.bootstrap-dark .m-xl-n2{margin:-.5rem!important}.bootstrap-dark .mt-xl-n2,.bootstrap-dark .my-xl-n2{margin-top:-.5rem!important}.bootstrap-dark .mr-xl-n2,.bootstrap-dark .mx-xl-n2{margin-right:-.5rem!important}.bootstrap-dark .mb-xl-n2,.bootstrap-dark .my-xl-n2{margin-bottom:-.5rem!important}.bootstrap-dark .ml-xl-n2,.bootstrap-dark .mx-xl-n2{margin-left:-.5rem!important}.bootstrap-dark .m-xl-n3{margin:-1rem!important}.bootstrap-dark .mt-xl-n3,.bootstrap-dark .my-xl-n3{margin-top:-1rem!important}.bootstrap-dark .mr-xl-n3,.bootstrap-dark .mx-xl-n3{margin-right:-1rem!important}.bootstrap-dark .mb-xl-n3,.bootstrap-dark .my-xl-n3{margin-bottom:-1rem!important}.bootstrap-dark .ml-xl-n3,.bootstrap-dark .mx-xl-n3{margin-left:-1rem!important}.bootstrap-dark .m-xl-n4{margin:-1.5rem!important}.bootstrap-dark .mt-xl-n4,.bootstrap-dark .my-xl-n4{margin-top:-1.5rem!important}.bootstrap-dark .mr-xl-n4,.bootstrap-dark .mx-xl-n4{margin-right:-1.5rem!important}.bootstrap-dark .mb-xl-n4,.bootstrap-dark .my-xl-n4{margin-bottom:-1.5rem!important}.bootstrap-dark .ml-xl-n4,.bootstrap-dark .mx-xl-n4{margin-left:-1.5rem!important}.bootstrap-dark .m-xl-n5{margin:-3rem!important}.bootstrap-dark .mt-xl-n5,.bootstrap-dark .my-xl-n5{margin-top:-3rem!important}.bootstrap-dark .mr-xl-n5,.bootstrap-dark .mx-xl-n5{margin-right:-3rem!important}.bootstrap-dark .mb-xl-n5,.bootstrap-dark .my-xl-n5{margin-bottom:-3rem!important}.bootstrap-dark .ml-xl-n5,.bootstrap-dark .mx-xl-n5{margin-left:-3rem!important}.bootstrap-dark .m-xl-auto{margin:auto!important}.bootstrap-dark .mt-xl-auto,.bootstrap-dark .my-xl-auto{margin-top:auto!important}.bootstrap-dark .mr-xl-auto,.bootstrap-dark .mx-xl-auto{margin-right:auto!important}.bootstrap-dark .mb-xl-auto,.bootstrap-dark .my-xl-auto{margin-bottom:auto!important}.bootstrap-dark .ml-xl-auto,.bootstrap-dark .mx-xl-auto{margin-left:auto!important}}.bootstrap-dark .stretched-link:after{background-color:#0000;bottom:0;content:"";left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.bootstrap-dark .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.bootstrap-dark .text-justify{text-align:justify!important}.bootstrap-dark .text-wrap{white-space:normal!important}.bootstrap-dark .text-nowrap{white-space:nowrap!important}.bootstrap-dark .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap-dark .text-left{text-align:left!important}.bootstrap-dark .text-right{text-align:right!important}.bootstrap-dark .text-center{text-align:center!important}@media(min-width:576px){.bootstrap-dark .text-sm-left{text-align:left!important}.bootstrap-dark .text-sm-right{text-align:right!important}.bootstrap-dark .text-sm-center{text-align:center!important}}@media(min-width:768px){.bootstrap-dark .text-md-left{text-align:left!important}.bootstrap-dark .text-md-right{text-align:right!important}.bootstrap-dark .text-md-center{text-align:center!important}}@media(min-width:992px){.bootstrap-dark .text-lg-left{text-align:left!important}.bootstrap-dark .text-lg-right{text-align:right!important}.bootstrap-dark .text-lg-center{text-align:center!important}}@media(min-width:1200px){.bootstrap-dark .text-xl-left{text-align:left!important}.bootstrap-dark .text-xl-right{text-align:right!important}.bootstrap-dark .text-xl-center{text-align:center!important}}.bootstrap-dark .text-lowercase{text-transform:lowercase!important}.bootstrap-dark .text-uppercase{text-transform:uppercase!important}.bootstrap-dark .text-capitalize{text-transform:capitalize!important}.bootstrap-dark .font-weight-light{font-weight:300!important}.bootstrap-dark .font-weight-lighter{font-weight:lighter!important}.bootstrap-dark .font-weight-normal{font-weight:400!important}.bootstrap-dark .font-weight-bold{font-weight:700!important}.bootstrap-dark .font-weight-bolder{font-weight:bolder!important}.bootstrap-dark .font-italic{font-style:italic!important}.bootstrap-dark .text-white{color:#fff!important}.bootstrap-dark .text-primary{color:#007bff!important}.bootstrap-dark a.text-primary:focus,.bootstrap-dark a.text-primary:hover{color:#0056b3!important}.bootstrap-dark .text-secondary{color:#6c757d!important}.bootstrap-dark a.text-secondary:focus,.bootstrap-dark a.text-secondary:hover{color:#494f54!important}.bootstrap-dark .text-success{color:#28a745!important}.bootstrap-dark a.text-success:focus,.bootstrap-dark a.text-success:hover{color:#19692c!important}.bootstrap-dark .text-info{color:#17a2b8!important}.bootstrap-dark a.text-info:focus,.bootstrap-dark a.text-info:hover{color:#0f6674!important}.bootstrap-dark .text-warning{color:#ffc107!important}.bootstrap-dark a.text-warning:focus,.bootstrap-dark a.text-warning:hover{color:#ba8b00!important}.bootstrap-dark .text-danger{color:#dc3545!important}.bootstrap-dark a.text-danger:focus,.bootstrap-dark a.text-danger:hover{color:#a71d2a!important}.bootstrap-dark .text-light{color:#f8f9fa!important}.bootstrap-dark a.text-light:focus,.bootstrap-dark a.text-light:hover{color:#cbd3da!important}.bootstrap-dark .text-dark{color:#343a40!important}.bootstrap-dark a.text-dark:focus,.bootstrap-dark a.text-dark:hover{color:#121416!important}.bootstrap-dark .text-body{color:#d3d3d3!important}.bootstrap-dark .text-muted{color:#6c757d!important}.bootstrap-dark .text-black-50{color:#00000080!important}.bootstrap-dark .text-white-50{color:#ffffff80!important}.bootstrap-dark .text-hide{background-color:initial;border:0;color:#0000;font:0/0 a;text-shadow:none}.bootstrap-dark .text-decoration-none{text-decoration:none!important}.bootstrap-dark .text-break{word-wrap:break-word!important;word-break:break-word!important}.bootstrap-dark .text-reset{color:inherit!important}.bootstrap-dark .visible{visibility:visible!important}.bootstrap-dark .invisible{visibility:hidden!important}.bootstrap-dark .alert-cell{background:#212529;color:#fff}.bootstrap-dark .rule-cell{background-color:#212529}.bootstrap-dark .config-yaml{background-color:#adb5bd;border:1px solid #495057;border-radius:4px;color:#000;display:block;font-size:13px;padding:10px;word-break:break-all}.bootstrap-dark .query-stats{color:#6c757d;flex-grow:1;font-size:.7rem}.bootstrap-dark .metrics-explorer.modal-dialog{max-width:750px;overflow-wrap:break-word}.bootstrap-dark .metrics-explorer .metric{cursor:pointer;margin:0;padding:5px}.bootstrap-dark .metrics-explorer .metric:hover{background:#212529}.bootstrap-dark button.metrics-explorer-btn{background-color:#343a40;border:1px solid #6c757d;color:#dee2e6}.bootstrap-dark .graph-controls button.clear-time-btn,.bootstrap-dark .table-controls button.clear-time-btn{background-color:#000;border:1px solid #6c757d;border-left:none}.bootstrap-dark .graph-controls button.clear-time-btn:hover,.bootstrap-dark .table-controls button.clear-time-btn:hover{color:#545b62}.bootstrap-dark button.execute-btn{border:1px solid #1a88ff;width:84px}.bootstrap-dark .expression-input .cm-expression-input{border:1px solid #6c757d;flex:1 1 auto;font-size:15px;padding:4px 0 0 8px}.bootstrap-dark .tab-content{border-bottom:1px solid hsla(0,0%,100%,.125);border-left:1px solid hsla(0,0%,100%,.125);border-right:1px solid hsla(0,0%,100%,.125);padding:10px}.bootstrap-dark .modal.show{overflow-y:auto}.bootstrap-dark .panel{margin-bottom:20px}.bootstrap-dark input[type=checkbox]:checked+label{color:#286090}.bootstrap-dark .custom-control-label{cursor:pointer}.bootstrap-dark .togglers-wrapper .form-group{margin-bottom:.5rem}.bootstrap-dark [for$=-toggler].custom-control-label:after,.bootstrap-dark [for$=-toggler].custom-control-label:before{height:1.12rem;left:-1.3rem;top:.28rem;width:1.12rem}.bootstrap-dark .capitalize-title:first-letter{text-transform:capitalize}.bootstrap-dark .input-group.expression-input{flex-wrap:nowrap;margin-bottom:10px}.bootstrap-dark .alert.alert-danger{margin-bottom:10px}.bootstrap-dark .nav-tabs .nav-link{cursor:pointer}.bootstrap-dark .tab-content .alert{margin-bottom:0}.bootstrap-dark .data-table.table{margin:10px 0 2px}.bootstrap-dark .data-table>tbody>tr>td{font-size:.8em;overflow:hidden;padding:5px 0 5px 8px}.bootstrap-dark .autosuggest-dropdown{background-color:#fff;border:1px solid #ced4da;color:#495057;font-size:1rem;left:56px;margin-top:-6px;position:absolute;z-index:1000}.bootstrap-dark .autosuggest-dropdown-list{list-style:none;margin:0;padding:0}.bootstrap-dark .autosuggest-dropdown-list li{background-color:initial;border:0;clear:both;display:block;padding:.25rem 1.5rem;white-space:nowrap;width:100%}.bootstrap-dark .autosuggest-dropdown-list li.autosuggest-dropdown-header{background-color:#bfdeff;font-size:10px;line-height:1.5;text-align:center;text-transform:uppercase}.bootstrap-dark .graph-controls,.bootstrap-dark .table-controls{margin-bottom:10px}.bootstrap-dark .graph-controls input,.bootstrap-dark .table-controls input{text-align:center}.bootstrap-dark .graph-controls .range-input input{width:50px}.bootstrap-dark .time-input input{border-right:none}.bootstrap-dark .time-input{width:270px!important}.bootstrap-dark .graph-controls input.resolution-input{width:90px}.bootstrap-dark .graph-controls>:not(:first-child){margin-left:20px}.bootstrap-dark .graph-legend{display:inline-block;font-size:.75em;margin:15px 0 15px 55px;padding:10px 5px}.bootstrap-dark .legend-item{border-radius:3px;cursor:pointer;display:flex;line-height:1.7;padding:0 5px}.bootstrap-dark .legend-item div{flex-wrap:wrap}.bootstrap-dark .legend-swatch{display:inline-block;height:7px;margin:6px 8px 2px 0;min-width:7px;outline:1.5px solid #ccc;outline-offset:1px}.bootstrap-dark .legend-item:hover{background:#0000002e}.bootstrap-dark .legend-metric-name{margin-right:1px}.bootstrap-dark .legend-label-name{font-weight:700}.bootstrap-dark .graph{margin:0 5px}.bootstrap-dark .graph-chart{fill:#495057;font-size:.8em;height:500px;width:100%}.bootstrap-dark .graph-chart .flot-overlay{cursor:crosshair}.bootstrap-dark .graph-tooltip{background:#000c;border-radius:3px;color:#fff;font-family:Arial,Helvetica,sans-serif;font-size:12px;padding:8px;white-space:nowrap}.bootstrap-dark .graph-tooltip .labels{font-size:11px;line-height:11px}.bootstrap-dark .graph-tooltip .detail-swatch{display:inline-block;height:10px;width:10px}.bootstrap-dark .add-panel-btn{margin-bottom:20px}.bootstrap-dark .target-head{font-size:large;font-weight:700}.bootstrap-dark .group-info{display:flex;justify-content:space-between;margin-bottom:10px;padding:10px}.bootstrap-dark .badges-wrapper>span{margin-right:5px;max-height:20px}.bootstrap-dark .rules-head{font-weight:600}.bootstrap-dark .rule_cell{background-color:#f5f5f5;display:block;font-family:monospace;white-space:pre-wrap}.bootstrap-dark .popup-message{background-color:#000000b3;border-radius:4px;color:#fff;display:none;font-size:14px;margin-right:15px;max-width:250px;min-width:120px;padding:8px 12px;position:absolute;right:100%;top:50%;transform:translateY(-50%);white-space:normal;width:-webkit-max-content;width:max-content}.bootstrap-dark .custom-control-label:hover .popup-message{display:block} +/*# sourceMappingURL=main.17d667f4.css.map*/ \ No newline at end of file diff --git a/pkg/ui/static/react/static/css/main.17d667f4.css.map b/pkg/ui/static/react/static/css/main.17d667f4.css.map new file mode 100644 index 0000000000..0350e3546e --- /dev/null +++ b/pkg/ui/static/react/static/css/main.17d667f4.css.map @@ -0,0 +1 @@ +{"version":3,"file":"static/css/main.17d667f4.css","mappings":"AAAA;;;;EAIE,CAAC,yxBAAk3B,kBAAkB,CAAC,QAAO,CAA3E,UAAU,CAAC,WAAW,CAAW,eAAe,CAAzB,SAAS,CAA5D,iBAAiB,CAAC,SAAsF,CAAC,4HAA4H,wBAAwB,CAAC,6DAA6D,2BAA2B,CAAC,qEAAiI,QAAQ,CAAC,wBAAuB,CAA/C,MAAM,CAAnD,iBAAiB,CAAmC,OAAO,CAApB,KAAK,CAA1B,oBAA2E,CAAC,2DAA2D,cAAc,CAAC,iCAAiC,eAAe,CAAC,+CAA+C,aAAa,CAAC,YAAY,CAAC,WAAW,CAAC,WAAW,CAA6H,iOAAiH,WAAW,CAAC,kLAAkL,WAAW,CAAC,yBAAyB,8DAA8D,UAAU,CAAC,CAAC,yBAAyB,8DAA8D,UAAU,CAAC,CAAC,yBAAyB,8DAA8D,UAAU,CAAC,CAAC,2GAA2G,UAAU,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,6DAA+J,6BAAkC,CAApI,2BAAiC,CAAC,4BAAkC,CAA0E,QAAO,CAAhB,QAAiB,CAAC,4DAAiI,4BAA4B,CAAjG,2BAAiC,CAAC,4BAAkC,CAAuC,QAAO,CAAhB,QAAiB,CAAC,0DAA0D,2BAAiC,CAAC,4BAAkC,CAA2B,0BAA+B,CAAC,WAAW,CAAC,QAAQ,CAAC,yDAAyD,2BAAiC,CAAC,4BAAkC,CAAC,yBAAyB,CAAC,WAAW,CAAC,QAAQ,CAAC,kEAAkE,SAAS,CAAC,SAAS,CAAC,iEAAiE,SAAS,CAAC,SAAS,CAAC,qDAAqD,WAAW,CAAC,gDAAgD,QAAQ,CAAC,gDAAgD,aAAa,CAAC,uDAAuD,eAAe,CAAC,0JAAqL,eAAe,CAA/B,eAAe,CAAiB,QAAO,CAAlD,UAAmD,CAAC,qDAAqD,WAAW,CAAC,gEAAkF,+JAA6K,CAAY,WAAU,CAArN,iBAAiB,CAA+K,UAAsB,CAAC,wEAAyE,yBAAyB,CAAC,0EAA2E,2BAA2B,CAAC,wEAAyE,yBAAyB,CAAC,0EAA2E,2BAA2B,CAAC,mEAAoE,oBAAoB,CAAC,qEAAsE,sBAAsB,CAAC,sEAAuE,sBAAsB,CAAC,+DAAgE,0BAA0B,CAAC,+DAAgE,+BAA+B,CAAC,gDAAgD,iBAAiB,CAAC,sDAAuD,sCAAsC,CAAC,mDAAsE,WAAW,CAAY,mBAAkB,CAAlD,QAAQ,CAAlB,SAAS,CAAsB,UAA8B,CAAC,wDAAwE,YAAY,CAA5B,eAAe,CAAc,UAAU,CAAC,0FAA0G,YAAW,CAA3B,eAA4B,CAAC,uCAAkD,QAAO,CAAlB,UAAmB,CAAC,oFAAsG,oBAAmB,CAArC,iBAAsC,CAAC,0CAA0C,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,wDAAwD,WAAW,CAAC,4GAA4G,cAAc,CAAC,aAAa,CAAC,kBAAkB,CAAC,qDAAsD,wBAAwB,CAAC,qDAAsD,oBAAoB,CAAC,+DAA+D,cAAc,CAAC,qEAAqE,kBAAkB,CAAC,0CAA0C,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,6CAAyF,aAAa,CAAC,cAAa,CAAvE,cAAc,CAAC,WAAW,CAAC,gBAA6C,CAAC,8CAA8C,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,uNAAuN,kBAAkB,CAAC,cAAc,CAAC,4FAA4F,aAAa,CAAC,gDAAgD,iBAAiB,CAAC,uDAAqK,gCAA+B,CAA/B,kBAA+B,CAA/B,wBAA+B,CAAmB,UAAU,CAA1K,UAAU,CAAC,oBAAoB,CAA+G,iBAAiB,CAAY,SAAS,CAAC,wGAAwG,wBAAwB,CAAC,UAAU,CAAC,8BAAoC,CAAC,8DAA8D,wBAAwB,CAAC,4GAA4G,cAAc,CAAC,aAAa,CAAC,kBAAkB,CAAC,+CAA4J,oBAAmB,CAAlC,cAAc,CAA5G,oBAAoB,CAAY,WAAW,CAAC,gBAAgB,CAAgB,iBAAiB,CAAhC,cAAc,CAAtD,UAA4G,CAAC,qDAAqD,kBAAkB,CAAC,sDAAsD,wBAAwB,CAAC,UAAU,CAAC,8BAAoC,CAAC,mDAAmD,aAAa,CAAC,sHAAsH,cAAc,CAAC,aAAa,CAAC,kBAAkB,CAAC,uDAAuD,WAAW,CAAC,gBAAgB,CAAC,sEAAoF,aAAwB,CAAxB,yBAAyB,CAAC,4EAA4E,aAAa,CAAC,87CAAk9C,cAAa,CAAjC,mBAAkC,CAAC,khDAAkhD,cAAc,CAAC,0CAA0C,cAAc,CCJt8W,kCACE,gBACF,CAEA,8BAGE,cAAe,CAFf,cAAe,CACf,eAEF,CAMA,+BAEE,aACF,CAEA,8BACE,UACF,CAEA,6BAEE,oBAAqB,CADrB,WAAY,CAEZ,oBACF,CAEA,iEAEE,SACF,CAEA,kEAEE,SACF,CAEA,+BAEE,SACF,CC1CA,gCACE,kBACF,CCFA,2BAEI,WAAY,CADZ,UAMJ,CCPA,2DDMI,kBAAmB,CAHnB,YAAa,CACb,qBAAsB,CACtB,sBCCJ,CANA,gCAEE,gBAIF,CAEA,uCACE,eAAgB,CAChB,YACF,CAEA,+BAEE,qBAAsB,CADtB,oBAEF,CChBA,yBAEE,UAAW,CADX,YAAa,CAEb,mCAAoC,CACpC,iBAAkB,CAClB,SACF,CAEA,oBACE,UACF,CAEA,uBACE,qCAAwC,CACxC,eAAgB,CAChB,6BAAoC,CACpC,oBACF,CAEA,0CACE,SACF,CAEA,gDACE,wBAAyB,CACzB,iBACF,CAEA,4BAME,qBAAsB,CAGtB,kBAAmB,CADnB,gBAAiB,CAHjB,cAAe,CADf,WAAY,CAFZ,iBAAkB,CAClB,eAAgB,CAIhB,8BAAgC,CANhC,OASF,CAEA,+CAGE,oDAA0E,CAF1E,eAAgB,CAChB,WAEF,CAEA,0BAIE,kBAAmB,CAFnB,YAAa,CAGb,sBAAuB,CAFvB,6BAA8B,CAF9B,UAKF,CAEA,sBAIE,eAAgB,CADhB,eAAgB,CAFhB,QAAS,CACT,SAGF,CAEA,wBAEE,eAAgB,CADhB,WAAY,CAEZ,aAAc,CACd,0BACF,CAEA,4BAME,kBAAmB,CALnB,qBAAsB,CAEtB,YAAa,CAEb,qBAAsB,CAEtB,iBAAkB,CAHlB,4BAA6B,CAF7B,aAMF,CAEA,yBAIE,cAAgB,CAFhB,6BAIF,CAEA,+CALE,kBAAmB,CAFnB,YAAa,CAIb,UAOF,CAEA,qBACE,qBAAsB,CACtB,aACF,CAEA,0BAOE,qBAAsB,CANtB,aAAc,CAEd,QAAS,CAGT,eAAgB,CAFhB,iBAAkB,CAClB,sBAAuB,CAHvB,SAMF,CAEA,6BAKE,0BAA2B,CAD3B,qBAAsB,CAHtB,YAAa,CACb,qBAAsB,CACtB,UAGF,CAEA,mBAGE,oBAAqB,CAErB,kBAAuB,CADvB,0BAA2B,CAE3B,aAAe,CACf,iBAAkB,CALlB,iBAAkB,CADlB,UAOF,CAEA,yBAEE,WAAY,CAMZ,qBAAsB,CALtB,WAAY,CAGZ,QAAS,CAFT,aAAe,CAGf,WAAY,CAEZ,uBAAwB,CAJxB,SAAU,CAJV,iBASF,CAEA,8DAGE,sCAAiD,CADjD,YAEF,CAMA,qBACE,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBACF,CAEA,0BACE,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBACF,CAEA,2BACE,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,iBAAkB,CAClB,cAAkB,CAClB,iBACF,CAEA,uBACE,yBACF,CACA,uBACE,yBACF,CACA,uBACE,yBACF,CACA,uBACE,yBACF,CACA,uBACE,yBACF,CACA,uBACE,yBACF,CAEA,0BACE,kBACF,CAEA,2BAGE,kBAAmB,CAFnB,YAAa,CACb,kBAEF,CCzMA,WAKE,iBAAkB,CAHlB,WAAY,CACZ,aAAc,CAFd,iBAAkB,CAKlB,iBAAkB,CAFlB,UAKF,CACA,wBAFE,yCAA6C,CAD7C,qBAMF,CACA,gBAGE,wBAAyB,CADzB,UAIF,CACA,iCAFE,iBAAkB,CADlB,UAAW,CAHX,iBAYF,CANA,iBAKE,wBAAyB,CAHzB,MAIF,CACA,kBAUE,qBAAsB,CADtB,wBAAyB,CADzB,iBAAkB,CAJlB,cAAe,CACf,mBAAoB,CAEpB,WAAY,CAJZ,WAAY,CAGZ,eAAgB,CALhB,iBAAkB,CAUlB,kBAAmB,CATnB,UAUF,CACA,+EACE,oBAAqB,CACrB,4BACF,CACA,wBACE,YACF,CACA,sCACE,oBAAqB,CACrB,gBACF,CACA,wBACE,oBACF,CACA,yBACE,oBAAqB,CACrB,0BAA2B,CAE3B,eACF,CACA,gBAKE,cAAe,CAFf,MAAO,CAFP,iBAAkB,CAClB,QAAS,CAET,UAEF,CACA,qBAME,UAAW,CADX,cAAe,CAHf,oBAAqB,CADrB,iBAAkB,CAGlB,iBAAkB,CADlB,qBAIF,CACA,4BACE,UACF,CACA,gBAIE,gBAAuB,CADvB,UAAW,CAFX,iBAAkB,CAClB,UAGF,CACA,eAOE,qBAAsB,CADtB,wBAAyB,CAGzB,iBAAkB,CAPlB,WAAY,CAMZ,cAAe,CAHf,UAAW,CAFX,gBAAiB,CAFjB,iBAAkB,CASlB,qBAAsB,CANtB,SAOF,CACA,sBACE,oBACF,CACA,uBACE,iBACF,CACA,oBACE,wBACF,CACA,qCACE,qBACF,CACA,yEAIE,qBAAsB,CAFtB,iBAAkB,CAClB,eAAgB,CAEhB,kBACF,CACA,4EAEE,4BACF,CACA,oBAEE,WAAY,CACZ,aAAc,CAFd,UAGF,CACA,oCACE,WAAY,CACZ,SACF,CACA,qCAEE,QAAS,CADT,QAAS,CAET,SACF,CACA,sCACE,gBAAiB,CACjB,kBACF,CACA,oCAGE,WAAY,CADZ,SAAU,CADV,KAGF,CACA,oCACE,WAAY,CACZ,SACF,CACA,mCACE,QAAS,CACT,kBACF,CAIA,6FACE,kBACF,CAQA,0GACE,sBAAwB,CACxB,wBAAyB,CAEzB,2BAA4B,CAD5B,uBAEF,CACA,0JAEE,wCAAyC,CACzC,4BACF,CACA,4EACE,yCAA0C,CAC1C,4BACF,CACA,uEAGE,mDAAyD,CADzD,kBAEF,CACA,mCACE,yDACF,CACA,qCACE,GACE,SAAU,CAEV,kBAAsB,CADtB,yBAEF,CACA,GAEE,kBAAsB,CADtB,yBAEF,CACF,CACA,sCACE,GAEE,kBAAsB,CADtB,yBAEF,CACA,GACE,SAAU,CAEV,kBAAsB,CADtB,yBAEF,CACF,CACA,mBAEE,YAAa,CADb,iBAAkB,CAElB,WAAY,CACZ,kBAGF,CACA,wCAFE,yCAA6C,CAD7C,qBAMF,CACA,0BACE,YACF,CACA,iCACE,iBACF,CACA,yBASE,wBAAyB,CACzB,iBAAkB,CAClB,0BAA2B,CAL3B,UAAW,CAFX,cAAe,CADf,WAAY,CAEZ,aAAc,CAHd,cAAe,CADf,eAAgB,CAMhB,iBAAkB,CAClB,oBAIF,CACA,yBAIE,kBAAyB,CACzB,kBAAmB,CAFnB,QAAS,CAFT,iBAAkB,CAClB,OAIF,CACA,0DAKE,wBAAyB,CADzB,sBAAuB,CAHvB,UAAW,CACX,QAAS,CACT,gBAGF,CCpPE,KAGE,wBAIF,WACE,oBACA,iGClBJ,iBCkBA,qBAGE,CAOA,sEAMF,aACE,MAiBA,sBCgP4B,aApRnB,CD8BT,wLCsO4B,eChGxB,gBD2GwB,gBAKA,CDvP9B,QACE,CC9BS,eATA,2CD0DX,mBACE,IASF,kBACE,SACA,iBACA,mBAcA,oBADF,YCkN8B,GDxM5B,mBADF,YCsF4B,uCDrE1B,eACA,CAFA,WACA,CAJF,yBAEE,yCACA,CADA,gCACA,CAEA,mEACA,SAIA,iBACA,oBACA,kBAHF,kBAUE,CAPA,SAGF,YAIE,yBAGF,eAIE,IAGF,eCkJ8B,ID9I9B,mBACE,cACA,YAGF,eACE,UAGF,kBCsI8B,ODjI9B,aEII,SFOF,aEPE,cFSF,CAJF,iBAEE,CAEA,sBACA,KAGF,kBACA,YCF0C,yBDS1C,aCV0C,qBDaxC,SGhLA,aFqKwC,0BACA,CDyBxC,4DG/LA,aHkME,qBACA,mBASJ,sFC6D8B,cCjH1B,KFkEF,6BAJA,kBAEA,CAJF,YAEE,CAEA,aAKA,QAQF,eAEE,KASA,iBACA,SAFF,qBASE,CAPA,IAGF,eAIE,OAQF,wBACE,SAOA,oBC0E4B,aAjVnB,CAiVmB,sBD9E9B,kBC8E8B,CAjVnB,eDwQT,IAOF,kBAEE,gCACA,OAQF,oBAEE,oBC4JsC,QDrJxC,eAEE,kCAQF,SACE,uCAQA,mBACA,kBEhKE,qBF0JJ,QAQE,cAGF,gBAEE,eAGF,mBAEE,eAMF,cACE,QAMF,gBACE,iDAOF,yBAIE,6GASE,cACE,yHAUJ,kBAJF,SAKE,wCAGF,qBAEE,UACA,UAIF,aACE,gBAEA,UAYA,SADA,QACA,CATF,WAME,UAIA,QAYA,aACA,CARF,aACE,CAIA,gBE9OI,oBFgPJ,CAHA,mBACA,CAHA,cACA,UACA,CAIA,mBAPA,UAQA,UAGF,sBACE,mFAIF,WAEE,eAQA,wBALF,mBAME,0CAOF,uBACE,8BASA,0BADF,YAEE,QAOF,oBACE,SAIA,eADF,iBAEE,UAGF,YACE,UAKF,sBACE,gBIrcA,sBHuQ4B,aApRnB,CGOT,wLH6P4B,eChGxB,gBD2GwB,gBAKA,CG9Q9B,QACE,CHPS,eATA,kBIPX,cAGI,iNAIA,yIAIA,+SAKF,uGACA,+KJ4R4B,eAEA,iBKzS9B,mBL0S8B,8BKjS9B,gBJqKM,8BIpKN,cJoKM,8BInKN,iBJmKM,8BIlKN,gBJkKM,8BIjKN,iBJiKM,8BIhKN,cJgKM,kBI9JN,iBJ8JM,gBD2IwB,uBKnS9B,cJwJM,gBDoIwB,gBARA,uBK/Q9B,gBJmJM,gBDqIwB,gBATA,uBK1Q9B,gBJ8IM,gBDsIwB,gBAVA,uBKrQ9B,gBJyIM,gBDuIwB,gBAXA,eAzKrB,QK9EP,gCL8EO,mBKjFT,eAIE,oCAQF,aJkGI,gBD2H0B,kCA6CA,yBKpQ9B,YL6Q8B,CMhV5B,kDADA,gBDoFF,cCnFE,8BDsFF,oBACE,+CAEA,kBLqP4B,wBK1O9B,aJ2DI,yBIzDF,wBL4BO,kBKxBT,kBJqEM,+BAhBF,cIhDJ,aACE,cLxGS,sCK4GT,YACE,CE5GF,gDAHA,YCJF,cDOE,2BPogCkC,qBA3gCzB,yBQST,qBCEE,CDLJ,cDCE,oBCcF,oBAEE,wBAIA,cADF,mBAEE,4BPiIE,cO9HJ,aRzBW,iBAyBD,qBC8HN,aD9HM,CUrCV,eAGE,mBAGA,aACE,gBVDO,wBASA,qBCoJP,UD7JO,CUOT,eTsJE,CSvJJ,mBDKI,oBCIA,cT8IA,iBS/IF,SV2Q4B,gBC5H1B,cStIJ,aACE,gBVfS,qBCoJP,aS9HA,CAFF,iBTgIE,CS9HA,iBACA,4BAKJ,gBVikCoC,kBU/jClC,uJCtCA,iBADA,iBACA,CAFA,iBACA,CAFA,kBACA,CCAA,UDGA,yBEmDE,+CDzCE,eZ+LiB,0BatJnB,wEDzCE,eZ+LiB,0BatJnB,iGDzCE,eZ+LiB,2BatJnB,0HDzCE,gBZ+LiB,kBYlKrB,YDnCA,eACA,CACA,kBADA,kBAEA,wBCuCE,cADF,cAEE,kEAIE,eAFF,eAGE,y6CEnDF,kBADA,kBACA,CAHF,iBACE,WAGA,iBAsBE,YACE,YACA,eACA,0BH4BN,aACE,eACA,0BAFF,YACE,cACA,0BAFF,uBACE,yBACA,0BAFF,YACE,cACA,0BAFF,YACE,cACA,0BAFF,uBACE,yBACA,sBGnBE,aHCJ,CACA,eADA,UAEA,mBGGQ,oBHbR,sBAIA,mBGSQ,qBHbR,uBAIA,mBGSQ,YHbR,cAIA,mBGSQ,qBHbR,uBAIA,mBGSQ,qBHbR,uBAIA,mBGSQ,YHbR,cAIA,mBGSQ,qBHbR,uBAIA,mBGSQ,qBHbR,uBAIA,mBGSQ,YHbR,cAIA,oBGSQ,qBHbR,uBAIA,oBGSQ,qBHbR,uBAIA,oBGSQ,aHbR,eAIA,yBGeI,gCAEA,6BAGE,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,qBACX,OADW,sBACX,QADW,sBACX,QADW,sBACX,QADW,sBAQP,uBHhBV,sBGgBU,wBHhBV,sBGgBU,eHhBV,sBGgBU,wBHhBV,sBGgBU,wBHhBV,sBGgBU,eHhBV,sBGgBU,wBHhBV,sBGgBU,wBHhBV,sBGgBU,eHhBV,uBGgBU,wBHhBV,uBGgBU,wBHhBV,yBEKE,mBC3BE,YACE,YACA,eACA,6BH4BN,aACE,eACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,6BAFF,YACE,cACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,yBGnBE,aHCJ,CACA,eADA,UAEA,sBGGQ,oBHbR,sBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,aHbR,eAIA,4BGeI,mCAEA,gCAGE,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,yBACX,QADW,yBACX,QADW,yBACX,QADW,yBAQP,aHhBV,yBGgBU,uBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,0BGgBU,wBHhBV,0BGgBU,wBHhBV,0BEKE,mBC3BE,YACE,YACA,eACA,6BH4BN,aACE,eACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,6BAFF,YACE,cACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,yBGnBE,aHCJ,CACA,eADA,UAEA,sBGGQ,oBHbR,sBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,aHbR,eAIA,4BGeI,mCAEA,gCAGE,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,yBACX,QADW,yBACX,QADW,yBACX,QADW,yBAQP,aHhBV,yBGgBU,uBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,0BGgBU,wBHhBV,0BGgBU,wBHhBV,0BEKE,mBC3BE,YACE,YACA,eACA,6BH4BN,aACE,eACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,6BAFF,YACE,cACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,yBGnBE,aHCJ,CACA,eADA,UAEA,sBGGQ,oBHbR,sBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,aHbR,eAIA,4BGeI,mCAEA,gCAGE,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,yBACX,QADW,yBACX,QADW,yBACX,QADW,yBAQP,aHhBV,yBGgBU,uBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,0BGgBU,wBHhBV,0BGgBU,wBHhBV,2BEKE,mBC3BE,YACE,YACA,eACA,6BH4BN,aACE,eACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,6BAFF,YACE,cACA,6BAFF,YACE,cACA,6BAFF,uBACE,yBACA,yBGnBE,aHCJ,CACA,eADA,UAEA,sBGGQ,oBHbR,sBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,qBHbR,uBAIA,sBGSQ,YHbR,cAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,qBHbR,uBAIA,uBGSQ,aHbR,eAIA,4BGeI,mCAEA,gCAGE,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,wBACX,OADW,yBACX,QADW,yBACX,QADW,yBACX,QADW,yBAQP,aHhBV,yBGgBU,uBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,yBGgBU,wBHhBV,yBGgBU,wBHhBV,yBGgBU,eHhBV,0BGgBU,wBHhBV,0BGgBU,wBHhBV,oBXgFO,celIP,kBfkIO,CenIT,UfYW,2CeHP,6BAHF,cfoV4B,mBehV1B,4BAIA,gCADF,qBAEE,+BAGF,4BACE,iDAUF,af8T4B,CelT5B,uFAEA,wBAEE,yEAIA,uBAEE,gJAMJ,QAIE,qDASF,0BfyR4B,wCAnVnB,kCEJT,aFyV4B,qFgB/V1B,wBD8FiC,oICvF/B,oBDuF2E,CC3E1D,6IAMf,wBANe,2FAnBnB,wBD8FiC,4ICvF/B,oBDuF2E,CC3E1D,mJAMf,wBANe,qFAnBnB,wBD8FiC,oICvF/B,oBDuF2E,CC3E1D,6IAMf,wBANe,4EAnBnB,wBD8FiC,wHCvF/B,oBDuF2E,CC3E1D,oIAMf,wBANe,qFAnBnB,wBD8FiC,oICvF/B,oBDuF2E,CC3E1D,6IAMf,wBANe,kFAnBnB,wBD8FiC,gICvF/B,oBDuF2E,CC3E1D,0IAMf,wBANe,+EAnBnB,wBD8FiC,4HCvF/B,oBDuF2E,CC3E1D,uIAMf,wBANe,4EAnBnB,wBD8FiC,wHCvF/B,oBDuF2E,CC3E1D,oIAMf,wBANe,4NAMf,iCANe,kChBlBZ,wBAQA,sBekGP,UfmQ0B,mCAtWnB,wBALA,sBegHP,af/GO,wBAHA,yBe0HX,UflHW,qFesHT,oBf+O4B,uCezO5B,QACE,gEAIA,0BfiO0B,mDA1WnB,sCEKT,UFuW4B,4Ba1S1B,gCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,iDAGA,QACE,6BF1GN,gCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,iDAGA,QACE,6BF1GN,gCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,iDAGA,QACE,8BF1GN,gCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,iDAGA,QACE,+BALF,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,8CAGA,QACE,0Bf5KC,2BiBUT,CjBHS,qBAPA,CiBUT,wBACA,sBjBkR4B,aAtRnB,CiBRX,aACE,CAGA,chB0KI,gBD2GwB,CiBvR5B,iCjB2esC,CApNV,eAKA,CA+MU,sBiBzetC,CAQA,qEAXA,UAiBA,uCCJI,yBDdN,eCeQ,uCDMN,wBACE,SACA,gCEfA,qBnBPO,qBA8d6B,CmBpdpC,iCAJF,aACE,CnBudoC,SA3FV,uCiBtW5B,ajBvBS,UiB0BP,sEAQF,wBjBtCS,UiB0CP,gLAQF,uCACE,+CAMF,WACE,0BACA,iDjBtDO,sBiByDT,ajBhES,8DiB4EX,aAEE,WACA,4BAaA,iBhBiEE,iBgBlEF,eACA,CAFA,kCACA,CAFF,+BjBoM8B,+BiB1L5B,iBhB0EI,iBgB3EJ,gCACA,CAFF,6BjBiI8B,+BiBxH5B,iBhBmEI,iBgBpEJ,iCACA,CAFF,8BjB2H8B,oCA1NnB,wBiBoHT,CACA,sCjB+J4B,aApRnB,CiB4GX,aACE,CAGA,chBoDI,gBDgHwB,CiBrK5B,eACA,CAFA,iBACA,CAFA,UASA,uGAIE,eAFF,eAGE,6BjB+F0B,oBiBjF5B,iBhB2BI,CgB7BN,gCjB6VwC,CChUlC,eDsDwB,CA0QU,oBSlepC,6BTuN0B,oBiBxE5B,iBhBmBI,CgBrBN,+BjBsVwC,CCjUlC,eDqDwB,CA4QU,kBSnepC,CQyJA,+GAIJ,WACE,wBAQF,kBjB2UwC,uBiBvUxC,aACE,kBjB4TsC,sBiBnTxC,YACE,eACA,CACA,iBADA,iBAEA,8DAIE,iBAFF,iBAGE,wBAUF,aACA,sBAFF,iBjBmSwC,8BACA,qBiB7RtC,gBjB6RsC,CiB9RxC,iBAGE,kHAGA,ajBvNS,8BiB6NX,eACE,+BAIA,kBACA,CAFF,mBACE,CAEA,oBADA,cjB+QsC,iDACA,ciBzQpC,qBjByQoC,CiB1QpC,YACA,CAFF,eAIE,4BhBrFA,ckBxHF,YACE,CnB4coC,aCrVpC,CkBtHA,iBnB2coC,CmB5cpC,UFyNqC,2BEvMrC,0BACA,sBnBoO0B,UmBrO1B,CAPA,YACA,CAGA,iBlBwHE,CkB9HF,MACA,ClB6HE,eDgHwB,CmBzO1B,gBACA,CAHA,cACA,qBACA,CAPF,iBACE,SACA,CACA,SVrCA,4FUmDA,QAEE,0EAKF,aAEE,mCASE,2QF+KiC,CEtKjC,wDASA,CF6JiC,2BEtKjC,CASA,2DACA,CCtFA,oBHkPiC,6CE5JjC,yCCtFA,oBpB2dgC,0EoB3dhC,uCHkPiC,CElJjC,4BFkJiC,2CExIjC,oJACA,uiBAoCuB,CArCvB,oEAqCuB,0CAKvB,qDACE,sEAGF,4GATuB,mKAtH3B,oBnB4coC,gFmBjcpC,wBACA,CAJA,oBAIA,CACA,6EnB0O0B,gCmBpO1B,CV9CA,qJUqDE,qFCnDE,oBHkPiC,+DE9KjC,aACA,CAFA,aACA,cADA,iBACA,CADA,UAEA,6BF6KiC,0BEtKjC,sBAFF,UFwKmC,CE5KjC,aACA,iBAGF,CAJE,OAIF,gBAHE,iBADA,mCACA,CAFA,0BACA,UAMA,gGAUA,0FnBqYgC,kDoB3dhC,qUDgHA,yDFkIiC,CElIjC,4BFkIiC,4DjByOD,oBmB3XhC,6CFkJiC,2CErHjC,qDAOF,2CF8GmC,iHErGjC,6EAEuB,CFmGU,kCEnGV,sCAMrB,imBFwIN,CEzII,oEFyIJ,4CAGE,qDAIF,2DACE,iIAaA,aACA,mEAIA,aACA,0EAGA,oBAGF,kFAKE,yBADF,oBACE,gFIrVyC,gCFkD7C,CAQE,yJAGA,oBACA,mEV9CA,8EUqDE,8MAOA,qDCxEM,kBCJmC,CF4EzC,6CCxEM,CCJmC,sDFqFvC,0CACA,CADA,UACA,iDACA,iGAEA,sGAGF,cE5FyC,CF4FzC,UE5FyC,2CF8FvC,uHC1FI,kBDmGJ,sEACA,2DnBqYgC,cmBrYhC,aCpGI,apBye4B,CoBze5B,kBDoGJ,UnBqYgC,0CqB7eO,2BF4HvC,qBE5HuC,WFkHvC,8BC9GI,CD8GJ,OC9GI,eCJmC,CFkHvC,qDnB2XgC,0BmB3XhC,UAUA,uUE5HuC,6GFkIvC,2QAWF,CAEE,yDAFF,2BAEE,6DAbA,iEAaA,4GE/IuC,qVFiKhB,kNAMrB,uiBAoBA,CApBA,oEAoBA,kIEzLF,iCAII,4IF4CV,aAEE,6QVpCA,yKUqDE,uLAOA,8MAWE,wBACA,CADA,oBACA,sLExFuC,gCF8FvC,CAUA,gWnBqYgC,gLqB7eO,qDF4HvC,yMACA,0DE7HuC,cF6HvC,aAGF,aEhIyC,CF6HvC,iBAGF,CAHE,UE7HuC,uGFkIvC,8BAOF,CAPE,OAOF,eEzIyC,CFkIvC,yFElIuC,2VF+IvC,iHE/IuC,qUFiKhB,iJAMrB,CEvKqC,iEFuKrC,qRANqB,8YA0BrB,imBGjKN,CHiKM,oEGjKN,kHtBwZ0B,oBsB5Y1B,iLtBoCW,aEhEb,6RqBqBE,6KvB2CW,2LuBvE8K,kNvBuE9K,wBEhEb,CFgEa,oBEhEb,0LqBPuG,gCAqBnG,CvBkDS,wWuBvE8K,oLA+CzL,oBAKI,iCAnDN,yNAD6D,8BA4B3D,wBvB2CW,6CuBlDT,cArBmG,qBvBuE1F,euBvE0F,eAqBnG,CvBkDS,uCuBlDT,kBvBkDS,6HuBvE8K,CAqBvL,wBAOF,kBAPE,qBArBuL,6KA+CzL,gCAKI,CApDqL,SAoDrL,mDvBmBO,0DEhEb,4EqBPuG,4CAcrG,wBAdqG,sBAcrG,UAdqG,+BAqBnG,6CAKJ,CALI,UAKJ,6DvB6Ca,4JuB/BX,wBAxC+I,qBAA0C,CAwCzL,UAxCyL,yKA+CzL,yBAKI,qBALJ,UAKI,2LApDiG,gCAcrG,2BAd2D,wBAA0C,sBAA1C,UAA0C,iCAqBnG,6CAOF,CAPE,UAOF,iEvB2CW,gKuB/BX,wBAxC0L,CAAD,qBAwCzL,UAxCyL,+KA+CzL,wBAKI,sBALJ,UDaF,iMC5DuG,gCAA1C,yBAA0C,6CAqBnG,CArBmG,UAqBnG,uDAOF,qBvB2CW,CuBlDT,UvBkDS,yNuBvEoI,wBAA0C,sBAA1C,UAA0C,yKA+CzL,wBDaF,qBC3DA,CA8CE,UA9CF,2LAWA,gCAZ6D,sBAA0C,yBAqBnG,qBArBmG,UAqBnG,CvBkDS,iFuBlDT,wBAOF,qBvB2CW,CuBlDT,UvBkDS,oJuBvEoI,wBAA0C,sBAwCzL,UAxCyL,gKA+CzL,wBAKI,qBDQN,CCbE,UDaF,kLC5DuG,gCAcrG,yBAdqG,6CAqBnG,CArByD,aAqBzD,uDAOF,qBvB2CW,CuBlDT,avBkDS,4NuBvE8K,oOAoDrL,wBvBmBO,sBuBnBP,avBmBO,2LuBHb,gCAEE,qEvBCW,CuBDX,UvBCW,8BuBKX,iMAMA,CANA,UAMA,iEvBXW,8NuBoBP,wBDzBN,qBtBKa,CuBoBP,UvBpBO,wNuBHb,uBAEE,4DAMA,oFvBLW,wBuBKX,sBvBLW,auBKX,wJvBLW,8NuBeX,wBAKI,sBALJ,aAKI,qLvBpBO,gCuBHb,sBAEE,8CAFF,UAEE,CAMA,iFAHF,wBvBFa,qBuBKX,CANA,UAMA,oJvBLW,8CuBWX,UvBXW,wLuBeX,sBvBfW,UuBeX,kLvBfW,iEuBHb,oBAEE,CAFF,aAEE,+DAGF,qBvBFa,CuBDX,UvBCW,6EuBKX,mHAMA,wBvBXW,CuBKX,avBLW,yNuBeX,sBvBfW,UuBeX,mNvBfW,mEuBDX,qBAFF,aAEE,iEvBCW,sBuBDX,UvBCW,iFuBKX,uHAMA,wBvBXW,CuBWX,avBXW,+NuBeX,qBAKI,CvBpBO,UuBoBP,yNvBpBO,gCuBHb,iCAEE,yEvBCW,wBuBKX,sBAHF,UAGE,gMvBLW,uOuBeX,wBAKI,sBALJ,UAKI,mNvBpBO,gCuBHb,8BAEE,sEvBCW,wBuBKX,sBvBLW,UuBKX,oLvBLW,yBuBWX,avBXW,wLuBeX,6CAKI,CvBpBO,UuBoBP,0MvBpBO,gCuBHb,iCAEE,yEvBCW,wBuBKX,sBvBLW,auBKX,gMvBLW,uOuBoBP,wBDdR,qBtB6M8B,CuBpM1B,avBoM0B,mNA7GY,gCArK/B,gCsBuFP,oBAWJ,CAXI,aAWJ,sCrBqEM,wBQlKF,sBRkKE,UQlKF,2ERkKE,gCQlKF,iFTua0B,yBsBxT5B,atBwT4B,8LwBzb9B,wBNqBQ,qBMlBN,CNiBI,UMjBJ,gNAWF,gCNOQ,mDOpBR,CPoBQ,aOpBR,qCAOA,wBACE,qBCoBE,CDrBJ,aCqBI,yEAIE,gCAhCJ,+EAGA,wBAsDI,CAtDJ,aAsDI,2LD9BJ,wBzBrBS,sByBqBT,azBrBS,6MaqDP,gCYjBE,8BAKA,qBAFF,aAEE,oCAPF,wBAEE,sBZiBF,UYdA,uEZcA,gCYjBE,6EZiBF,wBYjBE,CZiBF,aYjBE,wLCdF,wBACE,qB1BgOwB,CA4fM,UA5fN,0M0BpMxB,gCDYF,CACA,qBAEA,azBirBgC,CyBlrBhC,eACA,CzBirBgC,gD0B7tBhC,aACE,0B1BgOwB,uD0B7NxB,yBAjBJ,6DAEA,mFD8DI,oBCtBA,iBDqBF,gBACE,CCtBA,kBDsBA,kDzB0qB8B,mB0B7tBhC,C1B6tBgC,kCyBhqBhC,oBC7DA,uB1BiO0B,wBADA,kC0B5NxB,wI1B6NwB,UADA,kB0BzMtB,8BA9BN,uCACA,iBACA,sDAiCE,iCACE,oCDuCA,yBADF,iBACE,8LAaF,iBEzGF,6BAEA,qDF4HA,4CAEA,CzBrHS,6ByBmHT,CzB4J4B,qBA/QnB,CyB8GT,UzBiK4B,CyBrK9B,oBACE,mBACA,sBASA,sDvBrHA,2BF0O4B,2BA9OnB,CA8OmB,sBA9OnB,0ByBuJP,qBACA,CARA,azB8F0B,CAjPnB,wByBmJP,ezBnJO,OAiPmB,gBAnPnB,kByBqJP,CzBnJO,+BAFA,CyB8IP,kBzBqG0B,gByBrG1B,QzB5IO,ayB2JP,gCASF,OADF,UACE,iCAKA,0CAEA,kCAGA,OzB1KS,UyB0KT,oCAKA,UADF,OACE,0BzB5KS,wC4BbX,C5BaW,U4BbX,oCAGE,2CACA,kCAEA,OAFA,UAEA,oCAEE,8EAKE,4MAcJ,wBAEA,6BACE,CAJF,6BACA,CAFA,YACA,CADA,WAZI,oBAEF,mBAGE,sBAYF,oGAQA,yGnBNA,8BmBeF,uBnBFE,CAbA,sDmBUF,uCnBXE,sBAcA,oDACA,amBmBJ,8CAEE,8JASE,WAJA,qBAIA,aAJA,wCAIA,8CAUF,8BACA,CALA,uBAGF,CAHE,uCADA,oBACA,0CAKA,mDAqBA,aACA,8CACA,uMASE,mJnBhFA,iCmByFF,CnBzFE,yBmBoFF,anBrFE,CACA,gBADA,qBACA,uCADA,UmB0FF,iEnBvGE,8HmB6HA,uJAEA,CAFA,iCAEA,gCAEE,aACA,6BCrJJ,aACA,CDqJI,aCzJN,CAEE,iBACA,CAFA,eACA,CAFF,oBACE,CAGA,kBACA,uIAEA,mBAIE,CANF,iBAEA,CAIE,qBAEA,gEAEA,msBAKE,4JAaF,4BADF,wBACE,wDAKA,CALA,sBAKA,4IAOA,+KpBhBA,0IAcA,uVoBUA,2JpBxBA,8iBoB6DE,mhCAiDN,gB7BoWwC,8WSnepC,4BRkKE,wBQlKF,wDoBgJJ,CpBhJI,YoBgJJ,yJ7BkVwC,sL6B/TtC,4yBAWF,0EpB7JI,+iBqBtBF,gBACA,kDACA,gDAGF,8B9B0fwC,kB8BrfxC,CAQE,wB9BxBS,yBAmPmB,sB8B7N5B,c9B+esC,a8BlftC,c9BqfsC,gB8BlftC,iBAJA,eACA,CAHF,sBAEE,CAIA,oC9B6N4B,kGAgJA,8GA2FU,+VAxd7B,0K8BgET,gCAEA,gUA2BE,oBADA,iBACA,iBADA,oBACA,qFrBxFA,orBqBsIF,4B9B2Z8C,CArBA,yBAqBA,kbAIA,2B8B5X5C,C9B4X4C,wB8B5X5C,4B9B/KO,gCA2iBqC,oB8B1X1C,a9B2X0C,sCA5iBrC,C8BgLL,iBACA,U9B0X0C,0GkBniB1C,eY+KA,OZ/KA,UY+KA,kBZ/KA,WY+KA,UZ/KA,uEACE,wBYmLJ,CZnLI,+BYmLJ,qEAEE,mH9BoV0C,oB8BlUhD,qFAIE,wB9B+D4B,qBAKA,CA+MU,UA/MV,kI8B7D5B,6JAQE,0DAQA,e9BzOO,CAwkByB,iB8B/VhC,C9BzOO,kBAPA,yC8B+PP,qBAGF,yB9B5PS,CAsXmB,mBAtXnB,gF8ByPP,WAJF,aAEE,Y9B+H0B,CA5XnB,Y8B2PT,C9B3PS,6B8B6PP,UAkBA,C9BzQO,uC8BwQP,gCACA,0D9B8NoC,oBAxGV,uF8B1G9B,4NAkBE,CAGF,6FAOE,yBAFA,oBAEA,6F9B4E4B,0KAjYnB,C8ByUP,sM9BiKoC,0B8BrJtC,uD9BhVS,iBAPA,oF8BiWT,2L9B/VS,C8B4WP,6FAcF,0BACA,+CACA,wDAOE,oBAJA,cAIA,mBAJA,aAIA,uD9BmOyC,wB8BjOzC,qB9BiOyC,wB8BlOzC,0B9BkOyC,sB8BlOzC,CACA,iIAOF,CARE,sBAQF,uCAGE,sDrBtYA,sPqB4YA,qDrB5YA,wCT+lByC,iOALA,yBS1lBzC,sBT+lByC,ckB7lBvC,qBACE,cY2YJ,iBAXF,iCZhYM,CY2YJ,e9BiNyC,CkB5lBrC,uClB4lBqC,sBkB7lBvC,UTFF,4IqBsaA,qBZpaE,CYoaF,aZpaE,qFACE,qBYqaJ,CZraI,gCYqaJ,oC9BuLyC,wBAfT,CAeS,aAfT,uC8BhKhC,Y9BkKgC,0C8B/JhC,WrBnbA,wDT0lByC,iBS1lBzC,CTulByC,gC8B5JzC,C9BrE0B,wCAoOe,CApOf,kBStX1B,oGqBkcA,CrBlcA,iFqBmcA,eZjcE,uDYgcF,iCACA,CrBncA,4BT+lByC,CkB7lBvC,8BACE,SYkcJ,S9B0JyC,C8B1JzC,gBAbF,S9BuK2C,wDAfT,oBACA,C8BpIhC,gC9BqIgC,sHA1lBzB,wBSQP,iEqB2dA,gB9BneO,qE8ByeP,yB9BveO,oD8BofL,8CAGF,C9BvfO,gB8B4eL,kCADF,OAIA,e9B/eO,C8B2eP,SAYA,mE9BvfO,8B8B4eL,sBAGF,C9B/eO,yB8B2eP,C9B3eO,KkBQL,CY+eF,oCAMJ,wBAGE,oDZxfI,ClBRK,S8B6fX,iB9B7fW,yC8B6fX,C9B7fW,SkBQL,0BYqfN,uBZpfQ,gBafN,CbcI,wBYqfN,CZrfM,kCadJ,gCAEA,+DAMA,+CACA,kDAIE,+CAMA,2CASJ,+CAGE,4CAEE,wDAcF,uB/BvCS,gBAPA,CSqBP,kCPZF,mBOYE,+BPZF,8G6BgCI,uGAKJ,CtB1BE,UTpBO,uCA0rByB,+C+BnoBhC,uBtBnCA,wEATA,iFTwO0B,2C+B/J5B,mBAEE,C/BtFO,WAmPmB,gBAnPnB,a+BuET,UAeE,CACA,2CCxEF,eACA,CDuEE,wBAOA,SACA,mBACA,CATA,YASA,2GAcA,uGC/FF,CDwEE,UCvEF,kMAIA,4CAIE,wBAqBF,mBhCkqBkC,oBgCxrBhC,WACA,gBADA,aADA,UhCyrBgC,qCgCpoBlC,eACE,CAzBF,iC9B1CA,mB8B6CE,C/BuHE,W+B3HJ,CACA,qCADA,aAIE,0GAcF,uGAOA,C/BkGI,U+BjGF,uCAUJ,oChC0lBoC,gFgCzkBlC,wBAGA,qCAQA,wBACA,mBvBxGE,oBRkKE,W+B5DJ,eACA,C/B2DI,a+B9DJ,UvBpGE,CuB4GA,kF9B9GF,wB8B8GE,mBAWF,CAXE,yCAQF,iBAGA,yDAIF,wBhCglBoC,CgC9kBlC,iEnBtEE,oOmBkFI,iGAFJ,sGAwBM,uIhC+hB0B,wRgClhB5B,CACE,eADF,mBACE,qDAeA,gCAGF,sBAIE,6DAIA,CAXA,kBAWA,2EnBhJN,2NmBoFM,qBnBjGN,kCmB6FA,CAGM,aAHN,qCAqBI,kDAGE,CAJF,eAIE,qDAEA,8EhC6hB0B,yBgCzhB1B,UhCyhB0B,gQgClhB5B,iCACE,iCAmBA,kBAGA,CARF,iBAQE,0NAPA,kBAGF,CAHE,4BAGF,6BnBxIJ,+CmBoFM,iBnBjGN,oBmB6FA,CAIM,kBAFF,uBAEE,CnBpFN,oBmBkFI,CAFJ,kBAoBI,+DACA,oBAGE,0DAEA,CACE,gCADF,cACE,kChC4hBwB,egCzhB1B,ehCyhB0B,4PgCjhB1B,wBAeA,4CAGF,CAlBE,gChCihB0B,qBgC/f5B,mEAIE,oBAGF,iCnB/IJ,8CmBgJM,oBnBhJN,2YmBwGM,wDAEA,6BACE,+CAGF,0ChCyhB0B,ybgC3f1B,gBAGF,iDA/DJ,gBAoBI,+CACA,+XAMI,wDhC4hBwB,sQgCjhB1B,mBADF,mBACE,mQAwCR,gBhCigBkC,oMExtBlC,YFwtBkC,+RAFA,wDACA,sHgChf9B,kBhCkf8B,ubgC7ehC,iDhC4egC,+DgCpelC,sBhCkekC,gBAKA,wFgClelC,kQhC+dkC,iMExtBlC,yD8B2QA,iBhCpRS,6VgCoSL,iEhCub8B,2LA3tBzB,+CgCiTT,iPAWE,chC5TO,CAwtByB,eAxtBzB,+GiCHX,iBACE,iDAKA,mBAFA,mBjCDS,iPiCgBP,gBAEA,8CACE,gBxBCF,4CACA,sCwBEA,2CACE,YxBUF,CACA,qQwBiBJ,eACE,gG/BhDA,e+B0DE,uNAiBF,eAEA,kHAMA,ejCwuBkC,ibAMA,eS3zBhC,oFwBuHF,sBAGF,CAHE,eAGF,8FxBhHI,wQwBsIA,8EjC6qBgC,gBiCppBhC,2QAgBI,exBzKJ,CACA,8HwB2KM,yDAGE,wHAKA,uExBrKR,kOwB+KQ,mDAKA,sBAcV,CAjBQ,eAiBR,8CpBvLE,8QJnBA,sCACA,ewB0OA,CxBxPA,iIwB8PE,UC1RN,kBAME,qBzBYE,wByBZF,qBlCGS,CSSP,iCyBLF,qBlCyhCkC,CkCpiClC,YACA,sBlCqiCkC,YkCliClC,CALA,iBlCqiCkC,kCkCrhC9B,ClCqhC8B,ckCrhC9B,8BAGA,sBlCkhC8B,kBkClhC9B,0CAWF,oFAIA,CALF,kBAKE,yC5B9BF,4C6BCF,CnCOW,6CMRT,CNQS,qBmCPX,qFnCwxBoC,YA/mBM,uBAxK/B,4BmCQT,wCAGE,oBnC+JsC,2BAxK/B,eACA,CmCUP,mBnCVO,kCmCgBP,enC4wBgC,iDA5ZN,kCmCxW1B,mBACE,yB1BcF,mEAfA,CAcA,eACA,CADA,sBAdA,qCACA,uDT5BO,yBAmPmB,gEmCpM1B,CnCoM0B,sBmCpM1B,oCnC/CO,uDoCJT,8BpCsO4B,qCoC9NxB,4DpC8NwB,qBoCrO1B,qB3B6CA,8BAfA,gCACA,C2BnBE,e3BkBF,iBAeA,iB2BjCE,c3BmBF,2ETuM0B,uEoC/NxB,yC3BqCF,2CACA,kDAdA,4C4B7BF,CDUI,6CCTJ,6BpC6JE,kBoC1JF,yBACA,sBACA,YACA,mB5BKE,8H4BHF,gDnBKI,yBACE,sDhBLN,8BmCGI,wBAMF,oCAOF,cAFF,aAEE,+C5BdE,4B4BgCF,CrCs3BkC,yBqCt3BlC,wHC5CI,yBACA,2HAMA,4BAZJ,gDtC2Ea,2BsCtET,CtCsES,wBsCtET,0HAMA,wBACA,6HtC+DS,2BsCtET,iCACA,6CAGF,yBAEE,iCACA,mBDqCJ,gCCjDA,oBtC2Ea,uDsCtET,6BACA,+DAKA,gBACA,2BDqCJ,CCtCI,4BDsCJ,iDrC0Ba,4FsCrET,0DAMA,wBAZJ,qBtC2Ea,CsCrET,YAGF,eAEE,CACA,gBADA,kBACA,CADA,mBtCgES,gEE5Db,qDoCTI,aAGF,YAEE,CALA,8BAKA,2DDsCJ,yBCjDA,CtC2Ea,oBsC3Eb,CpCeA,mCoCTI,qCAKA,qBALA,aAGF,eAEE,CALA,cAKA,uBtCgES,qBsCtET,yBACA,CtCqES,cqC1Bb,aCjDA,CtC2Ea,kCsC3Eb,oBtC2Ea,CsC/DT,iBANA,6BAKA,6CACA,CANA,kCAKA,CALA,SAMA,6BtC6yB8B,gCAjzBzB,CuCRT,UADF,SvCSW,8CuCDP,gCAKF,CAbF,6BAQI,C1BoDA,a0B/CF,6CCRA,iCxC09BkC,CwC39BpC,8BxC29BoC,yCS78BhC,wB+BHF,qBAIF,C/BDI,oB+BCJ,2CAUE,qBAGA,qBAEE,CxC8P0B,awCpQ9B,CACE,YADF,mBAOI,sCAGA,iBAUF,gBACqH,CAZnH,qBAYmH,6DC5CrH,+BACE,CD2CmE,4BC3CnE,4DD2CmH,gCAAhD,CADrE,6BACqE,sCC3CnE,iCAGF,CAJA,oBAIA,6DDwCyB,+BAA4C,CAAgD,4BAAhD,4DCvCnE,gCDuCmH,CC3CnH,6BD2CmH,mBCvCnH,oBDuCmH,CAA5F,qBAA4C,aC5CrE,8BACE,CD2CmE,mBC3CnE,kBD2CmH,6HC3CnH,CAIA,uBAJA,yDAIA,kBDsCF,eACqH,oDAAhD,oBC5CrE,yBACE,oCAGF,iBACE,iCDuCuB,mBAA4C,CAA5C,kBAA4F,kBAAhD,2BC3CnE,yBADF,UACE,mED2CmH,wBAA5F,CAA4F,UAA5F,mEC3CvB,gCAIA,CAJA,SAIA,6BCPA,wBACA,CADA,UACA,uEAOF,wBACA,C1C+9BkC,U0C/9BlC,uEAOF,gCAEE,CjCHE,SiCGF,2B1CdS,wB0CkBT,CAFA,UAEA,mEAGA,wBxBRI,CwBQJ,UxBRI,mEwBWN,iCxBVQ,SwBUR,gJCYE,CDZF,UCYE,6DDNA,gCACE,CADF,SACE,2BAGE,yBAHF,aAGE,mEEvCJ,wBAIA,CALA,aAKA,mECGA,gCpCSE,CoCZF,SpCYE,0BoCGF,wB7CPS,C6CMX,U7CNW,iE6CST,wB3CPA,C2COA,UAIE,iE7CnBO,gC6CyBT,C7CzBS,SAQA,yBAPA,wB6CmCX,C7CnCW,a6CmCX,+D7CrCW,yB6CwCT,aAIA,+DpCxBE,gCACA,CoCyBF,SpCzBE,wBoC6BF,yBpC7BE,UoC6BF,6DpCfE,gGTnCO,gC6C8DT,CALE,SAKF,uB7CqL4B,gEAnPnB,iBAmPmB,yB6C9K5B,sBACE,+CAGE,e7C4JwB,C6C5JxB,eAHF,e7C+J0B,mB6C5IxB,uBAGE,qBAHF,mBADF,sBACE,C7C4IwB,iB6CzItB,2BpC1BJ,aAZA,sEoC2CI,wDAME,cpCrCN,sBoCqCM,CpCrCN,yCoCqCM,mDAGF,qB7C2HsB,C6C9HpB,a7C8HoB,8B6CzHpB,+DAEA,aACE,6BhC1DR,6CgCmCA,C7C6I0B,a6C7I1B,gCACE,iEAGE,apC1BJ,2BAZA,yFoC2CI,wBpC3CJ,uCAYA,qCoCqCM,8CADF,aACE,2BAGF,wB7C2HsB,oC6CzHpB,wCAEA,wBACE,qB7CsHkB,C6CzHpB,a7CyHoB,8BahL1B,yBgCmCA,sCACE,uCAGE,6CpC1BJ,CoCuBE,apCvBF,6BAZA,8DoC2CI,apC3CJ,yBAYA,8CAZA,aAYA,4BoCqCM,6DAGF,qCAEE,8C7CyHoB,a6CzHpB,2BAEA,wBACE,oC7CsHkB,aahL1B,CgCoCE,qBpCnCF,8CoCsCI,apCtCJ,iBoCsCI,YpC1BJ,aAZA,CoCsCI,epCtCJ,0BoCiDM,yBpCrCN,WoC+BI,YpC3CJ,sBAYA,yDoCoCI,CACE,0BADF,kBACE,uC7C8HoB,yB6CzHpB,iKAnBJ,0BAGE,mCpC1BJ,iDAZA,uCoC2CI,kCpC3CJ,cAYA,0CoCoCI,CpCpCJ,YoCoCI,wBACE,gCAKA,qBALA,kCAGF,C7C2HsB,e6CzHpB,CAFF,cAEE,iDAEA,mBACE,CAHF,UAGE,mFAmBR,yBpCvHA,kCoCsHF,CpCtHE,SoCuHA,2CAGE,yBADF,aACE,6BAYqC,wDAA+B,aAA/B,wBAA+B,iBAA/B,yC3CxIzC,8B2CwIwE,gCC9IlE,wC9CHG,iC6CiJ+D,CC9IlE,kCD8IkE,2EAA/B,mH3CxIzC,qB2CwIwE,CAA/B,oBAA+B,yDC9IlE,kFD8IkE,oBCrJxE,CDqJwE,eCrJxE,mCDqJyC,4I3CxIzC,+D4CNM,2B9CHG,C8CGH,8B9CHG,2D6CiJ+D,YCrJxE,qEDqJyC,oHC9InC,sBD8IkE,gBC9IlE,8D9CHG,kB6CiJ+D,mGAA/B,4F3CxIzC,2B2CwIwE,CAA/B,8BAA+B,8DC9IlE,YAGF,wEAVJ,mBDqJwE,oGAA/B,qGAA+B,kBC9IlE,mE9CHG,gC6CiJ+D,4FAA/B,wH3CxIzC,Y2CwIwE,wEC3IpE,mB9CNK,C8CGH,oB9CHG,+E6CiJ+D,qBAA/B,CAA+B,gBAA/B,oJC9InC,4HCTN,2B9CmLI,C4C5BoE,8B7CwI5C,8D+CzR5B,oFAKE,uHAiBF,qBACA,CAFF,gBAEE,2BACA,qCAOA,kBCtCF,mE/CoLM,gCD8tB8B,0BgD14BlC,kEvCUE,4BTo4BgC,8BgDx4BlC,8DAKE,oFAaJ,mBACE,CALE,oBAKF,+EhDw3BkC,qBgDn3BlC,ChDzBS,gBgDyBT,8CACA,+CvCZE,8ETm3BgC,qBiDx4BpC,qCAIE,wBAEE,CAJF,aAIE,mIAuBJ,wBACE,CARA,aAQA,mEAOA,6CACE,CAJF,UAIE,uCjDu6BgC,wBkB/7B9B,ClB+7B8B,akB/7B9B,uIlBk8B8B,yBiDl6BlC,ajDk6BkC,qEiD35BlC,6CAEA,CAFA,UAEA,qCAEE,yKASA,wBAIJ,CAJI,aAIJ,mEAGE,wBAGA,qBACE,CAJF,UAIE,kCACA,wBAEA,CAFA,aAEA,6HAOA,sGAGE,6CAIA,CAJA,UAIA,qCAOJ,wBACA,CAFF,aAEE,mIxC1FE,wBwCsGF,CAJA,aAIA,mEAUA,wBjDjHS,sBiDgHT,UjDhHS,oCiDsHT,wBjD8zBkC,CiD/zBlC,ajD+zBkC,iIiDpzBlC,wBxCtHE,CwCsHF,axCtHE,kEwCyHF,wBjDwzBkC,qBiDrzBhC,CxC3HA,UwC2HA,mCAMF,wBjDuI4B,CiDxI9B,ajDwI8B,+HiDrH5B,wBAEA,CAFA,aAEA,iExCxIE,6CACA,CwCwIF,UxCxIE,kCwC+IA,yBADF,aAMF,6HjDkxBoC,wBiDrwBhC,CAFF,aAEE,gEAIA,6CAEA,CAFA,UAEA,mBAKF,UACE,CANA,WACE,iCAIJ,eACE,4DAEA,UACE,kIpC9JF,oCbm5BgC,wBan5BhC,Ubm5BgC,SiDjuBlC,6BjDguBkC,mBkD78BpC,mBlDg2BoC,4IkD/1BlC,gBAEA,ClD61BkC,kBkD71BlC,elD61BkC,8CAlkBN,oBAKA,2BmD9R5B,SACA,wBACA,aACA,kCACA,YACA,0BAEA,kBACA,CDFA,2BlDk1BkC,CC1qB9B,0BiDxKJ,ClDk1BkC,iCkD70BhC,0ClDm1BgC,2CkD70B9B,CCRJ,alDqKI,CkDxKJ,YACA,CACA,qBDSI,wBACA,cACA,wBACA,+EAKN,mBACE,wBAEA,CAFA,OAGE,UADF,eACE,CAHF,4CAGE,0DAGE,CAHF,4BAGE,sClDrBK,4BkDsBL,iClDtBK,uCkD6BT,yGAGE,8ClDkzBgC,mGkD7yB9B,oDlDrCK,kJkD6CT,8DAGE,8GAGE,0CAON,UACE,ClD3DS,qFkD2DT,iFlDwxBkC,WADA,CkDrxBlC,sBlDqxBkC,2JkD9wB9B,YlDpEK,2BSCP,2B2ClBJ,CF+GE,qBlD9FS,CoDjBX,sBAGE,oBAEA,CpDq1BkC,kCAn1BzB,CoDFT,UF0GA,oBAJF,iBlD+uBoC,CAn1BzB,UoDFT,4BpD+2BkC,sMmDj3BlC,sBnDiS4B,CmD5R5B,+BACA,yCAEA,0CAEA,CAVA,anDiS4B,6BmD7R5B,aAOA,iClDsKI,6BD7KK,CmDQT,YnDRS,yBoDOT,gBpDPS,eoDOT,wB3CIE,a2CCF,aACE,C3CFA,iB2CEA,0BAIA,mBAME,2CAEA,CAJA,4CAEA,CANF,4BAIE,CpDw2B8B,YACA,eoD72BhC,wCAQE,8EpDq2B8B,6FoD71BlC,yBACE,sGAGE,oDACA,+BpD21B8B,2GA5pBN,2BArOnB,mFoDkDX,0BpD40BoC,oFoDz0BlC,qBACE,gBpDw0BgC,EADA,oBACA,qBoDr0BhC,sMpDw0BgC,CAHA,kBAGA,iCoDh0BhC,CpDjEO,sBA83ByB,gBoD7zBhC,epDoK0B,CoD5K1B,SpDq0BgC,SoDlzBlC,CAnBE,kBpD4K0B,gCoDlKxB,qBpDnEK,sCA83ByB,mBA93BzB,iBoDyEX,oBpDqzBoC,CoDr0BhC,YAmBF,0BACE,iIAIE,kBpDgzB8B,oBoDhzB9B,WADA,iBpDizB8B,yFoD5yBhC,wFpDrFO,8GoDgGP,qBpD6xBgC,CoD/xBhC,0BAEA,CAHF,KpDgyBkC,8EoDxxBhC,2GpDyxBgC,yIoD9wBhC,gJAIE,epD6wB8B,+MoD9uBlC,wBnD0BI,CmD3BJ,0BACA,CAFF,QnD4BM,4EmDtBJ,e3CnIE,0F2C2IJ,aAJI,mBAKF,wGClJF,sBAEE,CALA,gCAGF,CAJA,MAME,2BCnBE,qBDwBJ,qBACE,CC3BE,UACA,CDqBF,oCCtBE,CACA,iBD0BF,qBAiBA,oBAGF,CAEE,2BASA,CAXF,qBAEE,CASA,sBACE,oBACA,CA7BF,sMnCZM,CmCyBN,kBnCzBM,iCmCiBR,CALE,OAWF,qBAEE,iBARF,eAGE,CAPA,eADA,CAFA,iBACA,CASA,0FAGF,CAZE,KACA,CAaA,yDAbA,YA8BE,sKAOA,iDAJF,aAIE,CAPA,iBAOA,0EAMA,2GnCxDE,+HmCoEJ,0BAGA,CnCtEM,0BmCiER,CnCjEQ,QmCsEN,oGrD29BmC,sBqDl9BnC,0BrDk9BmC,CqDn9BnC,UrDm9BmC,CqD/8BnC,6EnCnFI,6GACE,wKmC6FN,4BAMA,CrD+7BmC,gCqDr8BnC,CrDq8BmC,MqD/7BnC,wGAYA,wBrDg8BmC,gCqDh8BnC,CrDg8BmC,QqDh8BnC,gFAGA,8GAGA,sBASF,4GAYE,6BAEA,CrDo5BmC,0BqDt5BnC,CrDs5BmC,KqDp5BnC,0GrD1JS,wBqDoKP,CAFA,0BrDlKO,CqDiKP,OAGA,8HnCtJI,+BmC+JJ,CnC/JI,WADF,uBmC6IJ,kBnC5IM,CmC2JJ,iBnC5JE,iBmCgKF,4EAaF,kBACA,0FE7LA,YAGF,eAHE,oCAGF,wGAQE,4BAHA,gCAGA,CAHA,OAIA,sGAmBE,uBALF,gCAKE,CALF,SAKE,4BvD6iCsB,wBuDpiCxB,gCAGA,yCACA,0CvDmiCwB,CALA,cAEA,CAFA,gBuDtiCxB,oBvD2iCwB,8CuD1hCxB,uCACE,CADF,oBACE,sBAEE,qDC3DN,8CACA,eACA,CADA,4BACA,kCACA,sBADA,aACA,2BACA,kCACA,4BADA,2CADA,iBACA,CACA,oCCFE,CDCF,UCAI,iLAKE,cANJ,+FACE,0HAKE,2BANJ,0CACE,uWAKE,mCANJ,CAMI,SANJ,uCACE,2GvDUF,qFuDVE,mBvDUF,wBuDLI,CALF,wDAKE,WALF,UADF,iBACE,kBvDUF,CuDVE,MAKE,6BALF,mBAKE,uCALF,gQvDUF,qBuDVE,oBvDUF,mCuDXA,yCACE,sFvDUF,kCwDJF,CDNI,oBvDUF,uBwDJF,wCACE,gNCLF,wCACA,iNAKA,iCACA,SACA,oCADA,OAKI,gBADF,eACE,CADF,iBAHF,cAGE,CAJF,oCAKI,oCADF,4BACE,sBADF,8BACE,CADF,8CACE,CADF,cACE,cADF,YACE,eADF,iBACE,YADF,mBACE,2BADF,qFACE,gBAIJ,yCACE,uCAWF,YAIA,WAJA,SACE,mBAGF,CAHE,iBALF,iBACE,UAGF,CAIA,iBACE,CALF,UAKE,CACA,2BASA,6CACA,CAFF,oCACE,CADF,+BALA,qBACE,kCACA,CADA,UAMA,+BAIA,kBADF,sBACE,CAIF,yBAYA,2CACE,CALF,6BACE,kBAGF,CAXE,oBAGF,YACE,CAOF,UAPE,sBAGF,CAJA,UL/DE,6BAGE,YADA,UACA,uCMOE,6a/CiDF,wB+CjDE,wc/CiDF,kC+CjDE,g7CAUN,4BAEI,weCrBJ,6BAGE,yBAEA,kDAGE,4BACA,6KAGF,8BAME,CACA,2BAEA,8BAEA,2BASA,8BACE,oKADF,wBACE,6BCzBF,mDACA,gEACA,yCACA,2BAEA,2CACA,CAHA,wCAGA,4BACA,0CACA,CAFA,2CAEA,0BACA,0CACA,CAFA,uCAEA,qDACA,4BACA,kFAEA,gDACA,mFACA,oEACA,0DACA,wFAEA,oDACA,sDACA,qEACA,sDACA,qEAEA,qFACA,+CACA,2EACA,wDACA,yEACA,2DAEA,gDACA,uEACA,6DACA,+CACA,2EACA,wDjDYA,4BiDlDA,6CACA,2DACA,sEACA,gFAEA,+BACA,sEACA,mDACA,wDACA,mDACA,oDACA,wDACA,qEAEA,uDACA,6EACA,2EACA,oFACA,2EAEA,4CACA,2EACA,0DACA,gFACA,kDAEA,0FACA,sDACA,uDACA,4DACA,wCADA,iBACA,gDACA,2NAKA,qCADA,iBACA,4DACA,mEACA,kBjDYA,0CiDlDA,yDACA,kEACA,wDACA,kEAEA,wEACA,+CACA,mDACA,+DACA,8CACA,8CACA,8CACA,6EAEA,0DACA,qEACA,sEACA,4GACA,0EAEA,+BACA,2FACA,4DACA,gEACA,8DAEA,mEACA,+DACA,gEACA,wEACA,sEACA,kEAEA,sDACA,6DACA,wFACA,4DACA,6DACA,qDjDYA,wBiDlDA,wDACA,gEACA,wEACA,iEAEA,oDACA,4DACA,0DACA,mDACA,iDACA,mDACA,qDACA,6DAEA,wEACA,yEACA,wEACA,8EACA,wEAEA,gEACA,iEACA,iEACA,kEACA,iEAEA,oEACA,qEACA,oEACA,0EACA,0EACA,+DAEA,0DACA,8DACA,+DACA,+DACA,gEACA,sDjDYA,wBiDlDA,wDACA,gEACA,wEACA,iEAEA,oDACA,4DACA,0DACA,mDACA,iDACA,mDACA,qDACA,6DAEA,wEACA,yEACA,wEACA,8EACA,wEAEA,gEACA,iEACA,iEACA,kEACA,iEAEA,oEACA,qEACA,oEACA,0EACA,0EACA,+DAEA,0DACA,8DACA,+DACA,+DACA,gEACA,sDC1CA,oDACA,4BACA,gEAFA,wEACA,uCACA,kDlDoDA,4BkDtDA,4DACA,gCACA,iDlDoDA,4BkDtDA,iDACA,mDACA,wBlDoDA,6BkDtDA,6DACA,oCACA,sECLF,mWCCA,2UAQA,qCjEkqBkC,8BiE3pBlC,sCjE2pBkC,0EiErpBpC,0EjEopBoC,+BkEtqBlC,gCAEA,yBAEA,iCAEA,+BACA,4DAUA,kCAIE,2BAEA,oCC5BJ,4FACA,mDACA,uFACA,iCCCI,uZAIJ,mDACA,uBAIA,qDACA,0EAEA,oCACA,kCCTQ,uCACA,gCAEE,wCAEF,uCAIA,uCAEE,sCAEF,kCAbA,gEACA,8BAEE,mCAEF,4BAEE,qCAEF,8BAEE,oCAEF,6BAbA,sEACA,kCAEE,gCAEF,qCAEE,8BAEF,CAEE,qCAEF,qCAEE,qCAfF,oCACA,sCAEE,+BAEF,gCAEE,yBAEF,iCAEE,+BAEF,+BAbA,+DACA,2BAEE,oCAEF,6BAEE,mCAEF,4BAEE,6CAEF,yBAEE,qBAfF,4CACA,yBAEE,8CAEF,4BAEE,qBAEF,2BAEE,8CAEF,0BAbA,qEACA,2BAEE,oBAEF,0BAEE,8CAEF,4BAEE,qBAEF,2BAEE,oBAfF,qDACA,gDAEE,qBAEF,2BAEE,kDAEF,iCAEE,0BAEF,8BAbA,6DACA,8BAEE,kCAEF,2BAEE,kDAEF,6BAEE,yBAEF,6BAEE,yBAfF,0DACA,+BAEE,2BAEF,4BAEE,wBAEF,6BAEE,iCAEF,0BAEE,uBAfF,0EAGE,gBAFF,cAEE,qBAEF,2DAIA,8CAEE,gBAEF,yCAZA,kBAEE,SAEF,CALA,sCACA,CADA,UAeE,iBAfF,CAGE,mBAHF,SAKA,0EAQA,UAFE,4BAEF,CAJA,gBAIA,kBAEE,CANF,UAME,uBAQF,uDACA,8DAIA,wEAIA,kDAEE,kBAEF,qCAEE,mBAfF,wDACA,oBAEE,wCAEF,sCAEE,sCAEF,kBAEE,uCAEF,yCAEE,qBAfF,4CACA,6CAEE,wBAEF,yBAEE,kDAEF,oBAEE,yCAEF,sBAEE,iBAfF,qDACA,yDAEE,wBAEF,mCAEE,yBAEF,mCAEE,uBAEF,wCAEE,mCAfF,4BACA,kCAEE,6BAEF,mCAEE,8BAEF,mCAEE,6CAEF,sBAEE,mCAMN,6DACA,4BAEE,mCAEF,6BAEE,mCAEF,2BAEE,sCAEF,mCAEE,yBA3DE,8DACA,mCAEE,4BAEF,mCAEE,0BAEF,wCAEE,mCAEF,2BAEE,mCAfF,gEAGE,iEAEF,4BAEE,iBAEF,wDAEE,yBAEF,mCAEE,2BAfF,+DACA,CAEE,4DAEF,iBAEE,sDAEF,uBAEE,mCAEF,yBAEE,mCAfF,6DACA,wBAEE,yCAEF,mCAEE,4BAEF,mCAEE,8BAEF,mCAbA,kEACA,6BAEE,wCAEF,mCAEE,8DAIA,gEAEF,8BAbA,+DACA,uCAEE,mCAEF,0BAEE,mCAEF,4BAEE,mCAEF,6BAEE,mCAfF,4CACA,wBAEE,mCAEF,4BAEE,iEAIA,kEAIA,mCAfF,oEACA,mCAEE,0BAEF,mCAEE,4BAEF,mCAEE,gEAIA,2BAfF,+EACA,4BAEE,qCAEF,8BAEE,qCAEF,+BAEE,qCAEF,6BAbA,8EACA,2BAEE,qCAEF,6BAEE,qCAEF,8BAEE,qCAEF,4BAEE,kBAfF,2DACA,0BAEE,qCAEF,iEAEE,6BAEF,qCAEE,2BAEF,kBAEE,wBAfF,iEACA,qCAEE,8BAEF,qCAEE,+BAEF,qCAEE,6BAEF,wCAEE,qCAQF,+DAGE,iEAEF,6BAEE,qCAEF,2BAEE,yCAEF,yCAEE,yBAfF,oEACA,yCAEE,4BAEF,yCAEE,0BAEF,yBAEE,qCAEF,yCAEE,sBAfF,iEACA,yCAEE,yBAEF,yCAEE,uBAEF,2CAEE,yCAEF,2BAbA,sEACA,yCAEE,8BAEF,yCAEE,6BAEF,yCAEE,yCAEF,0BAEE,yCAfF,qEAGE,sEAIA,+CAEF,8DAEE,yBAEF,yCAQJ,oEACA,4BAEE,yCAEF,0BAEE,2CAEF,yCAEE,oEAIA,6BxDTF,yCwDlDI,8BACA,yCAEE,4BAEF,oBAEE,8DAIA,kEAIA,2BAfF,qEACA,yCAEE,0BAEF,oBAEE,4DAEF,uBAEE,yCAEF,yBAEE,CAfF,kEACA,yCAEE,wBAEF,4CAEE,yCAEF,4BAEE,yCAEF,8BAEE,CAfF,uEACA,yCAEE,6BAEF,oBAEE,gEAIA,oEAIA,6BAfF,uEACA,yCAEE,4BAEF,oBAEE,+DAIA,mEAEF,4BAbA,sEACA,yCAEE,2BAEF,oBAEE,iEAIA,qEAIA,8BAfF,wEAGE,yCAEF,6BAEE,0CAEF,yCAEE,0BAEF,yCAbA,qEACA,6BAEE,yCAEF,2BAEE,6CAEF,2CAEE,4BAEF,2CAbA,yEACA,+BAEE,2CAEF,6BAEE,qBAEF,uBAEE,2CAEF,2BAEE,2CAfF,wEAGE,8BAEF,2CAEE,4BAEF,2CAEE,2CAEF,0BAEE,CAfF,sEACA,2CAEE,6BAEF,2CAEE,2BAEF,6CAEE,2CAEF,4BAbA,yEACA,2CAEE,+BAEF,2CAEE,6BAEF,qBAEE,iEAIA,0BAQF,uEACA,2CAEE,6BAEF,2CAEE,2BAEF,uBAEE,oEAIA,yBAfF,0EACA,+CAEE,4BAEF,+CAEE,0BAEF,0BAEE,qCAEF,yCAEE,sBAfF,iEACA,yCAEE,yBAEF,yCAEE,uBAEF,2CAEE,yCAEF,2BAbA,sEACA,yCAEE,8BAEF,yCAEE,6BAEF,yCAEE,yCAEF,0BAEE,yCAfF,qEAGE,sEAIA,+CAEF,8DAEE,yBAEF,yCAQJ,oEACA,4BAEE,yCAEF,0BAEE,2CAEF,yCAEE,oEAIA,6BxDTF,yCwDlDI,8BACA,yCAEE,4BAEF,oBAEE,8DAIA,kEAIA,2BAfF,qEACA,yCAEE,0BAEF,oBAEE,4DAEF,uBAEE,yCAEF,yBAEE,CAfF,kEACA,yCAEE,wBAEF,4CAEE,yCAEF,4BAEE,yCAEF,8BAEE,CAfF,uEACA,yCAEE,6BAEF,oBAEE,gEAIA,oEAIA,6BAfF,uEACA,yCAEE,4BAEF,oBAEE,+DAIA,mEAEF,4BAbA,sEACA,yCAEE,2BAEF,oBAEE,iEAIA,qEAIA,8BAfF,wEAGE,yCAEF,6BAEE,0CAEF,yCAEE,0BAEF,yCAbA,qEACA,6BAEE,yCAEF,2BAEE,6CAEF,2CAEE,4BAEF,2CAbA,yEACA,+BAEE,2CAEF,6BAEE,qBAEF,uBAEE,2CAEF,2BAEE,2CAfF,wEAGE,8BAEF,2CAEE,4BAEF,2CAEE,2CAEF,0BAEE,CAfF,sEACA,2CAEE,6BAEF,2CAEE,2BAEF,6CAEE,2CAEF,4BAbA,yEACA,2CAEE,+BAEF,2CAEE,6BAEF,qBAEE,iEAIA,0BAQF,uEACA,2CAEE,6BAEF,2CAEE,2BAEF,uBAEE,oEAIA,yBAfF,0EACA,+CAEE,4BAEF,+CAEE,0BAEF,0BAEE,qCAEF,yCAEE,sBAfF,iEACA,yCAEE,yBAEF,yCAEE,uBAEF,2CAEE,yCAEF,2BAbA,sEACA,yCAEE,8BAEF,yCAEE,6BAEF,yCAEE,yCAEF,0BAEE,yCAfF,qEAGE,sEAIA,+CAEF,8DAEE,yBAEF,yCAQJ,oEACA,4BAEE,yCAEF,0BAEE,2CAEF,yCAEE,oEAIA,6BxDTF,yCwDlDI,8BACA,yCAEE,4BAEF,oBAEE,8DAIA,kEAIA,2BAfF,qEACA,yCAEE,0BAEF,oBAEE,4DAEF,uBAEE,yCAEF,yBAEE,yCAfF,0BACA,yCAEE,wBAEF,4CAEE,yCAEF,4BAEE,yCAEF,8BAEE,yCAfF,+BACA,yCAEE,6BAEF,oBAEE,gEAEF,2BAEE,yCAIA,6BAfF,uEACA,yCAEE,4BAEF,oBAEE,+DAIA,mEAEF,4BAbA,sEACA,yCAEE,2BAEF,oBAEE,iEAIA,qEAIA,8BAfF,wEAGE,yCAEF,6BAEE,0CAEF,yCAEE,0BAEF,yCAbA,qEACA,6BAEE,yCAEF,2BAEE,6CAEF,2CAEE,4BAEF,2CAbA,yEACA,+BAEE,2CAEF,6BAEE,qBAEF,uBAEE,2CAEF,2BAEE,2CAfF,wEAGE,8BAEF,2CAEE,4BAEF,2CAEE,2CAEF,0BAEE,2CAfF,4BACA,2CAEE,6BAEF,2CAEE,2BAEF,6CAEE,2CAEF,4BAbA,yEACA,2CAEE,+BAEF,2CAEE,6BAEF,qBAEE,iEAIA,0BAQF,uEACA,2CAEE,6BAEF,2CAEE,2BAEF,uBAEE,oEAEF,yBAbA,0EACA,+CAEE,4BAEF,+CAEE,0BAEF,2BAEE,qCAEF,yCAEE,sBAfF,iEACA,yCAEE,yBAEF,yCAEE,uBAEF,2CAEE,yCAEF,2BAbA,sEACA,yCAEE,8BAEF,yCAEE,6BAEF,yCAEE,yCAEF,0BAEE,yCAfF,qEAGE,sEAIA,+CAEF,8DAEE,yBAEF,yCAQJ,oEACA,4BAEE,yCAEF,0BAEE,2CAEF,yCAEE,oEAIA,6BChEJ,yCAKE,8BAGA,yCAGA,4BCVJ,oJAIA,2BACA,qEACA,yCACA,0BCTE,oBACA,mBACA,yCDeE,uBACA,kEACA,yC1DqCA,0B0DvCA,iEACA,4CACA,qEAFA,uEACA,yCACA,wE1DqCA,6B0DvCA,2CACA,yCACA,oE1DqCA,6B0DvCA,yCACA,uEACA,4BAMJ,mFACA,mEACA,qEAIA,8BACA,mEACA,qFACA,4BACA,uEACA,yCAIA,gCEvCE,wCACE,iDvEUF,sBuELM,yCANN,0BACE,qEvEUF,yCuEXA,6BACE,oEvEUF,qBuELM,wBANN,2CACE,4BvEUF,2CuEXA,8BACE,0EvEUF,2CuEXA,6BACE,4CvEUF,2CuELM,2BALJ,wEvEUF,2CuEXA,8BACE,2CvEUF,4BuELM,qBFuCR,iEACA,0BAEA,uEACA,2CAIA,6BGtDE,2CACA,2BAEA,qBHuDF,mEAEA,4BACE,2CAMF,yEIhEE,+BAGF,2CCkBE,6B9EjBa,2C8EsBb,2CAKE,0BAEA,2CAEA,4B9E5Ba,2C8E+Bb,6BAIA,2C9EhCgB,2B8EqClB,uBACE,qBACA,+CAIA,yBACA,+C9E1CkB,0EELX,4B4EuDP,4GAOA,uB5ErEO,Q4EoEP,CACA,WADA,OACA,oBAJF,iB5EjES,e4EoEP,SACA,4HASA,sDAGF,uBACE,4BAEA,yBACA,4BAGF,2BACE,eACA,0CACA,CACA,+CAMA,wBAGF,0BACE,yBAGF,2BACE,yBAGF,yBACE,yBAGF,2BACE,2GAGF,yBAGE,yBAEA,qDAGF,4BACE,2BAIF,0BACE,yBAEA,yBAIA,qDAIA,4BAGF,2BACE,2BAGF,yBACE,yBAGF,2BAEE,0BACA,4BAGF,2BACE,6BAEA,kCAEA,4BAEA,kCACA,6BAKA,mCACA,+BAIA,yBACA,iCAEA,6BAEA,gCACA,uDAGF,yBACE,gCAEA,4BACA,yBACA,mDAGF,oBAEE,iDAGF,iEAKA,uBACE,4BAGF,uBACE,qEAIA,uBAIA,iDAGF,iEAKE,uBAEA,uBACA,uBAGF,2DAIE,uBACA,0BAGF,uBACE,iEAMA,uBACA,yBACA,uBACA,+DAIA,uBAIA,+CAIA,6DAOF,uBAEE,uBAGA,uBACA,2DAIA,uBAGF,uBAEE,+CAEA,uBACA,2BAEA,yBAGF,2BACE,yBACA,uBAMA,wBAIA,UANA,WACA,CAFF,UACE,CAEA,gBAIA,kCAIA,8BACA,wBAKA,8BAEA,CAHA,+BAGA,+CAIA,qBACA,4BAIA,uBAGF,2BACE,wBAEA,kBACA,CAFA,aAEA,CAIA,8CADF,wBAWE,CAVA,wBAOA,qBACA,kBACA,CALA,WADA,cACA,eADA,YACA,qBAMA,yBACA,aACA,CADA,2BACA,2CAEA,wCAGJ,sCACE,mzICvWF,KCuBE,6BACA,2CAHF,sBACE,iBAGA,qBAUA,yB9EiQ4B,a+E1PhB,CDbZ,wL9EuP4B,eChGxB,gBD2GwB,gBAKA,C8ExQ9B,QACE,CCaY,eADA,4BDFd,aCGc,uB3E1Cd,cAGI,iNAIA,yIAIA,+SAKF,uGACA,2OJ4R4B,eAEA,iBKzS9B,mBL0S8B,wCKjS9B,gBJqKM,wCIpKN,cJoKM,wCInKN,iBJmKM,wCIlKN,gBJkKM,wCIjKN,iBJiKM,wCIhKN,cJgKM,uBI9JN,iBJ8JM,gBD2IwB,4BKnS9B,cJwJM,gBDoIwB,gBARA,4BK/Q9B,gBJmJM,gBDqIwB,gBATA,4BK1Q9B,gBJ8IM,gBDsIwB,gBAVA,4BKrQ9B,gBJyIM,gBDuIwB,gBAXA,oBAzKrB,QK9EP,gCL8EO,mBKjFT,eAIE,8CAQF,aJkGI,gBD2H0B,4CA6CA,yBKpQ9B,YL6Q8B,CMhV5B,4DADA,gBDoFF,cCnFE,mCDsFF,oBACE,oDAEA,kBLqP4B,6BK1O9B,aJ2DI,yBIzDF,6BL4BO,kBKxBT,kBJqEM,oCAhBF,cIhDJ,aACE,cLxGS,2CK4GT,YACE,4BE/GF,YCJF,cDOE,gCPogCkC,qBA3gCzB,yBQST,qBCEE,CFPF,YEOE,cFPF,CCEF,cDCE,yBCcF,oBAEE,6BAIA,cADF,mBAEE,iCPiIE,cO9HJ,aRzBW,sBAyBD,qBC8HN,aD9HM,CUrCV,eAGE,wBAGA,aACE,qBVDO,wBASA,qBCoJP,UD7JO,CUOT,eTsJE,CSvJJ,mBDKI,yBCIA,cT8IA,iBS/IF,SV2Q4B,qBC5H1B,cStIJ,aACE,gBVfS,0BCoJP,aS9HA,CAFF,iBTgIE,CS9HA,iBACA,iCAKJ,gBVikCoC,kBU/jClC,qLCtCA,iBADA,iBACA,CAFA,iBACA,CAFA,kBACA,CCAA,UDGA,yBEmDE,yDDzCE,eZ+LiB,0BatJnB,uFDzCE,eZ+LiB,0BatJnB,qHDzCE,eZ+LiB,2BatJnB,mJDzCE,gBZ+LiB,uBYlKrB,YDnCA,eACA,CACA,kBADA,kBAEA,6BCuCE,cADF,cAEE,4EAIE,eAFF,eAGE,uwDEnDF,kBADA,kBACA,CAHF,iBACE,WAGA,sBAsBE,YACE,YACA,eACA,+BH4BN,aACE,eACA,+BAFF,YACE,cACA,+BAFF,uBACE,yBACA,+BAFF,YACE,cACA,+BAFF,YACE,cACA,+BAFF,uBACE,yBACA,2BGnBE,aHCJ,CACA,eADA,UAEA,wBGGQ,oBHbR,sBAIA,wBGSQ,qBHbR,uBAIA,wBGSQ,YHbR,cAIA,wBGSQ,qBHbR,uBAIA,wBGSQ,qBHbR,uBAIA,wBGSQ,YHbR,cAIA,wBGSQ,qBHbR,uBAIA,wBGSQ,qBHbR,uBAIA,wBGSQ,YHbR,cAIA,yBGSQ,qBHbR,uBAIA,yBGSQ,qBHbR,uBAIA,yBGSQ,aHbR,eAIA,8BGeI,qCAEA,kCAGE,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,0BACX,OADW,2BACX,QADW,2BACX,QADW,2BACX,QADW,2BAQP,uBHhBV,2BGgBU,wBHhBV,2BGgBU,eHhBV,2BGgBU,wBHhBV,2BGgBU,wBHhBV,2BGgBU,eHhBV,2BGgBU,wBHhBV,2BGgBU,wBHhBV,2BGgBU,eHhBV,4BGgBU,wBHhBV,4BGgBU,wBHhBV,yBEKE,wBC3BE,YACE,YACA,eACA,kCH4BN,aACE,eACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,kCAFF,YACE,cACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,8BGnBE,aHCJ,CACA,eADA,UAEA,2BGGQ,oBHbR,sBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,aHbR,eAIA,iCGeI,wCAEA,qCAGE,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,8BACX,QADW,8BACX,QADW,8BACX,QADW,8BAQP,aHhBV,8BGgBU,uBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,+BGgBU,wBHhBV,+BGgBU,wBHhBV,0BEKE,wBC3BE,YACE,YACA,eACA,kCH4BN,aACE,eACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,kCAFF,YACE,cACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,8BGnBE,aHCJ,CACA,eADA,UAEA,2BGGQ,oBHbR,sBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,aHbR,eAIA,iCGeI,wCAEA,qCAGE,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,8BACX,QADW,8BACX,QADW,8BACX,QADW,8BAQP,aHhBV,8BGgBU,uBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,+BGgBU,wBHhBV,+BGgBU,wBHhBV,0BEKE,wBC3BE,YACE,YACA,eACA,kCH4BN,aACE,eACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,kCAFF,YACE,cACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,8BGnBE,aHCJ,CACA,eADA,UAEA,2BGGQ,oBHbR,sBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,aHbR,eAIA,iCGeI,wCAEA,qCAGE,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,8BACX,QADW,8BACX,QADW,8BACX,QADW,8BAQP,aHhBV,8BGgBU,uBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,+BGgBU,wBHhBV,+BGgBU,wBHhBV,2BEKE,wBC3BE,YACE,YACA,eACA,kCH4BN,aACE,eACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,kCAFF,YACE,cACA,kCAFF,YACE,cACA,kCAFF,uBACE,yBACA,8BGnBE,aHCJ,CACA,eADA,UAEA,2BGGQ,oBHbR,sBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,qBHbR,uBAIA,2BGSQ,YHbR,cAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,qBHbR,uBAIA,4BGSQ,aHbR,eAIA,iCGeI,wCAEA,qCAGE,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,6BACX,OADW,8BACX,QADW,8BACX,QADW,8BACX,QADW,8BAQP,aHhBV,8BGgBU,uBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,8BGgBU,wBHhBV,8BGgBU,wBHhBV,8BGgBU,eHhBV,+BGgBU,wBHhBV,+BGgBU,wBHhBV,yBXgFO,celIP,kBfkIO,CenIT,UgEsCc,qDhE7BV,6BAHF,cfoV4B,mBehV1B,iCAIA,gCADF,qBAEE,oCAGF,4BACE,2DAUF,af8T4B,CelT5B,sGAEA,wBAEE,mFAIA,uBAEE,oKAMJ,QAIE,0DASF,0BfyR4B,6C+EzThB,kC7E9BZ,aFyV4B,oGgB/V1B,wBD8FiC,wJCvF/B,oBDuF2E,CC3E1D,4JAMf,wBANe,0GAnBnB,wBD8FiC,gKCvF/B,oBDuF2E,CC3E1D,kKAMf,wBANe,oGAnBnB,wBD8FiC,wJCvF/B,oBDuF2E,CC3E1D,4JAMf,wBANe,2FAnBnB,wBD8FiC,4ICvF/B,oBDuF2E,CC3E1D,mJAMf,wBANe,oGAnBnB,wBD8FiC,wJCvF/B,oBDuF2E,CC3E1D,4JAMf,wBANe,iGAnBnB,wBD8FiC,oJCvF/B,oBDuF2E,CC3E1D,yJAMf,wBANe,8FAnBnB,wBD8FiC,gJCvF/B,oBDuF2E,CC3E1D,sJAMf,wBANe,2FAnBnB,wBD8FiC,4ICvF/B,oBDuF2E,CC3E1D,mJAMf,wBANe,0PAMf,iCANe,uC+DnBZ,wB/ESA,sBekGP,afmQ0B,wCAtWnB,wBALA,sBegHP,agE9GO,6BALA,wB/ESA,oGesHT,oBf+O4B,4CezO5B,QACE,qEAIA,0BfiO0B,wDA1WnB,sCEKT,UFuW4B,4Ba1S1B,qCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,sDAGA,QACE,6BF1GN,qCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,sDAGA,QACE,6BF1GN,qCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,sDAGA,QACE,8BF1GN,qCEqGI,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,sDAGA,QACE,oCALF,iCAJJ,aAEI,CACA,eACA,CAFA,UAGA,mDAGA,QACE,CiE/JM,88DAEA,aAEI,CAJJ,yPAEA,aAEI,6BCbpB,aFLW,+BAOA,2B9DIT,C8DXS,qBAOA,C9DIT,wBACA,sBjBkR4B,a+E9RnB,c9DCT,CAGA,chB0KI,gBD2GwB,CiBvR5B,iCjB2esC,CApNV,eAKA,CA+MU,sBiBzetC,CAQA,qEAXA,UAiBA,uCCJI,8BDdN,eCeQ,4CDMN,wBACE,SACA,qC8DvBO,wBAmCG,qBA2D0B,C5DnFpC,iCAJF,a4DPS,CA8F6B,S/EsSV,4CiBtW5B,ajBvBS,UiB0BP,gFAQF,wB8DpCS,U9DwCP,oMAQF,uCACE,oDAMF,WACE,0BACA,sD8D9DO,sB9DiET,a8D1DS,wE9DsEX,aAEE,WACA,iCAaA,iBhBiEE,iBgBlEF,eACA,CAFA,kCACA,CAFF,+BjBoM8B,oCiB1L5B,iBhB0EI,iBgB3EJ,gCACA,CAFF,6BjBiI8B,oCiBxH5B,iBhBmEI,iBgBpEJ,iCACA,CAFF,8BjB2H8B,yCA1NnB,wBiBoHT,CACA,sCjB+J4B,aApRnB,CiB4GX,aACE,CAGA,chBoDI,gBDgHwB,CiBrK5B,eACA,CAFA,iBACA,CAFA,UASA,iHAIE,eAFF,eAGE,kCjB+F0B,oBiBjF5B,iBhB2BI,CgB7BN,gCjB6VwC,CChUlC,eDsDwB,CA0QU,oBSlepC,kCTuN0B,oBiBxE5B,iBhBmBI,CgBrBN,+BjBsVwC,CCjUlC,eDqDwB,CA4QU,kBSnepC,CQyJA,8HAIJ,WACE,6BAQF,kBjB2UwC,4BiBvUxC,aACE,kBjB4TsC,2BiBnTxC,YACE,eACA,CACA,iBADA,iBAEA,wEAIE,iBAFF,iBAGE,6BAUF,aACA,sBAFF,iBjBmSwC,mCACA,qBiB7RtC,gBjB6RsC,CiB9RxC,iBAGE,4HAGA,ajBvNS,mCiB6NX,eACE,oCAIA,kBACA,CAFF,mBACE,CAEA,oBADA,cjB+QsC,sDACA,ciBzQpC,qBjByQoC,CiB1QpC,YACA,CAFF,eAIE,iChBrFA,ckBxHF,YACE,CnB4coC,aCrVpC,CkBtHA,iBnB2coC,CmB5cpC,UFyNqC,gCEvMrC,0BACA,sBnBoO0B,amBrO1B,CAPA,YACA,CAGA,iBlBwHE,CkB9HF,MACA,ClB6HE,eDgHwB,CmBzO1B,gBACA,CAHA,cACA,qBACA,CAPF,iBACE,SACA,CACA,SVrCA,sGUmDA,QAEE,oFAKF,aAEE,wCASE,2QF+KiC,CEtKjC,wDC5EA,CHkPiC,2BEtKjC,CC5EA,2DDsFA,CCtFA,oBHkPiC,6CE5JjC,8CCtFA,qBpB2dgC,8EmB3XhC,uCFkJiC,CElJjC,4BFkJiC,gDExIjC,yJACA,uiBAoCuB,CArCvB,oEAqCuB,oGAKvB,8DACE,mIAaJ,cAnByB,kFAwBvB,6EAEE,oBAhJN,qFAOF,wBAGE,CF+MqC,oBE/MrC,mFAKA,gCAGA,CV7CA,+JUqDE,0FAOA,qDFwLmC,mCE/KjC,aACA,CF8KiC,YE/KjC,2CACA,kCAGA,0BF2KiC,sBE3KjC,cAFA,YACA,kBACA,CAFA,OAEA,gBADA,qDADA,oCF6KiC,0GE7JjC,oGCrFA,apB2dgC,0CmB3XhC,qUFkJiC,CElIjC,wDFkIiC,4BElIjC,CFkIiC,4DjByOD,iEiBzOC,oEEvHnC,iCAEE,gDFqHiC,mMEnGV,CFmGU,kCEnGV,2CAKvB,imBFmIF,CExIyB,oEFwIzB,iDAEA,oBAIF,iCAEE,gEAKF,2IAME,qFASA,cACA,8EAIA,oBACA,uFAMA,wBACA,CAFF,oBAEE,qFAGA,gCEzSF,CASA,mKAIA,oBACA,wEAGA,oBACA,iCV9CA,0HUqDE,sLAOA,mBAPA,YAKF,cAEE,mGCxEM,CCJmC,sBDInC,UCJmC,sDFqFvC,2GAEA,UACA,4DACA,CADA,aACA,gGAGF,aE5FyC,cF8FvC,CE9FuC,iCFyFvC,iBAKA,2IASA,gEACA,oHAUA,+CC9GI,CD8GJ,cnB2XgC,amB3XhC,kBnB2XgC,OmB3XhC,gBnB2XgC,gBmB3XhC,CnB2XgC,oCoBze5B,iBpBye4B,mBoBze5B,oIDwHJ,iOACA,uHAKA,2QElIuC,yDF+IvC,CE/IuC,4BF+IvC,4DAbA,iEAaA,sHE/IuC,mNFyJvC,4BEzJuC,0HF+JvC,6EAEuB,CEjKgB,kCFiKhB,4GAKvB,uiBALuB,6LA0BrB,2MAjJR,aAEE,iSAkBA,mLAOE,yZAgBE,6OAIA,iCCrFI,oXDoGJ,0LAUA,kRAUA,+DACA,cADA,YACA,4FAKA,8DElIuC,aFkIvC,kBAFF,OAEE,iCElIuC,mCFkIvC,CALA,iBAGF,UEhIyC,SFkIvC,wIElIuC,iPF+IvC,2HE/IuC,qUFgKrC,CACqB,yDADrB,2BACqB,6DAlBvB,oBAOF,6CAWyB,0HAMrB,+KAGF,uCATuB,CAMrB,4BANqB,8VA0BrB,imBDxKF,CC8IuB,oED9IvB,4HIOJ,qDtB8W0B,0JsBlW1B,8TCrBA,uLAcA,qMvB2CW,4NuBvE8K,iPrBO3L,gCqBP6D,CAqBzD,4XvBkDS,8LuBvE8K,kSAC3L,avBsEa,sBuBvE0F,wBAYvG,uBAEE,CAdqG,oBAqBnG,CrBdJ,cFgEa,qBuBvE0F,evBuE1F,eEhEb,CqBPuG,gBAcrG,sBAd2D,CrBO7D,iBqBP6D,CAqBzD,6HvBkDS,CuBvE0F,0CAA1C,qBvBuEhD,iMuB/BX,gCAxCyL,CAqC3L,SArC2L,kNA+CzL,iDDaF,wBC3DA,qBvBsEa,CuBnBP,avBmBO,oCEhEb,6CqBP6D,CvBuEhD,auBvEgD,uEAc3D,wBAd2D,qBAA0C,kCAYvG,aASI,6EAOF,wBvB2CW,sBuB7Cb,avB6Ca,wLuB/BX,wBAxC+I,qBAA0C,CAwCzL,aAxCyL,0MA+CzL,gCAKI,gCvBmBO,8CuBtEb,avBsEa,sCuBvEgD,wBAA0C,sBrBOvG,aqBPuG,2EAA1C,wBAA0C,sDAqBnG,CAPF,aAOE,iFvBkDS,8CuB3CX,avB2CW,8LuBvEoI,wBAA0C,sBAA1C,aAA0C,gNAoDrL,gCAnDN,8BvBsEa,6CEhEb,CFgEa,aEhEb,oCqBPuG,8CAA1C,aAA0C,oHAqBnG,kCArByD,aAqBzD,6EvBkDS,mPuBvE8K,qQAoDrL,gCAnDN,2BvBsEa,wBEhEb,sBFgEa,aEhEb,iCqBPuG,yKAqBnG,kCArByD,aAqBzD,uEvBkDS,0OuBvE8K,8CAA1C,aAA0C,iMAoDrL,gCAnDN,8BvBsEa,6CEhEb,CFgEa,aEhEb,oCqBPuG,8CAA1C,aAA0C,oHAqBnG,kCArBmG,aAqBnG,6EvBkDS,mPuBvE8K,qQDkE3L,gCtBKa,6BuBbqC,wBvBarC,sBEhEb,aFgEa,gFuBHb,CvBGa,auBHb,qEAEE,6CAGF,iCAGE,CANA,aAMA,2TvBLW,kQsBLb,gCtBKa,4BEhEb,wBqBmDkD,qBvBarC,8KuBDX,8EvBCW,CuBDX,avBCW,yEuBKX,6OvBLW,+PuBeX,gCDpBF,2BtBKa,6CEhEb,CFgEa,aEhEb,iCFgEa,4HuBHb,wBAEE,uDAFF,aAEE,uEAMA,0OvBLW,4PuBeX,gCAKI,sCvBpBO,qBsBLb,atBKa,4CuBbqC,wBvBarC,sBuBbqC,avBarC,uFuBHb,gCAEE,6FvBCW,wBuBKX,CvBLW,auBKX,gNvBLW,8CuBWX,avBXW,kOuBoBP,gCDzBN,wCtBKa,kCEhEb,8CFgEa,sJuBDX,iIAMA,4PvBLW,mSuBoBP,gCvBpBO,sCEhEb,oBqBmDkD,CvBarC,auBbqC,4CvBarC,kJuBDX,6HAMA,sPvBLW,6RsBLb,gCtBKa,mCuBbqC,oBvBarC,CEhEb,aFgEa,qLuBDX,uHAMA,6OvBLW,oRuBoBP,gCvBpBO,sCEhEb,oBqBmDkD,CvBarC,auBbqC,4CvBarC,kJuBDX,6HAMA,sPvBLW,6R+E7Ba,gC/EiIc,qCAEA,qB+EjId,a/EiIc,2CsBtFxC,wBtBsFwC,sBsBtFxC,atBsFwC,qFsB9EtC,gCAWJ,2Fb7FI,wBaiGJ,CbjGI,aaiGJ,6MtBsU8B,0RkBpatB,gCMjBJ,oCAUJ,oBACE,CALE,aAKF,0CAGA,6CNEI,CMHJ,aNGI,mFACE,yHOZN,wBCoBE,CDpBF,aCoBE,0MAzBF,wBAsDI,sBAtDJ,aAsDI,CD1CN,2NsDHW,gCtDkBT,mChBbE,oBgBuBA,ChBvBA,agBuBA,yCAKA,wBAEE,qBZYF,CYjBE,aZiBF,iFYjBE,gCAKA,uFALA,wBAIA,CAJA,aAIA,CACA,sMAPF,wBAEE,sBZiBF,aYjBE,yNzBmNwB,gC0BtP5B,2BACA,cADA,eACA,qBACA,iCACA,wCA8CE,gEDaA,yBAEA,uEzBkrBgC,a0B7tBhC,oBACE,4DAdJ,oBAiBI,iBAjBJ,iBAiBI,kBAhBJ,4DAyCI,oBADF,iBACE,iBAxCJ,oBAwCI,4BDsBA,+DAQF,gBACA,CACA,sIzBmK0B,U0B5NxB,qDAWA,uCACE,sBAGF,kD1B8MwB,+C0B1MtB,YA9BN,6BACA,wBACA,CADA,kBACA,kEAkCI,2CDsCF,yGACE,6GEzFJ,4CFmHA,CErHA,6BAEA,CAHA,qBACA,CF6GF,UE9GE,CF4FI,oBAYF,mBACA,sBAaF,8CAGA,azBiK4B,gC+EnRnB,4EACA,qBtD+IP,CsDgBgC,ctDxClC,YACA,0BsDuCkC,CtDzClC,OAkBE,esDzIO,CtDyHT,mDAJA,iBAEA,CsDyCkC,etDvBhC,CAlBF,qBAyBE,qCsDxIM,gEtD4IR,CsD5IQ,OtD4IR,yBsDzJS,uCtD6JP,0DASF,iBAIF,0BACE,uCAEA,iBsD7KS,yCtDgLT,SAIF,CAJE,OAIF,0BACE,uCsDxLS,0DnDCT,UAFF,OAEE,2BACA,uCACA,0DAGE,SACA,CADA,OACA,0EAKE,CALF,qBAKE,+QAKA,aAMN,2CAGE,6BAGE,CAHF,wBADA,KAIE,mDAQA,iGAFF,UAEE,CARA,6DAQA,yDnBPA,gEACA,0DmBeF,UnBFE,oBACA,CmBCF,YnBFE,CmBEF,WnBfE,KAcA,kDmBqBF,WAFF,oBACE,CACA,aADA,kBACA,yEASE,uDADF,2BACE,CAJA,UAGF,CANA,oBAGE,0CAIA,wDAKF,aACA,8QA4BA,yDAIE,6BAJF,QAEA,eAEE,gDAKA,kCAFF,UAEE,eALA,cAKA,gBALA,qBAGF,CAEE,sCALA,UAKA,2EnBhFA,yBADA,+BACA,6EmByFF,wBnBxGE,CAeA,+BAfA,iFmB4HF,wBAEE,CnB7HA,iCmB6HA,8NAIE,cAJF,aAEA,sBAEE,CACA,+DCtJJ,mBACA,CAHF,iBAEE,CACA,qBACA,0EACA,gCAEA,wVAQE,ujBAKE,mSAaF,sEAKA,cpBIA,0GoBGA,oJAEA,mBpBnBA,CoBiBA,oBpBjBA,qCACA,4JAcA,uUoBUA,CpBVA,4BoBUA,kIpBxBA,4ZoBmDF,sFAOE,gDADA,iBACA,kMAGE,+wBpB9EF,0MoB+HJ,S7BoWwC,0eSnepC,4BoBgJJ,CpBhJI,yBoBgJJ,gF7BkVwC,qD6B/TtC,sjCAWF,6dpB7JI,sDoBwKJ,iBpB3JI,qCACA,mDyE/CI,kBzE8CJ,CAbA,iDqBzBF,qBACA,CoDJM,cALA,azE+CJ,8CyE1CI,CzE0CJ,gBADA,sBACA,CyE1CI,iBzE2BJ,mBqBvBF,4GAIA,wHASA,+B9BufsC,8VA1CA,oB8BtbtC,iB9BsbsC,iBA3FV,kBA2FU,4GAiEQ,8X8Bvd9C,oBAFA,iBAEA,iBAJF,oBAIE,+F9BgcsC,qB8BrbpC,usBA0CA,4BACE,CADF,yBACE,CA0BA,+gBAKF,2B9B0X4C,C8B/X1C,wB9B+X0C,kE8B9W9C,4BAGE,CAHF,yBAGE,CACE,gC9BmY0C,gC8B3X1C,oB9B2X0C,oDADA,iB8BhY1C,UAOA,wC9B2X0C,qCA5iBrC,uCA2iBqC,mJkBniB1C,kIACE,gCYmLJ,wFAEE,8GAkBN,wBACE,qBACA,C9BgU8C,U8BhU9C,4IiDxNS,ajDgOT,0JrBpNE,wBqByNF,uC9B0PsC,e8BtPpC,CAFF,iB9BwPsC,C8BtPpC,gEiDlOO,8CjDuPP,CiDvPO,mBjDuPP,0FiDvPO,WAPA,aAOA,aAPA,a/EglByB,iB8B/VhC,WiDjPO,CAOA,UjDkQT,CAXE,4CiDzPO,gCjDoQT,+DAKA,oBACE,4F9B+NoC,4N8BrMxC,mGAKE,wBAIA,CAJA,oBAIA,kGAMA,0K9B4E4B,C8B9D1B,gNAKF,0BACE,4DASF,0G9BvD4B,2L8B0E1B,mGAKA,0BAEA,gCrBnWA,iFqBkXF,mBACA,CAFA,aACA,iCACA,4D9B0O2C,4C8BlOzC,CADA,uB9BmOyC,C8BvOzC,yBAIA,CAJA,uBAKA,iIACA,CAFA,sBAEA,uC9BiOyC,2D8B7NzC,0G9BxJ0B,qBAkXe,6BS1lBzC,qMTulByC,C8BpN3C,iO9B3YS,yBSQP,sBSEE,aYiYJ,CrBnYE,qBSEE,+BYyYF,iCACA,CZ1YE,gBY0YF,sCZ1YE,CYiYJ,sBrBnYE,UTulByC,sCA/Wf,oBAkXe,CS1lBzC,iCT0lByC,SS1lBzC,mLqBsaA,qBZpaE,CYoaF,gCZpaE,yCY4ZJ,wBZ3ZM,CY2ZN,aZ3ZM,wDYqaJ,+C9BuLyC,W8BlL3C,0B9BoKkC,mCSjlBhC,iBqBwbF,C9B0JkC,gCA1lBzB,C8B2bP,qBrBnbA,oBTRO,kB8BgcT,mCrBxbE,kBqB2bA,+B9BrE0B,qBAoOe,kBS1lBzC,CTsX0B,iBStX1B,qKqBmcA,0CZjcE,2BTFF,kBqBkcA,UACA,CrBncA,SSEE,6DACE,qDlB4lBqC,gI8BhJzC,wBACA,sEAKF,gB9B7dS,0E8BkeT,yBACE,oCAWE,mEAGF,C9B/eO,gBSMP,iCTNO,CSMP,OTNO,gBSMP,SqByeA,6EAJA,aACE,C9B5eK,e8B2eP,C9B3eO,uBSMP,+BqBufJ,CAdI,yC9B/eO,4E8B6fX,CAVI,QACE,C9BpfK,iB8BofL,yCAGF,CAHE,SASN,+BAGE,uCZxfI,CYqfN,wBAGE,CAHF,kCZrfM,yGYqfN,+CCngBE,uDAIA,+CAKA,+FAIE,iDAMA,6DgDsCgC,wChD5BlC,wBAEA,4BACE,CAJJ,8BACE,CAGE,8GtBVA,uGsEmCgC,ChD7BpC,UgD6BoC,uC/ElDzB,oD+BoCL,oGgD7CK,wBAqCG,8DtEdV,wBACA,sCsB8CF,CAZE,0BtBnCA,CsBiCF,YAEE,CgDIgC,UhDQlC,iDA2BE,eACA,CtBpFA,wBsB4DF,S/BvES,oBSWP,YTXO,2G+BuFP,uGAOA,CtBnFA,UsBoFA,uCACA,gDAWA,oBAEF,CACE,wECjGF,wBACA,iDAEA,2JAmCA,gBA9BE,wBACA,SACA,oBAPF,YAIA,iBACE,CALF,gCAOE,0GhCwrBgC,uGgC5pBlC,CAnCA,UAmCA,uC9B1CA,yC8BsDF,mBACE,gBACA,kDAGA,kEAQE,wBACA,mBASJ,CACE,mBAfE,WAGF,eACE,CAJA,uBhCwmBgC,uEgC1kBlC,mBACA,+CAQA,wB/B8DI,mB+B5DJ,CAHF,iBAGE,8DAEA,wBvBxGE,uEPFF,c8B8GE,0DAOF,wBAEA,0DAEA,cACA,mDhCmlBkC,wBgC9kBlC,gHnBtEE,4PAbA,sCmB6FA,YAoBI,gBACA,gCADA,cACA,2BAGE,iGAGE,wDhC4hBwB,uVgCjhB1B,iDAeA,8CAGF,wBAIE,oBAJF,aAIE,+FnB5IN,yUAbA,wBmB6FA,CnB7FA,UmB6FA,yEAqBI,aAEA,kBACE,mFAGE,2CAGF,uChCyhB0B,qcgC3f1B,+BAIA,qBnBhJN,oRmBmFM,eACA,CAFF,eACE,CnBnFN,cmBoFM,uCnBjGN,cmB6FA,CnB7FA,emB6FA,4CAqBI,wDAGE,6FAGE,kBAGF,CAHE,2BAGF,iChCyhB0B,iQgCjhB1B,kCAeA,CAfA,WhCihB0B,qBgClhB5B,YACE,uBhCihB0B,WgClgB1B,mDAGF,4CAIE,gSnB5IN,0FmBkFI,oBACE,2BACA,+CAJN,kBAoBI,8DACA,iBAEA,yDAGE,kBACE,CAHF,mBAGE,iShC4hBwB,uFgClhB5B,mDACE,sBAcF,gBACE,mDAGF,yCAIE,gSAvCF,yIAlBE,+CACA,kBAmBF,8DACE,iBAEA,yDAIA,kBhCyhB0B,CgC5hBxB,mBhC4hBwB,iSgClhB5B,gBACE,sDAeA,oEAGF,sBAIE,mEAIA,yCAcR,gShC+fkC,wDACA,iFAEA,2NgC7ehC,ChC6egC,mBgC7ehC,iShC0egC,sEAEA,0FExtBlC,mEFwtBkC,0CgC7clC,gShCpRS,yDgC6RP,kChC2bgC,wPACA,uUAEA,oSA3tBzB,0SgCuTP,eADF,eACE,+DAGF,0DhC8ZkC,uEAxtBzB,qTiCCT,gBAEA,mD8CES,iEtEMP,sBwBFF,gBACE,gDAIF,aAEE,gJxBIA,eACA,qDwBEA,eACE,qHxBWF,6EwBFA,eAIJ,2OAqBE,e/BrDA,+C+B6DA,sBjCyvBkC,CiC5vBhC,ejC4vBgC,oDiC9uBlC,wQ8C1B0B,4C9CwC1B,eAEA,CxBlFE,mJwBgGF,gBASF,gSAcE,mHxB9GE,eACA,yOIgCA,eoB6FJ,2HAaM,eAEA,qdxBrIF,uGwB8KQ,6IAKA,8QAUA,uFAKA,eAcV,CjCgmBkC,sSiCtkBhC,iCxBpOA,oBACA,wBwB0OA,CxB1OA,yBwB0OA,qCxBxPA,sBwBoPE,kCxBvOF,awBoOA,iBxBjPA,0BAVA,cwBsQA,cxBtQA,mCyBjBF,qBACA,CAFF,kBAEE,+CAIA,yCzBYE,2CyBLF,CAPA,kBAOA,8C6CNS,4C7CaL,CAJF,6C6CTO,C/E+hCyB,qBkClhC9B,+FAWF,wCAOF,a6C/BS,C7C4BP,4C6C5BO,6B5CPX,oBACE,gC1BiBE,gBHbF,mB6BCF,uCAEE,eACA,kCnCqxBkC,oB+E/uBR,uC5ChC1B,iDAKE,0B4CVO,6C5CgBP,C4CuBwB,e5C7BxB,CAFA,sBAQA,0CnC4wBgC,uDmCpwBhC,8B1BcA,0BACA,0C0BTA,CALE,sBAKF,yC1BNA,uDACA,mCsEfM,e5CgCR,C4ChCQ,qB5CgCR,sE4ChCQ,qBAPC,wD9EuKL,gCDqDwB,CoCtO5B,QACE,uBnCgLE,C8E1KK,iB3CPT,cpCsO4B,0FSzL1B,aACA,oE2BjCE,yC3BkBF,2CACA,4DTuM0B,4CoC/NxB,CnCyKA,6CmCzKA,kC3BqCF,kBACA,oD2BjCE,+B3BkBF,kBACA,CADA,kBACA,kC4B9BJ,QACE,CACA,epC6JE,iBD4H0B,CqC1R5B,iBrC0R4B,oCqCrR5B,kBACA,yBACA,4B5BKE,mI4BHF,anBKI,CmBLJ,anBKI,oDACE,4BhBLN,CgBKM,yBhBLN,kImCuBF,yBrCi4BoC,qIA51BrB,iFsCrET,4BADA,wBACA,oIANJ,wBtC2Ea,uIsCrET,iEAGF,oBAEE,uDACA,cDqCJ,mBCjDA,UtC2Ea,6EE5Db,6BoCVI,oBACA,sGAKA,eACA,CDqCJ,2BCjDA,CAYI,4BAZJ,sDtC2Ea,yBE5Db,yBoCVI,+CACA,+DANJ,wBtC2Ea,sBsChET,2BACA,CDqCJ,eCjDA,CAYI,kBDqCJ,CCrCI,mBtC+DS,mDE5Db,kBoCVI,0DACA,aAKA,aALA,8BAKA,gEDsCJ,yBCjDA,CtC2Ea,oBsC3Eb,CpCeA,wCoCTI,0CAKA,qBALA,aAGF,eAEE,CALA,cAKA,4BtCgES,8CsCtET,CtCsES,cqC1Bb,aCjDA,CtC2Ea,kCsC3Eb,qBAYI,iBAPA,kCACA,wBAKA,sBALA,4CAKA,kCDsCJ,gCrC0Ba,CsC/DT,SDqCJ,CCrCI,StC+DS,mDsCtET,gCACA,CpCSJ,6BoCVI,CtCsES,asCrET,kDAKA,iCACA,CAHF,8BAGE,8CtC6yB8B,wBSxyBhC,sBTwyBgC,oBSxyBhC,gD8BNJ,qBAEE,qB9BIE,C8BVA,cAIJ,YAJI,mB9BUA,2C+BZF,iBxCy9BkC,iBwC19BlC,qBxC09BkC,kEwCh9BlC,+BxCiR4B,CwCnR9B,4BxCmR8B,iEwChQ5B,gCAGE,CANF,6BAOE,2CAEA,iBAWmH,iBAXnH,oBAWmH,kEC3CnH,gCADF,4BACE,iED2CuB,gCAA4C,CADrE,6BACqE,wBAAgD,oBAA5F,CC5CzB,qBACE,6BAGF,cACE,CALF,kBACE,CAIA,kBDuCuB,6HCvCvB,CDsCF,sBACqH,CCvCnH,yDDuCmH,sCAA5F,8DC5CzB,oBACE,8BAGF,YACE,6BDsCF,iBACqH,sCC5CrH,oBD4CqE,iBC5CrE,CD4CyB,kBC5CzB,gCACE,wBAIA,CAJA,aAIA,6EDuCmE,yBAA5C,aC5CzB,6EAKE,gCDuCmH,CCxCrH,SDwCqH,kCAAhD,yBAA5C,aAA4C,iFCvCnE,wBDsCF,CCtCE,aDsCF,iFC3CA,gCACE,CD2CmE,SC3CnE,gCAIA,wBCPA,CDOA,aCPA,6EAMF,wB1Ck+BkC,C0Cn+BpC,aAGE,6EjCOE,gCiCEF,C1CXS,S0CWT,6BAEA,wB1CfS,C0CcT,a1CdS,uEA0+ByB,wB0Cr9BlC,C1Cq9BkC,a0Cr9BlC,uExBPM,gCwBUR,CxBVQ,SwBUR,2KCYE,CDZF,aCYE,6EDNA,gCACE,CADF,SACE,+BAGE,wBAJJ,CAII,aAJJ,CAKM,0EExCN,wBAIA,CAJA,aAIA,2ECIA,gCpCQE,CoCTF,SpCSE,8BsEZO,wBlCiBT,CAFA,aAEA,yE3CPA,wB6EVS,ClCiBT,akCjBS,yEAMA,gCA8BG,CA9BH,SA8BG,CA/BH,4BlCiCX,wBAEE,CkCnCS,alCmCT,uEkC4BkC,wBlCvBlC,CkCuBkC,alCvBlC,uEpCxBE,gCACA,CADA,SACA,4BAaA,wBACA,qBoCeF,kBpChBE,CoCgBF,iBpCfE,qEoCmBF,mCkCakC,gBlCVhC,ckCUgC,ClCVhC,ekCUgC,wBAtD1B,4CAPC,kBAOD,ClCkDN,sBkCzDO,ClCwDT,iBkCjDQ,gClCwDR,aACE,gFAEA,kBACE,2CAgBA,qC7C4IwB,iB6C7I1B,CACE,QADF,MACE,yCAGE,wBpC1BJ,qBAZA,CoCsCI,apCtCJ,2DoC2CI,4CpC3CJ,aAYA,0DoCqCM,sBpCrCN,aoCqCM,6DAGF,8CAEE,qEAGE,qB7CsHkB,C6CzHpB,a7CyHoB,mCahL1B,oEgCoCE,0CAGE,6CpC1BJ,CoCuBE,apCvBF,gCAZA,iEoC2CI,apC3CJ,gCAYA,8FoCqCM,oEAGF,a7C2HsB,+B6CzHpB,6FAGE,wB7CsHkB,2CahL1B,2CgCoCE,4FAGE,wBpC1BJ,0CAZA,0CoC2CI,wBpC3CJ,qBAYA,CoC+BI,apC/BJ,iGoCqCM,iDAGF,0B7C2HsB,2B6CzHpB,4BAGE,wB7CsHkB,qBahL1B,CgCuDM,aAEA,gBACE,CAHF,yBAEA,CAFA,ehCvDN,+BgCuCI,wBpC1BJ,CoCuBE,WhCpCF,YgCmCA,sBACE,yDAGE,CpC1BJ,yBAZA,CoCsCI,kBpCtCJ,qEoC2CI,epC3CJ,wCAYA,+GoC0CM,kEAEA,iD7CuHoB,uCahL1B,uCgCoCE,6DAGE,CAHF,YAGE,6BpC1BJ,qCoC+BI,qBpC3CJ,kDoC2CI,CpC3CJ,coC2CI,yCpC/BJ,wITmK0B,wB6CzHpB,CAFF,kC7C2HsB,C6C9HpB,SAKA,wEAGE,CAHF,aAGE,kCpCpGR,0BoCsHF,sCACE,CAJJ,oCpCnHI,CT0N0B,iB6CnG1B,8CAEA,8BACE,gCCzIJ,6CDqJyC,yJC9InC,2BD8IkE,aC9IlE,6DD8IkE,yDkCrJ/D,SlCqJ+D,mEAA/B,gH3CxIzC,C2CwIyC,e3CxIzC,wC4CNM,uFiCPG,gClCqJ+D,8FAA/B,sI3CxIzC,0E4CNM,mBAGF,CAHE,oBAGF,iFAVJ,qBDqJwE,0CAA/B,oIAA+B,gCC9IlE,iGD8IkE,6HAA/B,4GAA+B,CAA/B,oBAA+B,oFC3IpE,qBiCVK,CjCOH,gBiCPG,0BlCqJ+D,oIAA/B,iIC9InC,6HD8IkE,yFAA/B,4HAA+B,sBAA/B,gBAA+B,EC9IlE,oFiCPG,wElCqJ+D,0DAA/B,kG3CxIzC,C2CwIyC,8B3CxIzC,mE4CNM,yFD8IkE,mBEvJxE,CFuJwE,oBEvJxE,oFAMA,qB7CKA,C6E8G8B,gB7E9G9B,2B6ETS,0ChCSP,0FAKE,gCAWN,0BACE,uEC7BF,2BhD64BoC,C+Cv2BlC,8B/Cu2BkC,mE+ElvBA,Y/BnJlC,6EAGA,mBvCOE,CuCTF,oBvCSE,oFuCCA,sBhD23BgC,gBgD33BhC,oCAKA,mEAQJ,oBACE,+D+B1BS,qBAyJyB,0C/B1HlC,wBACA,CADA,aACA,6ICjCF,wBAEE,CjDs4BkC,aiDt4BlC,wEASF,wBAGE,qBjD4pBkC,CiDpqBhC,UjDoqBgC,4CiDppBlC,yBAHA,aAGA,CAOF,gJASI,wBjDu6BgC,CiDv6BhC,ajDu6BgC,0EkB97B5B,6C+B0BN,CAJA,UAIA,0CjDq6BkC,wBiDh6BlC,CjDg6BkC,aiDh6BlC,6IASA,wBACE,CAHF,aAGE,wEACA,6CAGF,CAHE,UAGF,uCAEE,wBAIA,CAJA,aAIA,uIAUF,wBACE,CAJF,aAIE,qEAGA,kGAMA,wBACA,CAFA,aAEA,6IAMA,wBACE,CAJA,aAIA,wEAUJ,wBAGA,qB8BxEY,C9BoEZ,U8BpEY,yC9B0EZ,wBACA,CADA,axCjGE,2ITDO,wBiDqHT,CjDrHS,aiDqHT,uEAMF,wBACE,qBACA,CjDuzBkC,UiDvzBlC,wCjD8zBkC,wBiD3zBlC,CjD2zBkC,aiD3zBlC,yIjD2zBkC,wBiDrzBhC,CjDqzBgC,aiDrzBhC,sEAYJ,wBAIE,qBjD0wBkC,CA7oBN,UA6oBM,uCiDnwBlC,wBACA,CAFA,aAEA,uIxCtIE,wBACA,CADA,aACA,qEwCoJJ,wBAEE,qBAEA,CAJF,UAIE,wBjD8wBkC,WiD7wBlC,YpCvIE,gCoC6IF,cjDuwBkC,CiDrwBhC,WjDqwBgC,wBiDrwBhC,8BAGF,+BACE,uHAOF,yCACE,wBAEA,UAFA,SAEA,kCACE,2CpC9JF,2BoC2KF,CpC3KE,2BoC2KF,0BpC3KE,Cbk5BgC,oBkD58BlC,CrC0DE,oCbk5BgC,CiDnvB9B,gBAQJ,CjD8uBkC,iBar5BhC,CoCuKF,ejD8uBkC,CAHA,SkD58BlC,yClD+1BkC,yLA7kBN,kBmDjR5B,CAIA,2BACA,CnD4R4B,0BmD7R5B,CACA,iCAGA,0CAEA,2CAEA,CnDgR4B,aAKA,CA6jBM,YA7kBN,CmDjR5B,qBAYA,6BDJA,cACA,6BAEA,elDg1BkC,oCkD90BlC,iBAEE,gBlDi1BgC,wBkD70BhC,YACE,CACA,YlD40B8B,MkD90BhC,CAGE,SACA,CAFA,eACA,ClD20B8B,qBkD50B9B,WAFF,YAIE,+DAKN,CALM,4BAKN,2CACE,2BAEA,CAFA,iCAEA,uCACE,qGAGE,cACA,mDlDtBK,+DkD4BX,YACE,mHlDszBkC,gBADA,4HkD7yB9B,sDlDrCK,mHkD6CT,+CAGE,WAHF,kEAGE,wGAGE,CACA,YADA,sBACA,+ElDpDK,sFkD2DT,4ClDuxBkC,2EkD/wB9B,oBACA,CANF,YlDqxBgC,sBADA,CkD9wB9B,UlD8wB8B,oBkDvxBlC,iBAGE,ClDoxBgC,UkD9wB9B,iClD9EK,qBkDwGT,CAFA,YlDtGS,CkDoGX,MlD+uBoC,CAz0BzB,ckD0FX,OlD+uBoC,WkD7uBlC,ClD6uBkC,YkD3uBlC,sCzC7FE,+C2ChBF,UACA,+BpDi3BkC,0IoD/2BlC,YpD+2BkC,iFAhlBN,6BmD9R5B,CAHA,YAGA,8BAGA,gBADA,eAEA,6BAEA,aACA,cAFA,iBAEA,+BlDuKI,kBmDxKJ,C3CME,2C2CGA,CANF,4C3CGE,C2CJF,4BACA,CDAA,YlDqKI,gBmDxKJ,wBpDLS,eoDcP,iCAGA,uDAIE,YACA,eACA,CANF,6BAEA,WAIE,yBACA,8BACA,6EAKN,8BpDg2BoC,wFoD71BlC,wCACE,wGAGE,2BACA,8CpD21B8B,6FoDv1BhC,epD2L0B,2BoDzLxB,0BpD5CK,2CAi4ByB,oBoDh0BhC,CpDjEO,aoDkDX,CpD40BoC,wLoDr0BhC,CpDw0BgC,kBoDx0BhC,kCAIE,qBpDo0B8B,iBoDx0BhC,gBAPJ,QpD40BoC,CAzpBN,UArOnB,kBoDyDP,gCAEA,qBACE,iBACA,qBpDo0B8B,yDAj4BzB,YAqOmB,+BoDlKxB,2CpDnEK,gGA83ByB,sJoDjzBhC,iHAIE,wHAIF,qBpDgJ0B,CA4pBM,0BoD5yBhC,CpD4yBgC,KA5pBN,wFArOnB,qHoDgGP,YACA,CAFA,OACA,WACA,CpD4xBgC,mHoDpxBpC,uBpDqxBoC,CoDzxBhC,gCAIJ,CAJI,OpDyxBgC,0FoDlxBlC,uHAIE,2HpDixBgC,oDoD7wB9B,QpD6wB8B,sFA5pBN,gBoD3GxB,mGnDmDA,amD1BJ,QnD0BI,YDusB8B,iHS/1BhC,sB2CsIA,C3CtIA,iCADA,M2CuIA,gCCrJJ,qBACE,sBrDES,WoDsJX,eACE,qBpDvJS,kBqDFT,CAGF,yBnCIQ,oBmCiBR,CAGE,4BAHF,qBAGE,4CAnBA,aACA,CACA,wLASA,CnCZM,kBmCYN,kCAfA,MAGF,CnCDM,qBACE,iBmCYN,eACA,CAXA,eACA,CANA,kBAgBA,gCACA,sCnCfI,qBmCFJ,MnCGM,yDmCAR,YAoBE,iCAKA,0CAFF,iBAEE,yFAcA,kBACE,mBACA,CAXF,UASA,CATA,+BAWE,CACA,wMAGF,yBAIE,gHAMA,0BACA,CAFA,0BACA,CAHF,QAIE,8GnCxDI,sBADF,0BACE,CADF,UACE,wFmCqEN,iBAGA,sGrDy9BmC,YqDn9BnC,uBAEA,CrDi9BmC,cqD/8BnC,CrD+8BmC,WqD/8BnC,oHnClFM,8DmCiER,MnCjEQ,kHmCwFJ,uBrD08BiC,CAhjC1B,gCqDsGP,CnD7FF,QFuiCmC,0FqD/7BnC,wHrD48BmC,4IqD37BrC,8BAFE,0BAEF,CAFE,KAEF,oHAiBE,wBrD25BmC,CqD55BnC,0BACA,CAFA,OrD65BmC,wIA9iC1B,+BqDoKP,CrDpKO,WAsjC0B,aqDr5BjC,CrDq5BiC,SqDp5BjC,kBrDlKO,CAojC0B,iBAEA,OqDr5BjC,UAGA,sFAIA,kBACA,oGAGF,WACE,gBnC/JI,oCmC+JJ,kHAkBF,2BEjMA,CvDES,gCqD+LT,CAFA,OE/LA,gHAQA,sBACA,CvDmkCwB,gCuDpkCxB,CvDokCwB,SuDnkCxB,iCAGA,wBvDmkCwB,gCAEA,yCuDpjCxB,0CAEE,CAnBF,+BADA,oBAoBE,uCvD2iCsB,2CAEA,auDpiCxB,CvDoiCwB,oBuDpiCxB,2BAGA,0DACA,kBAGF,iCAME,gBvD0hCwB,4BuD1hCxB,uCACE,UAEE,YAFF,aAEE,gCC1DN,6DACA,CAFA,wBACA,mBADA,kBAEA,qCAFA,UAEA,uCACA,8CACA,gHACA,aCFE,0GACE,oIAKE,2BANJ,+CACE,gYvDUF,mCuDLI,CvDKJ,SuDLI,uCANJ,qHACE,2IADF,QACE,0DvDUF,CuDVE,UADF,kBACE,kBADF,MvDWA,6BuDVE,mBvDUF,uCuDXA,8EACE,sVvDUF,yFuDVE,mCADF,gCACE,CADF,UACE,6PvDUF,6CwDJF,iNCLA,sCACA,SACA,oCADA,OAEA,gBADA,eACA,CADA,gCADA,oCAEA,yCAIA,2BACA,CADA,sBACA,8BACA,CADA,4BAHA,mBAEA,eAFA,cACA,4CAGA,WAHA,kBACA,CAEA,2BAGE,CAPF,UAOE,uCACE,wCADF,eACE,+CADF,uDACE,qBADF,mBACE,iBADF,6BACE,4BADF,qDACE,kCAKF,6CAQA,CATF,kBACE,mBADF,8BACE,CANA,oBACE,YADF,uBACE,WAaF,oCAIA,8BADF,UACE,CAGF,6CACE,6DAMA,2CAGF,CAJE,6BACA,mBALA,oBAGF,aAEE,UAFF,sBACE,CADF,UAKA,kCACE,WACA,CADA,UACA,uCAGF,8DACE,uBACA,kCAGF,gCACE,4BAGF,4BACE,+BAGF,+BACE,CAGF,8BACE,+BLxEA,oCAGE,oCMOE,2/B/CiDF,kC+CjDE,sgB/CiDF,kC+CjDE,ogCAUN,uCAEI,wgBCrBJ,iCAEE,8BAEA,gCACA,8BAGE,+BACA,8MAGF,0BAQE,8BAGA,qEASA,yCACE,qJCzBF,2CDwBA,2CCxBA,+BAEA,2CADA,uCACA,6BACA,yFAEA,4DACA,qDACA,iCACA,sBADA,aACA,+CACA,mDACA,iCACA,wDACA,wEAEA,wFACA,qDACA,mFACA,0EACA,0FAEA,2DACA,oDACA,mFACA,8DACA,qFAEA,uDACA,+EACA,4DACA,kFACA,qDACA,6FAEA,wDACA,yDACA,uDACA,+EACA,4DACA,2DjDYA,uBiDlDA,oDACA,8FACA,wDACA,sFAEA,sDACA,oDACA,4DACA,2DACA,oDACA,wDACA,6DACA,wDAEA,sFACA,mEACA,gGACA,8DACA,8EAEA,oGACA,2DACA,4DACA,iEACA,6BAEA,CAFA,sCAEA,8RAIA,qCADA,iBACA,iEACA,wEAEA,iEACA,8DACA,2CACA,yFACA,uEACA,sCjDYA,uCiDlDA,oDACA,4FACA,4DACA,0EAEA,mDACA,uDACA,+FACA,oCACA,sCACA,2EACA,0EACA,uCAEA,+EACA,oEACA,qGACA,mEACA,iGAEA,wEACA,oEACA,qEACA,6EACA,uCAEA,4EACA,0FACA,kEACA,+DACA,oGACA,kEAEA,qDACA,yDACA,sGACA,oCACA,gFACA,uDjDYA,iCiDlDA,iEACA,+DACA,6EACA,sDAEA,0DACA,qGACA,oCACA,2EACA,4CACA,6EACA,uCACA,kFAEA,uEACA,mEACA,oEACA,yEACA,8GAEA,yEACA,iCACA,uEACA,gFACA,8EAEA,0EACA,8DACA,qEACA,wGACA,oEACA,qEAEA,sDACA,yDACA,sGACA,oCACA,gFACA,uDjDYA,iCiDlDA,iEACA,+DACA,6EACA,uDAEA,yDACA,qGACA,oCACA,2EACA,4CACA,6EACA,uCACA,kFAEA,uEACA,mEACA,oEACA,iHACA,sEAEA,yEACA,0EACA,8BACA,gFACA,8EAEA,0EACA,8DACA,qEACA,wGACA,oEACA,qEAEA,sDACA,0DACA,qGACA,oCACA,gFACA,uDC1CA,2DACA,uCACA,+DlDoDA,uBkDtDA,sDACA,sDACA,mClDoDA,0DkDtDA,uBACA,+EACA,yClDoDA,kCkDtDA,4CACA,6EACA,uCAFA,kFACA,uCACA,qECLF,kYCCA,qVAOA,yBjEmqBkC,sCiE7pBpC,+BAIE,oCjEypBkC,oEiErpBpC,oEjEopBoC,6BkEvqBlC,wCAGA,4BAEA,2BACA,6BAEA,4FAaE,sCAGA,oCACA,yCC7BJ,sEACA,yDACA,iGACA,+BCCI,6bAIJ,6EACA,uCAIA,4CACA,uCAEA,sEACA,qCCTQ,sEAGE,sEAIA,uEAIA,sEAIA,kCAfF,uEACA,0CAEE,8BAEF,2CAEE,qCAEF,0CAEE,oCAIA,2CAfF,oEACA,yBAEE,sCAEF,+BAEE,oCAEF,6BAEE,uCAEF,2BAEE,yCAfF,qEACA,4BAEE,8BAEF,oBAEE,mDAEF,6BAEE,6CAEF,+BAEE,oBAfF,sDACA,gCAEE,8CAEF,+BAEE,qDAEF,qBAEE,oDAEF,0BAEE,+BAfF,qDACA,qBAEE,oDAEF,2BAEE,+BAEF,qDAEE,qBAEF,gCAEE,oBAfF,oEACA,0BAEE,mCAEF,kCAEE,8DAIA,6DAEF,CAEE,+BAfF,kFACA,kCAEE,yBAEF,oCAEE,+DAIA,4DAEF,wBAEE,kCAfF,2DACA,4BAIA,OAFE,6BAEF,2CAEE,QAEF,QAFE,uBAEF,uEAIA,4BAEE,uBAfF,8DAKA,kBAEE,UAJA,sCAEF,CAFE,UAFF,kBAME,mBANF,SAME,oFAPF,UAaA,WAEE,kBAJA,eAEF,CAbA,mBAaA,UAbA,kFAGE,oEAIA,6EAIA,uDAEF,uBAEE,mBAfF,iEACA,mBAEE,4CAEF,yBAEE,2CAEF,2CAEE,2CAEF,oBAEE,wBAQF,mEACA,iDAEE,yBAEF,sDAEE,yBAEF,uDAEE,yBAEF,8CAEE,sBAfF,qFAGE,mEAEF,wBAEE,6CAEF,yBAEE,6CAEF,uBAEE,sBAfF,oEACA,2BAEE,6CAEF,6BAEE,6CAEF,8BAEE,yEAIA,4CAfF,uEACA,6CAEE,4BAEF,6CAEE,6BAEF,6CAEE,2BAEF,sBAEE,qBAfF,sEACA,6CAEE,2BAEF,6CAEE,4BAEF,6CAEE,gDAEF,uBAEE,6CAMN,wEAGE,0EAIA,2EAEF,4BAEE,2CAEF,6CxDPA,yBwDlDI,wEACA,6CAEE,4BAEF,6CAEE,0BAEF,sBAEE,gEAIA,wBAfF,kHAGE,uEAIA,sEAEF,6CAEE,4BAEF,6CAbA,2EACA,+BAEE,6CAEF,6BAEE,6CAEF,6CAEE,wEAIA,6BAfF,2EACA,6CAEE,4BAEF,sBAEE,mEAIA,uEAEF,4BAEE,6CAfF,0EAGE,iDAEF,wBAEE,6CAEF,4BAEE,2EAEF,6CAbA,4EACA,6BAEE,4CAEF,6CAEE,0BAEF,6CAEE,4BAEF,6CAEE,6BAfF,6CACA,2BAEE,+CAEF,+CAEE,4BAEF,+CAEE,8BAEF,+CAbA,8EACA,6BAEE,8CAEF,+CAEE,2BAEF,+CAEE,4EAIA,8BAfF,2EACA,uBAEE,qEAIA,yEAEF,4BAEE,+CAEF,6BAEE,+CAfF,4BACA,8CAEE,+CAEF,4BAEE,+CAEF,8BAEE,+CAEF,+BAEE,+CAfF,oDACA,sBAEE,+CAEF,yEAEE,4BAEF,+CAEE,6BAEF,+CAbA,yEACA,mDAEE,yBAEF,mDAEE,2BAEF,mDAEE,4BAEF,mDAUA,2EACA,qEAEE,sBAEF,mDAEE,wBAEF,mDAEE,4EAIA,uBAfF,mGAGE,8EAIA,gFAEF,8BAEE,mDAEF,4BAEE,yBAfF,yEACA,0BAEE,mDAEF,4BAEE,mDAEF,6BAEE,mDAEF,2BAEE,yBAfF,wEACA,yBAEE,mDAEF,2BAEE,+EAEF,mDAEE,0BAEF,yBAEE,uBAfF,8EACA,mDAEE,6BAEF,mDAEE,8BAEF,mDAEE,4BAEF,yBAEE,qBAMN,4EACA,mDAEE,2BAEF,mDAEE,+EAIA,mDAEF,mBAEE,mDA3DE,0EACA,yBAEE,mDAEF,0BAEE,mDAEF,wBAEE,iDAEF,mDAbA,+EACA,8BAEE,mDAEF,+BAEE,mDAEF,6BAEE,gDAEF,mDAbA,8EACA,6BAEE,mDAEF,8BAEE,mDAEF,4BAEE,yBAEF,yEAbA,6EAGE,+EAIA,gFAIA,oDAEF,wBAEE,mDAfF,+EAGE,iFAIA,kFAIA,sDAEF,sBAEE,mDAfF,6EAGE,+EAIA,gFAIA,qDAEF,wBAEE,qDAfF,4BACA,qDAEE,8BAEF,qDAEE,+BAEF,qDAEE,6BAIA,0BAfF,4EACA,2BAEE,qDAEF,6BAEE,qDAEF,8BAEE,qDAEF,4BAEE,0BAfF,2EACA,0BAEE,qDAEF,4BAEE,qDAEF,6BAEE,qDAEF,2BAEE,0BAfF,6EACA,4BAEE,qDAEF,8BAEE,qDAEF,+BAEE,qDAIA,6BAfF,qGAGE,+EAIA,iFAIA,kFAIA,2BAfF,0GAGE,kFAIA,oFAIA,4BAEF,yDAUA,4EACA,qEAEE,sBAEF,mDAEE,wBAEF,mDAEE,4EAIA,uBAfF,mGAGE,8EAIA,gFAEF,8BAEE,mDAEF,4BAEE,yBAfF,yEACA,0BAEE,mDAEF,4BAEE,mDAEF,6BAEE,mDAEF,2BAEE,yBAfF,wEACA,yBAEE,mDAEF,2BAEE,+EAEF,mDAEE,0BAEF,yBAEE,uBAfF,8EACA,mDAEE,6BAEF,mDAEE,8BAEF,mDAEE,4BAEF,yBAEE,qBAMN,4EACA,mDAEE,2BAEF,mDAEE,+EAIA,mDAEF,mBAEE,mDA3DE,0EACA,yBAEE,mDAEF,0BAEE,mDAEF,wBAEE,iDAEF,mDAbA,+EACA,8BAEE,mDAEF,+BAEE,mDAEF,6BAEE,gDAEF,mDAbA,8EACA,6BAEE,mDAEF,8BAEE,mDAEF,4BAEE,yBAEF,yEAbA,6EAGE,+EAIA,gFAIA,oDAEF,wBAEE,mDAfF,+EAGE,iFAIA,kFAIA,sDAEF,sBAEE,mDAfF,6EAGE,+EAIA,gFAIA,qDAEF,wBAEE,qDAfF,4BACA,qDAEE,8BAEF,qDAEE,+BAEF,qDAEE,6BAIA,0BAfF,4EACA,2BAEE,qDAEF,6BAEE,qDAEF,8BAEE,qDAEF,4BAEE,0BAfF,2EACA,0BAEE,qDAEF,4BAEE,qDAEF,6BAEE,qDAEF,2BAEE,0BAfF,6EACA,4BAEE,qDAEF,8BAEE,qDAEF,+BAEE,qDAIA,6BAfF,qGAGE,+EAIA,iFAIA,kFAIA,2BAfF,0GAGE,kFAIA,oFAIA,4BAEF,yDAUA,4EACA,qEAEE,sBAEF,mDAEE,wBAEF,mDAEE,4EAIA,uBAfF,mGAGE,8EAIA,gFAEF,8BAEE,mDAEF,4BAEE,yBAfF,yEACA,0BAEE,mDAEF,4BAEE,mDAEF,6BAEE,mDAEF,2BAEE,yBAfF,wEACA,yBAEE,mDAEF,2BAEE,+EAEF,mDAEE,0BAEF,yBAEE,uBAfF,8EACA,mDAEE,6BAEF,mDAEE,8BAEF,mDAEE,4BAEF,yBAEE,qBAMN,4EACA,mDAEE,2BAEF,mDAEE,+EAIA,mDAEF,mBAEE,mDA3DE,0EACA,yBAEE,mDAEF,0BAEE,mDAEF,wBAEE,iDAEF,mDAbA,+EACA,8BAEE,mDAEF,+BAEE,mDAEF,6BAEE,gDAEF,mDAbA,8EACA,6BAEE,mDAEF,8BAEE,mDAEF,4BAEE,yBAEF,yEAbA,6EAGE,+EAIA,gFAIA,oDAEF,wBAEE,mDAfF,+EAGE,iFAIA,kFAIA,sDAEF,sBAEE,mDAfF,6EAGE,+EAIA,gFAIA,qDAEF,wBAEE,qDAfF,4BACA,qDAEE,8BAEF,qDAEE,+BAEF,qDAEE,6BAIA,0BAfF,4EACA,2BAEE,qDAEF,6BAEE,qDAEF,8BAEE,qDAEF,4BAEE,0BAfF,2EACA,0BAEE,qDAEF,4BAEE,qDAEF,6BAEE,qDAEF,2BAEE,0BAfF,6EACA,4BAEE,qDAEF,8BAEE,qDAEF,+BAEE,qDAIA,6BAfF,qGAGE,+EAIA,iFAIA,kFAIA,2BAfF,0GAGE,kFAIA,oFAIA,6BAEF,wDAUA,6EACA,qEAEE,sBAEF,mDAEE,wBAEF,mDAEE,4EAIA,uBAfF,mGAGE,8EAIA,gFAEF,8BAEE,mDAEF,4BAEE,yBAfF,yEACA,0BAEE,mDAEF,4BAEE,mDAEF,6BAEE,mDAEF,2BAEE,yBAfF,wEACA,yBAEE,mDAEF,2BAEE,+EAEF,mDAEE,0BAEF,yBAEE,uBAfF,8EACA,mDAEE,6BAEF,mDAEE,8BAEF,mDAEE,4BAEF,yBAEE,qBAMN,4EACA,mDAEE,2BAEF,mDAEE,+EAIA,mDAEF,mBAEE,mDChEJ,uBAGE,CACA,kDAKA,4ECRJ,8HAIA,2EACA,4BACA,iFCRE,mDAEA,+BDeE,mDACA,sDACA,0EAFA,8EACA,gFACA,8B1DqCA,mD0DvCA,4BACA,+CACA,6E1DqCA,mD0DvCA,4BACA,mDACA,gFAFA,4EACA,mDACA,+EAMJ,iFACA,+BACA,gFAIA,+CACA,6EACA,mDACA,+EACA,gFACA,2BAIA,kDEvCE,qDACE,iFAKI,8BALJ,oFvEUF,qDuEXA,6BACE,sGAKI,2BANN,qDACE,6BvEUF,qDuEXA,8BACE,iFAKI,gDANN,qDACE,0BvEUF,qDuEXA,4BACE,kFvEUF,qDuEXA,2BACE,kDvEUF,qDqEkCF,iFACA,8BAEA,qDACA,oFGnDE,6BAEA,0BACA,sBACA,qDHuDF,+EAGE,4BACA,qDAKF,6BIjEA,qDAIA,2BACE,4BIRS,qBASA,kFHyBT,yDGxBS,2BH6BP,yDAGA,4BAGF,yDGvCS,0BH6CT,wCAOE,uBALA,QAEF,CAGE,WAHF,OACE,mBAEA,CALA,gCAEF,SAGE,iCGjDO,gGHyDP,mHAGF,8BG3DS,4BH+DP,qHAEA,yBACE,6BAKF,0BACA,yDAGF,yBACE,8BAEA,yBACA,gCAGF,2BACE,2DACA,wDAEA,yBAKF,gCAIA,0BACE,4DAIA,wDAIA,yDAIA,+IAMA,yBAEA,0DAGF,iCACE,4BAIF,iCACE,kCAEA,iCAIA,kCAGF,kCACE,mCAIA,oCAGF,yBACE,sCAGF,6BAEE,qCACA,yBAIA,mCACA,yBAEA,qCAGA,4BACA,8BAGF,2BAEE,6BACA,mDAIA,uBAEA,2EAIA,+EAGF,+EAKE,6EAGF,2EAEE,uBAKA,mDAGF,qEAKE,uBAGF,+BACE,kGAIA,uBAIA,8BAGF,uBACE,yEAGA,uBAIA,6BAEA,uBACA,uEAKA,uBAGF,4BAEE,uBACA,qEAGA,uBAGF,4BACE,oDAIA,uDAIA,yBAIA,gCAGF,yBAKE,4BAKA,wBAGF,UAPE,WAGF,CAHE,WAGF,gBAIA,uCAEE,8BACA,6BAIA,+BAHA,+BAGA,6BAIA,uBACA,sDAIA,4BAEA,2BAGF,6BACE,kBAGF,CAHE,UAGF,CACE,2BACA,wBAGF,8BAIE,wBAIA,yBACA,kBAGF,CARE,WAHA,aACA,CACA,cACA,CAFA,YACA,CACA,oBAQF,8BAIA,aACE,CAJA,WAGF,gBACE,gDAEA,eACA,yBAGF,2CAIE,mCACA,iDAEA,kBACA,6CAIA,iDACA,CAFA,aAEA,6GAMF","sources":["../node_modules/tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.min.css","pages/targets/ScrapePoolPanel.module.css","pages/targets/TargetLabels.module.css","thanos/pages/notFound/NotFound.module.css","thanos/pages/errorBoundary/ErrorBoundary.module.css","thanos/pages/blocks/blocks.module.css","../node_modules/rc-slider/assets/index.css","themes/app.scss","themes/light.scss","../node_modules/bootstrap/scss/_reboot.scss","../node_modules/bootstrap/scss/_variables.scss","../node_modules/bootstrap/scss/vendor/_rfs.scss","../node_modules/bootstrap/scss/mixins/_hover.scss","themes/_bootstrap_light.scss","../node_modules/bootstrap/scss/_root.scss","../node_modules/bootstrap/scss/_type.scss","../node_modules/bootstrap/scss/mixins/_lists.scss","../node_modules/bootstrap/scss/mixins/_image.scss","../node_modules/bootstrap/scss/_images.scss","../node_modules/bootstrap/scss/mixins/_border-radius.scss","../node_modules/bootstrap/scss/_code.scss","../node_modules/bootstrap/scss/mixins/_grid.scss","../node_modules/bootstrap/scss/_grid.scss","../node_modules/bootstrap/scss/mixins/_breakpoints.scss","../node_modules/bootstrap/scss/mixins/_grid-framework.scss","../node_modules/bootstrap/scss/_tables.scss","../node_modules/bootstrap/scss/mixins/_table-row.scss","../node_modules/bootstrap/scss/_forms.scss","../node_modules/bootstrap/scss/mixins/_transition.scss","../node_modules/bootstrap/scss/mixins/_forms.scss","../node_modules/@forevolve/bootstrap-dark/scss/mixins-overrides/_dark-forms.scss","../node_modules/@forevolve/bootstrap-dark/scss/_form-overrides.scss","../node_modules/bootstrap/scss/_buttons.scss","../node_modules/bootstrap/scss/mixins/_buttons.scss","../node_modules/bootstrap/scss/_transitions.scss","../node_modules/bootstrap/scss/_dropdown.scss","../node_modules/bootstrap/scss/mixins/_caret.scss","../node_modules/bootstrap/scss/mixins/_nav-divider.scss","../node_modules/bootstrap/scss/_button-group.scss","../node_modules/bootstrap/scss/_input-group.scss","../node_modules/bootstrap/scss/_custom-forms.scss","../node_modules/bootstrap/scss/_nav.scss","../node_modules/bootstrap/scss/_navbar.scss","../node_modules/bootstrap/scss/_card.scss","../node_modules/bootstrap/scss/_breadcrumb.scss","../node_modules/bootstrap/scss/_pagination.scss","../node_modules/bootstrap/scss/mixins/_pagination.scss","../node_modules/bootstrap/scss/_badge.scss","../node_modules/bootstrap/scss/mixins/_badge.scss","../node_modules/bootstrap/scss/_jumbotron.scss","../node_modules/bootstrap/scss/_alert.scss","../node_modules/bootstrap/scss/mixins/_alert.scss","../node_modules/bootstrap/scss/_progress.scss","../node_modules/bootstrap/scss/mixins/_gradients.scss","../node_modules/bootstrap/scss/_media.scss","../node_modules/bootstrap/scss/_list-group.scss","../node_modules/bootstrap/scss/mixins/_list-group.scss","../node_modules/bootstrap/scss/_close.scss","../node_modules/bootstrap/scss/_toasts.scss","../node_modules/bootstrap/scss/_modal.scss","../node_modules/bootstrap/scss/_tooltip.scss","../node_modules/bootstrap/scss/mixins/_reset-text.scss","../node_modules/bootstrap/scss/_popover.scss","../node_modules/bootstrap/scss/_carousel.scss","../node_modules/bootstrap/scss/mixins/_clearfix.scss","../node_modules/bootstrap/scss/_spinners.scss","../node_modules/bootstrap/scss/utilities/_align.scss","../node_modules/bootstrap/scss/mixins/_background-variant.scss","../node_modules/bootstrap/scss/utilities/_background.scss","../node_modules/bootstrap/scss/utilities/_borders.scss","../node_modules/bootstrap/scss/utilities/_display.scss","../node_modules/bootstrap/scss/utilities/_embed.scss","../node_modules/bootstrap/scss/utilities/_flex.scss","../node_modules/bootstrap/scss/utilities/_float.scss","../node_modules/bootstrap/scss/utilities/_interactions.scss","../node_modules/bootstrap/scss/utilities/_position.scss","../node_modules/bootstrap/scss/mixins/_screen-reader.scss","../node_modules/bootstrap/scss/utilities/_shadows.scss","../node_modules/bootstrap/scss/utilities/_sizing.scss","../node_modules/bootstrap/scss/utilities/_spacing.scss","../node_modules/bootstrap/scss/utilities/_stretched-link.scss","../node_modules/bootstrap/scss/utilities/_text.scss","../node_modules/bootstrap/scss/mixins/_text-truncate.scss","../node_modules/bootstrap/scss/mixins/_text-emphasis.scss","../node_modules/bootstrap/scss/mixins/_text-hide.scss","../node_modules/bootstrap/scss/utilities/_visibility.scss","themes/_shared.scss","themes/dark.scss","themes/_bootstrap_dark.scss","../node_modules/@forevolve/bootstrap-dark/scss/_dark-variables.scss","../node_modules/@forevolve/bootstrap-dark/scss/mixins/_dark-table-row.scss","../node_modules/@forevolve/bootstrap-dark/scss/_dark-tables.scss","../node_modules/@forevolve/bootstrap-dark/scss/_dark-input-group.scss"],"sourcesContent":["/*!@preserve\r\n * Tempus Dominus Bootstrap4 v5.39.0 (https://tempusdominus.github.io/bootstrap-4/)\r\n * Copyright 2016-2020 Jonathan Peterson and contributors\r\n * Licensed under MIT (https://github.com/tempusdominus/bootstrap-3/blob/master/LICENSE)\r\n */.bootstrap-datetimepicker-widget .btn[data-action=clear]::after,.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]::after,.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]::after,.bootstrap-datetimepicker-widget .btn[data-action=incrementHours]::after,.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]::after,.bootstrap-datetimepicker-widget .btn[data-action=showHours]::after,.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]::after,.bootstrap-datetimepicker-widget .btn[data-action=today]::after,.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]::after,.bootstrap-datetimepicker-widget .picker-switch::after,.bootstrap-datetimepicker-widget table th.next::after,.bootstrap-datetimepicker-widget table th.prev::after,.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}body.tempusdominus-bootstrap-datetimepicker-widget-day-click,body.tempusdominus-bootstrap-datetimepicker-widget-day-click *{cursor:pointer!important}body.tempusdominus-bootstrap-datetimepicker-widget-day-click{position:relative!important}.tempusdominus-bootstrap-datetimepicker-widget-day-click-glass-panel{position:absolute;z-index:999999999999;top:0;left:0;right:0;bottom:0;cursor:pointer!important}.bootstrap-datetimepicker-widget .datepicker-days tbody td{cursor:pointer}.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{display:block;margin:2px 0;padding:4px;width:14rem}.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons{width:16rem}.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks{width:16rem}.bootstrap-datetimepicker-widget.dropdown-menu.tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks.tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons{width:17rem}@media (min-width:576px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:after,.bootstrap-datetimepicker-widget.dropdown-menu:before{content:\"\";display:inline-block;position:absolute}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before{border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);top:-7px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after{border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;top:-6px;left:8px}.bootstrap-datetimepicker-widget.dropdown-menu.top:before{border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:after{border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.float-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.dropdown-menu.float-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget.dropdown-menu.wider{width:16rem}.bootstrap-datetimepicker-widget .list-unstyled{margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:54px;font-weight:700;font-size:1.2em;margin:0}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]{text-align:center;font-family:Arial,sans-serif,-apple-system,system-ui,\"Segoe UI\",Roboto,\"Helvetica Neue\",\"Noto Sans\",\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";width:38px;height:38px}.bootstrap-datetimepicker-widget .btn[data-action=incrementHours]::after{content:\"Increment Hours\"}.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]::after{content:\"Increment Minutes\"}.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]::after{content:\"Decrement Hours\"}.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]::after{content:\"Decrement Minutes\"}.bootstrap-datetimepicker-widget .btn[data-action=showHours]::after{content:\"Show Hours\"}.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]::after{content:\"Show Minutes\"}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]::after{content:\"Toggle AM/PM\"}.bootstrap-datetimepicker-widget .btn[data-action=clear]::after{content:\"Clear the picker\"}.bootstrap-datetimepicker-widget .btn[data-action=today]::after{content:\"Set the date to today\"}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget .picker-switch::after{content:\"Toggle Date and Time Screens\"}.bootstrap-datetimepicker-widget .picker-switch td{padding:0;margin:0;height:auto;width:auto;line-height:inherit}.bootstrap-datetimepicker-widget .picker-switch td span{line-height:2.5;height:2.5em;width:100%}.bootstrap-datetimepicker-widget .picker-switch.picker-switch-with-feathers-icons td span{line-height:2.8;height:2.8em}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget table td,.bootstrap-datetimepicker-widget table th{text-align:center;border-radius:.25rem}.bootstrap-datetimepicker-widget table th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table th.picker-switch{width:145px}.bootstrap-datetimepicker-widget table th.disabled,.bootstrap-datetimepicker-widget table th.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget table th.prev::after{content:\"Previous Month\"}.bootstrap-datetimepicker-widget table th.next::after{content:\"Next Month\"}.bootstrap-datetimepicker-widget table thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#e9ecef}.bootstrap-datetimepicker-widget table td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget table td.cw{font-size:.8em;height:20px;line-height:20px;color:#6c757d;cursor:default}.bootstrap-datetimepicker-widget table td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table td.day:hover,.bootstrap-datetimepicker-widget table td.hour:hover,.bootstrap-datetimepicker-widget table td.minute:hover,.bootstrap-datetimepicker-widget table td.second:hover{background:#e9ecef;cursor:pointer}.bootstrap-datetimepicker-widget table td.new,.bootstrap-datetimepicker-widget table td.old{color:#6c757d}.bootstrap-datetimepicker-widget table td.today{position:relative}.bootstrap-datetimepicker-widget table td.today:before{content:\"\";display:inline-block;border:solid transparent;border-width:0 0 7px 7px;border-bottom-color:#007bff;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget table td.active,.bootstrap-datetimepicker-widget table td.active:hover{background-color:#007bff;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget table td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget table td.disabled,.bootstrap-datetimepicker-widget table td.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget table td span{display:inline-block;width:54px;height:54px;line-height:54px;margin-top:2px;margin-bottom:2px;cursor:pointer;border-radius:.25rem}.bootstrap-datetimepicker-widget table td span:hover{background:#e9ecef}.bootstrap-datetimepicker-widget table td span.active{background-color:#007bff;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget table td span.old{color:#6c757d}.bootstrap-datetimepicker-widget table td span.disabled,.bootstrap-datetimepicker-widget table td span.disabled:hover{background:0 0;color:#6c757d;cursor:not-allowed}.bootstrap-datetimepicker-widget.usetwentyfour td.hour{height:27px;line-height:27px}.bootstrap-datetimepicker-widget .timepicker .timepicker-picker a.btn{color:#007bff;color:var(--blue,#007bff)}.bootstrap-datetimepicker-widget .timepicker .timepicker-picker a.btn:hover{color:#0056b3}.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showHours],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showMinutes],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showSeconds],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=togglePeriod],.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.day,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.hour,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.minute,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.second{pointer-events:none;cursor:default}.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=decrementSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=incrementSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showHours]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showMinutes]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=showSeconds]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td [data-action=togglePeriod]:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.day:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.hour:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.minute:hover,.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget-readonly table td.second:hover{background:0 0}.input-group [data-toggle=datetimepicker]{cursor:pointer}",".container {\n margin-top: -12px;\n}\n\n.title {\n font-size: 20px;\n font-weight: bold;\n cursor: pointer;\n}\n\n.normal {\n composes: title;\n}\n\n.danger {\n composes: title;\n color: rgb(242, 65, 65);\n}\n\n.table {\n width: 100%;\n}\n\n.cell {\n height: auto;\n word-wrap: break-word;\n word-break: break-all;\n}\n\n.endpoint, .labels {\n composes: cell;\n width: 25%;\n}\n\n.state, .last-scrape {\n composes: cell;\n width: 10%;\n}\n\n.errors {\n composes: cell;\n width: 30%;\n}\n",".discovered {\n white-space: nowrap;\n}\n",".container{\n width: 100%;\n height: 85vh;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n}",".container {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n}\n\nbutton.detailsBtn {\n font-size: 1.2em;\n margin: 2em 0;\n}\n\n.errorDiv {\n white-space: pre-wrap;\n font-family: monospace;\n}\n",".container {\n display: flex;\n --top: 72px;\n min-height: calc(100vh - var(--top));\n position: relative;\n z-index: 1;\n}\n\n.grid {\n width: 100%;\n}\n\n.sources {\n max-height: calc(100vh - 2 * var(--top));\n overflow-y: auto;\n scrollbar-color: #b1b1b1 transparent;\n scrollbar-width: thin;\n}\n\n.sources::-webkit-scrollbar {\n width: 8px;\n}\n\n.sources::-webkit-scrollbar-thumb {\n background-color: #b1b1b1;\n border-radius: 6px;\n}\n\n.blockDetails {\n width: 0;\n overflow-x: hidden;\n overflow-y: auto;\n min-width: 0;\n max-width: 55vw;\n box-sizing: border-box;\n transition: all 0.2s ease-in-out;\n margin-top: -16px;\n margin-right: -15px;\n}\n\n.blockDetails.open {\n min-width: 420px;\n padding: 2em;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n}\n\n.detailsTop {\n width: 100%;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap-reverse;\n}\n\n.header {\n margin: 0;\n padding: 0;\n font-weight: 700;\n font-size: 1.1em;\n}\n\n.closeBtn {\n border: none;\n background: none;\n font-size: 2em;\n transform: translateY(-10%);\n}\n\n.timeRangeDiv {\n box-sizing: border-box;\n padding: 0em 3em;\n display: flex;\n justify-content: space-evenly;\n flex-direction: column;\n align-items: center;\n height: var(--top);\n}\n\n.timeRange {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.9em;\n width: 100%;\n}\n\n.source {\n width: 100%;\n display: flex;\n align-items: center;\n}\n\n.title {\n box-sizing: border-box;\n padding: 0 1em;\n}\n\n.title > span {\n display: block;\n width: 8vw;\n margin: 0;\n text-align: center;\n text-overflow: ellipsis;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.rowsContainer {\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n border-left: solid 3px teal;\n}\n\n.row {\n width: 100%;\n position: relative;\n --block-height: 1.2em;\n height: var(--block-height);\n box-sizing: content-box;\n margin: 0.1em 0;\n overflow-x: hidden;\n}\n\n.blockSpan {\n position: absolute;\n border: none;\n height: 100%;\n min-width: 0.5%;\n padding: 0;\n margin: 0;\n min-width: 0;\n box-sizing: border-box;\n mix-blend-mode: multiply;\n}\n\n.blockSpan:hover,\n.blockSpan:focus {\n outline: none;\n box-shadow: 0 0 0 0.2rem rgba(0, 0, 0, 0.3) inset;\n}\n\n/*\n* block colors\n* https://coolors.co/9b5de5-f15bb5-fee440-00bbf9-00f5d4\n*/\n.res-0 {\n --level-1: #bd96ee;\n --level-2: #9250e2;\n --level-3: #7c2cdd;\n --level-4: #681fc1;\n --level-5: #4c178c;\n --level-6: #391169;\n}\n\n.res-300000 {\n --level-1: #f15bb5;\n --level-2: #ef43aa;\n --level-3: #eb1e99;\n --level-4: #ce1283;\n --level-5: #a90f6b;\n --level-6: #830b53;\n}\n\n.res-3600000 {\n --level-1: #70dbff;\n --level-2: #47d1ff;\n --level-3: #1fc7ff;\n --level-4: #00b8f5;\n --level-5: #0099cc;\n --level-6: #007aa3;\n}\n\n.level-1 {\n background: var(--level-1);\n}\n.level-2 {\n background: var(--level-2);\n}\n.level-3 {\n background: var(--level-3);\n}\n.level-4 {\n background: var(--level-4);\n}\n.level-5 {\n background: var(--level-5);\n}\n.level-6 {\n background: var(--level-6);\n}\n\n.blockInput {\n margin-bottom: 12px;\n}\n\n.blockFilter {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n",".rc-slider {\n position: relative;\n height: 14px;\n padding: 5px 0;\n width: 100%;\n border-radius: 6px;\n touch-action: none;\n box-sizing: border-box;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n.rc-slider * {\n box-sizing: border-box;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n.rc-slider-rail {\n position: absolute;\n width: 100%;\n background-color: #e9e9e9;\n height: 4px;\n border-radius: 6px;\n}\n.rc-slider-track {\n position: absolute;\n left: 0;\n height: 4px;\n border-radius: 6px;\n background-color: #abe2fb;\n}\n.rc-slider-handle {\n position: absolute;\n width: 14px;\n height: 14px;\n cursor: pointer;\n cursor: -webkit-grab;\n margin-top: -5px;\n cursor: grab;\n border-radius: 50%;\n border: solid 2px #96dbfa;\n background-color: #fff;\n touch-action: pan-x;\n}\n.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {\n border-color: #57c5f7;\n box-shadow: 0 0 0 5px #96dbfa;\n}\n.rc-slider-handle:focus {\n outline: none;\n}\n.rc-slider-handle-click-focused:focus {\n border-color: #96dbfa;\n box-shadow: unset;\n}\n.rc-slider-handle:hover {\n border-color: #57c5f7;\n}\n.rc-slider-handle:active {\n border-color: #57c5f7;\n box-shadow: 0 0 5px #57c5f7;\n cursor: -webkit-grabbing;\n cursor: grabbing;\n}\n.rc-slider-mark {\n position: absolute;\n top: 18px;\n left: 0;\n width: 100%;\n font-size: 12px;\n}\n.rc-slider-mark-text {\n position: absolute;\n display: inline-block;\n vertical-align: middle;\n text-align: center;\n cursor: pointer;\n color: #999;\n}\n.rc-slider-mark-text-active {\n color: #666;\n}\n.rc-slider-step {\n position: absolute;\n width: 100%;\n height: 4px;\n background: transparent;\n}\n.rc-slider-dot {\n position: absolute;\n bottom: -2px;\n margin-left: -4px;\n width: 8px;\n height: 8px;\n border: 2px solid #e9e9e9;\n background-color: #fff;\n cursor: pointer;\n border-radius: 50%;\n vertical-align: middle;\n}\n.rc-slider-dot-active {\n border-color: #96dbfa;\n}\n.rc-slider-dot-reverse {\n margin-right: -4px;\n}\n.rc-slider-disabled {\n background-color: #e9e9e9;\n}\n.rc-slider-disabled .rc-slider-track {\n background-color: #ccc;\n}\n.rc-slider-disabled .rc-slider-handle,\n.rc-slider-disabled .rc-slider-dot {\n border-color: #ccc;\n box-shadow: none;\n background-color: #fff;\n cursor: not-allowed;\n}\n.rc-slider-disabled .rc-slider-mark-text,\n.rc-slider-disabled .rc-slider-dot {\n cursor: not-allowed !important;\n}\n.rc-slider-vertical {\n width: 14px;\n height: 100%;\n padding: 0 5px;\n}\n.rc-slider-vertical .rc-slider-rail {\n height: 100%;\n width: 4px;\n}\n.rc-slider-vertical .rc-slider-track {\n left: 5px;\n bottom: 0;\n width: 4px;\n}\n.rc-slider-vertical .rc-slider-handle {\n margin-left: -5px;\n touch-action: pan-y;\n}\n.rc-slider-vertical .rc-slider-mark {\n top: 0;\n left: 18px;\n height: 100%;\n}\n.rc-slider-vertical .rc-slider-step {\n height: 100%;\n width: 4px;\n}\n.rc-slider-vertical .rc-slider-dot {\n left: 2px;\n margin-bottom: -4px;\n}\n.rc-slider-vertical .rc-slider-dot:first-child {\n margin-bottom: -4px;\n}\n.rc-slider-vertical .rc-slider-dot:last-child {\n margin-bottom: -4px;\n}\n.rc-slider-tooltip-zoom-down-enter,\n.rc-slider-tooltip-zoom-down-appear {\n animation-duration: 0.3s;\n animation-fill-mode: both;\n display: block !important;\n animation-play-state: paused;\n}\n.rc-slider-tooltip-zoom-down-leave {\n animation-duration: 0.3s;\n animation-fill-mode: both;\n display: block !important;\n animation-play-state: paused;\n}\n.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,\n.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {\n animation-name: rcSliderTooltipZoomDownIn;\n animation-play-state: running;\n}\n.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {\n animation-name: rcSliderTooltipZoomDownOut;\n animation-play-state: running;\n}\n.rc-slider-tooltip-zoom-down-enter,\n.rc-slider-tooltip-zoom-down-appear {\n transform: scale(0, 0);\n animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\n}\n.rc-slider-tooltip-zoom-down-leave {\n animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);\n}\n@keyframes rcSliderTooltipZoomDownIn {\n 0% {\n opacity: 0;\n transform-origin: 50% 100%;\n transform: scale(0, 0);\n }\n 100% {\n transform-origin: 50% 100%;\n transform: scale(1, 1);\n }\n}\n@keyframes rcSliderTooltipZoomDownOut {\n 0% {\n transform-origin: 50% 100%;\n transform: scale(1, 1);\n }\n 100% {\n opacity: 0;\n transform-origin: 50% 100%;\n transform: scale(0, 0);\n }\n}\n.rc-slider-tooltip {\n position: absolute;\n left: -9999px;\n top: -9999px;\n visibility: visible;\n box-sizing: border-box;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n.rc-slider-tooltip * {\n box-sizing: border-box;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n.rc-slider-tooltip-hidden {\n display: none;\n}\n.rc-slider-tooltip-placement-top {\n padding: 4px 0 8px 0;\n}\n.rc-slider-tooltip-inner {\n padding: 6px 2px;\n min-width: 24px;\n height: 24px;\n font-size: 12px;\n line-height: 1;\n color: #fff;\n text-align: center;\n text-decoration: none;\n background-color: #6c6c6c;\n border-radius: 6px;\n box-shadow: 0 0 4px #d9d9d9;\n}\n.rc-slider-tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {\n bottom: 4px;\n left: 50%;\n margin-left: -4px;\n border-width: 4px 4px 0;\n border-top-color: #6c6c6c;\n}\n","/* THIS FILE WAS COPIED INTO THANOS FROM PROMETHEUS \n (LIVING AT https://github.com/prometheus/prometheus/blob/main/web/ui/react-app/src/themes/app.scss),\n PROMETHEUS CODE WAS LICENSED UNDER AN APACHE 2.0 LICENSE, SEE\n https://github.com/prometheus/prometheus/blob/main/LICENSE.\n*/\n\n/* This file contains styles that are applied to root document, which cannot be\n nested under theme selectors. */\n\n html {\n /* https://github.com/prometheus/prometheus/issues/7434 */\n /* Scroll to hash-fragment-links counting the fixed navbar 40px tall with 16px padding */\n scroll-padding-top: 56px;\n }\n \n /* Font used for autocompletion item icons. */\n @font-face {\n font-family: 'codicon';\n src: local('codicon'), url(../fonts/codicon.ttf) format('truetype');\n }","/* THIS FILE WAS COPIED INTO THANOS FROM PROMETHEUS \n (LIVING AT https://github.com/prometheus/prometheus/blob/main/web/ui/react-app/src/themes/light.scss),\n PROMETHEUS CODE WAS LICENSED UNDER AN APACHE 2.0 LICENSE, SEE\n https://github.com/prometheus/prometheus/blob/main/LICENSE.\n*/\n@import 'bootstrap_light';\n\n@import '~bootstrap/scss/functions';\n@import '~bootstrap/scss/variables';\n\n$alert-cell-color: inherit;\n$rule-cell-bg: #f5f5f5;\n\n$config-yaml-color: #333;\n$config-yaml-bg: #f5f5f5;\n$config-yaml-border: #ccc;\n\n$query-stats-color: #71808e;\n\n$metrics-explorer-bg: #efefef;\n\n$clear-time-btn-bg: $white;\n\n.bootstrap {\n @import './shared';\n}","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`