From 5e884b83be7681b4d3c43653309fd438757bd647 Mon Sep 17 00:00:00 2001 From: Sairam Arunachalam Date: Tue, 15 Oct 2024 16:20:30 -0700 Subject: [PATCH] fix(ui): prefill parameters for workflow submit form. Fixes #1214 Signed-off-by: Sairam Arunachalam --- .devcontainer/devcontainer.json | 24 + .gitignore | 1 + .spelling | 3 + Makefile | 26 +- USERS.md | 1 + api/jsonschema/schema.json | 8 +- api/openapi-spec/swagger.json | 14 +- cmd/argo/commands/archive/get.go | 10 +- cmd/argo/commands/archive/list.go | 7 +- cmd/argo/commands/archive/resubmit.go | 6 +- cmd/argo/commands/archive/retry.go | 6 +- cmd/argo/commands/clustertemplate/create.go | 11 +- cmd/argo/commands/clustertemplate/get.go | 7 +- cmd/argo/commands/clustertemplate/lint.go | 10 +- cmd/argo/commands/clustertemplate/list.go | 15 +- cmd/argo/commands/clustertemplate/update.go | 11 +- cmd/argo/commands/common/flags.go | 48 + cmd/argo/commands/common/flags_test.go | 35 + cmd/argo/commands/common/get.go | 12 +- cmd/argo/commands/common/get_test.go | 10 +- cmd/argo/commands/common/submit.go | 20 +- cmd/argo/commands/cron/create.go | 13 +- cmd/argo/commands/cron/get.go | 7 +- cmd/argo/commands/cron/lint.go | 7 +- cmd/argo/commands/cron/list.go | 24 +- cmd/argo/commands/cron/update.go | 11 +- cmd/argo/commands/cron/util.go | 13 +- cmd/argo/commands/cron/util_test.go | 7 +- cmd/argo/commands/get.go | 10 +- cmd/argo/commands/lint.go | 11 +- cmd/argo/commands/lint_test.go | 61 + cmd/argo/commands/list.go | 11 +- cmd/argo/commands/resubmit.go | 4 +- cmd/argo/commands/retry.go | 4 +- cmd/argo/commands/submit.go | 8 +- cmd/argo/commands/template/create.go | 11 +- cmd/argo/commands/template/get.go | 7 +- cmd/argo/commands/template/lint.go | 10 +- cmd/argo/commands/template/list.go | 13 +- cmd/argo/commands/template/update.go | 11 +- cmd/workflow-controller/main.go | 17 +- config/config.go | 22 +- config/workflow_events.go | 9 + config/workflow_events_test.go | 14 + dev/nix/conf.nix | 6 +- docs/cli/argo_archive_list.md | 2 +- docs/cli/argo_cluster-template_get.md | 2 +- docs/cli/argo_cron_get.md | 2 +- docs/cli/argo_get.md | 2 +- docs/cli/argo_list.md | 2 +- docs/cli/argo_template_get.md | 2 +- docs/client-libraries.md | 12 +- docs/cron-workflows.md | 50 +- docs/deprecations.md | 75 + docs/environment-variables.md | 2 + docs/fields.md | 12 +- docs/metrics.md | 17 + docs/running-locally.md | 35 + docs/synchronization.md | 135 +- docs/upgrading.md | 15 + docs/variables.md | 13 +- docs/workflow-controller-configmap.yaml | 7 + docs/workflow-templates.md | 31 - examples/http-hello-world.yaml | 5 +- ...nchronization-mutex-tmpl-level-legacy.yaml | 11 +- .../synchronization-mutex-tmpl-level.yaml | 9 +- ...synchronization-mutex-wf-level-legacy.yaml | 6 +- examples/synchronization-mutex-wf-level.yaml | 4 +- .../synchronization-tmpl-level-legacy.yaml | 6 +- examples/synchronization-tmpl-level.yaml | 6 +- examples/synchronization-wf-level-legacy.yaml | 6 +- examples/synchronization-wf-level.yaml | 6 +- hack/git/hooks/commit-msg | 2 +- hack/manifests/crdgen.sh | 2 +- hack/manifests/crds.go | 48 +- hack/manifests/main.go | 4 +- hack/update-sso-redirect-url.sh | 8 + manifests/base/crds/full/README.md | 3 +- .../crds/full/argoproj.io_cronworkflows.yaml | 4 +- manifests/base/crds/minimal/README.md | 2 +- .../argoproj.io_workflowartifactgctasks.yaml | 1101 ++++++++++- .../argoproj.io_workfloweventbindings.yaml | 649 +++++- .../argoproj.io_workflowtaskresults.yaml | 1 + manifests/quick-start-minimal.yaml | 1748 ++++++++++++++++- manifests/quick-start-mysql.yaml | 1748 ++++++++++++++++- manifests/quick-start-postgres.yaml | 1748 ++++++++++++++++- manifests/quick-start/sso/dex/dex-cm.yaml | 1 + mkdocs.yml | 2 + persist/sqldb/selector.go | 14 +- pkg/apiclient/offline-client.go | 60 +- .../offline-cron-workflow-service-client.go | 2 +- pkg/apiclient/workflow/workflow.pb.go | 238 ++- pkg/apiclient/workflow/workflow.proto | 2 + .../workflow/v1alpha1/cron_workflow_types.go | 21 +- .../v1alpha1/cron_workflow_types_test.go | 15 +- pkg/apis/workflow/v1alpha1/generated.pb.go | 1410 ++++++------- pkg/apis/workflow/v1alpha1/generated.proto | 8 +- .../workflow/v1alpha1/openapi_generated.go | 8 +- .../IoArgoprojWorkflowV1alpha1StopStrategy.md | 4 +- sdks/java/client/docs/WorkflowServiceApi.md | 6 +- sdks/python/README.md | 4 + .../api/workflow_service_api.py | 6 + ...rgoproj_workflow_v1alpha1_stop_strategy.py | 16 +- .../client/docs/CronWorkflowServiceApi.md | 6 +- .../IoArgoprojWorkflowV1alpha1StopStrategy.md | 4 +- sdks/python/client/docs/WorkflowServiceApi.md | 4 +- server/cronworkflow/cron_workflow_server.go | 6 +- server/utils/list_options.go | 17 +- server/workflow/store/lister.go | 8 +- server/workflow/store/sqlite_store.go | 8 +- server/workflow/store/sqlite_store_test.go | 39 + server/workflow/workflow_server.go | 7 +- .../archived_workflow_server.go | 2 +- test/e2e/cron_test.go | 4 +- test/e2e/metrics_test.go | 68 + .../cronworkflow-deprecated-schedule.yaml | 21 + .../testdata/cronworkflow-metrics-forbid.yaml | 3 +- .../cronworkflow-metrics-replace.yaml | 3 +- .../cronworkflow_deprecated_schedule.yaml | 21 + .../synchronization-deprecated-mutex.yaml | 13 + .../synchronization-deprecated-semaphore.yaml | 15 + .../workflow-deprecated-podpriority.yaml | 11 + ui/package.json | 5 +- .../cluster-workflow-template-details.tsx | 1 + .../shared/components/dropdown/dropdown.tsx | 5 +- .../app/shared/components/input-filter.scss | 10 + ui/src/app/shared/components/input-filter.tsx | 10 +- ui/src/app/shared/components/links.test.ts | 15 + ui/src/app/shared/components/links.tsx | 15 +- .../shared/components/object-parser.test.ts | 127 ++ ui/src/app/shared/components/object-parser.ts | 11 +- ui/src/app/shared/get_workflow_params.test.ts | 37 + ui/src/app/shared/get_workflow_params.ts | 30 + ui/src/app/shared/history.ts | 11 +- ui/src/app/shared/services/utils.ts | 5 + .../app/shared/services/workflows-service.ts | 7 +- ui/src/app/webpack.config.js | 27 +- .../workflow-template-details.tsx | 1 + .../components/submit-workflow-panel.tsx | 17 +- .../workflows/components/workflow-creator.tsx | 10 +- .../workflow-filters/workflow-filters.scss | 6 +- .../workflow-filters/workflow-filters.tsx | 53 + .../workflows-list/workflows-list.tsx | 54 +- ui/yarn.lock | 10 +- util/context/context.go | 35 + util/context/context_test.go | 16 + util/deprecation/deprecation.go | 56 + util/deprecation/deprecation_test.go | 38 + util/telemetry/attributes.go | 2 + util/telemetry/counter_deprecations.go | 28 + util/telemetry/exporter_prometheus_test.go | 26 +- util/telemetry/metrics.go | 22 +- workflow/controller/agent.go | 9 +- workflow/controller/controller.go | 10 +- workflow/controller/dag.go | 2 +- .../estimation/estimator_factory.go | 8 + workflow/controller/operator.go | 40 +- workflow/controller/operator_test.go | 16 +- workflow/controller/workflowpod.go | 38 +- workflow/controller/workflowpod_test.go | 8 +- workflow/cron/controller.go | 4 +- workflow/cron/operator.go | 99 +- workflow/cron/operator_test.go | 32 +- workflow/metrics/metrics.go | 1 + workflow/sync/multiple_test.go | 61 +- workflow/sync/mutex_test.go | 48 +- workflow/sync/sync_manager.go | 21 +- workflow/sync/sync_manager_test.go | 80 +- workflow/sync/syncitems.go | 6 +- workflow/validate/validate.go | 5 +- workflow/validate/validate_test.go | 2 +- 171 files changed, 9826 insertions(+), 1570 deletions(-) create mode 100644 cmd/argo/commands/common/flags.go create mode 100644 cmd/argo/commands/common/flags_test.go create mode 100644 config/workflow_events.go create mode 100644 config/workflow_events_test.go create mode 100644 docs/deprecations.md create mode 100755 hack/update-sso-redirect-url.sh create mode 100644 test/e2e/testdata/cronworkflow-deprecated-schedule.yaml create mode 100644 test/e2e/testdata/cronworkflow_deprecated_schedule.yaml create mode 100644 test/e2e/testdata/synchronization-deprecated-mutex.yaml create mode 100644 test/e2e/testdata/synchronization-deprecated-semaphore.yaml create mode 100644 test/e2e/testdata/workflow-deprecated-podpriority.yaml create mode 100644 ui/src/app/shared/components/input-filter.scss create mode 100644 ui/src/app/shared/components/object-parser.test.ts create mode 100644 ui/src/app/shared/get_workflow_params.test.ts create mode 100644 ui/src/app/shared/get_workflow_params.ts create mode 100644 util/context/context.go create mode 100644 util/context/context_test.go create mode 100644 util/deprecation/deprecation.go create mode 100644 util/deprecation/deprecation_test.go create mode 100644 util/telemetry/counter_deprecations.go diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f073bfb4df1f..a36d736e8358 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,5 +29,29 @@ "remoteEnv": { "PATH": "${containerEnv:PATH}:/home/vscode/go/bin", "GOPATH": "/home/vscode/go" + }, + "customizations": { + "vscode": { + "settings": { + "launch": { + "configurations": [ + { + "name": "Attach to argo server", + "type": "go", + "request": "attach", + "mode": "local", + "processId": "argo" + }, + { + "name": "Attach to workflow controller", + "type": "go", + "request": "attach", + "mode": "local", + "processId": "workflow-controller" + } + ] + } + } + } } } diff --git a/.gitignore b/.gitignore index c24fdb1b5f25..e4048074607d 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ git-ask-pass.sh sdks/python/client/dist/* /v3/ /cmd/argoexec/commands/test.txt +/db-dumps/ # Do not commit rendered installation manifests since they are misleading to users. manifests/install.yaml diff --git a/.spelling b/.spelling index 8a3401f1ca5b..6bfe6bd93bde 100644 --- a/.spelling +++ b/.spelling @@ -23,6 +23,7 @@ 5xx 8Ki 90m +ARGO_TEMPLATE Alexandre Alibaba Ang @@ -102,6 +103,7 @@ PVCs Peixuan Ploomber Postgres +PriorityClass RCs Roadmap RoleBinding @@ -164,6 +166,7 @@ govaluate gzipped i.e. idempotence +inputs.parameters instantiator instantiators jenkins diff --git a/Makefile b/Makefile index f3acdfd3c550..110407fb3aee 100644 --- a/Makefile +++ b/Makefile @@ -50,12 +50,16 @@ endif PROFILE ?= minimal KUBE_NAMESPACE ?= argo # namespace where Kubernetes resources/RBAC will be installed PLUGINS ?= $(shell [ $PROFILE = plugins ] && echo false || echo true) -UI ?= false # start the UI +UI ?= false # start the UI with HTTP +UI_SECURE ?= false # start the UI with HTTPS API ?= $(UI) # start the Argo Server TASKS := controller ifeq ($(API),true) TASKS := controller server endif +ifeq ($(UI_SECURE),true) +TASKS := controller server ui +endif ifeq ($(UI),true) TASKS := controller server ui endif @@ -486,6 +490,9 @@ ifeq ($(RUN_MODE),kubernetes) kubectl -n $(KUBE_NAMESPACE) scale deploy/workflow-controller --replicas 1 kubectl -n $(KUBE_NAMESPACE) scale deploy/argo-server --replicas 1 endif +ifeq ($(UI_SECURE)$(PROFILE),truesso) + KUBE_NAMESPACE=$(KUBE_NAMESPACE) ./hack/update-sso-redirect-url.sh +endif .PHONY: argosay argosay: @@ -563,7 +570,7 @@ endif grep '127.0.0.1.*postgres' /etc/hosts grep '127.0.0.1.*mysql' /etc/hosts ifeq ($(RUN_MODE),local) - env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) PROFILE=$(PROFILE) kit $(TASKS) + env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) ARGO_UI_SECURE=$(UI_SECURE) PROFILE=$(PROFILE) kit $(TASKS) endif .PHONY: wait @@ -581,11 +588,22 @@ endif .PHONY: postgres-cli postgres-cli: - kubectl exec -ti `kubectl get pod -l app=postgres -o name|cut -c 5-` -- psql -U postgres + kubectl exec -ti svc/postgres -- psql -U postgres + +.PHONY: postgres-dump +postgres-dump: + @mkdir -p db-dumps + kubectl exec svc/postgres -- pg_dump --clean -U postgres > "db-dumps/postgres-$(BUILD_DATE).sql" .PHONY: mysql-cli mysql-cli: - kubectl exec -ti `kubectl get pod -l app=mysql -o name|cut -c 5-` -- mysql -u mysql -ppassword argo + kubectl exec -ti svc/mysql -- mysql -u mysql -ppassword argo + +.PHONY: mysql-dump +mysql-dump: + @mkdir -p db-dumps + kubectl exec svc/mysql -- mysqldump --no-tablespaces -u mysql -ppassword argo > "db-dumps/mysql-$(BUILD_DATE).sql" + test-cli: ./dist/argo diff --git a/USERS.md b/USERS.md index 344b8fd3ea97..7ebc6b5ad099 100644 --- a/USERS.md +++ b/USERS.md @@ -158,6 +158,7 @@ Currently, the following organizations are **officially** using Argo Workflows: 1. [Procore](https://www.procore.com) 1. [Promaton](https://www.promaton.com/) 1. [Prudential](https://www.prudential.com.sg/) +1. [Pvotal Technologies](https://pvotal.tech/) 1. [Quantibio](http://quantibio.com/us/en/) 1. [QuantumBlack](https://quantumblack.com/) 1. [Raccoon Digital Marketing](https://raccoon.ag/) diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index c454d10098e8..8e5601aaac0b 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -6843,15 +6843,15 @@ "type": "object" }, "io.argoproj.workflow.v1alpha1.StopStrategy": { - "description": "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + "description": "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", "properties": { - "condition": { - "description": "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + "expression": { + "description": "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", "type": "string" } }, "required": [ - "condition" + "expression" ], "type": "object" }, diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 222e843ad7cc..b2577b4b353c 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -2961,6 +2961,12 @@ "description": "Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\".", "name": "fields", "in": "query" + }, + { + "type": "string", + "description": "Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact.", + "name": "nameFilter", + "in": "query" } ], "responses": { @@ -10861,14 +10867,14 @@ } }, "io.argoproj.workflow.v1alpha1.StopStrategy": { - "description": "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + "description": "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", "type": "object", "required": [ - "condition" + "expression" ], "properties": { - "condition": { - "description": "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + "expression": { + "description": "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", "type": "string" } } diff --git a/cmd/argo/commands/archive/get.go b/cmd/argo/commands/archive/get.go index cf91949eb661..07dcbd860ef4 100644 --- a/cmd/argo/commands/archive/get.go +++ b/cmd/argo/commands/archive/get.go @@ -10,12 +10,16 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowarchivepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowarchive" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.EnumFlagValue{ + AllowedValues: []string{"json", "yaml", "wide"}, + Value: "wide", + } command := &cobra.Command{ Use: "get UID", Short: "get a workflow in the archive", @@ -41,11 +45,11 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printWorkflow(wf, output) + printWorkflow(wf, output.String()) return nil }, } - command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/archive/list.go b/cmd/argo/commands/archive/list.go index 8972fab18f9c..1ea5946537b6 100644 --- a/cmd/argo/commands/archive/list.go +++ b/cmd/argo/commands/archive/list.go @@ -10,6 +10,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowarchivepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowarchive" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/printer" @@ -18,7 +19,7 @@ import ( func NewListCommand() *cobra.Command { var ( selector string - output string + output = common.NewPrintWorkflowOutputValue("wide") chunkSize int64 ) command := &cobra.Command{ @@ -50,10 +51,10 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{Output: output, Namespace: true, UID: true}) + return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{Output: output.String(), Namespace: true, UID: true}) }, } - command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) command.Flags().StringVarP(&selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") command.Flags().Int64VarP(&chunkSize, "chunk-size", "", 0, "Return large lists in chunks rather than all at once. Pass 0 to disable.") return command diff --git a/cmd/argo/commands/archive/resubmit.go b/cmd/argo/commands/archive/resubmit.go index 1143c42bffc6..fb26dde5172e 100644 --- a/cmd/argo/commands/archive/resubmit.go +++ b/cmd/argo/commands/archive/resubmit.go @@ -33,7 +33,7 @@ func (o *resubmitOps) hasSelector() bool { func NewResubmitCommand() *cobra.Command { var ( resubmitOpts resubmitOps - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() ) command := &cobra.Command{ Use: "resubmit [WORKFLOW...]", @@ -87,7 +87,7 @@ func NewResubmitCommand() *cobra.Command { command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") command.Flags().Int32Var(&resubmitOpts.priority, "priority", 0, "workflow priority") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -140,7 +140,7 @@ func resubmitArchivedWorkflows(ctx context.Context, archiveServiceClient workflo if err != nil { return err } - printWorkflow(lastResubmitted, cliSubmitOpts.Output) + printWorkflow(lastResubmitted, cliSubmitOpts.Output.String()) } if len(resubmittedUids) == 1 { diff --git a/cmd/argo/commands/archive/retry.go b/cmd/argo/commands/archive/retry.go index de3eead996d9..585ee5b19606 100644 --- a/cmd/argo/commands/archive/retry.go +++ b/cmd/argo/commands/archive/retry.go @@ -35,7 +35,7 @@ func (o *retryOps) hasSelector() bool { func NewRetryCommand() *cobra.Command { var ( - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() retryOpts retryOps ) command := &cobra.Command{ @@ -92,7 +92,7 @@ func NewRetryCommand() *cobra.Command { } command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -146,7 +146,7 @@ func retryArchivedWorkflows(ctx context.Context, archiveServiceClient workflowar if err != nil { return err } - printWorkflow(lastRetried, cliSubmitOpts.Output) + printWorkflow(lastRetried, cliSubmitOpts.Output.String()) } if len(retriedUids) == 1 { // watch or wait when there is only one workflow retried diff --git a/cmd/argo/commands/clustertemplate/create.go b/cmd/argo/commands/clustertemplate/create.go index 94457fa5f494..6bbfe0b4bb49 100644 --- a/cmd/argo/commands/clustertemplate/create.go +++ b/cmd/argo/commands/clustertemplate/create.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) type cliCreateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewCreateCommand() *cobra.Command { - var cliCreateOpts cliCreateOpts + var cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "create FILE1 FILE2...", Short: "create a cluster workflow template", @@ -35,7 +36,7 @@ func NewCreateCommand() *cobra.Command { return createClusterWorkflowTemplates(cmd.Context(), args, &cliCreateOpts) }, } - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -62,7 +63,7 @@ func createClusterWorkflowTemplates(ctx context.Context, filePaths []string, cli if err != nil { return fmt.Errorf("Failed to create cluster workflow template: %s, %v", wftmpl.Name, err) } - printClusterWorkflowTemplate(created, cliOpts.output) + printClusterWorkflowTemplate(created, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/clustertemplate/get.go b/cmd/argo/commands/clustertemplate/get.go index ff704bf45a87..e12331af5896 100644 --- a/cmd/argo/commands/clustertemplate/get.go +++ b/cmd/argo/commands/clustertemplate/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" clusterworkflowtmplpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get CLUSTER WORKFLOW_TEMPLATE...", @@ -29,12 +30,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printClusterWorkflowTemplate(wftmpl, output) + printClusterWorkflowTemplate(wftmpl, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/clustertemplate/lint.go b/cmd/argo/commands/clustertemplate/lint.go index 141346189e60..e2addeb27a84 100644 --- a/cmd/argo/commands/clustertemplate/lint.go +++ b/cmd/argo/commands/clustertemplate/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,10 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } ) command := &cobra.Command{ @@ -32,11 +36,11 @@ func NewLintCommand() *cobra.Command { Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.ClusterWorkflowTemplatePlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.ClusterWorkflowTemplatePlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict workflow validation") return command } diff --git a/cmd/argo/commands/clustertemplate/list.go b/cmd/argo/commands/clustertemplate/list.go index 71d714893681..9bd2cee48362 100644 --- a/cmd/argo/commands/clustertemplate/list.go +++ b/cmd/argo/commands/clustertemplate/list.go @@ -8,16 +8,15 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) -type listFlags struct { - output string // --output -} - func NewListCommand() *cobra.Command { - var listArgs listFlags + var output = common.EnumFlagValue{ + AllowedValues: []string{"wide", "name"}, + } command := &cobra.Command{ Use: "list", Short: "list cluster workflow templates", @@ -44,7 +43,7 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch output.String() { case "", "wide": printTable(cwftmplList.Items) case "name": @@ -52,12 +51,12 @@ func NewListCommand() *cobra.Command { fmt.Println(cwftmp.ObjectMeta.Name) } default: - return fmt.Errorf("Unknown output mode: %s", listArgs.output) + return fmt.Errorf("Unknown output mode: %s", output.String()) } return nil }, } - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/clustertemplate/update.go b/cmd/argo/commands/clustertemplate/update.go index 2ef63615180e..78cad5877408 100644 --- a/cmd/argo/commands/clustertemplate/update.go +++ b/cmd/argo/commands/clustertemplate/update.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { - var cliUpdateOpts cliUpdateOpts + var cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "update FILE1 FILE2...", Short: "update a cluster workflow template", @@ -34,7 +35,7 @@ func NewUpdateCommand() *cobra.Command { return updateClusterWorkflowTemplates(cmd.Context(), args, &cliUpdateOpts) }, } - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -68,7 +69,7 @@ func updateClusterWorkflowTemplates(ctx context.Context, filePaths []string, cli if err != nil { return fmt.Errorf("Failed to update cluster workflow template: %s, %v", wftmpl.Name, err) } - printClusterWorkflowTemplate(updated, cliOpts.output) + printClusterWorkflowTemplate(updated, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/common/flags.go b/cmd/argo/commands/common/flags.go new file mode 100644 index 000000000000..085905bb8a55 --- /dev/null +++ b/cmd/argo/commands/common/flags.go @@ -0,0 +1,48 @@ +package common + +import ( + "errors" + "fmt" + "slices" + "strings" + + "github.com/spf13/pflag" +) + +// EnumFlagValue represents a CLI flag that can take one of a fixed set of values, and validates +// that the provided value is one of the allowed values. +// There's several libraries for this (e.g. https://github.com/thediveo/enumflag), but they're overkill. +type EnumFlagValue struct { + AllowedValues []string + Value string +} + +func (e *EnumFlagValue) Usage() string { + return fmt.Sprintf("One of: %s", strings.Join(e.AllowedValues, "|")) +} + +func (e *EnumFlagValue) String() string { + return e.Value +} + +func (e *EnumFlagValue) Set(v string) error { + if slices.Contains(e.AllowedValues, v) { + e.Value = v + return nil + } else { + return errors.New(e.Usage()) + } +} + +func (e *EnumFlagValue) Type() string { + return "string" +} + +var _ pflag.Value = &EnumFlagValue{} + +func NewPrintWorkflowOutputValue(value string) EnumFlagValue { + return EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "wide"}, + Value: value, + } +} diff --git a/cmd/argo/commands/common/flags_test.go b/cmd/argo/commands/common/flags_test.go new file mode 100644 index 000000000000..efadec0b38a5 --- /dev/null +++ b/cmd/argo/commands/common/flags_test.go @@ -0,0 +1,35 @@ +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEnumFlagValue(t *testing.T) { + e := EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "wide"}, + Value: "json", + } + t.Run("Usage", func(t *testing.T) { + assert.Equal(t, "One of: name|json|yaml|wide", e.Usage()) + }) + + t.Run("String", func(t *testing.T) { + assert.Equal(t, "json", e.String()) + }) + + t.Run("Type", func(t *testing.T) { + assert.Equal(t, "string", e.Type()) + }) + + t.Run("Set", func(t *testing.T) { + err := e.Set("name") + require.NoError(t, err) + assert.Equal(t, "name", e.Value) + + err = e.Set("invalid") + require.Error(t, err, "One of: name|json|yaml|wide") + }) +} diff --git a/cmd/argo/commands/common/get.go b/cmd/argo/commands/common/get.go index 0740978b0307..4e2422ad86de 100644 --- a/cmd/argo/commands/common/get.go +++ b/cmd/argo/commands/common/get.go @@ -20,7 +20,7 @@ import ( const onExitSuffix = "onExit" type GetFlags struct { - Output string + Output EnumFlagValue NodeFieldSelectorString string // Only used for backwards compatibility @@ -147,9 +147,9 @@ func PrintWorkflowHelper(wf *wfv1.Workflow, getArgs GetFlags) string { w := tabwriter.NewWriter(writerBuffer, 0, 0, 2, ' ', 0) out += "\n" // apply a dummy FgDefault format to align tab writer with the rest of the columns - if getArgs.Output == "wide" { + if getArgs.Output.String() == "wide" { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tARTIFACTS\tMESSAGE\tRESOURCESDURATION\tNODENAME\n", ansiFormat("STEP", FgDefault)) - } else if getArgs.Output == "short" { + } else if getArgs.Output.String() == "short" { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tMESSAGE\tNODENAME\n", ansiFormat("STEP", FgDefault)) } else { _, _ = fmt.Fprintf(w, "%s\tTEMPLATE\tPODNAME\tDURATION\tMESSAGE\n", ansiFormat("STEP", FgDefault)) @@ -171,7 +171,7 @@ func PrintWorkflowHelper(wf *wfv1.Workflow, getArgs GetFlags) string { onExitRoot.renderNodes(w, wf, 0, " ", " ", getArgs) } _ = w.Flush() - if getArgs.Output == "short" { + if getArgs.Output.String() == "short" { out = writerBuffer.String() } else { out += writerBuffer.String() @@ -498,7 +498,7 @@ func printNode(w *tabwriter.Writer, node wfv1.NodeStatus, wfName, nodePrefix str } else { args = []interface{}{nodePrefix, fmtNodeName, fmtTemplateName, "", "", node.Message, ""} } - if getArgs.Output == "wide" { + if getArgs.Output.String() == "wide" { msg := args[len(args)-2] args[len(args)-2] = getArtifactsString(node) args[len(args)-1] = msg @@ -507,7 +507,7 @@ func printNode(w *tabwriter.Writer, node wfv1.NodeStatus, wfName, nodePrefix str args[len(args)-1] = node.HostNodeName } _, _ = fmt.Fprintf(w, "%s%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", args...) - } else if getArgs.Output == "short" { + } else if getArgs.Output.String() == "short" { if node.Type == wfv1.NodeTypePod { args[len(args)-1] = node.HostNodeName } diff --git a/cmd/argo/commands/common/get_test.go b/cmd/argo/commands/common/get_test.go index 7b98d4fadfca..f042bc66c7a2 100644 --- a/cmd/argo/commands/common/get_test.go +++ b/cmd/argo/commands/common/get_test.go @@ -54,9 +54,7 @@ func TestPrintNode(t *testing.T) { nodeTemplateRefName := "testTemplateRef" nodeID := "testID" nodeMessage := "test" - getArgs := GetFlags{ - Output: "", - } + getArgs := GetFlags{} timestamp := metav1.Time{ Time: time.Now(), } @@ -105,7 +103,7 @@ func TestPrintNode(t *testing.T) { testPrintNodeImpl(t, "", node, getArgs) getArgs = GetFlags{ - Output: "", + Output: EnumFlagValue{AllowedValues: []string{"short", "wide"}}, } node.TemplateName = nodeTemplateName @@ -124,13 +122,13 @@ func TestPrintNode(t *testing.T) { expectedPodName = util.GeneratePodName(workflowName, nodeName, templateName, nodeID, util.GetPodNameVersion()) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\n", NodeTypeIconMap[wfv1.NodeTypeSuspend], nodeName, nodeTemplateRefName, nodeTemplateRefName, "", "", nodeMessage, ""), node, getArgs) - getArgs.Output = "wide" + require.NoError(t, getArgs.Output.Set("wide")) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\t%s\t\n", NodeTypeIconMap[wfv1.NodeTypeSuspend], nodeName, nodeTemplateRefName, nodeTemplateRefName, "", "", getArtifactsString(node), nodeMessage, ""), node, getArgs) node.Type = wfv1.NodeTypePod testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\t%s\t%s\n", JobStatusIconMap[wfv1.NodeRunning], nodeName, nodeTemplateRefName, nodeTemplateRefName, expectedPodName, "0s", getArtifactsString(node), nodeMessage, "", kubernetesNodeName), node, getArgs) - getArgs.Output = "short" + require.NoError(t, getArgs.Output.Set("short")) testPrintNodeImpl(t, fmt.Sprintf("%s %s\t%s/%s\t%s\t%s\t%s\t%s\n", JobStatusIconMap[wfv1.NodeRunning], nodeName, nodeTemplateRefName, nodeTemplateRefName, expectedPodName, "0s", nodeMessage, kubernetesNodeName), node, getArgs) getArgs.Status = "foobar" diff --git a/cmd/argo/commands/common/submit.go b/cmd/argo/commands/common/submit.go index 905e55ea4c08..0867c980dfda 100644 --- a/cmd/argo/commands/common/submit.go +++ b/cmd/argo/commands/common/submit.go @@ -11,17 +11,23 @@ import ( // CliSubmitOpts holds submission options specific to CLI submission (e.g. controlling output) type CliSubmitOpts struct { - Output string // --output - Wait bool // --wait - Watch bool // --watch - Log bool // --log - Strict bool // --strict - Priority *int32 // --priority + Output EnumFlagValue // --output + Wait bool // --wait + Watch bool // --watch + Log bool // --log + Strict bool // --strict + Priority *int32 // --priority GetArgs GetFlags ScheduledTime string // --scheduled-time Parameters []string // --parameter } +func NewCliSubmitOpts() CliSubmitOpts { + return CliSubmitOpts{ + Output: NewPrintWorkflowOutputValue(""), + } +} + func WaitWatchOrLog(ctx context.Context, serviceClient workflowpkg.WorkflowServiceClient, namespace string, workflowNames []string, cliSubmitOpts CliSubmitOpts) error { if cliSubmitOpts.Log { for _, workflow := range workflowNames { @@ -35,7 +41,7 @@ func WaitWatchOrLog(ctx context.Context, serviceClient workflowpkg.WorkflowServi } } if cliSubmitOpts.Wait { - WaitWorkflows(ctx, serviceClient, namespace, workflowNames, false, !(cliSubmitOpts.Output == "" || cliSubmitOpts.Output == "wide")) + WaitWorkflows(ctx, serviceClient, namespace, workflowNames, false, !(cliSubmitOpts.Output.String() == "" || cliSubmitOpts.Output.String() == "wide")) } else if cliSubmitOpts.Watch { for _, workflow := range workflowNames { if err := WatchWorkflow(ctx, serviceClient, namespace, workflow, cliSubmitOpts.GetArgs); err != nil { diff --git a/cmd/argo/commands/cron/create.go b/cmd/argo/commands/cron/create.go index fd97f535c58e..592289d0beb8 100644 --- a/cmd/argo/commands/cron/create.go +++ b/cmd/argo/commands/cron/create.go @@ -7,20 +7,21 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/util" ) type cliCreateOpts struct { - output string // --output - schedule string // --schedule - strict bool // --strict + output common.EnumFlagValue // --output + schedule string // --schedule + strict bool // --strict } func NewCreateCommand() *cobra.Command { var ( - cliCreateOpts cliCreateOpts + cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} submitOpts wfv1.SubmitOpts parametersFile string ) @@ -40,7 +41,7 @@ func NewCreateCommand() *cobra.Command { } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, false) - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") command.Flags().StringVar(&cliCreateOpts.schedule, "schedule", "", "override cron workflow schedule") return command @@ -90,7 +91,7 @@ func CreateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliCr if err != nil { return fmt.Errorf("Failed to create cron workflow: %v", err) } - fmt.Print(getCronWorkflowGet(created)) + fmt.Print(getCronWorkflowGet(ctx, created)) } return nil } diff --git a/cmd/argo/commands/cron/get.go b/cmd/argo/commands/cron/get.go index 75e5e242e150..fbbdd7ba561c 100644 --- a/cmd/argo/commands/cron/get.go +++ b/cmd/argo/commands/cron/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get CRON_WORKFLOW...", @@ -33,12 +34,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printCronWorkflow(cronWf, output) + printCronWorkflow(ctx, cronWf, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/cron/lint.go b/cmd/argo/commands/cron/lint.go index 5c7f3a863885..5ba988a2991b 100644 --- a/cmd/argo/commands/cron/lint.go +++ b/cmd/argo/commands/cron/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,7 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{AllowedValues: []string{"pretty", "simple"}, Value: "pretty"} ) command := &cobra.Command{ @@ -31,11 +32,11 @@ func NewLintCommand() *cobra.Command { DefaultNamespace: client.Namespace(), Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.CronWorkflowPlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.CronWorkflowPlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict validation") return command } diff --git a/cmd/argo/commands/cron/list.go b/cmd/argo/commands/cron/list.go index d4ccfc4b118b..f1c2c272293a 100644 --- a/cmd/argo/commands/cron/list.go +++ b/cmd/argo/commands/cron/list.go @@ -1,6 +1,7 @@ package cron import ( + "context" "fmt" "os" "text/tabwriter" @@ -11,18 +12,21 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) type listFlags struct { - allNamespaces bool // --all-namespaces - output string // --output - labelSelector string // --selector + allNamespaces bool // --all-namespaces + output common.EnumFlagValue // --output + labelSelector string // --selector } func NewListCommand() *cobra.Command { - var listArgs listFlags + var listArgs = listFlags{ + output: common.EnumFlagValue{AllowedValues: []string{"wide", "name"}}, + } command := &cobra.Command{ Use: "list", Short: "list cron workflows", @@ -48,26 +52,26 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch listArgs.output.String() { case "", "wide": - printTable(cronWfList.Items, &listArgs) + printTable(ctx, cronWfList.Items, &listArgs) case "name": for _, cronWf := range cronWfList.Items { fmt.Println(cronWf.ObjectMeta.Name) } default: - return fmt.Errorf("Unknown output mode: %s", listArgs.output) + return fmt.Errorf("Unknown output mode: %s", listArgs.output.String()) } return nil }, } command.Flags().BoolVarP(&listArgs.allNamespaces, "all-namespaces", "A", false, "Show workflows from all namespaces") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVarP(&listArgs.labelSelector, "selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.") return command } -func printTable(wfList []wfv1.CronWorkflow, listArgs *listFlags) { +func printTable(ctx context.Context, wfList []wfv1.CronWorkflow, listArgs *listFlags) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) if listArgs.allNamespaces { _, _ = fmt.Fprint(w, "NAMESPACE\t") @@ -85,7 +89,7 @@ func printTable(wfList []wfv1.CronWorkflow, listArgs *listFlags) { cleanLastScheduledTime = "N/A" } var cleanNextScheduledTime string - if next, err := GetNextRuntime(&cwf); err == nil { + if next, err := GetNextRuntime(ctx, &cwf); err == nil { cleanNextScheduledTime = humanize.RelativeDurationShort(next, time.Now()) } else { cleanNextScheduledTime = "N/A" diff --git a/cmd/argo/commands/cron/update.go b/cmd/argo/commands/cron/update.go index e1340267fe95..807a8c4e0b2d 100644 --- a/cmd/argo/commands/cron/update.go +++ b/cmd/argo/commands/cron/update.go @@ -7,19 +7,20 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/util" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { var ( - cliUpdateOpts cliUpdateOpts + cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} submitOpts wfv1.SubmitOpts parametersFile string ) @@ -48,7 +49,7 @@ func NewUpdateCommand() *cobra.Command { } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, false) - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -89,7 +90,7 @@ func updateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliUp if err != nil { return fmt.Errorf("Failed to update workflow template: %v", err) } - fmt.Print(getCronWorkflowGet(updated)) + fmt.Print(getCronWorkflowGet(ctx, updated)) } return nil } diff --git a/cmd/argo/commands/cron/util.go b/cmd/argo/commands/cron/util.go index eefbd754c0c1..82db7983dcde 100644 --- a/cmd/argo/commands/cron/util.go +++ b/cmd/argo/commands/cron/util.go @@ -1,6 +1,7 @@ package cron import ( + "context" "encoding/json" "fmt" "log" @@ -22,10 +23,10 @@ import ( // GetNextRuntime returns the next time the workflow should run in local time. It assumes the workflow-controller is in // UTC, but nevertheless returns the time in the local timezone. -func GetNextRuntime(cwf *v1alpha1.CronWorkflow) (time.Time, error) { +func GetNextRuntime(ctx context.Context, cwf *v1alpha1.CronWorkflow) (time.Time, error) { var nextRunTime time.Time now := time.Now().UTC() - for _, schedule := range cwf.Spec.GetSchedulesWithTimezone() { + for _, schedule := range cwf.Spec.GetSchedulesWithTimezone(ctx) { cronSchedule, err := cron.ParseStandard(schedule) if err != nil { return time.Time{}, err @@ -77,7 +78,7 @@ func unmarshalCronWorkflows(wfBytes []byte, strict bool) []wfv1.CronWorkflow { return nil } -func printCronWorkflow(wf *wfv1.CronWorkflow, outFmt string) { +func printCronWorkflow(ctx context.Context, wf *wfv1.CronWorkflow, outFmt string) { switch outFmt { case "name": fmt.Println(wf.ObjectMeta.Name) @@ -88,13 +89,13 @@ func printCronWorkflow(wf *wfv1.CronWorkflow, outFmt string) { outBytes, _ := yaml.Marshal(wf) fmt.Print(string(outBytes)) case "wide", "": - fmt.Print(getCronWorkflowGet(wf)) + fmt.Print(getCronWorkflowGet(ctx, wf)) default: log.Fatalf("Unknown output format: %s", outFmt) } } -func getCronWorkflowGet(cwf *wfv1.CronWorkflow) string { +func getCronWorkflowGet(ctx context.Context, cwf *wfv1.CronWorkflow) string { const fmtStr = "%-30s %v\n" out := "" @@ -116,7 +117,7 @@ func getCronWorkflowGet(cwf *wfv1.CronWorkflow) string { out += fmt.Sprintf(fmtStr, "LastScheduledTime:", humanize.Timestamp(cwf.Status.LastScheduledTime.Time)) } - next, err := GetNextRuntime(cwf) + next, err := GetNextRuntime(ctx, cwf) if err == nil { out += fmt.Sprintf(fmtStr, "NextScheduledTime:", humanize.Timestamp(next)+" (assumes workflow-controller is in UTC)") } diff --git a/cmd/argo/commands/cron/util_test.go b/cmd/argo/commands/cron/util_test.go index 0eb696d14ab9..e1e0ab9e623c 100644 --- a/cmd/argo/commands/cron/util_test.go +++ b/cmd/argo/commands/cron/util_test.go @@ -1,6 +1,7 @@ package cron import ( + "context" "testing" "time" @@ -56,13 +57,13 @@ Conditions: func TestPrintCronWorkflow(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(invalidCwf) - out := getCronWorkflowGet(cronWf) + out := getCronWorkflowGet(context.Background(), cronWf) assert.Contains(t, out, expectedOut) } func TestNextRuntime(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(invalidCwf) - next, err := GetNextRuntime(cronWf) + next, err := GetNextRuntime(context.Background(), cronWf) require.NoError(t, err) assert.LessOrEqual(t, next.Unix(), time.Now().Add(1*time.Minute).Unix()) assert.Greater(t, next.Unix(), time.Now().Unix()) @@ -94,7 +95,7 @@ spec: func TestNextRuntimeWithMultipleSchedules(t *testing.T) { var cronWf = v1alpha1.MustUnmarshalCronWorkflow(cronMultipleSchedules) - next, err := GetNextRuntime(cronWf) + next, err := GetNextRuntime(context.Background(), cronWf) require.NoError(t, err) assert.LessOrEqual(t, next.Unix(), time.Now().Add(1*time.Minute).Unix()) assert.Greater(t, next.Unix(), time.Now().Unix()) diff --git a/cmd/argo/commands/get.go b/cmd/argo/commands/get.go index c1b50cded144..e5c34ddb995b 100644 --- a/cmd/argo/commands/get.go +++ b/cmd/argo/commands/get.go @@ -14,7 +14,11 @@ import ( ) func NewGetCommand() *cobra.Command { - var getArgs common.GetFlags + var getArgs = common.GetFlags{ + Output: common.EnumFlagValue{ + AllowedValues: []string{"name", "json", "yaml", "short", "wide"}, + }, + } command := &cobra.Command{ Use: "get WORKFLOW...", @@ -50,7 +54,7 @@ func NewGetCommand() *cobra.Command { }, } - command.Flags().StringVarP(&getArgs.Output, "output", "o", "", "Output format. One of: json|yaml|short|wide") + command.Flags().VarP(&getArgs.Output, "output", "o", "Output format. "+getArgs.Output.Usage()) command.Flags().BoolVar(&common.NoColor, "no-color", false, "Disable colorized output") command.Flags().BoolVar(&common.NoUtf8, "no-utf8", false, "Use plain 7-bits ascii characters") command.Flags().StringVar(&getArgs.Status, "status", "", "Filter by status (Pending, Running, Succeeded, Skipped, Failed, Error)") @@ -59,7 +63,7 @@ func NewGetCommand() *cobra.Command { } func printWorkflow(wf *wfv1.Workflow, getArgs common.GetFlags) error { - switch getArgs.Output { + switch getArgs.Output.String() { case "name": fmt.Println(wf.ObjectMeta.Name) case "json": diff --git a/cmd/argo/commands/lint.go b/cmd/argo/commands/lint.go index 9dcc17329303..643c4a39f6e9 100644 --- a/cmd/argo/commands/lint.go +++ b/cmd/argo/commands/lint.go @@ -20,8 +20,11 @@ func NewLintCommand() *cobra.Command { var ( strict bool lintKinds []string - output string - offline bool + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } + offline bool ) command := &cobra.Command{ @@ -37,12 +40,12 @@ func NewLintCommand() *cobra.Command { cat manifests.yaml | argo lint --kinds=workflows,cronworkflows -`, Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return runLint(cmd.Context(), args, offline, lintKinds, output, strict) + return runLint(cmd.Context(), args, offline, lintKinds, output.String(), strict) }, } command.Flags().StringSliceVar(&lintKinds, "kinds", []string{"all"}, fmt.Sprintf("Which kinds will be linted. Can be: %s", strings.Join(allKinds, "|"))) - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "Perform strict workflow validation") command.Flags().BoolVar(&offline, "offline", false, "perform offline linting. For resources referencing other resources, the references will be resolved from the provided args") command.Flags().BoolVar(&common.NoColor, "no-color", false, "Disable colorized output") diff --git a/cmd/argo/commands/lint_test.go b/cmd/argo/commands/lint_test.go index 92aa37dde127..da109835d648 100644 --- a/cmd/argo/commands/lint_test.go +++ b/cmd/argo/commands/lint_test.go @@ -221,4 +221,65 @@ spec: require.NoError(t, err) assert.False(t, fatal, "should not have exited") }) + + workflowMultiDocsPath := filepath.Join(subdir, "workflowMultiDocs.yaml") + err = os.WriteFile(workflowMultiDocsPath, []byte(` +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: hello-world-template-local-arg-1 +spec: + templates: + - name: hello-world + inputs: + parameters: + - name: msg + value: 'hello world' + container: + image: busybox + command: [echo] + args: ['{{inputs.parameters.msg}}'] +--- +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: hello-world-template-local-arg-2 +spec: + templates: + - name: hello-world + inputs: + parameters: + - name: msg + value: 'hello world' + container: + image: busybox + command: [echo] + args: ['{{inputs.parameters.msg}}'] +--- +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: hello-world-local-arg- +spec: + entrypoint: whalesay + templates: + - name: whalesay + steps: + - - name: hello-world + templateRef: + name: hello-world-template-local-arg-2 + template: hello-world +`), 0644) + require.NoError(t, err) + + t.Run("linting a workflow in multi-documents yaml", func(t *testing.T) { + defer func() { logrus.StandardLogger().ExitFunc = nil }() + var fatal bool + logrus.StandardLogger().ExitFunc = func(int) { fatal = true } + err = runLint(context.Background(), []string{workflowMultiDocsPath}, true, nil, "pretty", false) + + require.NoError(t, err) + assert.False(t, fatal, "should not have exited") + }) + } diff --git a/cmd/argo/commands/list.go b/cmd/argo/commands/list.go index e5258175df2f..db0a311c6a2d 100644 --- a/cmd/argo/commands/list.go +++ b/cmd/argo/commands/list.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/selection" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + cmdcommon "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/printer" @@ -28,7 +29,7 @@ type listFlags struct { running bool resubmitted bool prefix string - output string + output cmdcommon.EnumFlagValue createdSince string finishedBefore string chunkSize int64 @@ -44,7 +45,7 @@ var ( ) func (f listFlags) displayFields() string { - switch f.output { + switch f.output.String() { case "name": return nameFields case "json", "yaml": @@ -58,7 +59,7 @@ func (f listFlags) displayFields() string { func NewListCommand() *cobra.Command { var ( - listArgs listFlags + listArgs = listFlags{output: cmdcommon.NewPrintWorkflowOutputValue("")} allNamespaces bool ) command := &cobra.Command{ @@ -108,7 +109,7 @@ func NewListCommand() *cobra.Command { return printer.PrintWorkflows(workflows, os.Stdout, printer.PrintOpts{ NoHeaders: listArgs.noHeaders, Namespace: allNamespaces, - Output: listArgs.output, + Output: listArgs.output.String(), }) }, } @@ -119,7 +120,7 @@ func NewListCommand() *cobra.Command { command.Flags().BoolVar(&listArgs.completed, "completed", false, "Show completed workflows. Mutually exclusive with --running.") command.Flags().BoolVar(&listArgs.running, "running", false, "Show running workflows. Mutually exclusive with --completed.") command.Flags().BoolVar(&listArgs.resubmitted, "resubmitted", false, "Show resubmitted workflows") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: name|wide|yaml|json") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVar(&listArgs.createdSince, "since", "", "Show only workflows created after than a relative duration") command.Flags().Int64VarP(&listArgs.chunkSize, "chunk-size", "", 0, "Return large lists in chunks rather than all at once. Pass 0 to disable.") command.Flags().BoolVar(&listArgs.noHeaders, "no-headers", false, "Don't print headers (default print headers).") diff --git a/cmd/argo/commands/resubmit.go b/cmd/argo/commands/resubmit.go index 049dafeb6101..7e59c36f51c3 100644 --- a/cmd/argo/commands/resubmit.go +++ b/cmd/argo/commands/resubmit.go @@ -31,7 +31,7 @@ func (o *resubmitOps) hasSelector() bool { func NewResubmitCommand() *cobra.Command { var ( resubmitOpts resubmitOps - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() ) command := &cobra.Command{ Use: "resubmit [WORKFLOW...]", @@ -86,7 +86,7 @@ func NewResubmitCommand() *cobra.Command { command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") command.Flags().Int32Var(&resubmitOpts.priority, "priority", 0, "workflow priority") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is resubmitted") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") diff --git a/cmd/argo/commands/retry.go b/cmd/argo/commands/retry.go index e202e2fe23c3..76ef55393a74 100644 --- a/cmd/argo/commands/retry.go +++ b/cmd/argo/commands/retry.go @@ -33,7 +33,7 @@ func (o *retryOps) hasSelector() bool { func NewRetryCommand() *cobra.Command { var ( - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() retryOpts retryOps ) command := &cobra.Command{ @@ -93,7 +93,7 @@ func NewRetryCommand() *cobra.Command { }, } command.Flags().StringArrayVarP(&cliSubmitOpts.Parameters, "parameter", "p", []string{}, "input parameter to override on the original workflow spec") - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes, only works when a single workflow is retried") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") diff --git a/cmd/argo/commands/submit.go b/cmd/argo/commands/submit.go index 0aa1f9f7d5ff..73c2d31c4902 100644 --- a/cmd/argo/commands/submit.go +++ b/cmd/argo/commands/submit.go @@ -24,7 +24,7 @@ func NewSubmitCommand() *cobra.Command { var ( submitOpts wfv1.SubmitOpts parametersFile string - cliSubmitOpts common.CliSubmitOpts + cliSubmitOpts = common.NewCliSubmitOpts() priority int32 from string ) @@ -90,7 +90,7 @@ func NewSubmitCommand() *cobra.Command { }, } util.PopulateSubmitOpts(command, &submitOpts, ¶metersFile, true) - command.Flags().StringVarP(&cliSubmitOpts.Output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliSubmitOpts.Output, "output", "o", "Output format. "+cliSubmitOpts.Output.Usage()) command.Flags().BoolVarP(&cliSubmitOpts.Wait, "wait", "w", false, "wait for the workflow to complete") command.Flags().BoolVar(&cliSubmitOpts.Watch, "watch", false, "watch the workflow until it completes") command.Flags().BoolVar(&cliSubmitOpts.Log, "log", false, "log the workflow until it completes") @@ -150,7 +150,7 @@ func validateOptions(workflows []wfv1.Workflow, submitOpts *wfv1.SubmitOpts, cli } if submitOpts.DryRun { - if cliOpts.Output == "" { + if cliOpts.Output.String() == "" { return errors.New("--dry-run should have an output option") } if submitOpts.ServerDryRun { @@ -159,7 +159,7 @@ func validateOptions(workflows []wfv1.Workflow, submitOpts *wfv1.SubmitOpts, cli } if submitOpts.ServerDryRun { - if cliOpts.Output == "" { + if cliOpts.Output.String() == "" { return errors.New("--server-dry-run should have an output option") } } diff --git a/cmd/argo/commands/template/create.go b/cmd/argo/commands/template/create.go index 6003407ebd74..cd36e87fb344 100644 --- a/cmd/argo/commands/template/create.go +++ b/cmd/argo/commands/template/create.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) type cliCreateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewCreateCommand() *cobra.Command { - var cliCreateOpts cliCreateOpts + var cliCreateOpts = cliCreateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "create FILE1 FILE2...", Short: "create a workflow template", @@ -25,7 +26,7 @@ func NewCreateCommand() *cobra.Command { return CreateWorkflowTemplates(cmd.Context(), args, &cliCreateOpts) }, } - command.Flags().StringVarP(&cliCreateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliCreateOpts.output, "output", "o", "Output format. "+cliCreateOpts.output.Usage()) command.Flags().BoolVar(&cliCreateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -56,7 +57,7 @@ func CreateWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *c if err != nil { return fmt.Errorf("Failed to create workflow template: %v", err) } - printWorkflowTemplate(created, cliOpts.output) + printWorkflowTemplate(created, cliOpts.output.String()) } return nil } diff --git a/cmd/argo/commands/template/get.go b/cmd/argo/commands/template/get.go index 2ed16f93c1ed..0e7bc96f8172 100644 --- a/cmd/argo/commands/template/get.go +++ b/cmd/argo/commands/template/get.go @@ -4,11 +4,12 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) func NewGetCommand() *cobra.Command { - var output string + var output = common.NewPrintWorkflowOutputValue("") command := &cobra.Command{ Use: "get WORKFLOW_TEMPLATE...", @@ -31,12 +32,12 @@ func NewGetCommand() *cobra.Command { if err != nil { return err } - printWorkflowTemplate(wftmpl, output) + printWorkflowTemplate(wftmpl, output.String()) } return nil }, } - command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide") + command.Flags().VarP(&output, "output", "o", "Output format. "+output.Usage()) return command } diff --git a/cmd/argo/commands/template/lint.go b/cmd/argo/commands/template/lint.go index 29c7f849766c..c516ba8e2499 100644 --- a/cmd/argo/commands/template/lint.go +++ b/cmd/argo/commands/template/lint.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" "github.com/argoproj/argo-workflows/v3/cmd/argo/lint" wf "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" ) @@ -13,7 +14,10 @@ import ( func NewLintCommand() *cobra.Command { var ( strict bool - output string + output = common.EnumFlagValue{ + AllowedValues: []string{"pretty", "simple"}, + Value: "pretty", + } ) command := &cobra.Command{ @@ -31,11 +35,11 @@ func NewLintCommand() *cobra.Command { DefaultNamespace: client.Namespace(), Printer: os.Stdout, } - return lint.RunLint(ctx, apiClient, []string{wf.WorkflowTemplatePlural}, output, false, opts) + return lint.RunLint(ctx, apiClient, []string{wf.WorkflowTemplatePlural}, output.String(), false, opts) }, } - command.Flags().StringVarP(&output, "output", "o", "pretty", "Linting results output format. One of: pretty|simple") + command.Flags().VarP(&output, "output", "o", "Linting results output format. "+output.Usage()) command.Flags().BoolVar(&strict, "strict", true, "perform strict workflow validation") return command } diff --git a/cmd/argo/commands/template/list.go b/cmd/argo/commands/template/list.go index 42b4b21aa59c..3dad60149e13 100644 --- a/cmd/argo/commands/template/list.go +++ b/cmd/argo/commands/template/list.go @@ -11,18 +11,19 @@ import ( "k8s.io/apimachinery/pkg/labels" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" ) type listFlags struct { - allNamespaces bool // --all-namespaces - output string // --output - labels string // --selector + allNamespaces bool // --all-namespaces + output common.EnumFlagValue // --output + labels string // --selector } func NewListCommand() *cobra.Command { - var listArgs listFlags + var listArgs = listFlags{output: common.EnumFlagValue{AllowedValues: []string{"wide", "name"}}} command := &cobra.Command{ Use: "list", Short: "list workflow templates", @@ -53,7 +54,7 @@ func NewListCommand() *cobra.Command { if err != nil { return err } - switch listArgs.output { + switch listArgs.output.String() { case "", "wide": printTable(wftmplList.Items, &listArgs) case "name": @@ -67,7 +68,7 @@ func NewListCommand() *cobra.Command { }, } command.Flags().BoolVarP(&listArgs.allNamespaces, "all-namespaces", "A", false, "Show workflows from all namespaces") - command.Flags().StringVarP(&listArgs.output, "output", "o", "", "Output format. One of: wide|name") + command.Flags().VarP(&listArgs.output, "output", "o", "Output format. "+listArgs.output.Usage()) command.Flags().StringVarP(&listArgs.labels, "selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") return command } diff --git a/cmd/argo/commands/template/update.go b/cmd/argo/commands/template/update.go index 95e5c7617786..4849a4783985 100644 --- a/cmd/argo/commands/template/update.go +++ b/cmd/argo/commands/template/update.go @@ -7,16 +7,17 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client" + "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/common" workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" ) type cliUpdateOpts struct { - output string // --output - strict bool // --strict + output common.EnumFlagValue // --output + strict bool // --strict } func NewUpdateCommand() *cobra.Command { - var cliUpdateOpts cliUpdateOpts + var cliUpdateOpts = cliUpdateOpts{output: common.NewPrintWorkflowOutputValue("")} command := &cobra.Command{ Use: "update FILE1 FILE2...", Short: "update a workflow template", @@ -34,7 +35,7 @@ func NewUpdateCommand() *cobra.Command { return updateWorkflowTemplates(cmd.Context(), args, &cliUpdateOpts) }, } - command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide") + command.Flags().VarP(&cliUpdateOpts.output, "output", "o", "Output format. "+cliUpdateOpts.output.Usage()) command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation") return command } @@ -73,7 +74,7 @@ func updateWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *c if err != nil { return fmt.Errorf("Failed to update workflow template: %v", err) } - printWorkflowTemplate(updated, cliOpts.output) + printWorkflowTemplate(updated, cliOpts.output.String()) } return nil } diff --git a/cmd/workflow-controller/main.go b/cmd/workflow-controller/main.go index 7bf2d0984fc7..9b2247c62fd4 100644 --- a/cmd/workflow-controller/main.go +++ b/cmd/workflow-controller/main.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "strings" + "sync" "time" "github.com/argoproj/pkg/cli" @@ -134,9 +135,15 @@ func NewRootCommand() *cobra.Command { } // for controlling the dummy metrics server + var wg sync.WaitGroup dummyCtx, dummyCancel := context.WithCancel(context.Background()) defer dummyCancel() - go wfController.RunPrometheusServer(dummyCtx, true) + + wg.Add(1) + go func() { + wfController.RunPrometheusServer(dummyCtx, true) + wg.Done() + }() go leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ Lock: &resourcelock.LeaseLock{ @@ -150,12 +157,18 @@ func NewRootCommand() *cobra.Command { Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(ctx context.Context) { dummyCancel() + wg.Wait() go wfController.Run(ctx, workflowWorkers, workflowTTLWorkers, podCleanupWorkers, cronWorkflowWorkers, workflowArchiveWorkers) - go wfController.RunPrometheusServer(ctx, false) + wg.Add(1) + go func() { + wfController.RunPrometheusServer(ctx, false) + wg.Done() + }() }, OnStoppedLeading: func() { log.WithField("id", nodeID).Info("stopped leading") cancel() + wg.Wait() go wfController.RunPrometheusServer(dummyCtx, true) }, OnNewLeader: func(identity string) { diff --git a/config/config.go b/config/config.go index edccd9fa1ba3..8462838b4ca5 100644 --- a/config/config.go +++ b/config/config.go @@ -6,6 +6,8 @@ import ( "net/url" "time" + metricsdk "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -24,6 +26,9 @@ type Config struct { // NodeEvents configures how node events are emitted NodeEvents NodeEvents `json:"nodeEvents,omitempty"` + // WorkflowEvents configures how workflow events are emitted + WorkflowEvents WorkflowEvents `json:"workflowEvents,omitempty"` + // Executor holds container customizations for the executor to use when running pods Executor *apiv1.Container `json:"executor,omitempty"` @@ -288,13 +293,28 @@ type MetricsConfig struct { Temporality MetricsTemporality `json:"temporality,omitempty"` } -func (mc MetricsConfig) GetSecure(defaultValue bool) bool { +func (mc *MetricsConfig) GetSecure(defaultValue bool) bool { if mc.Secure != nil { return *mc.Secure } return defaultValue } +func (mc *MetricsConfig) GetTemporality() metricsdk.TemporalitySelector { + switch mc.Temporality { + case MetricsTemporalityCumulative: + return func(metricsdk.InstrumentKind) metricdata.Temporality { + return metricdata.CumulativeTemporality + } + case MetricsTemporalityDelta: + return func(metricsdk.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + } + default: + return metricsdk.DefaultTemporalitySelector + } +} + type WorkflowRestrictions struct { TemplateReferencing TemplateReferencing `json:"templateReferencing,omitempty"` } diff --git a/config/workflow_events.go b/config/workflow_events.go new file mode 100644 index 000000000000..45dfa250f719 --- /dev/null +++ b/config/workflow_events.go @@ -0,0 +1,9 @@ +package config + +type WorkflowEvents struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func (e WorkflowEvents) IsEnabled() bool { + return e.Enabled == nil || *e.Enabled +} diff --git a/config/workflow_events_test.go b/config/workflow_events_test.go new file mode 100644 index 000000000000..235400ae67bc --- /dev/null +++ b/config/workflow_events_test.go @@ -0,0 +1,14 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/utils/ptr" +) + +func TestWorkflowEvents_IsEnabled(t *testing.T) { + assert.True(t, WorkflowEvents{}.IsEnabled()) + assert.False(t, WorkflowEvents{Enabled: ptr.To(false)}.IsEnabled()) + assert.True(t, WorkflowEvents{Enabled: ptr.To(true)}.IsEnabled()) +} diff --git a/dev/nix/conf.nix b/dev/nix/conf.nix index 68ca78dff0aa..1850eb2d0f22 100644 --- a/dev/nix/conf.nix +++ b/dev/nix/conf.nix @@ -24,6 +24,7 @@ rec { LOGS = "true"; # same as CTRL - not acted upon UI = "true"; # same as CTRL API = "true"; # same as CTRL + UI_SECURE = "false"; PLUGINS = "false"; }; controller = { @@ -50,7 +51,10 @@ rec { args = "--loglevel ${env.LOG_LEVEL} server --namespaced=${env.NAMESPACED} --auth-mode ${env.AUTH_MODE} --secure=${env.SECURE} --x-frame-options=SAMEORIGIN"; }; ui = { - env = { }; + env = { + ARGO_UI_SECURE = "${env.UI_SECURE}"; + ARGO_SECURE = "${env.SECURE}"; + }; args = "--cwd ui start"; }; } diff --git a/docs/cli/argo_archive_list.md b/docs/cli/argo_archive_list.md index c27daefa86c8..72f710582d72 100644 --- a/docs/cli/argo_archive_list.md +++ b/docs/cli/argo_archive_list.md @@ -28,7 +28,7 @@ argo archive list [flags] ``` --chunk-size int Return large lists in chunks rather than all at once. Pass 0 to disable. -h, --help help for list - -o, --output string Output format. One of: json|yaml|wide (default "wide") + -o, --output string Output format. One of: name|json|yaml|wide (default "wide") -l, --selector string Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2) ``` diff --git a/docs/cli/argo_cluster-template_get.md b/docs/cli/argo_cluster-template_get.md index 883efc666340..93168ddc1ac2 100644 --- a/docs/cli/argo_cluster-template_get.md +++ b/docs/cli/argo_cluster-template_get.md @@ -10,7 +10,7 @@ argo cluster-template get CLUSTER WORKFLOW_TEMPLATE... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/cli/argo_cron_get.md b/docs/cli/argo_cron_get.md index ce50ab0aca4b..e61141040612 100644 --- a/docs/cli/argo_cron_get.md +++ b/docs/cli/argo_cron_get.md @@ -10,7 +10,7 @@ argo cron get CRON_WORKFLOW... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/cli/argo_get.md b/docs/cli/argo_get.md index 3f3ffdcfede4..f72d8db767d8 100644 --- a/docs/cli/argo_get.md +++ b/docs/cli/argo_get.md @@ -25,7 +25,7 @@ argo get WORKFLOW... [flags] --no-color Disable colorized output --no-utf8 Use plain 7-bits ascii characters --node-field-selector string selector of node to display, eg: --node-field-selector phase=abc - -o, --output string Output format. One of: json|yaml|short|wide + -o, --output string Output format. One of: name|json|yaml|short|wide --status string Filter by status (Pending, Running, Succeeded, Skipped, Failed, Error) ``` diff --git a/docs/cli/argo_list.md b/docs/cli/argo_list.md index 05ae34c77c5a..55b47de123ea 100644 --- a/docs/cli/argo_list.md +++ b/docs/cli/argo_list.md @@ -48,7 +48,7 @@ argo list [flags] -h, --help help for list --no-headers Don't print headers (default print headers). --older string List completed workflows finished before the specified duration (e.g. 10m, 3h, 1d) - -o, --output string Output format. One of: name|wide|yaml|json + -o, --output string Output format. One of: name|json|yaml|wide --prefix string Filter workflows by prefix --resubmitted Show resubmitted workflows --running Show running workflows. Mutually exclusive with --completed. diff --git a/docs/cli/argo_template_get.md b/docs/cli/argo_template_get.md index 054abb1cba3d..2d539988ec05 100644 --- a/docs/cli/argo_template_get.md +++ b/docs/cli/argo_template_get.md @@ -10,7 +10,7 @@ argo template get WORKFLOW_TEMPLATE... [flags] ``` -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide + -o, --output string Output format. One of: name|json|yaml|wide ``` ### Options inherited from parent commands diff --git a/docs/client-libraries.md b/docs/client-libraries.md index 451c381495cf..c8fb03cbdc5a 100644 --- a/docs/client-libraries.md +++ b/docs/client-libraries.md @@ -12,11 +12,11 @@ Client libraries often handle common tasks such as authentication for you. The following client libraries are auto-generated using [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator-cli). Please expect very minimal support from the Argo team. -| Language | Client Library | Examples/Docs | -|----------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| -| Golang | [`apiclient.go`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/apiclient.go) | [Example](https://github.com/argoproj/argo-workflows/blob/main/cmd/argo/commands/submit.go) | -| Java | [Java](https://github.com/argoproj/argo-workflows/blob/main/sdks/java) | | -| Python | [Python](https://github.com/argoproj/argo-workflows/blob/main/sdks/python) | | +| Language | Client Library | Examples/Docs | +|----------|---------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| Golang | [`apiclient.go`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/apiclient.go) | [Example](https://github.com/argoproj/argo-workflows/blob/main/cmd/argo/commands/submit.go) | +| Java | [Java](https://github.com/argoproj/argo-workflows/blob/main/sdks/java) | | +| Python | ⚠️ deprecated [Python](https://github.com/argoproj/argo-workflows/blob/main/sdks/python) | Use one of the [community-maintained](#community-maintained-client-libraries) instead. Will be removed in version 3.7 | ## Community-maintained client libraries @@ -24,5 +24,5 @@ The following client libraries are provided and maintained by their authors, not | Language | Client Library | Examples/Docs | |----------|---------------------------------------------------------|--------------------------------------------------------------------------| -| Python | [Couler](https://github.com/couler-proj/couler) | Multi-workflow engine support Python SDK | | Python | [Hera](https://github.com/argoproj-labs/hera-workflows) | Easy and accessible Argo workflows construction and submission in Python | +| Python | [Couler](https://github.com/couler-proj/couler) | Multi-workflow engine support Python SDK. May be unmaintained. | diff --git a/docs/cron-workflows.md b/docs/cron-workflows.md index 281366a5feef..cdc7b440420c 100644 --- a/docs/cron-workflows.md +++ b/docs/cron-workflows.md @@ -44,14 +44,15 @@ You can use `CronWorkflow.spec.workflowMetadata` to add `labels` and `annotation | Option Name | Default Value | Description | |:----------------------------:|:----------------------:|-------------| | `schedule` | None | [Cron schedule](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`. Deprecated, use `schedules`. | -| `schedules` | None | v3.6 and after: List of [Cron schedules](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`, `0 1 * * *`. Either `schedule` or `schedules` must be provided. | +| `schedules` | None | v3.6 and after: List of [Cron schedules](#cron-schedule-syntax) to run `Workflows`. Example: `5 4 * * *`, `0 1 * * *`. Either `schedule` or `schedules` must be provided. | | `timezone` | Machine timezone | [IANA Timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to run `Workflows`. Example: `America/Los_Angeles` | | `suspend` | `false` | If `true` Workflow scheduling will not occur. Can be set from the CLI, GitOps, or directly | | `concurrencyPolicy` | `Allow` | What to do if multiple `Workflows` are scheduled at the same time. `Allow`: allow all, `Replace`: remove all old before scheduling new, `Forbid`: do not allow any new while there are old | | `startingDeadlineSeconds` | `0` | Seconds after [the last scheduled time](#crash-recovery) during which a missed `Workflow` will still be run. | | `successfulJobsHistoryLimit` | `3` | Number of successful `Workflows` to persist | | `failedJobsHistoryLimit` | `1` | Number of failed `Workflows` to persist | -| `stopStrategy` | `nil` | v3.6 and after: defines if the CronWorkflow should stop scheduling based on a condition | +| `stopStrategy.expression` | `nil` | v3.6 and after: defines if the CronWorkflow should stop scheduling based on an expression, which if present must evaluate to false for the workflow to be created | +| `when` | None | v3.6 and after: An optional [expression](walk-through/conditionals.md) which will be evaluated on each cron schedule hit and the workflow will only run if it evaluates to `true` | ### Cron Schedule Syntax @@ -109,35 +110,70 @@ For example, with `timezone: America/Los_Angeles`: | | 2 | 2020-11-02 02:01:00 -0800 PST | | | 3 | 2020-11-03 02:01:00 -0800 PST | +#### Skip forward (missing schedule) + +You can use `when` to schedule once per day, even if the time you want is in a daylight saving skip forward period where it would otherwise be scheduled twice. + +An example 02:30:00 schedule + +```yaml +schedules: + - 30 2 * * * + - 0 3 * * * +when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 3600 }}" +``` + +The 3:00 run of the schedule will not be scheduled every day of the year except on the day when the clock leaps forward over 2:30. +The `when` expression prevents this workflow from running more than once an hour. +In that case the 3:00 run will run, as 2:30 was skipped over. + +!!! Warning "Can run at 3:00" + If you create this CronWorkflow between the desired time and 3:00 it will run at 3:00 as it has never run before. + +#### Skip backwards (duplication) + +You can use `when` to schedule once per day, even if the time you want is in a daylight saving skip backwards period where it would otherwise not be scheduled. + +An example 01:30:00 schedule + +```yaml +schedules: + - 30 1 * * * +when: "{{= cronworkflow.lastScheduledTime == nil || (now() - cronworkflow.lastScheduledTime).Seconds() > 7200 }}" +``` + +This will schedule at the first 01:30 on a skip backwards change. +The second will not run because of the `when` expression, which prevents this workflow running more often than once every 2 hours.. + ### Automatically Stopping a `CronWorkflow` > v3.6 and after You can configure a `CronWorkflow` to automatically stop based on an [expression](variables.md#expression) with `stopStrategy.condition`. -You can use the [variables](variables.md#stopstrategy) `failed` and `succeeded`. +You can use the [variables](variables.md#cronworkflows) `cronworkflow.failed` and `cronworkflow.succeede2d`. For example, if you want to stop scheduling new workflows after one success: ```yaml stopStrategy: - condition: "succeeded >= 1" + expression: "cronworkflow.succeeded >= 1" ``` You can also stop scheduling new workflows after three failures with: ```yaml stopStrategy: - condition: "failed >= 3" + expression: "cronworkflow.failed >= 3" ``` !!! Warning "Scheduling vs. Completions" Depending on the time it takes to schedule and run a workflow, the number of completions can exceed the configured maximum. - For example, if you configure the `CronWorkflow` to schedule every minute (`* * * * *`) and stop after one success (`succeeded >= 1`). + For example, if you configure the `CronWorkflow` to schedule every minute (`* * * * *`) and stop after one success (`cronworkflow.succeeded >= 1`). If the `Workflow` takes 90 seconds to run, the `CronWorkflow` will actually stop after two completions. This is because when the stopping condition is achieved, there is _already_ another `Workflow` running. - For that reason, prefer conditions like `succeeded >= 1` over `succeeded == 1`. + For that reason, prefer conditions like `cronworkflow.succeeded >= 1` over `cronworkflow.succeeded == 1`. ## Managing `CronWorkflow` diff --git a/docs/deprecations.md b/docs/deprecations.md new file mode 100644 index 000000000000..b830701e6794 --- /dev/null +++ b/docs/deprecations.md @@ -0,0 +1,75 @@ +# Deprecations + +Sometimes a feature of Argo Workflows is deprecated. +You should stop using a deprecated feature as it may be removed in a future minor or major release of Argo Workflows. + +To determine if you are using a deprecated feature the [`deprecated_feature`](metrics.md#deprecated_feature) metric can help. +This metric will go up for each use of a deprecated feature by the workflow controller. +This means it may go up once or many times for a single event. +If the number is going up the feature is still in use by your system. +If the metric is not present or no longer increasing are no longer using the monitored deprecated features. + +## `cronworkflow schedule` + +The spec field `schedule` which takes a single value is replaced by `schedules` which takes a list. +To update this replace the `schedule` with `schedules` as in the following example + +```yaml +spec: + schedule: "30 1 * * *" +``` + +is replaced with + +```yaml +spec: + schedules: + - "30 1 * * *" +``` + +## `synchronization mutex` + +The synchronization field `mutex` which takes a single value is replaced by `mutexes` which takes a list. +To update this replace `mutex` with `mutexes` as in the following example + +```yaml +synchronization: + mutex: + name: foobar +``` + +is replaced with + +```yaml +synchronization: + mutexes: + - name: foobar +``` + +## `synchronization semaphore` + +The synchronization field `semaphore` which takes a single value is replaced by `semaphores` which takes a list. +To update this replace `semaphore` with `semaphores` as in the following example + +```yaml +synchronization: + semaphore: + configMapKeyRef: + name: my-config + key: workflow +``` + +is replaced with + +```yaml +synchronization: + semaphores: + - configMapKeyRef: + name: my-config + key: workflow +``` + +## `workflow podpriority` + +The Workflow spec field `podPriority` which takes a numeric value is deprecated and `podPriorityClassName` should be used instead. +To update this you will need a [PriorityClass](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass) in your cluster and refer to that using `podPriorityClassName`. diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 66f0145724e5..45ee275208e7 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -23,6 +23,7 @@ This document outlines environment variables that can be used to customize behav | `ARGO_AGENT_CPU_LIMIT` | `resource.Quantity` | `100m` | CPU resource limit for the agent. | | `ARGO_AGENT_MEMORY_LIMIT` | `resource.Quantity` | `256m` | Memory resource limit for the agent. | | `ARGO_POD_STATUS_CAPTURE_FINALIZER` | `bool` | `false` | The finalizer blocks the deletion of pods until the controller captures their status. +| `ARGO_TEMPLATE_WITH_INPUTS_PARAMETERS` | `bool` | `true` | Whether to keep inputs.parameters inside the ARGO_TEMPLATE environment variable of pods. | `BUBBLE_ENTRY_TEMPLATE_ERR` | `bool` | `true` | Whether to bubble up template errors to workflow. | | `CACHE_GC_PERIOD` | `time.Duration` | `0s` | How often to perform memoization cache GC, which is disabled by default and can be enabled by providing a non-zero duration. | | `CACHE_GC_AFTER_NOT_HIT_DURATION` | `time.Duration` | `30s` | When a memoization cache has not been hit after this duration, it will be deleted. | @@ -55,6 +56,7 @@ This document outlines environment variables that can be used to customize behav | `WORKFLOW_GC_PERIOD` | `time.Duration` | `5m` | The periodicity for GC of workflows. | | `SEMAPHORE_NOTIFY_DELAY` | `time.Duration` | `1s` | Tuning Delay when notifying semaphore waiters about availability in the semaphore | | `WATCH_CONTROLLER_SEMAPHORE_CONFIGMAPS` | `bool` | `true` | Whether to watch the Controller's ConfigMap and semaphore ConfigMaps for run-time changes. When disabled, the Controller will only read these ConfigMaps once and will have to be manually restarted to pick up new changes. | +| `SKIP_WORKFLOW_DURATION_ESTIMATION` | `bool` | `false` | Whether to lookup resource usage from prior workflows to estimate usage for new workflows. | CLI parameters of the Controller can be specified as environment variables with the `ARGO_` prefix. For example: diff --git a/docs/fields.md b/docs/fields.md index a34f743aace1..5cc3c8697016 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -1994,12 +1994,12 @@ SynchronizationStatus stores the status of semaphore and mutex. ## StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ### Fields | Field Name | Field Type | Description | |:----------:|:----------:|---------------| -|`condition`|`string`|v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.| +|`expression`|`string`|v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.| ## Artifact @@ -2399,7 +2399,11 @@ Mutex holds Mutex configuration - [`synchronization-mutex-tmpl-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-mutex-wf-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) ### Fields @@ -3291,7 +3295,11 @@ MutexStatus contains which objects hold mutex locks, and which objects this work - [`synchronization-mutex-tmpl-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-mutex-wf-level-legacy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) ### Fields diff --git a/docs/metrics.md b/docs/metrics.md index d9bae309d34e..a1cd4adb586f 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -265,6 +265,23 @@ Suppressed runs due to `concurrencyPolicy: Forbid` will not be counted. | `name` | ⚠️ The name of the CronWorkflow | | `namespace` | The namespace of the CronWorkflow | +#### `deprecated_feature` + +A counter which goes up when a feature which is [deprecated](deprecations.md) is used. +🚨 This counter may go up much more than once for a single use of the feature. + +| attribute | explanation | +|-------------|---------------------------------------------| +| `feature` | The name of the feature used | +| `namespace` | The namespace of the item using the feature | + +`feature` will be one of: + +- [`cronworkflow schedule`](deprecations.md#cronworkflow_schedule) +- [`synchronization mutex`](deprecations.md#synchronization_mutex) +- [`synchronization semaphore`](deprecations.md#synchronization_semaphore) +- [`workflow podpriority`](deprecations.md#workflow_podpriority) + #### `gauge` A gauge of the number of workflows currently in the cluster in each phase. The `Running` count does not mean that a workflows pods are running, just that the controller has scheduled them. A workflow can be stuck in `Running` with pending pods for a long time. diff --git a/docs/running-locally.md b/docs/running-locally.md index 8e5c53ced90d..85f67f0ac5ac 100644 --- a/docs/running-locally.md +++ b/docs/running-locally.md @@ -148,12 +148,41 @@ You'll have, either: * Postgres on , run `make postgres-cli` to access. * MySQL on , run `make mysql-cli` to access. +To back up the database, use `make postgres-dump` or `make mysql-dump`, which will generate a SQL dump in the `db-dumps/` directory. + +```console +make postgres-dump +``` + +To restore the backup, use `make postgres-cli` or `make mysql-cli`, piping in the file from the `db-dumps/` directory. + +Note that this is destructive and will delete any data you have stored. + +```console +make postgres-cli < db-dumps/2024-10-16T17:11:58Z.sql +``` + To test SSO integration, use `PROFILE=sso`: ```bash make start UI=true PROFILE=sso ``` +## TLS + +By default, `make start` will start Argo in [plain text mode](tls.md#plain-text). +To simulate a TLS proxy in front of Argo, use `UI_SECURE=true` (which implies `UI=true`): + +```bash +make start UI_SECURE=true +``` + +To start Argo in [encrypted mode](tls.md#encrypted), use `SECURE=true`, which can be optionally combined with `UI_SECURE=true`: + +```bash +make start SECURE=true UI_SECURE=true +``` + ### Running E2E tests locally Start up Argo Workflows using the following: @@ -206,6 +235,12 @@ Tests often fail: that's good. To diagnose failure: If tests run slowly or time out, factory reset your Kubernetes cluster. +### Debugging using Visual Studio Code + +When using the Dev Container with VSCode, use the `Attach to argo server` and/or `Attach to workflow controller` launch configurations to attach to the `argo` or `workflow-controller` processes, respectively. + +This will allow you to start a debug session, where you can inspect variables and set breakpoints. + ## Committing Before you commit code and raise a PR, always run: diff --git a/docs/synchronization.md b/docs/synchronization.md index 8c5ef695ce90..d18de01fcc8d 100644 --- a/docs/synchronization.md +++ b/docs/synchronization.md @@ -24,10 +24,6 @@ data: template: "2" # Two instances of template can run at a given time in particular namespace ``` -!!! Warning - Each synchronization block may only refer to either a semaphore or a mutex. - If you specify both only the semaphore will be locked. - ## Workflow-level Synchronization You can limit parallel execution of workflows by using the same synchronization reference. @@ -36,44 +32,14 @@ In this example the synchronization key `workflow` is configured as limit `"1"`, Using a semaphore configured by a `ConfigMap`: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-wf-level- -spec: - entrypoint: hello-world - synchronization: - semaphores: - - configMapKeyRef: - name: my-config - key: workflow - templates: - - name: hello-world - container: - image: busybox - command: [echo] - args: ["hello world"] +```yaml title="examples/synchronization-wf-level.yaml" +--8<-- "examples/synchronization-wf-level.yaml:12" ``` Using a mutex is equivalent to a limit `"1"` semaphore: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-wf-level- -spec: - entrypoint: hello-world - synchronization: - mutexes: - - name: workflow - templates: - - name: hello-world - container: - image: busybox - command: [echo] - args: ["hello world"] +```yaml title="examples/synchronization-mutex-wf-level.yaml" +--8<-- "examples/synchronization-mutex-wf-level.yaml:3" ``` ## Template-level Synchronization @@ -85,77 +51,16 @@ This applies even when multiple steps or tasks within a workflow or different wo Using a semaphore configured by a `ConfigMap`: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-tmpl-level- -spec: - entrypoint: synchronization-tmpl-level-example - templates: - - name: synchronization-tmpl-level-example - steps: - - - name: synchronization-acquire-lock - template: acquire-lock - arguments: - parameters: - - name: seconds - value: "{{item}}" - withParam: '["1","2","3","4","5"]' - - - name: acquire-lock - synchronization: - semaphores: - - configMapKeyRef: - name: my-config - key: template - container: - image: alpine:latest - command: [sh, -c] - args: ["sleep 10; echo acquired lock"] +```yaml title="examples/synchronization-tmpl-level.yaml" +--8<-- "examples/synchronization-tmpl-level.yaml:11" ``` Using a mutex will limit to a single concurrent execution of the template: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: synchronization-tmpl-level- -spec: - entrypoint: synchronization-tmpl-level-example - templates: - - name: synchronization-tmpl-level-example - steps: - - - name: synchronization-acquire-lock - template: acquire-lock - arguments: - parameters: - - name: seconds - value: "{{item}}" - withParam: '["1","2","3","4","5"]' - - - name: acquire-lock - synchronization: - mutexes: - - name: template - container: - image: alpine:latest - command: [sh, -c] - args: ["sleep 10; echo acquired lock"] +```yaml title="examples/synchronization-mutex-tmpl-level.yaml" +--8<-- "examples/synchronization-mutex-tmpl-level.yaml:3" ``` -Examples: - -1. [Workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level.yaml) -1. [Workflow level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level.yaml) -1. [Step level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-tmpl-level.yaml) -1. [Step level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level.yaml) -1. [Legacy workflow level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-wf-level-legacy.yaml) -1. [Legacy workflow level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-wf-level-legacy.yaml) -1. [Legacy step level semaphore](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-tmpl-level-legacy.yaml) -1. [Legacy step level mutex](https://github.com/argoproj/argo-workflows/blob/main/examples/synchronization-mutex-tmpl-level-legacy.yaml) - ## Queuing When a workflow cannot acquire a lock it will be placed into a ordered queue. @@ -204,30 +109,6 @@ Examples: !!! Warning If a Workflow is at the front of the queue and it needs to acquire multiple locks, all other Workflows that also need those same locks will wait. This applies even if the other Workflows only wish to acquire a subset of those locks. -## Legacy - -In workflows prior to 3.6 you can only specify one lock in any one workflow or template using either a mutex: - -```yaml - synchronization: - mutex: - ... -``` - -or a semaphore: - -```yaml - synchronizaion: - semamphore: - ... -``` - -Specifying both would not work in <3.6, only the semaphore would be used. - -The single `mutex` and `semaphore` syntax still works in version 3.6 but is considered deprecated. -Both the `mutex` and the `semaphore` will be taken in version 3.6 with this syntax. -This syntax can be mixed with `mutexes` and `semaphores`, all locks will be required. - ## Other Parallelism support You can also [restrict parallelism at the Controller-level](parallelism.md). diff --git a/docs/upgrading.md b/docs/upgrading.md index d17f155899a8..74ec313eb94f 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -5,6 +5,15 @@ the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summar ## Upgrading to v3.6 +### Deprecations + +The following features are deprecated and will be removed in a future verison of Argo Workflows: + +* The Python SDK is deprecated, we recommend migrating to [Hera](https://github.com/argoproj-labs/hera) +* `schedule` in CronWorkflows, `podPriority`, `mutex` and `semaphore` in Workflows and WorkflowTemplates. + +For more information on how to migrate these see [deprecations](deprecations.md) + ### Fixed Server `--basehref` inconsistency For consistency, the Server now uses `--base-href` and `ARGO_BASE_HREF`. @@ -31,6 +40,7 @@ The following are new metrics: * `cronworkflows_concurrencypolicy_triggered` * `cronworkflows_triggered_total` +* `deprecated_feature` * `is_leader` * `k8s_request_duration` * `pod_pending_count` @@ -78,6 +88,11 @@ Custom metrics, as defined by a workflow, could be defined as one type (say coun The Prometheus `/metrics` endpoint now has TLS enabled by default. To disable this set `metricsConfig.secure` to `false`. +### JSON templating fix + +When returning a map or array in an expression, you would get a Golang representation. +This now returns plain JSON. + ## Upgrading to v3.5 There are no known breaking changes in this release. diff --git a/docs/variables.md b/docs/variables.md index 5274e1f812b1..330d71572c49 100644 --- a/docs/variables.md +++ b/docs/variables.md @@ -197,6 +197,8 @@ Only available for `successCondition` | `cronworkflow.annotations.` | CronWorkflow annotations (`string`) | | `cronworkflow.annotations.json` | CronWorkflow annotations as a JSON string (`string`) | | `cronworkflow.lastScheduledTime` | The time since this workflow was last scheduled, value is nil on first run (`*time.Time`) | +| `cronworkflow.failed` | Counts how many times child workflows failed | +| `cronworkflow.succeeded` | Counts how many times child workflows succeeded | ### `RetryStrategy` @@ -290,17 +292,6 @@ For `Template`-level metrics: | `workflow.status` | Workflow status. One of: `Succeeded`, `Failed`, `Error` | | `workflow.failures` | A list of JSON objects containing information about nodes that failed or errored during execution. Available fields: `displayName`, `message`, `templateName`, `phase`, `podName`, and `finishedAt`. | -### `stopStrategy` - -> v3.6 and after - -When using the `condition` field within the [`stopStrategy` of a `CronWorkflow`](cron-workflows.md#automatically-stopping-a-cronworkflow), special variables are available. - -| Variable | Description| -|----------|------------| -| `failed` | Counts how many times child workflows failed | -| `succeeded` | Counts how many times child workflows succeeded | - ### Knowing where you are The idea with creating a `WorkflowTemplate` is that they are reusable bits of code you will use in many actual Workflows. Sometimes it is useful to know which workflow you are part of. diff --git a/docs/workflow-controller-configmap.yaml b/docs/workflow-controller-configmap.yaml index efb6cdabe113..b91e457d9f1d 100644 --- a/docs/workflow-controller-configmap.yaml +++ b/docs/workflow-controller-configmap.yaml @@ -41,6 +41,13 @@ data: nodeEvents: | enabled: true + # Whether or not to emit events on workflow status changes. These can take a up a lot of space in + # k8s (typically etcd), see nodeEvents above. + # This config item allows you to disable this. + # (since v3.6) + workflowEvents: | + enabled: true + # uncomment following lines if workflow controller runs in a different k8s cluster with the # workflow workloads, or needs to communicate with the k8s apiserver using an out-of-cluster # kubeconfig secret diff --git a/docs/workflow-templates.md b/docs/workflow-templates.md index bb52956fab80..63b66dc29229 100644 --- a/docs/workflow-templates.md +++ b/docs/workflow-templates.md @@ -249,37 +249,6 @@ spec: value: "hello world" ``` -You should **never** reference another template directly on a `template` object (outside of a `steps` or `dag` template). -This includes both using `template` and `templateRef`. -This behavior is deprecated, no longer supported, and will be removed in a future version. - -Here is an example of a **deprecated** reference that **should not be used**: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: workflow-template-hello-world- -spec: - entrypoint: hello-world - templates: - - name: hello-world - template: # You should NEVER use "template" here. Use it under a "steps" or "dag" template (see above). - templateRef: # You should NEVER use "templateRef" here. Use it under a "steps" or "dag" template (see above). - name: workflow-template-1 - template: print-message - arguments: # Arguments here are ignored. Use them under a "steps" or "dag" template (see above). - parameters: - - name: message - value: "hello world" -``` - -The reasoning for deprecating this behavior is that a `template` is a "definition": it defines inputs and things to be -done once instantiated. With this deprecated behavior, the same template object is allowed to be an "instantiator": -to pass in "live" arguments and reference other templates (those other templates may be "definitions" or "instantiators"). - -This behavior has been problematic and dangerous. It causes confusion and has design inconsistencies. - ### Create `Workflow` from `WorkflowTemplate` Spec > v2.9 and after diff --git a/examples/http-hello-world.yaml b/examples/http-hello-world.yaml index 1c58b604b507..429120d4582e 100644 --- a/examples/http-hello-world.yaml +++ b/examples/http-hello-world.yaml @@ -22,8 +22,8 @@ spec: continueOn: failed: true arguments: - parameters: [{name: url, value: "http://openlibrary.org/people/george08/nofound.json"}] - + parameters: [{name: url, value: "https://raw.githubusercontent.com/argoproj/argo-workflows/thisisnotahash/pkg/apis/workflow/v1alpha1/generated.swagger.json"}] + - name: http inputs: parameters: @@ -31,4 +31,3 @@ spec: http: # url: http://dummy.restapiexample.com/api/v1/employees url: "{{inputs.parameters.url}}" - diff --git a/examples/synchronization-mutex-tmpl-level-legacy.yaml b/examples/synchronization-mutex-tmpl-level-legacy.yaml index 9652e48a7d0a..3ad2648c0b9c 100644 --- a/examples/synchronization-mutex-tmpl-level-legacy.yaml +++ b/examples/synchronization-mutex-tmpl-level-legacy.yaml @@ -1,6 +1,5 @@ # This example demonstrates the use of a Synchronization Mutex lock on template execution. Mutex lock limits # only one of the template execution across the workflows in the namespace which has same Mutex lock. - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: @@ -28,8 +27,10 @@ spec: - name: acquire-lock synchronization: - mutex: + mutex: # deprecated: v3.5 and before name: welcome + # mutexes: # v3.6 and after + # - name: welcome container: image: alpine:latest command: [sh, -c] @@ -37,9 +38,11 @@ spec: - name: acquire-lock-1 synchronization: - mutex: + mutex: # deprecated: v3.5 and before name: test + # mutexes: # v3.6 and after + # - name: test container: image: alpine:latest command: [sh, -c] - args: ["sleep 50; echo acquired lock"] \ No newline at end of file + args: ["sleep 50; echo acquired lock"] diff --git a/examples/synchronization-mutex-tmpl-level.yaml b/examples/synchronization-mutex-tmpl-level.yaml index c2368cca835d..948634e92e0f 100644 --- a/examples/synchronization-mutex-tmpl-level.yaml +++ b/examples/synchronization-mutex-tmpl-level.yaml @@ -1,6 +1,5 @@ # This example demonstrates the use of a Synchronization Mutex lock on template execution. Mutex lock limits # only one of the template execution across the workflows in the namespace which has same Mutex lock. - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: @@ -28,8 +27,10 @@ spec: - name: acquire-lock synchronization: - mutexes: + mutexes: # v3.6 and after - name: welcome + # mutex: # deprecated: v3.5 and before + # name: welcome container: image: alpine:latest command: [sh, -c] @@ -37,8 +38,10 @@ spec: - name: acquire-lock-1 synchronization: - mutexes: + mutexes: # v3.6 and after - name: test + # mutex: # deprecated: v3.5 and before + # name: test container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-mutex-wf-level-legacy.yaml b/examples/synchronization-mutex-wf-level-legacy.yaml index f13b199c6aaa..cc4689bbd234 100644 --- a/examples/synchronization-mutex-wf-level-legacy.yaml +++ b/examples/synchronization-mutex-wf-level-legacy.yaml @@ -7,8 +7,10 @@ metadata: spec: entrypoint: hello-world synchronization: - mutex: - name: test + mutex: # deprecated: v3.5 and before + name: test + # mutexes: # v3.6 and after + # - name: test templates: - name: hello-world container: diff --git a/examples/synchronization-mutex-wf-level.yaml b/examples/synchronization-mutex-wf-level.yaml index 00494c3a8cd0..8d3f45af4811 100644 --- a/examples/synchronization-mutex-wf-level.yaml +++ b/examples/synchronization-mutex-wf-level.yaml @@ -7,8 +7,10 @@ metadata: spec: entrypoint: hello-world synchronization: - mutexes: + mutexes: # v3.6 and after - name: test + # mutex: # deprecated: v3.5 and before + # name: test templates: - name: hello-world container: diff --git a/examples/synchronization-tmpl-level-legacy.yaml b/examples/synchronization-tmpl-level-legacy.yaml index b8c0f79c6c6f..1bc96e22f04f 100644 --- a/examples/synchronization-tmpl-level-legacy.yaml +++ b/examples/synchronization-tmpl-level-legacy.yaml @@ -27,10 +27,14 @@ spec: - name: acquire-lock synchronization: - semaphore: + semaphore: # deprecated: v3.5 and before configMapKeyRef: name: my-config key: template + # semaphores: # v3.6 and after + # - configMapKeyRef: + # name: my-config + # key: template container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-tmpl-level.yaml b/examples/synchronization-tmpl-level.yaml index d9eafd230ca1..47232505ee32 100644 --- a/examples/synchronization-tmpl-level.yaml +++ b/examples/synchronization-tmpl-level.yaml @@ -27,10 +27,14 @@ spec: - name: acquire-lock synchronization: - semaphores: + semaphores: # v3.6 and after - configMapKeyRef: name: my-config key: template + # semaphore: # deprecated: v3.5 and before + # configMapKeyRef: + # name: my-config + # key: template container: image: alpine:latest command: [sh, -c] diff --git a/examples/synchronization-wf-level-legacy.yaml b/examples/synchronization-wf-level-legacy.yaml index b7ed90a092ca..fa89a65c200d 100644 --- a/examples/synchronization-wf-level-legacy.yaml +++ b/examples/synchronization-wf-level-legacy.yaml @@ -16,10 +16,14 @@ metadata: spec: entrypoint: hello-world synchronization: - semaphore: + semaphore: # deprecated: v3.5 and before configMapKeyRef: name: my-config key: workflow + # semaphores: # v3.6 and after + # - configMapKeyRef: + # name: my-config + # key: workflow templates: - name: hello-world container: diff --git a/examples/synchronization-wf-level.yaml b/examples/synchronization-wf-level.yaml index 33a8e11f7eb2..060c09cf1711 100644 --- a/examples/synchronization-wf-level.yaml +++ b/examples/synchronization-wf-level.yaml @@ -16,10 +16,14 @@ metadata: spec: entrypoint: hello-world synchronization: - semaphores: + semaphores: # v3.6 and after - configMapKeyRef: name: my-config key: workflow + # semaphore: # deprecated: v3.5 and before + # configMapKeyRef: + # name: my-config + # key: workflow templates: - name: hello-world container: diff --git a/hack/git/hooks/commit-msg b/hack/git/hooks/commit-msg index bae720f594fc..73600e06f051 100755 --- a/hack/git/hooks/commit-msg +++ b/hack/git/hooks/commit-msg @@ -6,7 +6,7 @@ grep -q 'Signed-off-by: ' "$1" || { exit 1 } -grep -qE '^(?:build|feat|fix|docs|style|refactor|perf|test|ci|chore|revert)\(?(?:\w+|\s|\-|_)?\)?!?:\s\w+' "$1" || grep -q 'Merge' "$1" || { +grep -qE '^(build|feat|fix|docs|style|refactor|perf|test|ci|chore|revert)\(?(\w+|\s|\-|_)?\)?!?:\s\w+' "$1" || grep -q 'Merge' "$1" || { echo >&2 '❌ Commit message must be semantic: https://github.com/zeke/semantic-pull-requests' >&2 exit 1 } diff --git a/hack/manifests/crdgen.sh b/hack/manifests/crdgen.sh index e75feab2af32..2b503ee91ca4 100755 --- a/hack/manifests/crdgen.sh +++ b/hack/manifests/crdgen.sh @@ -18,5 +18,5 @@ find manifests/base/crds/full -name 'argoproj.io*.yaml' | while read -r file; do minimal="manifests/base/crds/minimal/$(basename "$file")" echo "Creating minimal CRD file: ${minimal}" cp "$file" "$minimal" - go run ./hack/manifests removecrdvalidation "$minimal" + go run ./hack/manifests minimizecrd "$minimal" done diff --git a/hack/manifests/crds.go b/hack/manifests/crds.go index b34096161bc5..5162500a920b 100644 --- a/hack/manifests/crds.go +++ b/hack/manifests/crds.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "path/filepath" @@ -46,25 +47,42 @@ func cleanCRD(filename string) { } } -func removeCRDValidation(filename string) { +// minimizeCRD is a workaround for two separate issues: +// 1. "Request entity too large: limit is 3145728" errors due to https://github.com/kubernetes/kubernetes/issues/82292 +// 2. "spec.validation.openAPIV3Schema.properties[spec].properties[tasks].additionalProperties.properties[steps].items.items: Required value: must be specified" due to kubebuilder issues (https://github.com/argoproj/argo-workflows/pull/3809#discussion_r472383090) +func minimizeCRD(filename string) { data, err := os.ReadFile(filepath.Clean(filename)) if err != nil { panic(err) } + + shouldMinimize := false + if len(data) > 1024*1024 { + fmt.Printf("Minimizing %s due to CRD size (%d) exceeding 1MB\n", filename, len(data)) + shouldMinimize = true + } + crd := make(obj) err = yaml.Unmarshal(data, &crd) if err != nil { panic(err) } - spec := crd["spec"].(obj) - versions := spec["versions"].([]interface{}) - version := versions[0].(obj) - properties := version["schema"].(obj)["openAPIV3Schema"].(obj)["properties"].(obj) - for k := range properties { - if k == "spec" || k == "status" { - properties[k] = obj{"type": "object", "x-kubernetes-preserve-unknown-fields": true, "x-kubernetes-map-type": "atomic"} + + if !shouldMinimize { + name := crd["metadata"].(obj)["name"].(string) + switch name { + case "cronworkflows.argoproj.io", "clusterworkflowtemplates.argoproj.io", "workflows.argoproj.io", "workflowtemplates.argoproj.io", "workflowtasksets.argoproj.io": + fmt.Printf("Minimizing %s due to kubebuilder issues\n", filename) + shouldMinimize = true } } + + if !shouldMinimize { + return + } + + crd = stripSpecAndStatusFields(crd) + data, err = yaml.Marshal(crd) if err != nil { panic(err) @@ -74,3 +92,17 @@ func removeCRDValidation(filename string) { panic(err) } } + +// stripSpecAndStatusFields strips the "spec" and "status" fields from the CRD, as those are usually the largest. +func stripSpecAndStatusFields(crd obj) obj { + spec := crd["spec"].(obj) + versions := spec["versions"].([]interface{}) + version := versions[0].(obj) + properties := version["schema"].(obj)["openAPIV3Schema"].(obj)["properties"].(obj) + for k := range properties { + if k == "spec" || k == "status" { + properties[k] = obj{"type": "object", "x-kubernetes-preserve-unknown-fields": true, "x-kubernetes-map-type": "atomic"} + } + } + return crd +} diff --git a/hack/manifests/main.go b/hack/manifests/main.go index 5a5292f99326..0b3284b5dc9b 100644 --- a/hack/manifests/main.go +++ b/hack/manifests/main.go @@ -8,8 +8,8 @@ func main() { switch os.Args[1] { case "cleancrd": cleanCRD(os.Args[2]) - case "removecrdvalidation": - removeCRDValidation(os.Args[2]) + case "minimizecrd": + minimizeCRD(os.Args[2]) default: panic(os.Args[1]) } diff --git a/hack/update-sso-redirect-url.sh b/hack/update-sso-redirect-url.sh new file mode 100755 index 000000000000..dece268307d5 --- /dev/null +++ b/hack/update-sso-redirect-url.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +# Rewrite the SSO redirect URL to use HTTPS to support "make start PROFILE=sso UI_SECURE=true". +# Can't use "kubectl patch" because the SSO config is a YAML string. +kubectl -n "${KUBE_NAMESPACE}" get configmap workflow-controller-configmap -o yaml | \ + sed 's@redirectUrl: http://localhost:8080/oauth2/callback@redirectUrl: https://localhost:8080/oauth2/callback@' | \ + kubectl apply -n "${KUBE_NAMESPACE}" -f - \ No newline at end of file diff --git a/manifests/base/crds/full/README.md b/manifests/base/crds/full/README.md index bca5186fefe5..e81aba5a49ea 100644 --- a/manifests/base/crds/full/README.md +++ b/manifests/base/crds/full/README.md @@ -1,3 +1,4 @@ # Full CRDs -These CRDs have full schema validation. As a result, they are large and probably not suitable to be used in your cluster. +These CRDs have the full schema. +As a result, they are large and probably not suitable to be used in your cluster due to [kubernetes/kubernetes#82292](https://github.com/kubernetes/kubernetes/issues/82292). \ No newline at end of file diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index 8864d4613139..4d46ecb5a95c 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -43,10 +43,10 @@ spec: type: integer stopStrategy: properties: - condition: + expression: type: string required: - - condition + - expression type: object successfulJobsHistoryLimit: format: int32 diff --git a/manifests/base/crds/minimal/README.md b/manifests/base/crds/minimal/README.md index 55f48f08081f..b7d131b4691e 100644 --- a/manifests/base/crds/minimal/README.md +++ b/manifests/base/crds/minimal/README.md @@ -1,3 +1,3 @@ # Minimal CRDs -These CRDs omit schema validation. +These CRDs omit large fields as a workaround for [kubernetes/kubernetes#82292](https://github.com/kubernetes/kubernetes/issues/82292). diff --git a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml index 35b1e2eab548..d5f34672e00f 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -24,13 +25,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml index 22e2ecf0f6b4..0477a0907692 100644 --- a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -24,9 +25,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml index 5f8d1f4e863f..bccbf467f6b4 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml @@ -1,3 +1,4 @@ +# This is an auto-generated file. DO NOT EDIT apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/manifests/quick-start-minimal.yaml b/manifests/quick-start-minimal.yaml index 2bb819f867c9..b6b42725cfc6 100644 --- a/manifests/quick-start-minimal.yaml +++ b/manifests/quick-start-minimal.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start-mysql.yaml b/manifests/quick-start-mysql.yaml index a1b95019f15f..4d59148b6169 100644 --- a/manifests/quick-start-mysql.yaml +++ b/manifests/quick-start-mysql.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start-postgres.yaml b/manifests/quick-start-postgres.yaml index 743bcd43cf68..80a8ce0aa6df 100644 --- a/manifests/quick-start-postgres.yaml +++ b/manifests/quick-start-postgres.yaml @@ -103,13 +103,1105 @@ spec: metadata: type: object spec: + properties: + artifactsByNode: + additionalProperties: + properties: + archiveLocation: + properties: + archiveLogs: + type: boolean + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + raw: + properties: + data: + type: string + required: + - data + type: object + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + type: object + artifacts: + additionalProperties: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true status: + properties: + artifactResultsByNode: + additionalProperties: + properties: + artifactResults: + additionalProperties: + properties: + error: + type: string + name: + type: string + success: + type: boolean + required: + - name + type: object + type: object + type: object + type: object type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec @@ -145,9 +1237,653 @@ spec: metadata: type: object spec: + properties: + event: + properties: + selector: + type: string + required: + - selector + type: object + submit: + properties: + arguments: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + dataTransferProtection: + type: string + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbConfigConfigMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbKeytabSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + usernameSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clientSecretSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + securityToken: + type: string + useSDKCreds: + type: boolean + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bucket: + type: string + caSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sessionTokenSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + type: object + metadata: + type: object + workflowTemplateRef: + properties: + clusterScope: + type: boolean + name: + type: string + type: object + required: + - workflowTemplateRef + type: object + required: + - event type: object - x-kubernetes-map-type: atomic - x-kubernetes-preserve-unknown-fields: true required: - metadata - spec diff --git a/manifests/quick-start/sso/dex/dex-cm.yaml b/manifests/quick-start/sso/dex/dex-cm.yaml index a99d186a28c2..689db0affb90 100644 --- a/manifests/quick-start/sso/dex/dex-cm.yaml +++ b/manifests/quick-start/sso/dex/dex-cm.yaml @@ -20,6 +20,7 @@ data: redirectURIs: - http://localhost:2746/oauth2/callback - http://localhost:8080/oauth2/callback + - https://localhost:8080/oauth2/callback name: Argo Server secret: ZXhhbXBsZS1hcHAtc2VjcmV0 connectors: diff --git a/mkdocs.yml b/mkdocs.yml index 52e1dbb74f3b..70dc812ae8bf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -32,6 +32,7 @@ markdown_extensions: - admonition - md_in_html - pymdownx.details + - pymdownx.snippets - pymdownx.superfences: custom_fences: # support mermaid diagrams per https://squidfunk.github.io/mkdocs-material/reference/diagrams/#configuration @@ -248,6 +249,7 @@ nav: - offloading-large-workflows.md - workflow-archive.md - metrics.md + - deprecations.md - workflow-executors.md - workflow-restrictions.md - sidecar-injection.md diff --git a/persist/sqldb/selector.go b/persist/sqldb/selector.go index 5e2b9cbb53ca..93a0b580ad7b 100644 --- a/persist/sqldb/selector.go +++ b/persist/sqldb/selector.go @@ -39,7 +39,19 @@ func BuildWorkflowSelector(in string, inArgs []any, tableName, labelTableName st clauses = append(clauses, db.Raw("namespace = ?", options.Namespace)) } if options.Name != "" { - clauses = append(clauses, db.Raw("name = ?", options.Name)) + nameFilter := options.NameFilter + if nameFilter == "" { + nameFilter = "Exact" + } + if nameFilter == "Exact" { + clauses = append(clauses, db.Raw("name = ?", options.Name)) + } + if nameFilter == "Contains" { + clauses = append(clauses, db.Raw("name like ?", "%"+options.Name+"%")) + } + if nameFilter == "Prefix" { + clauses = append(clauses, db.Raw("name like ?", options.Name+"%")) + } } if options.NamePrefix != "" { clauses = append(clauses, db.Raw("name like ?", options.NamePrefix+"%")) diff --git a/pkg/apiclient/offline-client.go b/pkg/apiclient/offline-client.go index 9446a71240b0..c6048d1dffe8 100644 --- a/pkg/apiclient/offline-client.go +++ b/pkg/apiclient/offline-client.go @@ -12,9 +12,8 @@ import ( "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/file" + "github.com/argoproj/argo-workflows/v3/workflow/common" "github.com/argoproj/argo-workflows/v3/workflow/templateresolution" - - "sigs.k8s.io/yaml" ) type offlineWorkflowTemplateGetterMap map[string]templateresolution.WorkflowTemplateNamespacedGetter @@ -50,42 +49,43 @@ func newOfflineClient(paths []string) (context.Context, Client, error) { for _, basePath := range paths { err := file.WalkManifests(basePath, func(path string, bytes []byte) error { - var generic map[string]interface{} - if err := yaml.Unmarshal(bytes, &generic); err != nil { - return fmt.Errorf("failed to parse YAML from file %s: %w", path, err) - } - switch generic["kind"] { - case "ClusterWorkflowTemplate": - cwftmpl := new(wfv1.ClusterWorkflowTemplate) - if err := yaml.Unmarshal(bytes, &cwftmpl); err != nil { - return fmt.Errorf("failed to unmarshal file %s as a ClusterWorkflowTemplate: %w", path, err) + for _, pr := range common.ParseObjects(bytes, false) { + obj, err := pr.Object, pr.Err + if err != nil { + return fmt.Errorf("failed to parse YAML from file %s: %w", path, err) } - if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[cwftmpl.Name]; ok { - return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", cwftmpl.Name) + if obj == nil { + continue // could not parse to kubernetes object } - clusterWorkflowTemplateGetter.clusterWorkflowTemplates[cwftmpl.Name] = cwftmpl - case "WorkflowTemplate": - wftmpl := new(wfv1.WorkflowTemplate) - if err := yaml.Unmarshal(bytes, &wftmpl); err != nil { - return fmt.Errorf("failed to unmarshal file %s as a WorkflowTemplate: %w", path, err) - } - getter, ok := workflowTemplateGetters[wftmpl.Namespace] - if !ok { - getter = &offlineWorkflowTemplateNamespacedGetter{ - namespace: wftmpl.Namespace, - workflowTemplates: map[string]*wfv1.WorkflowTemplate{}, + objName := obj.GetName() + namespace := obj.GetNamespace() + + switch v := obj.(type) { + case *wfv1.ClusterWorkflowTemplate: + if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName]; ok { + return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", objName) + } + clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName] = v + + case *wfv1.WorkflowTemplate: + getter, ok := workflowTemplateGetters[namespace] + if !ok { + getter = &offlineWorkflowTemplateNamespacedGetter{ + namespace: namespace, + workflowTemplates: map[string]*wfv1.WorkflowTemplate{}, + } + workflowTemplateGetters[namespace] = getter } - workflowTemplateGetters[wftmpl.Namespace] = getter - } - if _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[wftmpl.Name]; ok { - return fmt.Errorf("duplicate WorkflowTemplate found: %q", wftmpl.Name) + if _, ok := getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName]; ok { + return fmt.Errorf("duplicate WorkflowTemplate found: %q", objName) + } + getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[objName] = v } - getter.(*offlineWorkflowTemplateNamespacedGetter).workflowTemplates[wftmpl.Name] = wftmpl - } + } return nil }) diff --git a/pkg/apiclient/offline-cron-workflow-service-client.go b/pkg/apiclient/offline-cron-workflow-service-client.go index 6104a207c89b..6dbd1a7bd407 100644 --- a/pkg/apiclient/offline-cron-workflow-service-client.go +++ b/pkg/apiclient/offline-cron-workflow-service-client.go @@ -19,7 +19,7 @@ type OfflineCronWorkflowServiceClient struct { var _ cronworkflow.CronWorkflowServiceClient = &OfflineCronWorkflowServiceClient{} func (o OfflineCronWorkflowServiceClient) LintCronWorkflow(ctx context.Context, req *cronworkflow.LintCronWorkflowRequest, _ ...grpc.CallOption) (*v1alpha1.CronWorkflow, error) { - err := validate.ValidateCronWorkflow(o.namespacedWorkflowTemplateGetterMap.GetNamespaceGetter(req.Namespace), o.clusterWorkflowTemplateGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, o.namespacedWorkflowTemplateGetterMap.GetNamespaceGetter(req.Namespace), o.clusterWorkflowTemplateGetter, req.CronWorkflow) if err != nil { return nil, err } diff --git a/pkg/apiclient/workflow/workflow.pb.go b/pkg/apiclient/workflow/workflow.pb.go index 0733f16480d2..9f2f76be21f7 100644 --- a/pkg/apiclient/workflow/workflow.pb.go +++ b/pkg/apiclient/workflow/workflow.pb.go @@ -191,7 +191,9 @@ type WorkflowListRequest struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` ListOptions *v1.ListOptions `protobuf:"bytes,2,opt,name=listOptions,proto3" json:"listOptions,omitempty"` // Fields to be included or excluded in the response. e.g. "items.spec,items.status.phase", "-items.status.nodes" - Fields string `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields,omitempty"` + Fields string `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields,omitempty"` + // Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact + NameFilter string `protobuf:"bytes,4,opt,name=nameFilter,proto3" json:"nameFilter,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -251,6 +253,13 @@ func (m *WorkflowListRequest) GetFields() string { return "" } +func (m *WorkflowListRequest) GetNameFilter() string { + if m != nil { + return m.NameFilter + } + return "" +} + type WorkflowResubmitRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` @@ -1312,98 +1321,98 @@ func init() { } var fileDescriptor_1f6bb75f9e833cb6 = []byte{ - // 1442 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0xcd, 0x6f, 0x1c, 0xb5, - 0x1b, 0xc7, 0xe5, 0xa4, 0x4d, 0x13, 0xe7, 0xa5, 0xad, 0x7f, 0x6d, 0x7f, 0xcb, 0xa8, 0x4d, 0x53, - 0x97, 0x42, 0x9a, 0x36, 0x33, 0x79, 0x29, 0xd0, 0x22, 0x81, 0x44, 0x9b, 0x12, 0x51, 0x96, 0x52, - 0xcd, 0x22, 0x21, 0xb8, 0xa0, 0xc9, 0xec, 0x93, 0xc9, 0x34, 0x3b, 0xe3, 0xc1, 0xf6, 0x6e, 0x15, - 0x4a, 0x91, 0xe0, 0x02, 0x07, 0x24, 0x0e, 0x1c, 0xb9, 0x20, 0x24, 0x04, 0x07, 0x04, 0x08, 0x09, - 0x09, 0x81, 0x84, 0x38, 0x70, 0xe0, 0x58, 0xa9, 0x57, 0x0e, 0xa8, 0xe2, 0x1f, 0xe0, 0x3f, 0x40, - 0xf6, 0xbc, 0x67, 0xb7, 0xdb, 0x21, 0xd9, 0x42, 0x6f, 0x63, 0xcf, 0xd8, 0xcf, 0xc7, 0xdf, 0xc7, - 0x7e, 0x9e, 0xc7, 0x83, 0x4f, 0x45, 0x9b, 0x9e, 0xe5, 0x44, 0xbe, 0xdb, 0xf2, 0x21, 0x94, 0xd6, - 0x0d, 0xc6, 0x37, 0xd7, 0x5b, 0xec, 0x46, 0xf6, 0x60, 0x46, 0x9c, 0x49, 0x46, 0x46, 0xd3, 0xb6, - 0x71, 0xd4, 0x63, 0xcc, 0x6b, 0x81, 0x1a, 0x63, 0x39, 0x61, 0xc8, 0xa4, 0x23, 0x7d, 0x16, 0x8a, - 0xf8, 0x3b, 0xe3, 0xdc, 0xe6, 0x79, 0x61, 0xfa, 0x4c, 0xbd, 0x0d, 0x1c, 0x77, 0xc3, 0x0f, 0x81, - 0x6f, 0x59, 0x89, 0x09, 0x61, 0x05, 0x20, 0x1d, 0xab, 0xb3, 0x68, 0x79, 0x10, 0x02, 0x77, 0x24, - 0x34, 0x93, 0x51, 0x2f, 0x79, 0xbe, 0xdc, 0x68, 0xaf, 0x99, 0x2e, 0x0b, 0x2c, 0x87, 0x7b, 0x2c, - 0xe2, 0xec, 0xba, 0x7e, 0x98, 0x4f, 0xcd, 0x8a, 0x7c, 0x92, 0x0c, 0xb1, 0xb3, 0xe8, 0xb4, 0xa2, - 0x0d, 0xa7, 0x7b, 0x3a, 0x9a, 0x43, 0x58, 0x2e, 0xe3, 0xd0, 0xc3, 0x24, 0xfd, 0x65, 0x08, 0x1f, - 0x7e, 0x35, 0x99, 0xe9, 0x12, 0x07, 0x47, 0x82, 0x0d, 0x6f, 0xb6, 0x41, 0x48, 0x72, 0x14, 0x8f, - 0x85, 0x4e, 0x00, 0x22, 0x72, 0x5c, 0xa8, 0xa1, 0x19, 0x34, 0x3b, 0x66, 0xe7, 0x1d, 0x64, 0x1d, - 0x67, 0x52, 0xd4, 0x86, 0x66, 0xd0, 0xec, 0xf8, 0xd2, 0x15, 0x33, 0xa7, 0x37, 0x53, 0x7a, 0xfd, - 0xf0, 0x46, 0x46, 0x6f, 0x76, 0x96, 0xcd, 0x68, 0xd3, 0x33, 0xd5, 0x02, 0xcc, 0x4c, 0xda, 0x74, - 0x01, 0x66, 0x0a, 0x62, 0x67, 0x73, 0x13, 0x8a, 0xb1, 0x1f, 0x0a, 0xe9, 0x84, 0x2e, 0xbc, 0xb0, - 0x52, 0x1b, 0x56, 0x18, 0x17, 0x87, 0x6a, 0xc8, 0x2e, 0xf4, 0x12, 0x8a, 0x27, 0x04, 0xf0, 0x0e, - 0xf0, 0x15, 0xbe, 0x65, 0xb7, 0xc3, 0xda, 0x9e, 0x19, 0x34, 0x3b, 0x6a, 0x97, 0xfa, 0xc8, 0x6b, - 0x78, 0xd2, 0xd5, 0xcb, 0x7b, 0x39, 0xd2, 0x7e, 0xaa, 0xed, 0xd5, 0xd0, 0xcb, 0x66, 0xac, 0x91, - 0x59, 0x74, 0x54, 0x8e, 0xa8, 0x1c, 0x65, 0x76, 0x16, 0xcd, 0x4b, 0xc5, 0xa1, 0x76, 0x79, 0x26, - 0xfa, 0x2d, 0xc2, 0x24, 0x25, 0x5f, 0x05, 0x99, 0xea, 0x47, 0xf0, 0x1e, 0x25, 0x57, 0x22, 0x9d, - 0x7e, 0x2e, 0x6b, 0x3a, 0xb4, 0x5d, 0xd3, 0x6b, 0x18, 0x7b, 0x20, 0x53, 0xc0, 0x61, 0x0d, 0xb8, - 0x50, 0x0d, 0x70, 0x35, 0x1b, 0x67, 0x17, 0xe6, 0x20, 0x47, 0xf0, 0xc8, 0xba, 0x0f, 0xad, 0xa6, - 0xd0, 0x9a, 0x8c, 0xd9, 0x49, 0x8b, 0x7e, 0x8a, 0xf0, 0xff, 0x52, 0xe4, 0xba, 0x2f, 0x64, 0x35, - 0x9f, 0x37, 0xf0, 0x78, 0xcb, 0x17, 0x19, 0x60, 0xec, 0xf6, 0xc5, 0x6a, 0x80, 0xf5, 0x7c, 0xa0, - 0x5d, 0x9c, 0xa5, 0x80, 0x38, 0x5c, 0x42, 0x7c, 0x1f, 0xe1, 0xff, 0x67, 0xfb, 0x01, 0x44, 0x7b, - 0x2d, 0xf0, 0x77, 0x21, 0xad, 0x81, 0x47, 0x03, 0x08, 0x98, 0xff, 0x16, 0x34, 0xb5, 0x9d, 0x51, - 0x3b, 0x6b, 0x93, 0x69, 0x8c, 0x23, 0x87, 0x3b, 0x01, 0x48, 0xe0, 0x6a, 0x5f, 0x0c, 0xcf, 0x8e, - 0xd9, 0x85, 0x1e, 0xfa, 0x2b, 0xc2, 0x87, 0x72, 0x12, 0xc9, 0xb7, 0x76, 0x8e, 0x71, 0x16, 0x1f, - 0xe4, 0x20, 0xa4, 0xc3, 0x65, 0xa3, 0xed, 0xba, 0x20, 0xc4, 0x7a, 0xbb, 0x95, 0xf0, 0x74, 0xbf, - 0x50, 0x5f, 0x87, 0xac, 0x09, 0xcf, 0x2b, 0x41, 0x1a, 0xd0, 0x02, 0x57, 0x32, 0x9e, 0x38, 0xb2, - 0xfb, 0xc5, 0x7d, 0x97, 0x71, 0x23, 0x3f, 0xe8, 0x4a, 0xcf, 0x00, 0x76, 0xb5, 0x8c, 0x6e, 0xb0, - 0xe1, 0x7b, 0x80, 0xd1, 0x3a, 0xae, 0xa5, 0x86, 0x5f, 0x01, 0x1e, 0xf8, 0x61, 0x21, 0xc8, 0xfc, - 0x63, 0xdb, 0xf4, 0xa3, 0xc2, 0xd6, 0x6d, 0x48, 0x16, 0xfd, 0x4b, 0xab, 0x20, 0x35, 0xbc, 0x2f, - 0x00, 0x21, 0x1c, 0x0f, 0x12, 0x17, 0xa4, 0x4d, 0x7a, 0xbb, 0x70, 0xfe, 0x1b, 0xbb, 0x39, 0xff, - 0x03, 0x02, 0x22, 0x87, 0xf0, 0xde, 0x68, 0xc3, 0x11, 0xa0, 0x63, 0xdc, 0x98, 0x1d, 0x37, 0xc8, - 0x1c, 0x3e, 0xc0, 0xda, 0x32, 0x6a, 0xcb, 0x6b, 0xf9, 0x2e, 0x19, 0xd1, 0x1f, 0x74, 0xf5, 0xd3, - 0x2b, 0xf8, 0x48, 0xb6, 0xa2, 0xb6, 0x88, 0x20, 0x6c, 0xee, 0xdc, 0x61, 0x77, 0x0a, 0xf2, 0xd4, - 0x99, 0xb7, 0x73, 0x79, 0x6a, 0x78, 0x5f, 0xc4, 0x9a, 0x57, 0xd5, 0xa0, 0x58, 0x94, 0xb4, 0x49, - 0x9e, 0xc3, 0xb8, 0xc5, 0xbc, 0x34, 0x2e, 0xed, 0xd1, 0x71, 0xe9, 0x44, 0x21, 0x2e, 0x99, 0x2a, - 0xfb, 0xa9, 0x28, 0x74, 0x8d, 0x35, 0xeb, 0xd9, 0x87, 0x76, 0x61, 0x90, 0xc2, 0xf1, 0x38, 0x44, - 0x89, 0x64, 0xfa, 0x59, 0x05, 0x0d, 0x91, 0xba, 0x21, 0x56, 0x2a, 0x6b, 0xd3, 0x1f, 0x51, 0x7e, - 0x9c, 0x56, 0xa0, 0x05, 0xbb, 0xd8, 0xd2, 0x2a, 0x37, 0x35, 0xf5, 0x14, 0xe5, 0xd0, 0x5f, 0x31, - 0x37, 0xad, 0x14, 0x87, 0xda, 0xe5, 0x99, 0xd4, 0x56, 0x58, 0x67, 0xdc, 0x85, 0x24, 0x27, 0xc6, - 0x0d, 0x5a, 0xcb, 0xdd, 0x9b, 0xb2, 0x8b, 0x88, 0x85, 0x02, 0xe8, 0x67, 0x6a, 0x59, 0x8e, 0x74, - 0x37, 0xd2, 0xf7, 0xe2, 0x21, 0x4c, 0x0d, 0x1f, 0x16, 0x76, 0x94, 0x86, 0xbd, 0xdc, 0x81, 0x50, - 0x0b, 0x2f, 0xb7, 0xa2, 0x4c, 0x78, 0xf5, 0x4c, 0xd6, 0xf0, 0x08, 0x5b, 0xbb, 0x0e, 0xae, 0x7c, - 0x00, 0x45, 0x4a, 0x32, 0xb3, 0xca, 0x54, 0x24, 0xc7, 0xf8, 0x0f, 0x05, 0xa3, 0xcf, 0xe2, 0xd1, - 0x3a, 0xf3, 0x2e, 0x87, 0x92, 0x6f, 0xa9, 0xd3, 0xe2, 0xb2, 0x50, 0x42, 0x28, 0x13, 0xe3, 0x69, - 0xb3, 0x78, 0x8e, 0x86, 0x4a, 0xe7, 0x88, 0x7e, 0x52, 0x2a, 0x0b, 0x42, 0xf9, 0x50, 0x95, 0x82, - 0xf4, 0xaf, 0xc2, 0x91, 0x6b, 0x94, 0xea, 0x81, 0xfe, 0x7c, 0x14, 0x4f, 0x70, 0x10, 0xac, 0xcd, - 0x5d, 0x78, 0xd1, 0x0f, 0x9b, 0xc9, 0xa2, 0x4b, 0x7d, 0xc5, 0x6f, 0x0a, 0x01, 0xa6, 0xd4, 0x47, - 0x38, 0x9e, 0x8c, 0xcb, 0x90, 0x72, 0xa0, 0xa9, 0xef, 0x7e, 0xb1, 0x8d, 0x74, 0x5a, 0x61, 0x97, - 0x4d, 0x2c, 0xfd, 0x7e, 0x18, 0xef, 0xcf, 0x73, 0x0b, 0xef, 0xf8, 0x2e, 0x90, 0x2f, 0x10, 0x9e, - 0x8a, 0x0b, 0xd2, 0xf4, 0x0d, 0x39, 0x9e, 0x4f, 0xda, 0xb3, 0x98, 0x37, 0x06, 0xe8, 0x11, 0x3a, - 0xfb, 0xde, 0x9d, 0x3f, 0x3f, 0x1e, 0xa2, 0xf4, 0x98, 0xbe, 0x58, 0x74, 0x16, 0xad, 0xfc, 0x72, - 0x72, 0x33, 0x53, 0xfd, 0xd6, 0xd3, 0x68, 0x8e, 0x7c, 0x8e, 0xf0, 0xf8, 0x2a, 0xc8, 0x0c, 0xf3, - 0x68, 0x37, 0x66, 0x5e, 0x30, 0x0f, 0x94, 0xf1, 0xac, 0x66, 0x7c, 0x8c, 0x3c, 0xda, 0x97, 0x31, - 0x7e, 0xbe, 0xa5, 0x38, 0x27, 0xd5, 0xa1, 0xca, 0x82, 0x1e, 0x39, 0xd6, 0x4d, 0x5a, 0xa8, 0x93, - 0x8d, 0xab, 0x83, 0x43, 0x55, 0xd3, 0xd2, 0x53, 0x1a, 0xf7, 0x38, 0xe9, 0x2f, 0x29, 0x79, 0x07, - 0x4f, 0x95, 0x83, 0x73, 0xc9, 0xf1, 0xbd, 0xc2, 0xb6, 0xd1, 0x43, 0xf2, 0x3c, 0x56, 0xd1, 0x33, - 0xda, 0xee, 0x29, 0x72, 0x72, 0xbb, 0xdd, 0x79, 0xd0, 0xb1, 0xac, 0x68, 0x7d, 0x01, 0x11, 0x81, - 0xc7, 0x0b, 0x81, 0xae, 0xe4, 0xce, 0xae, 0xf8, 0x67, 0x3c, 0xd2, 0x2b, 0x01, 0xc7, 0x66, 0x4f, - 0x6b, 0xb3, 0x27, 0xc9, 0x89, 0xd4, 0xac, 0x90, 0x1c, 0x9c, 0xc0, 0xea, 0x69, 0xf4, 0x5d, 0x84, - 0xa7, 0xe2, 0x2c, 0xd5, 0x6f, 0xbb, 0x97, 0x72, 0xb0, 0x31, 0x73, 0xef, 0x0f, 0x92, 0x44, 0x97, - 0x6c, 0x90, 0xb9, 0x6a, 0x1b, 0xe4, 0x3b, 0x84, 0x27, 0x75, 0xe9, 0x9f, 0x21, 0x4c, 0x77, 0x5b, - 0x28, 0xde, 0x0d, 0x06, 0xba, 0x99, 0x9f, 0xd0, 0xac, 0x96, 0x31, 0x57, 0x85, 0xd5, 0xe2, 0x0a, - 0x43, 0x9d, 0xbe, 0x9f, 0x10, 0x3e, 0x90, 0xde, 0x9c, 0x32, 0xee, 0x13, 0xbd, 0xb8, 0x4b, 0xb7, - 0xab, 0x81, 0xa2, 0x9f, 0xd7, 0xe8, 0x4b, 0xc6, 0x7c, 0x45, 0xf4, 0x98, 0x44, 0xd1, 0x7f, 0x8f, - 0xf0, 0x54, 0x7c, 0x4f, 0xe9, 0xe7, 0xf6, 0xd2, 0x4d, 0x66, 0xa0, 0xe4, 0x4f, 0x6a, 0xf2, 0x05, - 0xe3, 0x4c, 0x65, 0xf2, 0x00, 0x14, 0xf7, 0x0f, 0x08, 0xef, 0x4f, 0x6a, 0xe6, 0x0c, 0xbc, 0xc7, - 0x76, 0x2c, 0x97, 0xd5, 0x03, 0x25, 0x7f, 0x4a, 0x93, 0x2f, 0x1a, 0x67, 0x2b, 0x91, 0x8b, 0x18, - 0x44, 0xa1, 0xff, 0x8c, 0xf0, 0xc1, 0xec, 0x86, 0x96, 0xc1, 0xd3, 0x6e, 0xf8, 0xed, 0xd7, 0xb8, - 0x81, 0xe2, 0x5f, 0xd0, 0xf8, 0xcb, 0x86, 0x59, 0x09, 0x5f, 0xa6, 0x28, 0x6a, 0x01, 0xdf, 0x20, - 0x3c, 0xa1, 0xee, 0x84, 0x19, 0x7b, 0x8f, 0x30, 0x5e, 0xb8, 0x33, 0x0e, 0x14, 0xfb, 0x9c, 0xc6, - 0x36, 0x8d, 0xd3, 0xd5, 0x54, 0x97, 0x2c, 0x52, 0xc4, 0x5f, 0x21, 0x3c, 0xde, 0xe8, 0x9f, 0x21, - 0x1b, 0x0f, 0x26, 0x43, 0x2e, 0x6b, 0xde, 0x79, 0x63, 0xb6, 0x1a, 0x2f, 0xe8, 0x43, 0xf9, 0x25, - 0xc2, 0x13, 0xaa, 0x30, 0xec, 0x27, 0x70, 0xa1, 0x70, 0x1c, 0x28, 0xf0, 0xbc, 0x06, 0x7e, 0x9c, - 0xd2, 0xfe, 0xc0, 0x2d, 0x3f, 0xd4, 0xa8, 0x6f, 0xe3, 0x7d, 0xf1, 0x6d, 0x4f, 0xf4, 0x12, 0x35, - 0xbf, 0x88, 0x1a, 0x24, 0x7f, 0x9b, 0x16, 0xcf, 0xf4, 0x19, 0x6d, 0xeb, 0x1c, 0x59, 0xaa, 0x24, - 0xce, 0xcd, 0xa4, 0x7e, 0xbe, 0x65, 0xb5, 0x98, 0xf7, 0xc1, 0x10, 0x5a, 0x40, 0x44, 0xe2, 0x89, - 0x82, 0xa9, 0x9d, 0x20, 0x2c, 0x68, 0x84, 0x39, 0x52, 0xcd, 0x3f, 0x2d, 0xe6, 0x2d, 0x20, 0xf2, - 0x35, 0xc2, 0x53, 0x8d, 0x72, 0xbc, 0x3f, 0xde, 0x2b, 0xf4, 0x3c, 0xa8, 0x68, 0x6f, 0x69, 0xe6, - 0xd3, 0xf4, 0x3e, 0x49, 0x35, 0x0b, 0xf2, 0x17, 0x57, 0x7f, 0xbb, 0x3b, 0x8d, 0x6e, 0xdf, 0x9d, - 0x46, 0x7f, 0xdc, 0x9d, 0x46, 0xaf, 0x5f, 0xa8, 0xfe, 0xfb, 0x7b, 0xdb, 0x6f, 0xfa, 0xb5, 0x11, - 0xfd, 0x37, 0x7b, 0xf9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6d, 0x5c, 0x66, 0x41, 0xc7, 0x17, - 0x00, 0x00, + // 1451 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0xcf, 0x6f, 0x1c, 0x35, + 0x14, 0xc7, 0xe5, 0x4d, 0x9b, 0x26, 0xce, 0x8f, 0xb6, 0xa6, 0x2d, 0xcb, 0xa8, 0x4d, 0x53, 0x97, + 0x42, 0x9a, 0x36, 0x33, 0xf9, 0x51, 0xa0, 0x45, 0x02, 0x89, 0x36, 0x6d, 0x44, 0x59, 0x4a, 0x35, + 0x8b, 0x84, 0xe0, 0x82, 0x26, 0xb3, 0xce, 0x64, 0x9a, 0x99, 0xf1, 0x60, 0x7b, 0xb7, 0x0a, 0xa5, + 0x48, 0x70, 0x81, 0x03, 0x12, 0x07, 0x8e, 0xdc, 0x90, 0x10, 0x1c, 0x10, 0x20, 0x24, 0x24, 0x04, + 0x12, 0xea, 0x81, 0x03, 0xc7, 0x4a, 0xbd, 0x72, 0x40, 0x15, 0xff, 0x00, 0xff, 0x01, 0xb2, 0xe7, + 0x97, 0x27, 0xbb, 0xdd, 0x0e, 0xc9, 0x06, 0x7a, 0x1b, 0x7b, 0xc6, 0x7e, 0x1f, 0x7f, 0x9f, 0xfd, + 0xde, 0xf3, 0xc0, 0x53, 0xf1, 0x86, 0x67, 0x39, 0xb1, 0xef, 0x06, 0x3e, 0x89, 0x84, 0x75, 0x93, + 0xb2, 0x8d, 0xb5, 0x80, 0xde, 0xcc, 0x1f, 0xcc, 0x98, 0x51, 0x41, 0xd1, 0x48, 0xd6, 0x36, 0x8e, + 0x7a, 0x94, 0x7a, 0x01, 0x91, 0x63, 0x2c, 0x27, 0x8a, 0xa8, 0x70, 0x84, 0x4f, 0x23, 0x9e, 0x7c, + 0x67, 0x9c, 0xdb, 0x38, 0xcf, 0x4d, 0x9f, 0xca, 0xb7, 0xa1, 0xe3, 0xae, 0xfb, 0x11, 0x61, 0x9b, + 0x56, 0x6a, 0x82, 0x5b, 0x21, 0x11, 0x8e, 0xd5, 0x59, 0xb0, 0x3c, 0x12, 0x11, 0xe6, 0x08, 0xd2, + 0x4a, 0x47, 0xbd, 0xea, 0xf9, 0x62, 0xbd, 0xbd, 0x6a, 0xba, 0x34, 0xb4, 0x1c, 0xe6, 0xd1, 0x98, + 0xd1, 0x1b, 0xea, 0x61, 0x2e, 0x33, 0xcb, 0x8b, 0x49, 0x72, 0xc4, 0xce, 0x82, 0x13, 0xc4, 0xeb, + 0x4e, 0xf7, 0x74, 0xb8, 0x80, 0xb0, 0x5c, 0xca, 0x48, 0x0f, 0x93, 0xf8, 0x4e, 0x0d, 0x1e, 0x7e, + 0x23, 0x9d, 0xe9, 0x12, 0x23, 0x8e, 0x20, 0x36, 0x79, 0xa7, 0x4d, 0xb8, 0x40, 0x47, 0xe1, 0x68, + 0xe4, 0x84, 0x84, 0xc7, 0x8e, 0x4b, 0xea, 0x60, 0x1a, 0xcc, 0x8c, 0xda, 0x45, 0x07, 0x5a, 0x83, + 0xb9, 0x14, 0xf5, 0xda, 0x34, 0x98, 0x19, 0x5b, 0xbc, 0x6a, 0x16, 0xf4, 0x66, 0x46, 0xaf, 0x1e, + 0xde, 0xce, 0xe9, 0xcd, 0xce, 0x92, 0x19, 0x6f, 0x78, 0xa6, 0x5c, 0x80, 0x99, 0x4b, 0x9b, 0x2d, + 0xc0, 0xcc, 0x40, 0xec, 0x7c, 0x6e, 0x84, 0x21, 0xf4, 0x23, 0x2e, 0x9c, 0xc8, 0x25, 0x2f, 0x2f, + 0xd7, 0x87, 0x24, 0xc6, 0xc5, 0x5a, 0x1d, 0xd8, 0x5a, 0x2f, 0xc2, 0x70, 0x9c, 0x13, 0xd6, 0x21, + 0x6c, 0x99, 0x6d, 0xda, 0xed, 0xa8, 0xbe, 0x67, 0x1a, 0xcc, 0x8c, 0xd8, 0xa5, 0x3e, 0xf4, 0x26, + 0x9c, 0x70, 0xd5, 0xf2, 0x5e, 0x8b, 0x95, 0x9f, 0xea, 0x7b, 0x15, 0xf4, 0x92, 0x99, 0x68, 0x64, + 0xea, 0x8e, 0x2a, 0x10, 0xa5, 0xa3, 0xcc, 0xce, 0x82, 0x79, 0x49, 0x1f, 0x6a, 0x97, 0x67, 0xc2, + 0xdf, 0x03, 0x88, 0x32, 0xf2, 0x15, 0x22, 0x32, 0xfd, 0x10, 0xdc, 0x23, 0xe5, 0x4a, 0xa5, 0x53, + 0xcf, 0x65, 0x4d, 0x6b, 0x5b, 0x35, 0xbd, 0x0e, 0xa1, 0x47, 0x44, 0x06, 0x38, 0xa4, 0x00, 0xe7, + 0xab, 0x01, 0xae, 0xe4, 0xe3, 0x6c, 0x6d, 0x0e, 0x74, 0x04, 0x0e, 0xaf, 0xf9, 0x24, 0x68, 0x71, + 0xa5, 0xc9, 0xa8, 0x9d, 0xb6, 0xf0, 0x1d, 0x00, 0x1f, 0xcb, 0x90, 0x1b, 0x3e, 0x17, 0xd5, 0x7c, + 0xde, 0x84, 0x63, 0x81, 0xcf, 0x73, 0xc0, 0xc4, 0xed, 0x0b, 0xd5, 0x00, 0x1b, 0xc5, 0x40, 0x5b, + 0x9f, 0x45, 0x43, 0x1c, 0xd2, 0x11, 0xd1, 0x14, 0x84, 0xd2, 0xf2, 0x15, 0x3f, 0x10, 0x84, 0xa5, + 0xf8, 0x5a, 0x0f, 0xfe, 0x08, 0xc0, 0xc7, 0xf3, 0xfd, 0x42, 0x78, 0x7b, 0x35, 0xf4, 0x77, 0x20, + 0xbd, 0x01, 0x47, 0x42, 0x12, 0x52, 0xff, 0x5d, 0xd2, 0x52, 0x1c, 0x23, 0x76, 0xde, 0x96, 0x24, + 0xb1, 0xc3, 0x9c, 0x90, 0x08, 0xc2, 0xe4, 0xbe, 0x19, 0x92, 0x24, 0x45, 0x0f, 0xfe, 0x0d, 0xc0, + 0x43, 0x05, 0x89, 0x60, 0x9b, 0xdb, 0xc7, 0x38, 0x0b, 0x0f, 0x32, 0xc2, 0x85, 0xc3, 0x44, 0xb3, + 0xed, 0xba, 0x84, 0xf3, 0xb5, 0x76, 0x90, 0xf2, 0x74, 0xbf, 0x90, 0x5f, 0x47, 0xb4, 0x45, 0xae, + 0x48, 0xc1, 0x9a, 0x24, 0x20, 0xae, 0xa0, 0x99, 0x52, 0xdd, 0x2f, 0x1e, 0xba, 0x8c, 0x9b, 0x45, + 0x20, 0x90, 0x7a, 0x86, 0x64, 0x47, 0xcb, 0xe8, 0x06, 0x1b, 0x7a, 0x00, 0x18, 0x6e, 0xc0, 0x7a, + 0x66, 0xf8, 0x75, 0xc2, 0x42, 0x3f, 0xd2, 0x82, 0xd0, 0xbf, 0xb6, 0x8d, 0x3f, 0xd5, 0xb6, 0x76, + 0x53, 0xd0, 0xf8, 0x3f, 0x5a, 0x05, 0xaa, 0xc3, 0x7d, 0x21, 0xe1, 0xdc, 0xf1, 0x48, 0xea, 0x82, + 0xac, 0x89, 0xef, 0x6a, 0xf1, 0xa1, 0xb9, 0x93, 0xf8, 0x30, 0x20, 0x20, 0x74, 0x08, 0xee, 0x8d, + 0xd7, 0x1d, 0x4e, 0x54, 0x0c, 0x1c, 0xb5, 0x93, 0x06, 0x9a, 0x85, 0x07, 0x68, 0x5b, 0xc4, 0x6d, + 0x71, 0xbd, 0xd8, 0x25, 0xc3, 0xea, 0x83, 0xae, 0x7e, 0x7c, 0x15, 0x1e, 0xc9, 0x57, 0xd4, 0xe6, + 0x31, 0x89, 0x5a, 0xdb, 0x77, 0xd8, 0x3d, 0x4d, 0x9e, 0x06, 0xf5, 0xb6, 0x2f, 0x4f, 0x1d, 0xee, + 0x8b, 0x69, 0xeb, 0x9a, 0x1c, 0x94, 0x88, 0x92, 0x35, 0xd1, 0x4b, 0x10, 0x06, 0xd4, 0xcb, 0xe2, + 0xd6, 0x1e, 0x15, 0xb7, 0x4e, 0x68, 0x71, 0xcb, 0x94, 0xd9, 0x51, 0x46, 0xa9, 0xeb, 0xb4, 0xd5, + 0xc8, 0x3f, 0xb4, 0xb5, 0x41, 0x12, 0xc7, 0x63, 0x24, 0x4e, 0x25, 0x53, 0xcf, 0x32, 0x68, 0xf0, + 0xcc, 0x0d, 0x89, 0x52, 0x79, 0x1b, 0xff, 0x0c, 0x8a, 0xe3, 0xb4, 0x4c, 0x02, 0xb2, 0x83, 0x2d, + 0x2d, 0x73, 0x57, 0x4b, 0x4d, 0x51, 0x4e, 0x0d, 0x15, 0x73, 0xd7, 0xb2, 0x3e, 0xd4, 0x2e, 0xcf, + 0x24, 0xb7, 0xc2, 0x1a, 0x65, 0x2e, 0x49, 0x73, 0x66, 0xd2, 0xc0, 0xf5, 0xc2, 0xbd, 0x19, 0x3b, + 0x8f, 0x69, 0xc4, 0x09, 0xfe, 0x42, 0x2e, 0xcb, 0x11, 0xee, 0x7a, 0xf6, 0x9e, 0x3f, 0x7a, 0xa9, + 0x03, 0x7f, 0xa2, 0xed, 0x28, 0x05, 0x7b, 0xb9, 0x43, 0x22, 0x25, 0xbc, 0xd8, 0x8c, 0x73, 0xe1, + 0xe5, 0x33, 0x5a, 0x85, 0xc3, 0x74, 0xf5, 0x06, 0x71, 0xc5, 0x2e, 0x14, 0x31, 0xe9, 0xcc, 0x32, + 0x53, 0xa1, 0x02, 0xe3, 0x7f, 0x14, 0x0c, 0xbf, 0x08, 0x47, 0x1a, 0xd4, 0xbb, 0x1c, 0x09, 0xb6, + 0x29, 0x4f, 0x8b, 0x4b, 0x23, 0x41, 0x22, 0x91, 0x1a, 0xcf, 0x9a, 0xfa, 0x39, 0xaa, 0x95, 0xce, + 0x11, 0xfe, 0xbc, 0x54, 0x36, 0x44, 0xe2, 0x91, 0x2a, 0x15, 0xf1, 0xdf, 0xda, 0x91, 0x6b, 0x96, + 0xea, 0x81, 0xfe, 0x7c, 0x18, 0x8e, 0x33, 0xc2, 0x69, 0x9b, 0xb9, 0xe4, 0x15, 0x3f, 0x6a, 0xa5, + 0x8b, 0x2e, 0xf5, 0xe9, 0xdf, 0x68, 0x01, 0xa6, 0xd4, 0x87, 0x18, 0x9c, 0x48, 0xca, 0x90, 0x72, + 0xa0, 0x69, 0xec, 0x7c, 0xb1, 0xcd, 0x6c, 0x5a, 0x6e, 0x97, 0x4d, 0x2c, 0xfe, 0x71, 0x18, 0xee, + 0x2f, 0x72, 0x0b, 0xeb, 0xf8, 0x2e, 0x41, 0x5f, 0x01, 0x38, 0x99, 0x14, 0xac, 0xd9, 0x1b, 0x74, + 0xbc, 0x98, 0xb4, 0x67, 0xb1, 0x6f, 0x0c, 0xd0, 0x23, 0x78, 0xe6, 0xc3, 0x7b, 0x7f, 0x7d, 0x56, + 0xc3, 0xf8, 0x98, 0xba, 0x78, 0x74, 0x16, 0xac, 0xe2, 0xf2, 0x72, 0x2b, 0x57, 0xfd, 0xf6, 0xf3, + 0x60, 0x16, 0x7d, 0x09, 0xe0, 0xd8, 0x0a, 0x11, 0x39, 0xe6, 0xd1, 0x6e, 0xcc, 0xa2, 0xa0, 0x1e, + 0x28, 0xe3, 0x59, 0xc5, 0xf8, 0x14, 0x7a, 0xb2, 0x2f, 0x63, 0xf2, 0x7c, 0x5b, 0x72, 0x4e, 0xc8, + 0x43, 0x95, 0x07, 0x3d, 0x74, 0xac, 0x9b, 0x54, 0xab, 0xa3, 0x8d, 0x6b, 0x83, 0x43, 0x95, 0xd3, + 0xe2, 0x53, 0x0a, 0xf7, 0x38, 0xea, 0x2f, 0x29, 0x7a, 0x1f, 0x4e, 0x96, 0x83, 0x73, 0xc9, 0xf1, + 0xbd, 0xc2, 0xb6, 0xd1, 0x43, 0xf2, 0x22, 0x56, 0xe1, 0x33, 0xca, 0xee, 0x29, 0x74, 0x72, 0xab, + 0xdd, 0x39, 0xa2, 0x62, 0x99, 0x6e, 0x7d, 0x1e, 0x20, 0x0e, 0xc7, 0xb4, 0x40, 0x57, 0x72, 0x67, + 0x57, 0xfc, 0x33, 0x9e, 0xe8, 0x95, 0x80, 0x13, 0xb3, 0xa7, 0x95, 0xd9, 0x93, 0xe8, 0x44, 0x66, + 0x96, 0x0b, 0x46, 0x9c, 0xd0, 0xea, 0x69, 0xf4, 0x03, 0x00, 0x27, 0x93, 0x2c, 0xd5, 0x6f, 0xbb, + 0x97, 0x72, 0xb0, 0x31, 0xfd, 0xe0, 0x0f, 0xd2, 0x44, 0x97, 0x6e, 0x90, 0xd9, 0x6a, 0x1b, 0xe4, + 0x07, 0x00, 0x27, 0x54, 0xe9, 0x9f, 0x23, 0x4c, 0x75, 0x5b, 0xd0, 0xef, 0x06, 0x03, 0xdd, 0xcc, + 0xcf, 0x28, 0x56, 0xcb, 0x98, 0xad, 0xc2, 0x6a, 0x31, 0x89, 0x21, 0x4f, 0xdf, 0x2f, 0x00, 0x1e, + 0xc8, 0x6e, 0x4e, 0x39, 0xf7, 0x89, 0x5e, 0xdc, 0xa5, 0xdb, 0xd5, 0x40, 0xd1, 0xcf, 0x2b, 0xf4, + 0x45, 0x63, 0xae, 0x22, 0x7a, 0x42, 0x22, 0xe9, 0x7f, 0x04, 0x70, 0x32, 0xb9, 0xa7, 0xf4, 0x73, + 0x7b, 0xe9, 0x26, 0x33, 0x50, 0xf2, 0x67, 0x15, 0xf9, 0xbc, 0x71, 0xa6, 0x32, 0x79, 0x48, 0x24, + 0xf7, 0x4f, 0x00, 0xee, 0x4f, 0x6b, 0xe6, 0x1c, 0xbc, 0xc7, 0x76, 0x2c, 0x97, 0xd5, 0x03, 0x25, + 0x7f, 0x4e, 0x91, 0x2f, 0x18, 0x67, 0x2b, 0x91, 0xf3, 0x04, 0x44, 0xa2, 0xff, 0x0a, 0xe0, 0xc1, + 0xfc, 0x86, 0x96, 0xc3, 0xe3, 0x6e, 0xf8, 0xad, 0xd7, 0xb8, 0x81, 0xe2, 0x5f, 0x50, 0xf8, 0x4b, + 0x86, 0x59, 0x09, 0x5f, 0x64, 0x28, 0x72, 0x01, 0xdf, 0x01, 0x38, 0x2e, 0xef, 0x84, 0x39, 0x7b, + 0x8f, 0x30, 0xae, 0xdd, 0x19, 0x07, 0x8a, 0x7d, 0x4e, 0x61, 0x9b, 0xc6, 0xe9, 0x6a, 0xaa, 0x0b, + 0x1a, 0x4b, 0xe2, 0x6f, 0x00, 0x1c, 0x6b, 0xf6, 0xcf, 0x90, 0xcd, 0xdd, 0xc9, 0x90, 0x4b, 0x8a, + 0x77, 0xce, 0x98, 0xa9, 0xc6, 0x4b, 0xd4, 0xa1, 0xfc, 0x1a, 0xc0, 0x71, 0x59, 0x18, 0xf6, 0x13, + 0x58, 0x2b, 0x1c, 0x07, 0x0a, 0x3c, 0xa7, 0x80, 0x9f, 0xc6, 0xb8, 0x3f, 0x70, 0xe0, 0x47, 0x0a, + 0xf5, 0x3d, 0xb8, 0x2f, 0xb9, 0xed, 0xf1, 0x5e, 0xa2, 0x16, 0x17, 0x51, 0x03, 0x15, 0x6f, 0xb3, + 0xe2, 0x19, 0xbf, 0xa0, 0x6c, 0x9d, 0x43, 0x8b, 0x95, 0xc4, 0xb9, 0x95, 0xd6, 0xcf, 0xb7, 0xad, + 0x80, 0x7a, 0x1f, 0xd7, 0xc0, 0x3c, 0x40, 0x02, 0x8e, 0x6b, 0xa6, 0xb6, 0x83, 0x30, 0xaf, 0x10, + 0x66, 0x51, 0x35, 0xff, 0x04, 0xd4, 0x9b, 0x07, 0xe8, 0x5b, 0x00, 0x27, 0x9b, 0xe5, 0x78, 0x7f, + 0xbc, 0x57, 0xe8, 0xd9, 0xad, 0x68, 0x6f, 0x29, 0xe6, 0xd3, 0xf8, 0x21, 0x49, 0x35, 0x0f, 0xf2, + 0x17, 0x57, 0x7e, 0xbf, 0x3f, 0x05, 0xee, 0xde, 0x9f, 0x02, 0x7f, 0xde, 0x9f, 0x02, 0x6f, 0x5d, + 0xa8, 0xfe, 0x7b, 0x7c, 0xcb, 0x6f, 0xfc, 0xd5, 0x61, 0xf5, 0xb7, 0x7b, 0xe9, 0x9f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x07, 0xe3, 0x32, 0x3c, 0xe7, 0x17, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2333,6 +2342,13 @@ func (m *WorkflowListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.NameFilter) > 0 { + i -= len(m.NameFilter) + copy(dAtA[i:], m.NameFilter) + i = encodeVarintWorkflow(dAtA, i, uint64(len(m.NameFilter))) + i-- + dAtA[i] = 0x22 + } if len(m.Fields) > 0 { i -= len(m.Fields) copy(dAtA[i:], m.Fields) @@ -3287,6 +3303,10 @@ func (m *WorkflowListRequest) Size() (n int) { if l > 0 { n += 1 + l + sovWorkflow(uint64(l)) } + l = len(m.NameFilter) + if l > 0 { + n += 1 + l + sovWorkflow(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4215,6 +4235,38 @@ func (m *WorkflowListRequest) Unmarshal(dAtA []byte) error { } m.Fields = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NameFilter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorkflow + } + 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 ErrInvalidLengthWorkflow + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWorkflow + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NameFilter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipWorkflow(dAtA[iNdEx:]) diff --git a/pkg/apiclient/workflow/workflow.proto b/pkg/apiclient/workflow/workflow.proto index edfeaf171280..17b234c06bfd 100644 --- a/pkg/apiclient/workflow/workflow.proto +++ b/pkg/apiclient/workflow/workflow.proto @@ -33,6 +33,8 @@ message WorkflowListRequest { k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions listOptions = 2; // Fields to be included or excluded in the response. e.g. "items.spec,items.status.phase", "-items.status.nodes" string fields = 3; + // Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact + string nameFilter = 4; } message WorkflowResubmitRequest { diff --git a/pkg/apis/workflow/v1alpha1/cron_workflow_types.go b/pkg/apis/workflow/v1alpha1/cron_workflow_types.go index d6c2d69aaf29..65cb6884eb18 100644 --- a/pkg/apis/workflow/v1alpha1/cron_workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/cron_workflow_types.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "context" "strings" v1 "k8s.io/api/core/v1" @@ -8,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" + "github.com/argoproj/argo-workflows/v3/util/deprecation" ) // CronWorkflow is the definition of a scheduled workflow resource @@ -69,11 +71,11 @@ type CronWorkflowSpec struct { When string `json:"when,omitempty" protobuf:"bytes,12,opt,name=when"` } -// v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +// StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after type StopStrategy struct { - // v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the - // variables `failed` or `succeeded` to access the number of failed or successful child workflows. - Condition string `json:"condition" protobuf:"bytes,1,opt,name=condition"` + // v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables + // `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. + Expression string `json:"expression" protobuf:"bytes,1,opt,name=expression"` } // CronWorkflowStatus is the status of a CronWorkflow @@ -169,17 +171,17 @@ func (c *CronWorkflowSpec) getScheduleString(withTimezone bool) string { // GetSchedulesWithTimezone returns all schedules configured for the CronWorkflow with a timezone. It handles // both Spec.Schedules and Spec.Schedule for backwards compatibility -func (c *CronWorkflowSpec) GetSchedulesWithTimezone() []string { - return c.getSchedules(true) +func (c *CronWorkflowSpec) GetSchedulesWithTimezone(ctx context.Context) []string { + return c.getSchedules(ctx, true) } // GetSchedules returns all schedules configured for the CronWorkflow. It handles both Spec.Schedules // and Spec.Schedule for backwards compatibility -func (c *CronWorkflowSpec) GetSchedules() []string { - return c.getSchedules(false) +func (c *CronWorkflowSpec) GetSchedules(ctx context.Context) []string { + return c.getSchedules(ctx, false) } -func (c *CronWorkflowSpec) getSchedules(withTimezone bool) []string { +func (c *CronWorkflowSpec) getSchedules(ctx context.Context, withTimezone bool) []string { var schedules []string if c.Schedule != "" { schedule := c.Schedule @@ -187,6 +189,7 @@ func (c *CronWorkflowSpec) getSchedules(withTimezone bool) []string { schedule = c.withTimezone(c.Schedule) } schedules = append(schedules, schedule) + deprecation.Record(ctx, deprecation.Schedule) } else { schedules = make([]string, len(c.Schedules)) for i, schedule := range c.Schedules { diff --git a/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go b/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go index 1822eec4f941..021b60f6e9de 100644 --- a/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go +++ b/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -21,14 +22,14 @@ func TestCronWorkflowSpec_GetScheduleStrings(t *testing.T) { Timezone: "", Schedule: "* * * * *", } - - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + ctx := context.Background() + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *", cwfSpec.GetScheduleString()) cwfSpec.Timezone = "America/Los_Angeles" - assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + assert.Equal(t, []string{"* * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *", cwfSpec.GetScheduleString()) assert.Equal(t, "CRON_TZ=America/Los_Angeles * * * * *", cwfSpec.GetScheduleWithTimezoneString()) @@ -39,8 +40,8 @@ func TestCronWorkflowSpec_GetScheduleStrings(t *testing.T) { assert.Equal(t, "* * * * *,0 * * * *", cwfSpec.GetScheduleString()) cwfSpec.Timezone = "America/Los_Angeles" - assert.Equal(t, []string{"* * * * *", "0 * * * *"}, cwfSpec.GetSchedules()) - assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *", "CRON_TZ=America/Los_Angeles 0 * * * *"}, cwfSpec.GetSchedulesWithTimezone()) + assert.Equal(t, []string{"* * * * *", "0 * * * *"}, cwfSpec.GetSchedules(ctx)) + assert.Equal(t, []string{"CRON_TZ=America/Los_Angeles * * * * *", "CRON_TZ=America/Los_Angeles 0 * * * *"}, cwfSpec.GetSchedulesWithTimezone(ctx)) assert.Equal(t, "* * * * *,0 * * * *", cwfSpec.GetScheduleString()) assert.Equal(t, "CRON_TZ=America/Los_Angeles * * * * *,CRON_TZ=America/Los_Angeles 0 * * * *", cwfSpec.GetScheduleWithTimezoneString()) } diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index a75856f9a30a..673ebb999d7d 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -4448,704 +4448,704 @@ func init() { } var fileDescriptor_724696e352c3df5f = []byte{ - // 11152 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7b, 0x70, 0x24, 0xc7, - 0x79, 0x18, 0xce, 0x59, 0x60, 0xf1, 0xf8, 0x16, 0xc0, 0xe1, 0xfa, 0x5e, 0x4b, 0x1c, 0x79, 0xa0, - 0x87, 0x22, 0x7f, 0xa4, 0x4d, 0xe1, 0xcc, 0xa3, 0xf4, 0x0b, 0x23, 0x25, 0x92, 0xf0, 0x38, 0xe0, - 0x8e, 0x00, 0x0e, 0x60, 0x2f, 0xee, 0xce, 0xa4, 0x68, 0x49, 0x83, 0xdd, 0xc6, 0xee, 0x10, 0xbb, - 0x33, 0xcb, 0x99, 0x59, 0xdc, 0x81, 0x0f, 0x49, 0xa1, 0xde, 0xb1, 0x6c, 0xc5, 0xb2, 0x24, 0x4b, - 0x4a, 0x52, 0xa5, 0x28, 0x52, 0xc2, 0x92, 0x5d, 0x49, 0xd9, 0x7f, 0xa5, 0xec, 0xff, 0x52, 0x29, - 0x97, 0x52, 0x4e, 0x25, 0x72, 0x45, 0x29, 0xe9, 0x0f, 0x1b, 0x8c, 0x2e, 0x89, 0x2a, 0x95, 0x44, - 0x55, 0xb1, 0x2a, 0x4e, 0xe2, 0xcb, 0xa3, 0x52, 0xfd, 0x9c, 0xee, 0xd9, 0x59, 0xdc, 0xe2, 0xae, - 0x81, 0x53, 0xd9, 0x7f, 0x01, 0xfb, 0x75, 0xf7, 0xf7, 0x75, 0xf7, 0x74, 0x7f, 0xfd, 0xbd, 0xfa, - 0x6b, 0x58, 0xaf, 0xfb, 0x49, 0xa3, 0xb3, 0x39, 0x53, 0x0d, 0x5b, 0xe7, 0xbd, 0xa8, 0x1e, 0xb6, - 0xa3, 0xf0, 0x65, 0xf6, 0xcf, 0x3b, 0x6f, 0x84, 0xd1, 0xf6, 0x56, 0x33, 0xbc, 0x11, 0x9f, 0xdf, - 0x79, 0xe6, 0x7c, 0x7b, 0xbb, 0x7e, 0xde, 0x6b, 0xfb, 0xf1, 0x79, 0x09, 0x3d, 0xbf, 0xf3, 0xb4, - 0xd7, 0x6c, 0x37, 0xbc, 0xa7, 0xcf, 0xd7, 0x49, 0x40, 0x22, 0x2f, 0x21, 0xb5, 0x99, 0x76, 0x14, - 0x26, 0x21, 0xfa, 0x40, 0x8a, 0x71, 0x46, 0x62, 0x64, 0xff, 0x7c, 0x58, 0x61, 0x9c, 0xd9, 0x79, - 0x66, 0xa6, 0xbd, 0x5d, 0x9f, 0xa1, 0x18, 0x67, 0x24, 0x74, 0x46, 0x62, 0x9c, 0x7a, 0xa7, 0xd6, - 0xa7, 0x7a, 0x58, 0x0f, 0xcf, 0x33, 0xc4, 0x9b, 0x9d, 0x2d, 0xf6, 0x8b, 0xfd, 0x60, 0xff, 0x71, - 0x82, 0x53, 0xee, 0xf6, 0xb3, 0xf1, 0x8c, 0x1f, 0xd2, 0xfe, 0x9d, 0xaf, 0x86, 0x11, 0x39, 0xbf, - 0xd3, 0xd5, 0xa9, 0xa9, 0x77, 0x68, 0x75, 0xda, 0x61, 0xd3, 0xaf, 0xee, 0xe6, 0xd5, 0x7a, 0x57, - 0x5a, 0xab, 0xe5, 0x55, 0x1b, 0x7e, 0x40, 0xa2, 0xdd, 0x74, 0xe8, 0x2d, 0x92, 0x78, 0x79, 0xad, - 0xce, 0xf7, 0x6a, 0x15, 0x75, 0x82, 0xc4, 0x6f, 0x91, 0xae, 0x06, 0xff, 0xff, 0x9d, 0x1a, 0xc4, - 0xd5, 0x06, 0x69, 0x79, 0x5d, 0xed, 0x9e, 0xe9, 0xd5, 0xae, 0x93, 0xf8, 0xcd, 0xf3, 0x7e, 0x90, - 0xc4, 0x49, 0x94, 0x6d, 0xe4, 0x5e, 0x84, 0xa1, 0xd9, 0x56, 0xd8, 0x09, 0x12, 0xf4, 0x5e, 0x28, - 0xee, 0x78, 0xcd, 0x0e, 0x29, 0x3b, 0x8f, 0x38, 0x4f, 0x8c, 0xce, 0x3d, 0xf6, 0xdd, 0xbd, 0xe9, - 0x07, 0x6e, 0xed, 0x4d, 0x17, 0xaf, 0x51, 0xe0, 0xed, 0xbd, 0xe9, 0x93, 0x24, 0xa8, 0x86, 0x35, - 0x3f, 0xa8, 0x9f, 0x7f, 0x39, 0x0e, 0x83, 0x99, 0x2b, 0x9d, 0xd6, 0x26, 0x89, 0x30, 0x6f, 0xe3, - 0xfe, 0xeb, 0x02, 0x1c, 0x9b, 0x8d, 0xaa, 0x0d, 0x7f, 0x87, 0x54, 0x12, 0x8a, 0xbf, 0xbe, 0x8b, - 0x1a, 0x30, 0x90, 0x78, 0x11, 0x43, 0x57, 0xba, 0xb0, 0x3a, 0x73, 0xaf, 0xdf, 0x7d, 0x66, 0xc3, - 0x8b, 0x24, 0xee, 0xb9, 0xe1, 0x5b, 0x7b, 0xd3, 0x03, 0x1b, 0x5e, 0x84, 0x29, 0x09, 0xd4, 0x84, - 0xc1, 0x20, 0x0c, 0x48, 0xb9, 0xc0, 0x48, 0x5d, 0xb9, 0x77, 0x52, 0x57, 0xc2, 0x40, 0x8d, 0x63, - 0x6e, 0xe4, 0xd6, 0xde, 0xf4, 0x20, 0x85, 0x60, 0x46, 0x85, 0x8e, 0xeb, 0x55, 0xbf, 0x5d, 0x1e, - 0xb0, 0x35, 0xae, 0x17, 0xfd, 0xb6, 0x39, 0xae, 0x17, 0xfd, 0x36, 0xa6, 0x24, 0xdc, 0xcf, 0x15, - 0x60, 0x74, 0x36, 0xaa, 0x77, 0x5a, 0x24, 0x48, 0x62, 0xf4, 0x31, 0x80, 0xb6, 0x17, 0x79, 0x2d, - 0x92, 0x90, 0x28, 0x2e, 0x3b, 0x8f, 0x0c, 0x3c, 0x51, 0xba, 0xb0, 0x7c, 0xef, 0xe4, 0xd7, 0x25, - 0xce, 0x39, 0x24, 0x3e, 0x39, 0x28, 0x50, 0x8c, 0x35, 0x92, 0xe8, 0x35, 0x18, 0xf5, 0xa2, 0xc4, - 0xdf, 0xf2, 0xaa, 0x49, 0x5c, 0x2e, 0x30, 0xfa, 0xcf, 0xdd, 0x3b, 0xfd, 0x59, 0x81, 0x72, 0xee, - 0xb8, 0x20, 0x3f, 0x2a, 0x21, 0x31, 0x4e, 0xe9, 0xb9, 0xbf, 0x37, 0x08, 0xa5, 0xd9, 0x28, 0x59, - 0x9a, 0xaf, 0x24, 0x5e, 0xd2, 0x89, 0xd1, 0x1f, 0x3a, 0x70, 0x22, 0xe6, 0xd3, 0xe6, 0x93, 0x78, - 0x3d, 0x0a, 0xab, 0x24, 0x8e, 0x49, 0x4d, 0xcc, 0xcb, 0x96, 0x95, 0x7e, 0x49, 0x62, 0x33, 0x95, - 0x6e, 0x42, 0x17, 0x83, 0x24, 0xda, 0x9d, 0x7b, 0x5a, 0xf4, 0xf9, 0x44, 0x4e, 0x8d, 0x37, 0xdf, - 0x9e, 0x46, 0x72, 0x28, 0x14, 0x13, 0xff, 0xc4, 0x38, 0xaf, 0xd7, 0xe8, 0x6b, 0x0e, 0x8c, 0xb5, - 0xc3, 0x5a, 0x8c, 0x49, 0x35, 0xec, 0xb4, 0x49, 0x4d, 0x4c, 0xef, 0x87, 0xed, 0x0e, 0x63, 0x5d, - 0xa3, 0xc0, 0xfb, 0x7f, 0x52, 0xf4, 0x7f, 0x4c, 0x2f, 0xc2, 0x46, 0x57, 0xd0, 0xb3, 0x30, 0x16, - 0x84, 0x49, 0xa5, 0x4d, 0xaa, 0xfe, 0x96, 0x4f, 0x6a, 0x6c, 0xe1, 0x8f, 0xa4, 0x2d, 0xaf, 0x68, - 0x65, 0xd8, 0xa8, 0x39, 0xb5, 0x08, 0xe5, 0x5e, 0x33, 0x87, 0x26, 0x61, 0x60, 0x9b, 0xec, 0x72, - 0x66, 0x83, 0xe9, 0xbf, 0xe8, 0xa4, 0x64, 0x40, 0x74, 0x1b, 0x8f, 0x08, 0xce, 0xf2, 0x9e, 0xc2, - 0xb3, 0xce, 0xd4, 0xfb, 0xe1, 0x78, 0x57, 0xd7, 0x0f, 0x82, 0xc0, 0xfd, 0xde, 0x10, 0x8c, 0xc8, - 0x4f, 0x81, 0x1e, 0x81, 0xc1, 0xc0, 0x6b, 0x49, 0x3e, 0x37, 0x26, 0xc6, 0x31, 0x78, 0xc5, 0x6b, - 0xd1, 0x1d, 0xee, 0xb5, 0x08, 0xad, 0xd1, 0xf6, 0x92, 0x06, 0xc3, 0xa3, 0xd5, 0x58, 0xf7, 0x92, - 0x06, 0x66, 0x25, 0xe8, 0x21, 0x18, 0x6c, 0x85, 0x35, 0xc2, 0xe6, 0xa2, 0xc8, 0x39, 0xc4, 0x6a, - 0x58, 0x23, 0x98, 0x41, 0x69, 0xfb, 0xad, 0x28, 0x6c, 0x95, 0x07, 0xcd, 0xf6, 0x8b, 0x51, 0xd8, - 0xc2, 0xac, 0x04, 0x7d, 0xd5, 0x81, 0x49, 0xb9, 0xb6, 0x57, 0xc2, 0xaa, 0x97, 0xf8, 0x61, 0x50, - 0x2e, 0x32, 0x8e, 0x82, 0xed, 0x6d, 0x29, 0x89, 0x79, 0xae, 0x2c, 0xba, 0x30, 0x99, 0x2d, 0xc1, - 0x5d, 0xbd, 0x40, 0x17, 0x00, 0xea, 0xcd, 0x70, 0xd3, 0x6b, 0xd2, 0x09, 0x29, 0x0f, 0xb1, 0x21, - 0x28, 0xce, 0xb0, 0xa4, 0x4a, 0xb0, 0x56, 0x0b, 0xdd, 0x84, 0x61, 0x8f, 0x73, 0xff, 0xf2, 0x30, - 0x1b, 0xc4, 0xf3, 0x36, 0x06, 0x61, 0x1c, 0x27, 0x73, 0xa5, 0x5b, 0x7b, 0xd3, 0xc3, 0x02, 0x88, - 0x25, 0x39, 0xf4, 0x14, 0x8c, 0x84, 0x6d, 0xda, 0x6f, 0xaf, 0x59, 0x1e, 0x61, 0x0b, 0x73, 0x52, - 0xf4, 0x75, 0x64, 0x4d, 0xc0, 0xb1, 0xaa, 0x81, 0x9e, 0x84, 0xe1, 0xb8, 0xb3, 0x49, 0xbf, 0x63, - 0x79, 0x94, 0x0d, 0xec, 0x98, 0xa8, 0x3c, 0x5c, 0xe1, 0x60, 0x2c, 0xcb, 0xd1, 0xbb, 0xa1, 0x14, - 0x91, 0x6a, 0x27, 0x8a, 0x09, 0xfd, 0xb0, 0x65, 0x60, 0xb8, 0x4f, 0x88, 0xea, 0x25, 0x9c, 0x16, - 0x61, 0xbd, 0x1e, 0x7a, 0x1f, 0x4c, 0xd0, 0x0f, 0x7c, 0xf1, 0x66, 0x3b, 0x22, 0x71, 0x4c, 0xbf, - 0x6a, 0x89, 0x11, 0x3a, 0x2d, 0x5a, 0x4e, 0x2c, 0x1a, 0xa5, 0x38, 0x53, 0x1b, 0xbd, 0x0e, 0xe0, - 0x29, 0x9e, 0x51, 0x1e, 0x63, 0x93, 0xb9, 0x62, 0x6f, 0x45, 0x2c, 0xcd, 0xcf, 0x4d, 0xd0, 0xef, - 0x98, 0xfe, 0xc6, 0x1a, 0x3d, 0x3a, 0x3f, 0x35, 0xd2, 0x24, 0x09, 0xa9, 0x95, 0xc7, 0xd9, 0x80, - 0xd5, 0xfc, 0x2c, 0x70, 0x30, 0x96, 0xe5, 0xee, 0xdf, 0x2e, 0x80, 0x86, 0x05, 0xcd, 0xc1, 0x88, - 0xe0, 0x6b, 0x62, 0x4b, 0xce, 0x3d, 0x2e, 0xbf, 0x83, 0xfc, 0x82, 0xb7, 0xf7, 0x72, 0xf9, 0xa1, - 0x6a, 0x87, 0xde, 0x80, 0x52, 0x3b, 0xac, 0xad, 0x92, 0xc4, 0xab, 0x79, 0x89, 0x27, 0x4e, 0x73, - 0x0b, 0x27, 0x8c, 0xc4, 0x38, 0x77, 0x8c, 0x7e, 0xba, 0xf5, 0x94, 0x04, 0xd6, 0xe9, 0xa1, 0xe7, - 0x00, 0xc5, 0x24, 0xda, 0xf1, 0xab, 0x64, 0xb6, 0x5a, 0xa5, 0x22, 0x11, 0xdb, 0x00, 0x03, 0x6c, - 0x30, 0x53, 0x62, 0x30, 0xa8, 0xd2, 0x55, 0x03, 0xe7, 0xb4, 0x72, 0xbf, 0x5f, 0x80, 0x09, 0x6d, - 0xac, 0x6d, 0x52, 0x45, 0x6f, 0x39, 0x70, 0x4c, 0x1d, 0x67, 0x73, 0xbb, 0x57, 0xe8, 0xaa, 0xe2, - 0x87, 0x15, 0xb1, 0xf9, 0x7d, 0x29, 0x2d, 0xf5, 0x53, 0xd0, 0xe1, 0xbc, 0xfe, 0x8c, 0x18, 0xc3, - 0xb1, 0x4c, 0x29, 0xce, 0x76, 0x6b, 0xea, 0x2b, 0x0e, 0x9c, 0xcc, 0x43, 0x91, 0xc3, 0x73, 0x1b, - 0x3a, 0xcf, 0xb5, 0xca, 0xbc, 0x28, 0x55, 0x3a, 0x18, 0x9d, 0x8f, 0xff, 0xdf, 0x02, 0x4c, 0xea, - 0x4b, 0x88, 0x49, 0x02, 0xff, 0xd4, 0x81, 0x53, 0x72, 0x04, 0x98, 0xc4, 0x9d, 0x66, 0x66, 0x7a, - 0x5b, 0x56, 0xa7, 0x97, 0x9f, 0xa4, 0xb3, 0x79, 0xf4, 0xf8, 0x34, 0x3f, 0x2c, 0xa6, 0xf9, 0x54, - 0x6e, 0x1d, 0x9c, 0xdf, 0xd5, 0xa9, 0x6f, 0x39, 0x30, 0xd5, 0x1b, 0x69, 0xce, 0xc4, 0xb7, 0xcd, - 0x89, 0x7f, 0xd1, 0xde, 0x20, 0x39, 0x79, 0x36, 0xfd, 0x6c, 0xb0, 0xfa, 0x07, 0xf8, 0xed, 0x11, - 0xe8, 0x3a, 0x43, 0xd0, 0xd3, 0x50, 0x12, 0xec, 0x78, 0x25, 0xac, 0xc7, 0xac, 0x93, 0x23, 0x7c, - 0xaf, 0xcd, 0xa6, 0x60, 0xac, 0xd7, 0x41, 0x35, 0x28, 0xc4, 0xcf, 0x88, 0xae, 0x5b, 0x60, 0x6f, - 0x95, 0x67, 0x94, 0x14, 0x39, 0x74, 0x6b, 0x6f, 0xba, 0x50, 0x79, 0x06, 0x17, 0xe2, 0x67, 0xa8, - 0xa4, 0x5e, 0xf7, 0x13, 0x7b, 0x92, 0xfa, 0x92, 0x9f, 0x28, 0x3a, 0x4c, 0x52, 0x5f, 0xf2, 0x13, - 0x4c, 0x49, 0x50, 0x0d, 0xa4, 0x91, 0x24, 0x6d, 0x76, 0xe2, 0x5b, 0xd1, 0x40, 0x2e, 0x6d, 0x6c, - 0xac, 0x2b, 0x5a, 0x4c, 0xbe, 0xa0, 0x10, 0xcc, 0xa8, 0xa0, 0xcf, 0x3a, 0x74, 0xc6, 0x79, 0x61, - 0x18, 0xed, 0x0a, 0xc1, 0xe1, 0xaa, 0xbd, 0x25, 0x10, 0x46, 0xbb, 0x8a, 0xb8, 0xf8, 0x90, 0xaa, - 0x00, 0xeb, 0xa4, 0xd9, 0xc0, 0x6b, 0x5b, 0x31, 0x93, 0x13, 0xec, 0x0c, 0x7c, 0x61, 0xb1, 0x92, - 0x19, 0xf8, 0xc2, 0x62, 0x05, 0x33, 0x2a, 0xf4, 0x83, 0x46, 0xde, 0x0d, 0x21, 0x63, 0x58, 0xf8, - 0xa0, 0xd8, 0xbb, 0x61, 0x7e, 0x50, 0xec, 0xdd, 0xc0, 0x94, 0x04, 0xa5, 0x14, 0xc6, 0x31, 0x13, - 0x29, 0xac, 0x50, 0x5a, 0xab, 0x54, 0x4c, 0x4a, 0x6b, 0x95, 0x0a, 0xa6, 0x24, 0xd8, 0x22, 0xad, - 0xc6, 0x4c, 0x1e, 0xb1, 0xb3, 0x48, 0xe7, 0x33, 0x94, 0x96, 0xe6, 0x2b, 0x98, 0x92, 0xa0, 0x2c, - 0xc3, 0x7b, 0xb5, 0x13, 0x71, 0x61, 0xa6, 0x74, 0x61, 0xcd, 0xc2, 0x7a, 0xa1, 0xe8, 0x14, 0xb5, - 0xd1, 0x5b, 0x7b, 0xd3, 0x45, 0x06, 0xc2, 0x9c, 0x90, 0xfb, 0x07, 0x03, 0x29, 0xbb, 0x90, 0xfc, - 0x1c, 0xfd, 0x3a, 0x3b, 0x08, 0x05, 0x2f, 0x10, 0xa2, 0xaf, 0x73, 0x68, 0xa2, 0xef, 0x09, 0x7e, - 0xe2, 0x19, 0xe4, 0x70, 0x96, 0x3e, 0xfa, 0xa2, 0xd3, 0xad, 0xdb, 0x7a, 0xf6, 0xcf, 0xb2, 0xf4, - 0x60, 0xe6, 0x67, 0xc5, 0xbe, 0x2a, 0xef, 0xd4, 0x67, 0x9d, 0x54, 0x88, 0x88, 0x7b, 0x9d, 0x03, - 0x1f, 0x31, 0xcf, 0x01, 0x8b, 0x0a, 0xb9, 0xce, 0xf7, 0x3f, 0xe7, 0xc0, 0xb8, 0x84, 0x53, 0xf1, - 0x38, 0x46, 0x37, 0x61, 0x44, 0xf6, 0x54, 0x7c, 0x3d, 0x9b, 0xb6, 0x00, 0x25, 0xc4, 0xab, 0xce, - 0x28, 0x6a, 0xee, 0x5b, 0x43, 0x80, 0xd2, 0xb3, 0xaa, 0x1d, 0xc6, 0x3e, 0xe3, 0x44, 0x77, 0x71, - 0x0a, 0x05, 0xda, 0x29, 0x74, 0xcd, 0xe6, 0x29, 0x94, 0x76, 0xcb, 0x38, 0x8f, 0xbe, 0x98, 0xe1, - 0xdb, 0xfc, 0x60, 0xfa, 0xf0, 0xa1, 0xf0, 0x6d, 0xad, 0x0b, 0xfb, 0x73, 0xf0, 0x1d, 0xc1, 0xc1, - 0xf9, 0xd1, 0xf5, 0x4b, 0x76, 0x39, 0xb8, 0xd6, 0x8b, 0x2c, 0x2f, 0x8f, 0x38, 0x87, 0xe5, 0x67, - 0xd7, 0x75, 0xab, 0x1c, 0x56, 0xa3, 0x6a, 0xf2, 0xda, 0x88, 0xf3, 0xda, 0x21, 0x5b, 0x34, 0x35, - 0x5e, 0x9b, 0xa5, 0xa9, 0xb8, 0xee, 0xab, 0x92, 0xeb, 0xf2, 0x53, 0xeb, 0x05, 0xcb, 0x5c, 0x57, - 0xa3, 0xdb, 0xcd, 0x7f, 0x5f, 0x81, 0x53, 0xdd, 0xf5, 0x30, 0xd9, 0x42, 0xe7, 0x61, 0xb4, 0x1a, - 0x06, 0x5b, 0x7e, 0x7d, 0xd5, 0x6b, 0x0b, 0x7d, 0x4d, 0xf1, 0xa2, 0x79, 0x59, 0x80, 0xd3, 0x3a, - 0xe8, 0x61, 0xce, 0x78, 0xb8, 0x45, 0xa4, 0x24, 0xaa, 0x0e, 0x2c, 0x93, 0x5d, 0xc6, 0x85, 0xde, - 0x33, 0xf2, 0xd5, 0x6f, 0x4c, 0x3f, 0xf0, 0xf1, 0x3f, 0x7e, 0xe4, 0x01, 0xf7, 0x8f, 0x06, 0xe0, - 0x6c, 0x2e, 0x4d, 0x21, 0xad, 0xff, 0xb6, 0x21, 0xad, 0x6b, 0xe5, 0x82, 0x8b, 0x5c, 0xb7, 0x29, - 0xc8, 0x6a, 0xe8, 0xf3, 0xe4, 0x72, 0xad, 0x18, 0xe7, 0x77, 0x8a, 0x4e, 0x54, 0xe0, 0xb5, 0x48, - 0xdc, 0xf6, 0xaa, 0x44, 0x8c, 0x5e, 0x4d, 0xd4, 0x15, 0x59, 0x80, 0xd3, 0x3a, 0x5c, 0x85, 0xde, - 0xf2, 0x3a, 0xcd, 0x44, 0x18, 0xca, 0x34, 0x15, 0x9a, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xc7, 0x01, - 0xd4, 0x4d, 0x55, 0x6c, 0xc4, 0x8d, 0xc3, 0x98, 0x87, 0xb9, 0xd3, 0xb7, 0x34, 0x25, 0x5c, 0x1b, - 0x69, 0x4e, 0x3f, 0xb4, 0x6f, 0xfa, 0xd1, 0xf4, 0x1c, 0xe2, 0xca, 0x41, 0x1f, 0x36, 0x34, 0x66, - 0x6a, 0xa9, 0x56, 0x49, 0x1c, 0x73, 0x73, 0x9c, 0x6e, 0x6a, 0x61, 0x60, 0x2c, 0xcb, 0xd1, 0x34, - 0x14, 0x49, 0x14, 0x85, 0x91, 0xd0, 0xb5, 0xd9, 0x32, 0xbe, 0x48, 0x01, 0x98, 0xc3, 0xdd, 0x1f, - 0x17, 0xa0, 0xdc, 0x4b, 0x3b, 0x41, 0xbf, 0xab, 0xe9, 0xd5, 0x42, 0x73, 0x12, 0x8a, 0x5f, 0x78, - 0x78, 0x3a, 0x51, 0x56, 0x01, 0xec, 0xa1, 0x61, 0x8b, 0x52, 0x9c, 0xed, 0xe0, 0xd4, 0x97, 0x34, - 0x0d, 0x5b, 0x47, 0x91, 0x73, 0xc0, 0x6f, 0x99, 0x07, 0xfc, 0xba, 0xed, 0x41, 0xe9, 0xc7, 0xfc, - 0x9f, 0x14, 0xe1, 0x84, 0x2c, 0xad, 0x10, 0x7a, 0x54, 0x3e, 0xdf, 0x21, 0xd1, 0x2e, 0xfa, 0x81, - 0x03, 0x27, 0xbd, 0xac, 0xe9, 0xc6, 0x27, 0x87, 0x30, 0xd1, 0x1a, 0xd5, 0x99, 0xd9, 0x1c, 0x8a, - 0x7c, 0xa2, 0x2f, 0x88, 0x89, 0x3e, 0x99, 0x57, 0xa5, 0x87, 0xdd, 0x3d, 0x77, 0x00, 0xe8, 0x59, - 0x18, 0x93, 0x70, 0x66, 0xee, 0xe1, 0x5b, 0x5c, 0x19, 0xb7, 0x67, 0xb5, 0x32, 0x6c, 0xd4, 0xa4, - 0x2d, 0x13, 0xd2, 0x6a, 0x37, 0xbd, 0x84, 0x68, 0x86, 0x22, 0xd5, 0x72, 0x43, 0x2b, 0xc3, 0x46, - 0x4d, 0xf4, 0x38, 0x0c, 0x05, 0x61, 0x8d, 0x5c, 0xae, 0x09, 0x03, 0xf1, 0x84, 0x68, 0x33, 0x74, - 0x85, 0x41, 0xb1, 0x28, 0x45, 0x8f, 0xa5, 0xd6, 0xb8, 0x22, 0xdb, 0x42, 0xa5, 0x3c, 0x4b, 0x1c, - 0xfa, 0x7b, 0x0e, 0x8c, 0xd2, 0x16, 0x1b, 0xbb, 0x6d, 0x42, 0xcf, 0x36, 0xfa, 0x45, 0x6a, 0x87, - 0xf3, 0x45, 0xae, 0x48, 0x32, 0xa6, 0xa9, 0x63, 0x54, 0xc1, 0xdf, 0x7c, 0x7b, 0x7a, 0x44, 0xfe, - 0xc0, 0x69, 0xaf, 0xa6, 0x96, 0xe0, 0xc1, 0x9e, 0x5f, 0xf3, 0x40, 0xae, 0x80, 0xbf, 0x06, 0x13, - 0x66, 0x27, 0x0e, 0xe4, 0x07, 0xf8, 0x27, 0xda, 0xb6, 0xe3, 0xe3, 0x12, 0xfc, 0xec, 0xbe, 0x49, - 0xb3, 0x6a, 0x31, 0x2c, 0x88, 0xa5, 0x67, 0x2e, 0x86, 0x05, 0xb1, 0x18, 0x16, 0xdc, 0x3f, 0x74, - 0xd2, 0xad, 0xa9, 0x89, 0x79, 0xf4, 0x60, 0xee, 0x44, 0x4d, 0xc1, 0x88, 0xd5, 0xc1, 0x7c, 0x15, - 0xaf, 0x60, 0x0a, 0x47, 0x5f, 0xd2, 0xb8, 0x23, 0x6d, 0xd6, 0x11, 0x6e, 0x0d, 0x4b, 0x26, 0x7a, - 0x03, 0x71, 0x37, 0xff, 0x13, 0x05, 0x38, 0xdb, 0x05, 0xf7, 0x8b, 0x05, 0x78, 0x78, 0x5f, 0xa1, - 0x35, 0xb7, 0xe3, 0xce, 0x7d, 0xef, 0x38, 0x3d, 0xd6, 0x22, 0xd2, 0x0e, 0xaf, 0xe2, 0x15, 0xf1, - 0xbd, 0xd4, 0xb1, 0x86, 0x39, 0x18, 0xcb, 0x72, 0x2a, 0x3a, 0x6c, 0x93, 0xdd, 0xc5, 0x30, 0x6a, - 0x79, 0x89, 0xe0, 0x0e, 0x4a, 0x74, 0x58, 0x96, 0x05, 0x38, 0xad, 0xe3, 0xfe, 0xc0, 0x81, 0x6c, - 0x07, 0x90, 0x07, 0x13, 0x9d, 0x98, 0x44, 0xf4, 0x48, 0xad, 0x90, 0x6a, 0x44, 0xe4, 0xf2, 0x7c, - 0x6c, 0x86, 0x7b, 0xfb, 0xe9, 0x08, 0x67, 0xaa, 0x61, 0x44, 0x66, 0x76, 0x9e, 0x9e, 0xe1, 0x35, - 0x96, 0xc9, 0x6e, 0x85, 0x34, 0x09, 0xc5, 0x31, 0x87, 0x6e, 0xed, 0x4d, 0x4f, 0x5c, 0x35, 0x10, - 0xe0, 0x0c, 0x42, 0x4a, 0xa2, 0xed, 0xc5, 0xf1, 0x8d, 0x30, 0xaa, 0x09, 0x12, 0x85, 0x03, 0x93, - 0x58, 0x37, 0x10, 0xe0, 0x0c, 0x42, 0xf7, 0xfb, 0x54, 0x7d, 0xd4, 0xa5, 0x56, 0xf4, 0x0d, 0x2a, - 0xfb, 0x50, 0xc8, 0x5c, 0x33, 0xdc, 0x9c, 0x0f, 0x83, 0xc4, 0xf3, 0x03, 0x22, 0x83, 0x05, 0x36, - 0x2c, 0xc9, 0xc8, 0x06, 0xee, 0xd4, 0x86, 0xdf, 0x5d, 0x86, 0x73, 0xfa, 0x42, 0x65, 0x9c, 0xcd, - 0x66, 0xb8, 0x99, 0xf5, 0x02, 0xd2, 0x4a, 0x98, 0x95, 0xb8, 0x3f, 0x75, 0xe0, 0x4c, 0x0f, 0x61, - 0x1c, 0x7d, 0xc5, 0x81, 0xf1, 0xcd, 0x9f, 0x89, 0xb1, 0x99, 0xdd, 0x40, 0xef, 0x83, 0x09, 0x0a, - 0xa0, 0x27, 0x91, 0x58, 0x9b, 0x05, 0xd3, 0x43, 0x35, 0x67, 0x94, 0xe2, 0x4c, 0x6d, 0xf7, 0x37, - 0x0a, 0x90, 0x43, 0x05, 0x3d, 0x05, 0x23, 0x24, 0xa8, 0xb5, 0x43, 0x3f, 0x48, 0x04, 0x33, 0x52, - 0x5c, 0xef, 0xa2, 0x80, 0x63, 0x55, 0x43, 0xe8, 0x1f, 0x62, 0x62, 0x0a, 0x5d, 0xfa, 0x87, 0xe8, - 0x79, 0x5a, 0x07, 0xd5, 0x61, 0xd2, 0xe3, 0xfe, 0x15, 0xb6, 0xf6, 0xd8, 0x32, 0x1d, 0x38, 0xc8, - 0x32, 0x3d, 0xc9, 0xdc, 0x9f, 0x19, 0x14, 0xb8, 0x0b, 0x29, 0x7a, 0x37, 0x94, 0x3a, 0x31, 0xa9, - 0x2c, 0x2c, 0xcf, 0x47, 0xa4, 0xc6, 0xb5, 0x62, 0xcd, 0xef, 0x77, 0x35, 0x2d, 0xc2, 0x7a, 0x3d, - 0xf7, 0x9f, 0x39, 0x30, 0x3c, 0xe7, 0x55, 0xb7, 0xc3, 0xad, 0x2d, 0x3a, 0x15, 0xb5, 0x4e, 0x94, - 0x1a, 0xb6, 0xb4, 0xa9, 0x58, 0x10, 0x70, 0xac, 0x6a, 0xa0, 0x0d, 0x18, 0xe2, 0x1b, 0x5e, 0x6c, - 0xbb, 0x5f, 0xd4, 0xc6, 0xa3, 0xe2, 0x78, 0xd8, 0x72, 0xe8, 0x24, 0x7e, 0x73, 0x86, 0xc7, 0xf1, - 0xcc, 0x5c, 0x0e, 0x92, 0xb5, 0xa8, 0x92, 0x44, 0x7e, 0x50, 0x9f, 0x03, 0x7a, 0x5c, 0x2c, 0x32, - 0x1c, 0x58, 0xe0, 0xa2, 0xc3, 0x68, 0x79, 0x37, 0x25, 0x39, 0xc1, 0x7e, 0xd4, 0x30, 0x56, 0xd3, - 0x22, 0xac, 0xd7, 0x73, 0xff, 0xc8, 0x81, 0xd1, 0x39, 0x2f, 0xf6, 0xab, 0x7f, 0x81, 0x98, 0xcf, - 0x87, 0xa0, 0x38, 0xef, 0x55, 0x1b, 0x04, 0x5d, 0xcd, 0x2a, 0xbd, 0xa5, 0x0b, 0x4f, 0xe4, 0x91, - 0x51, 0x0a, 0xb0, 0x4e, 0x69, 0xbc, 0x97, 0x6a, 0xec, 0xbe, 0xed, 0xc0, 0xc4, 0x7c, 0xd3, 0x27, - 0x41, 0x32, 0x4f, 0xa2, 0x84, 0x4d, 0x5c, 0x1d, 0x26, 0xab, 0x0a, 0x72, 0x37, 0x53, 0xc7, 0x56, - 0xeb, 0x7c, 0x06, 0x05, 0xee, 0x42, 0x8a, 0x6a, 0x70, 0x8c, 0xc3, 0xd2, 0x5d, 0x71, 0xa0, 0xf9, - 0x63, 0xd6, 0xd1, 0x79, 0x13, 0x03, 0xce, 0xa2, 0x74, 0x7f, 0xe2, 0xc0, 0x99, 0xf9, 0x66, 0x27, - 0x4e, 0x48, 0x74, 0x5d, 0x70, 0x23, 0x29, 0xde, 0xa2, 0x8f, 0xc0, 0x48, 0x4b, 0x7a, 0x6c, 0x9d, - 0x3b, 0x2c, 0x60, 0xc6, 0xcf, 0x68, 0x6d, 0xda, 0x99, 0xb5, 0xcd, 0x97, 0x49, 0x35, 0x59, 0x25, - 0x89, 0x97, 0x86, 0x17, 0xa4, 0x30, 0xac, 0xb0, 0xa2, 0x36, 0x0c, 0xc6, 0x6d, 0x52, 0xb5, 0x17, - 0xdd, 0x25, 0xc7, 0x50, 0x69, 0x93, 0x6a, 0xca, 0xd7, 0x99, 0xaf, 0x91, 0x51, 0x72, 0xff, 0x97, - 0x03, 0x67, 0x7b, 0x8c, 0x77, 0xc5, 0x8f, 0x13, 0xf4, 0x52, 0xd7, 0x98, 0x67, 0xfa, 0x1b, 0x33, - 0x6d, 0xcd, 0x46, 0xac, 0x18, 0x82, 0x84, 0x68, 0xe3, 0xfd, 0x28, 0x14, 0xfd, 0x84, 0xb4, 0xa4, - 0x19, 0xda, 0x82, 0xc1, 0xa8, 0xc7, 0x58, 0xe6, 0xc6, 0x65, 0x8c, 0xdf, 0x65, 0x4a, 0x0f, 0x73, - 0xb2, 0xee, 0x36, 0x0c, 0xcd, 0x87, 0xcd, 0x4e, 0x2b, 0xe8, 0x2f, 0x52, 0x26, 0xd9, 0x6d, 0x93, - 0xec, 0x19, 0xc9, 0xc4, 0x7f, 0x56, 0x22, 0x0d, 0x47, 0x03, 0xf9, 0x86, 0x23, 0xf7, 0x9f, 0x3b, - 0x40, 0x77, 0x55, 0xcd, 0x17, 0x9e, 0x44, 0x8e, 0x8e, 0x13, 0x7c, 0x58, 0x47, 0x77, 0x7b, 0x6f, - 0x7a, 0x5c, 0x55, 0xd4, 0xf0, 0x7f, 0x08, 0x86, 0x62, 0xa6, 0x92, 0x8b, 0x3e, 0x2c, 0x4a, 0xf9, - 0x99, 0x2b, 0xea, 0xb7, 0xf7, 0xa6, 0xfb, 0x0a, 0xdb, 0x9c, 0x51, 0xb8, 0x85, 0xd3, 0x53, 0x60, - 0xa5, 0x02, 0x5f, 0x8b, 0xc4, 0xb1, 0x57, 0x97, 0x1a, 0x9e, 0x12, 0xf8, 0x56, 0x39, 0x18, 0xcb, - 0x72, 0xf7, 0xcb, 0x0e, 0x8c, 0xab, 0xc3, 0x8b, 0x8a, 0xef, 0xe8, 0x8a, 0x7e, 0xcc, 0xf1, 0x95, - 0xf2, 0x70, 0x0f, 0x8e, 0x23, 0x0e, 0xf2, 0xfd, 0x4f, 0xc1, 0x77, 0xc1, 0x58, 0x8d, 0xb4, 0x49, - 0x50, 0x23, 0x41, 0x95, 0xaa, 0xdf, 0x74, 0x85, 0x8c, 0xce, 0x4d, 0x52, 0x7d, 0x73, 0x41, 0x83, - 0x63, 0xa3, 0x96, 0xfb, 0x4d, 0x07, 0x1e, 0x54, 0xe8, 0x2a, 0x24, 0xc1, 0x24, 0x89, 0x76, 0x55, - 0x98, 0xe6, 0xc1, 0x4e, 0xab, 0xeb, 0x54, 0xfe, 0x4d, 0x22, 0x4e, 0xfc, 0xee, 0x8e, 0xab, 0x12, - 0x97, 0x96, 0x19, 0x12, 0x2c, 0xb1, 0xb9, 0xbf, 0x36, 0x00, 0x27, 0xf5, 0x4e, 0x2a, 0x06, 0xf3, - 0x09, 0x07, 0x40, 0xcd, 0x00, 0x3d, 0x90, 0x07, 0xec, 0xf8, 0xae, 0x8c, 0x2f, 0x95, 0xb2, 0x20, - 0x05, 0x8e, 0xb1, 0x46, 0x16, 0xbd, 0x00, 0x63, 0x3b, 0x74, 0x53, 0x90, 0x55, 0x2a, 0x2e, 0xc4, - 0xe5, 0x01, 0xd6, 0x8d, 0xe9, 0xbc, 0x8f, 0x79, 0x2d, 0xad, 0x97, 0x9a, 0x03, 0x34, 0x60, 0x8c, - 0x0d, 0x54, 0x54, 0xd3, 0x19, 0x8f, 0xf4, 0x4f, 0x22, 0x6c, 0xe2, 0x1f, 0xb4, 0x38, 0xc6, 0xec, - 0x57, 0x9f, 0x3b, 0x7e, 0x6b, 0x6f, 0x7a, 0xdc, 0x00, 0x61, 0xb3, 0x13, 0xee, 0x0b, 0xc0, 0xe6, - 0xc2, 0x0f, 0x3a, 0x64, 0x2d, 0x40, 0x8f, 0x4a, 0x1b, 0x1d, 0xf7, 0xab, 0x28, 0xce, 0xa1, 0xdb, - 0xe9, 0xa8, 0x2e, 0xbb, 0xe5, 0xf9, 0x4d, 0x16, 0xbe, 0x48, 0x6b, 0x29, 0x5d, 0x76, 0x91, 0x41, - 0xb1, 0x28, 0x75, 0x67, 0x60, 0x78, 0x9e, 0x8e, 0x9d, 0x44, 0x14, 0xaf, 0x1e, 0x75, 0x3c, 0x6e, - 0x44, 0x1d, 0xcb, 0xe8, 0xe2, 0x0d, 0x38, 0x35, 0x1f, 0x11, 0x2f, 0x21, 0x95, 0x67, 0xe6, 0x3a, - 0xd5, 0x6d, 0x92, 0xf0, 0xd0, 0xae, 0x18, 0xbd, 0x17, 0xc6, 0x43, 0x76, 0x64, 0xac, 0x84, 0xd5, - 0x6d, 0x3f, 0xa8, 0x0b, 0x93, 0xeb, 0x29, 0x81, 0x65, 0x7c, 0x4d, 0x2f, 0xc4, 0x66, 0x5d, 0xf7, - 0xdf, 0x17, 0x60, 0x6c, 0x3e, 0x0a, 0x03, 0xc9, 0x16, 0x8f, 0xe0, 0x28, 0x4b, 0x8c, 0xa3, 0xcc, - 0x82, 0xbb, 0x53, 0xef, 0x7f, 0xaf, 0xe3, 0x0c, 0xbd, 0xae, 0x58, 0xe4, 0x80, 0x2d, 0x15, 0xc4, - 0xa0, 0xcb, 0x70, 0xa7, 0x1f, 0xdb, 0x64, 0xa0, 0xee, 0x7f, 0x70, 0x60, 0x52, 0xaf, 0x7e, 0x04, - 0x27, 0x68, 0x6c, 0x9e, 0xa0, 0x57, 0xec, 0x8e, 0xb7, 0xc7, 0xb1, 0xf9, 0xf6, 0xb0, 0x39, 0x4e, - 0xe6, 0xeb, 0xfe, 0xaa, 0x03, 0x63, 0x37, 0x34, 0x80, 0x18, 0xac, 0x6d, 0x21, 0xe6, 0x1d, 0x92, - 0xcd, 0xe8, 0xd0, 0xdb, 0x99, 0xdf, 0xd8, 0xe8, 0x09, 0xe5, 0xfb, 0x71, 0xb5, 0x41, 0x6a, 0x9d, - 0xa6, 0x3c, 0xbe, 0xd5, 0x94, 0x56, 0x04, 0x1c, 0xab, 0x1a, 0xe8, 0x25, 0x38, 0x5e, 0x0d, 0x83, - 0x6a, 0x27, 0x8a, 0x48, 0x50, 0xdd, 0x5d, 0x67, 0x77, 0x24, 0xc4, 0x81, 0x38, 0x23, 0x9a, 0x1d, - 0x9f, 0xcf, 0x56, 0xb8, 0x9d, 0x07, 0xc4, 0xdd, 0x88, 0xb8, 0xb3, 0x20, 0xa6, 0x47, 0x96, 0x50, - 0xb8, 0x34, 0x67, 0x01, 0x03, 0x63, 0x59, 0x8e, 0xae, 0xc2, 0x99, 0x38, 0xf1, 0xa2, 0xc4, 0x0f, - 0xea, 0x0b, 0xc4, 0xab, 0x35, 0xfd, 0x80, 0xaa, 0x12, 0x61, 0x50, 0xe3, 0xae, 0xc4, 0x81, 0xb9, - 0xb3, 0xb7, 0xf6, 0xa6, 0xcf, 0x54, 0xf2, 0xab, 0xe0, 0x5e, 0x6d, 0xd1, 0x87, 0x60, 0x4a, 0xb8, - 0x23, 0xb6, 0x3a, 0xcd, 0xe7, 0xc2, 0xcd, 0xf8, 0x92, 0x1f, 0x53, 0x3d, 0x7e, 0xc5, 0x6f, 0xf9, - 0x09, 0x73, 0x18, 0x16, 0xe7, 0xce, 0xdd, 0xda, 0x9b, 0x9e, 0xaa, 0xf4, 0xac, 0x85, 0xf7, 0xc1, - 0x80, 0x30, 0x9c, 0xe6, 0xcc, 0xaf, 0x0b, 0xf7, 0x30, 0xc3, 0x3d, 0x75, 0x6b, 0x6f, 0xfa, 0xf4, - 0x62, 0x6e, 0x0d, 0xdc, 0xa3, 0x25, 0xfd, 0x82, 0x89, 0xdf, 0x22, 0xaf, 0x86, 0x01, 0x61, 0x81, - 0x2a, 0xda, 0x17, 0xdc, 0x10, 0x70, 0xac, 0x6a, 0xa0, 0x97, 0xd3, 0x95, 0x48, 0xb7, 0x8b, 0x08, - 0x38, 0x39, 0x38, 0x87, 0x63, 0xaa, 0xc9, 0x75, 0x0d, 0x13, 0x8b, 0xa4, 0x34, 0x70, 0xa3, 0x4f, - 0x3a, 0x30, 0x16, 0x27, 0xa1, 0xba, 0xd7, 0x20, 0x22, 0x4e, 0x2c, 0x2c, 0xfb, 0x8a, 0x86, 0x95, - 0x0b, 0x3e, 0x3a, 0x04, 0x1b, 0x54, 0xd1, 0x2f, 0xc0, 0xa8, 0x5c, 0xc0, 0x71, 0xb9, 0xc4, 0x64, - 0x25, 0xa6, 0xc6, 0xc9, 0xf5, 0x1d, 0xe3, 0xb4, 0x9c, 0x8a, 0xb2, 0x37, 0x1a, 0x24, 0x60, 0x31, - 0xb7, 0x9a, 0x28, 0x7b, 0xbd, 0x41, 0x02, 0xcc, 0x4a, 0xdc, 0x1f, 0x0f, 0x00, 0xea, 0x66, 0x7c, - 0x68, 0x19, 0x86, 0xbc, 0x6a, 0xe2, 0xef, 0xc8, 0x78, 0xc3, 0x47, 0xf3, 0x84, 0x02, 0x3e, 0x81, - 0x98, 0x6c, 0x11, 0xba, 0xee, 0x49, 0xca, 0x2d, 0x67, 0x59, 0x53, 0x2c, 0x50, 0xa0, 0x10, 0x8e, - 0x37, 0xbd, 0x38, 0x91, 0x3d, 0xac, 0xd1, 0x0f, 0x29, 0x8e, 0x8b, 0x9f, 0xef, 0xef, 0x53, 0xd1, - 0x16, 0x73, 0xa7, 0xe8, 0x7e, 0x5c, 0xc9, 0x22, 0xc2, 0xdd, 0xb8, 0xd1, 0xc7, 0x98, 0x74, 0xc5, - 0x45, 0x5f, 0x29, 0xd6, 0x2c, 0x5b, 0x91, 0x3c, 0x38, 0x4e, 0x43, 0xb2, 0x12, 0x64, 0xb0, 0x46, - 0x12, 0x9d, 0x87, 0x51, 0xb6, 0x6f, 0x48, 0x8d, 0xf0, 0xdd, 0x3f, 0x90, 0x0a, 0xc1, 0x15, 0x59, - 0x80, 0xd3, 0x3a, 0x9a, 0x94, 0xc1, 0x37, 0x7c, 0x0f, 0x29, 0x03, 0x3d, 0x0b, 0xc5, 0x76, 0xc3, - 0x8b, 0x65, 0x0c, 0xbb, 0x2b, 0xb9, 0xf6, 0x3a, 0x05, 0x32, 0xd6, 0xa4, 0x7d, 0x4b, 0x06, 0xc4, - 0xbc, 0x81, 0xfb, 0x2f, 0x00, 0x86, 0x17, 0x66, 0x97, 0x36, 0xbc, 0x78, 0xbb, 0x0f, 0x1d, 0x88, - 0x6e, 0x43, 0x21, 0xac, 0x66, 0x19, 0xa9, 0x14, 0x62, 0xb1, 0xaa, 0x81, 0x02, 0x18, 0xf2, 0x03, - 0xca, 0x79, 0xca, 0x13, 0xb6, 0xfc, 0x0c, 0x4a, 0x9f, 0x63, 0x86, 0xa0, 0xcb, 0x0c, 0x3b, 0x16, - 0x54, 0xd0, 0xeb, 0x30, 0xea, 0xc9, 0x2b, 0x44, 0xe2, 0xfc, 0x5f, 0xb6, 0x61, 0x40, 0x17, 0x28, - 0xf5, 0x10, 0x26, 0x01, 0xc2, 0x29, 0x41, 0xf4, 0x71, 0x07, 0x4a, 0x72, 0xe8, 0x98, 0x6c, 0x09, - 0xdf, 0xf6, 0xaa, 0xbd, 0x31, 0x63, 0xb2, 0xc5, 0xe3, 0x5b, 0x34, 0x00, 0xd6, 0x49, 0x76, 0xe9, - 0x4c, 0xc5, 0x7e, 0x74, 0x26, 0x74, 0x03, 0x46, 0x6f, 0xf8, 0x49, 0x83, 0x9d, 0xf0, 0xc2, 0xa7, - 0xb6, 0x78, 0xef, 0xbd, 0xa6, 0xe8, 0xd2, 0x19, 0xbb, 0x2e, 0x09, 0xe0, 0x94, 0x16, 0xdd, 0x0e, - 0xf4, 0x07, 0xbb, 0x82, 0xc5, 0xce, 0x86, 0x51, 0xb3, 0x01, 0x2b, 0xc0, 0x69, 0x1d, 0x3a, 0xc5, - 0x63, 0xf4, 0x57, 0x85, 0xbc, 0xd2, 0xa1, 0xac, 0x45, 0xc4, 0x2c, 0x5a, 0x58, 0x57, 0x12, 0x23, - 0x9f, 0xac, 0xeb, 0x1a, 0x0d, 0x6c, 0x50, 0x54, 0xac, 0x73, 0xb4, 0x17, 0xeb, 0x44, 0xaf, 0x73, - 0x1d, 0x8e, 0x2b, 0x13, 0xe2, 0x34, 0x58, 0xb1, 0xa3, 0xdf, 0x70, 0x9c, 0xfc, 0x5a, 0x43, 0xfa, - 0x1b, 0x6b, 0xf4, 0x28, 0xc7, 0x08, 0x83, 0x8b, 0x37, 0xfd, 0x44, 0x5c, 0xc6, 0x50, 0x1c, 0x63, - 0x8d, 0x41, 0xb1, 0x28, 0xe5, 0xb1, 0x1b, 0x74, 0x11, 0xc4, 0xe2, 0x14, 0xd0, 0x62, 0x37, 0x18, - 0x18, 0xcb, 0x72, 0xf4, 0x77, 0x1d, 0x28, 0x36, 0xc2, 0x70, 0x3b, 0x2e, 0x8f, 0xb3, 0xc5, 0x61, - 0x41, 0xa6, 0x16, 0x1c, 0x67, 0xe6, 0x12, 0x45, 0x6b, 0x5e, 0x2f, 0x2b, 0x32, 0xd8, 0xed, 0xbd, - 0xe9, 0x89, 0x15, 0x7f, 0x8b, 0x54, 0x77, 0xab, 0x4d, 0xc2, 0x20, 0x6f, 0xbe, 0xad, 0x41, 0x2e, - 0xee, 0x90, 0x20, 0xc1, 0xbc, 0x57, 0x53, 0x9f, 0x73, 0x00, 0x52, 0x44, 0x39, 0x4e, 0x52, 0x62, - 0x86, 0x15, 0x58, 0x50, 0xa8, 0x8d, 0xae, 0xe9, 0x5e, 0xd7, 0x7f, 0xe5, 0x40, 0x89, 0x0e, 0x4e, - 0xb2, 0xc0, 0xc7, 0x61, 0x28, 0xf1, 0xa2, 0x3a, 0x91, 0x8e, 0x02, 0xf5, 0x39, 0x36, 0x18, 0x14, - 0x8b, 0x52, 0x14, 0x40, 0x31, 0xf1, 0xe2, 0x6d, 0x29, 0xc6, 0x5f, 0xb6, 0x36, 0xc5, 0xa9, 0x04, - 0x4f, 0x7f, 0xc5, 0x98, 0x93, 0x41, 0x4f, 0xc0, 0x08, 0x3d, 0x3a, 0x16, 0xbd, 0x58, 0xc6, 0xee, - 0x8c, 0x51, 0x26, 0xbe, 0x28, 0x60, 0x58, 0x95, 0xba, 0xbf, 0x51, 0x80, 0xc1, 0x05, 0xae, 0xd0, - 0x0d, 0xc5, 0x61, 0x27, 0xaa, 0x12, 0x21, 0xd8, 0x5b, 0x58, 0xd3, 0x14, 0x6f, 0x85, 0xe1, 0xd4, - 0x54, 0x2a, 0xf6, 0x1b, 0x0b, 0x5a, 0xe8, 0x4b, 0x0e, 0x4c, 0x24, 0x91, 0x17, 0xc4, 0x5b, 0xcc, - 0x25, 0xe3, 0x87, 0x81, 0x98, 0x22, 0x0b, 0xab, 0x70, 0xc3, 0xc0, 0x5b, 0x49, 0x48, 0x3b, 0xf5, - 0x0c, 0x99, 0x65, 0x38, 0xd3, 0x07, 0xf7, 0x37, 0x1d, 0x80, 0xb4, 0xf7, 0xe8, 0xb3, 0x0e, 0x8c, - 0x7b, 0x7a, 0xcc, 0xa8, 0x98, 0xa3, 0x35, 0x7b, 0xfe, 0x5b, 0x86, 0x96, 0xdb, 0x32, 0x0c, 0x10, - 0x36, 0x09, 0xbb, 0xef, 0x86, 0x22, 0xdb, 0x1d, 0x4c, 0xe9, 0x11, 0xb6, 0xef, 0xac, 0xb1, 0x4b, - 0xda, 0xc4, 0xb1, 0xaa, 0xe1, 0xbe, 0x04, 0x13, 0x17, 0x6f, 0x92, 0x6a, 0x27, 0x09, 0x23, 0x6e, - 0xf9, 0xef, 0x71, 0x47, 0xc8, 0xb9, 0xab, 0x3b, 0x42, 0xdf, 0x71, 0xa0, 0xa4, 0x05, 0x10, 0xd2, - 0x93, 0xba, 0x3e, 0x5f, 0xe1, 0x06, 0x0e, 0x31, 0x55, 0xcb, 0x56, 0x42, 0x14, 0x39, 0xca, 0xf4, - 0x18, 0x51, 0x20, 0x9c, 0x12, 0xbc, 0x43, 0x80, 0x9f, 0xfb, 0x07, 0x0e, 0x9c, 0xca, 0x8d, 0x76, - 0xbc, 0xcf, 0xdd, 0x36, 0x9c, 0xec, 0x85, 0x3e, 0x9c, 0xec, 0xbf, 0xe3, 0x40, 0x8a, 0x89, 0xb2, - 0xa2, 0xcd, 0xb4, 0xe7, 0x1a, 0x2b, 0x12, 0x94, 0x44, 0x29, 0x7a, 0x1d, 0xce, 0x98, 0x5f, 0xf0, - 0x2e, 0xfd, 0x2d, 0x5c, 0x39, 0xcd, 0xc7, 0x84, 0x7b, 0x91, 0x70, 0xbf, 0xe6, 0x40, 0x71, 0xc9, - 0xeb, 0xd4, 0x49, 0x5f, 0xe6, 0x32, 0xca, 0xc7, 0x22, 0xe2, 0x35, 0x13, 0xa9, 0x3a, 0x08, 0x3e, - 0x86, 0x05, 0x0c, 0xab, 0x52, 0x34, 0x0b, 0xa3, 0x61, 0x9b, 0x18, 0x3e, 0xc2, 0x47, 0xe5, 0xec, - 0xad, 0xc9, 0x02, 0x7a, 0xec, 0x30, 0xea, 0x0a, 0x82, 0xd3, 0x56, 0xee, 0x0f, 0x8a, 0x50, 0xd2, - 0xee, 0xc5, 0x50, 0x59, 0x20, 0x22, 0xed, 0x30, 0x2b, 0x2f, 0xd3, 0x05, 0x83, 0x59, 0x09, 0xdd, - 0x83, 0x11, 0xd9, 0xf1, 0x63, 0xce, 0xb6, 0x8c, 0x3d, 0x88, 0x05, 0x1c, 0xab, 0x1a, 0x68, 0x1a, - 0x8a, 0x35, 0xd2, 0x4e, 0x1a, 0xac, 0x7b, 0x83, 0x3c, 0x38, 0x70, 0x81, 0x02, 0x30, 0x87, 0xd3, - 0x0a, 0x5b, 0x24, 0xa9, 0x36, 0x98, 0x65, 0x58, 0x44, 0x0f, 0x2e, 0x52, 0x00, 0xe6, 0xf0, 0x1c, - 0x2f, 0x66, 0xf1, 0xf0, 0xbd, 0x98, 0x43, 0x96, 0xbd, 0x98, 0xa8, 0x0d, 0x27, 0xe2, 0xb8, 0xb1, - 0x1e, 0xf9, 0x3b, 0x5e, 0x42, 0xd2, 0xd5, 0x37, 0x7c, 0x10, 0x3a, 0x67, 0xd8, 0x4d, 0xf5, 0xca, - 0xa5, 0x2c, 0x16, 0x9c, 0x87, 0x1a, 0x55, 0xe0, 0x94, 0x1f, 0xc4, 0xa4, 0xda, 0x89, 0xc8, 0xe5, - 0x7a, 0x10, 0x46, 0xe4, 0x52, 0x18, 0x53, 0x74, 0xe2, 0x9e, 0xad, 0x8a, 0xa7, 0xbd, 0x9c, 0x57, - 0x09, 0xe7, 0xb7, 0x45, 0x4b, 0x70, 0xbc, 0xe6, 0xc7, 0xde, 0x66, 0x93, 0x54, 0x3a, 0x9b, 0xad, - 0x90, 0xab, 0xe6, 0xa3, 0x0c, 0xe1, 0x83, 0xd2, 0x8e, 0xb4, 0x90, 0xad, 0x80, 0xbb, 0xdb, 0xa0, - 0x67, 0x61, 0x2c, 0xf6, 0x83, 0x7a, 0x93, 0xcc, 0x45, 0x5e, 0x50, 0x6d, 0x88, 0x0b, 0xba, 0xca, - 0xde, 0x5e, 0xd1, 0xca, 0xb0, 0x51, 0x93, 0xed, 0x79, 0xde, 0x26, 0x23, 0x0d, 0x8a, 0xda, 0xa2, - 0xd4, 0xfd, 0xa1, 0x03, 0x63, 0x7a, 0x2c, 0x3b, 0x95, 0xb4, 0xa1, 0xb1, 0xb0, 0x58, 0xe1, 0x67, - 0x81, 0xbd, 0x13, 0xff, 0x92, 0xc2, 0x99, 0x2a, 0xcb, 0x29, 0x0c, 0x6b, 0x34, 0xfb, 0xb8, 0x99, - 0xfe, 0x28, 0x14, 0xb7, 0x42, 0x2a, 0x90, 0x0c, 0x98, 0x86, 0xfa, 0x45, 0x0a, 0xc4, 0xbc, 0xcc, - 0xfd, 0x6f, 0x0e, 0x9c, 0xce, 0x0f, 0xd3, 0xff, 0x59, 0x18, 0xe4, 0x05, 0x00, 0x3a, 0x14, 0x83, - 0xa9, 0x6b, 0xb9, 0x29, 0x64, 0x09, 0xd6, 0x6a, 0xf5, 0x37, 0xec, 0x7f, 0x59, 0x00, 0x8d, 0x26, - 0xfa, 0xbc, 0x03, 0xe3, 0x94, 0xec, 0x72, 0xb4, 0x69, 0x8c, 0x76, 0xcd, 0xce, 0x68, 0x15, 0xda, - 0xd4, 0x1f, 0x61, 0x80, 0xb1, 0x49, 0x1c, 0xfd, 0x02, 0x8c, 0x7a, 0xb5, 0x5a, 0x44, 0xe2, 0x58, - 0x79, 0xf6, 0x98, 0xb5, 0x6a, 0x56, 0x02, 0x71, 0x5a, 0x4e, 0x99, 0x68, 0xa3, 0xb6, 0x15, 0x53, - 0xbe, 0x24, 0x18, 0xb7, 0x62, 0xa2, 0x94, 0x08, 0x85, 0x63, 0x55, 0x03, 0x5d, 0x83, 0xd3, 0x35, - 0x2f, 0xf1, 0xb8, 0xfc, 0x46, 0xa2, 0xf5, 0x28, 0x4c, 0x48, 0x95, 0x31, 0x7d, 0x1e, 0x81, 0x7a, - 0x4e, 0xb4, 0x3d, 0xbd, 0x90, 0x5b, 0x0b, 0xf7, 0x68, 0xed, 0xfe, 0xea, 0x20, 0x98, 0x63, 0x42, - 0x35, 0x38, 0xb6, 0x1d, 0x6d, 0xce, 0xb3, 0x80, 0x8b, 0xbb, 0x09, 0x7c, 0x60, 0x01, 0x09, 0xcb, - 0x26, 0x06, 0x9c, 0x45, 0x29, 0xa8, 0x2c, 0x93, 0xdd, 0xc4, 0xdb, 0xbc, 0xeb, 0xb0, 0x87, 0x65, - 0x13, 0x03, 0xce, 0xa2, 0x44, 0xef, 0x86, 0xd2, 0x76, 0xb4, 0x29, 0x59, 0x7f, 0x36, 0x86, 0x66, - 0x39, 0x2d, 0xc2, 0x7a, 0x3d, 0xfa, 0x69, 0xb6, 0xa3, 0x4d, 0x7a, 0xda, 0xca, 0x0c, 0x10, 0xea, - 0xd3, 0x2c, 0x0b, 0x38, 0x56, 0x35, 0x50, 0x1b, 0xd0, 0xb6, 0x9c, 0x3d, 0x15, 0x5e, 0x22, 0x4e, - 0xa8, 0xfe, 0xa3, 0x53, 0x58, 0x5c, 0xff, 0x72, 0x17, 0x1e, 0x9c, 0x83, 0x1b, 0xbd, 0x00, 0x67, - 0xb6, 0xa3, 0x4d, 0x21, 0x84, 0xac, 0x47, 0x7e, 0x50, 0xf5, 0xdb, 0x46, 0xb6, 0x87, 0x69, 0xd1, - 0xdd, 0x33, 0xcb, 0xf9, 0xd5, 0x70, 0xaf, 0xf6, 0xee, 0xef, 0x0e, 0x02, 0xbb, 0xa7, 0x4a, 0x79, - 0x6c, 0x8b, 0x24, 0x8d, 0xb0, 0x96, 0x95, 0xab, 0x56, 0x19, 0x14, 0x8b, 0x52, 0x19, 0xbd, 0x5a, - 0xe8, 0x11, 0xbd, 0x7a, 0x03, 0x86, 0x1b, 0xc4, 0xab, 0x91, 0x48, 0x5a, 0x26, 0x57, 0xec, 0xdc, - 0xac, 0xbd, 0xc4, 0x90, 0xa6, 0xea, 0x3d, 0xff, 0x1d, 0x63, 0x49, 0x0d, 0xbd, 0x07, 0x26, 0xa8, - 0x80, 0x14, 0x76, 0x12, 0xe9, 0x5c, 0xe0, 0x96, 0x49, 0x76, 0x52, 0x6f, 0x18, 0x25, 0x38, 0x53, - 0x13, 0x2d, 0xc0, 0xa4, 0x70, 0x04, 0x28, 0x8b, 0xa7, 0x98, 0x58, 0x95, 0x86, 0xa3, 0x92, 0x29, - 0xc7, 0x5d, 0x2d, 0x58, 0xf4, 0x61, 0x58, 0xe3, 0xbe, 0x60, 0x3d, 0xfa, 0x30, 0xac, 0xed, 0x62, - 0x56, 0x82, 0x5e, 0x85, 0x11, 0xfa, 0x77, 0x31, 0x0a, 0x5b, 0xc2, 0xe6, 0xb3, 0x6e, 0x67, 0x76, - 0x28, 0x0d, 0xa1, 0x81, 0x32, 0xc1, 0x71, 0x4e, 0x50, 0xc1, 0x8a, 0x1e, 0xd5, 0x83, 0xe4, 0xf9, - 0x5e, 0xd9, 0xf6, 0xdb, 0xd7, 0x48, 0xe4, 0x6f, 0xed, 0x32, 0x61, 0x64, 0x24, 0xd5, 0x83, 0x2e, - 0x77, 0xd5, 0xc0, 0x39, 0xad, 0xdc, 0xcf, 0x17, 0x60, 0x4c, 0xbf, 0xee, 0x7c, 0xa7, 0x90, 0xe6, - 0x38, 0x5d, 0x14, 0x5c, 0xeb, 0xbd, 0x64, 0x61, 0xd8, 0x77, 0x5a, 0x10, 0x0d, 0x18, 0xf4, 0x3a, - 0x42, 0x0a, 0xb5, 0x62, 0x5c, 0x63, 0x23, 0xee, 0x24, 0x0d, 0x7e, 0x2f, 0x8e, 0x05, 0x1b, 0x33, - 0x0a, 0xee, 0xa7, 0x06, 0x60, 0x44, 0x16, 0xa2, 0x4f, 0x3a, 0x00, 0x69, 0xd0, 0x97, 0x60, 0xa5, - 0xeb, 0x36, 0x22, 0x82, 0xf4, 0x78, 0x35, 0xcd, 0x46, 0xaf, 0xe0, 0x58, 0xa3, 0x8b, 0x12, 0x18, - 0x0a, 0x69, 0xe7, 0x2e, 0xd8, 0xbb, 0xb2, 0xbf, 0x46, 0x09, 0x5f, 0x60, 0xd4, 0x53, 0x73, 0x1c, - 0x83, 0x61, 0x41, 0x8b, 0x6a, 0x96, 0x9b, 0x32, 0x16, 0xd1, 0x9e, 0xe9, 0x5a, 0x85, 0x37, 0xa6, - 0x8a, 0xa2, 0x02, 0xe1, 0x94, 0xa0, 0xfb, 0x34, 0x4c, 0x98, 0x9b, 0x81, 0x6a, 0x1a, 0x9b, 0xbb, - 0x09, 0xe1, 0x76, 0x8c, 0x31, 0xae, 0x69, 0xcc, 0x51, 0x00, 0xe6, 0x70, 0xf7, 0xfb, 0x0e, 0x40, - 0xca, 0x5e, 0xfa, 0x70, 0x1d, 0x3c, 0xaa, 0x1b, 0xe1, 0x7a, 0xa9, 0x73, 0x1f, 0x83, 0x51, 0xf6, - 0x0f, 0xdb, 0xe8, 0x03, 0xb6, 0x22, 0x07, 0xd2, 0x7e, 0x8a, 0xad, 0xce, 0x64, 0x8d, 0x6b, 0x92, - 0x10, 0x4e, 0x69, 0xba, 0x21, 0x4c, 0x66, 0x6b, 0xa3, 0x0f, 0xc2, 0x58, 0x2c, 0x8f, 0xd5, 0xf4, - 0xf2, 0x5e, 0x9f, 0xc7, 0x2f, 0xf7, 0xdb, 0x69, 0xcd, 0xb1, 0x81, 0xcc, 0x5d, 0x83, 0x21, 0xab, - 0x53, 0xe8, 0x7e, 0xdb, 0x81, 0x51, 0xe6, 0x3a, 0xad, 0x47, 0x5e, 0x2b, 0x6d, 0x32, 0xb0, 0xcf, - 0xac, 0xc7, 0x30, 0xcc, 0x75, 0x7f, 0x19, 0x72, 0x64, 0x81, 0xcb, 0xf0, 0x4c, 0x7b, 0x29, 0x97, - 0xe1, 0x46, 0x86, 0x18, 0x4b, 0x4a, 0xee, 0xa7, 0x0b, 0x30, 0x74, 0x39, 0x68, 0x77, 0xfe, 0xd2, - 0x67, 0x7b, 0x5b, 0x85, 0xc1, 0xcb, 0x09, 0x69, 0x99, 0x49, 0x09, 0xc7, 0xe6, 0x1e, 0xd3, 0x13, - 0x12, 0x96, 0xcd, 0x84, 0x84, 0xd8, 0xbb, 0x21, 0x23, 0xf2, 0x84, 0xed, 0x39, 0xbd, 0xc0, 0xf8, - 0x14, 0x8c, 0xae, 0x78, 0x9b, 0xa4, 0xb9, 0x4c, 0x76, 0xd9, 0x75, 0x43, 0x1e, 0x1d, 0xe2, 0xa4, - 0x06, 0x03, 0x23, 0x92, 0x63, 0x01, 0x26, 0x58, 0x6d, 0xb5, 0x19, 0xa8, 0x46, 0x42, 0xd2, 0x8c, - 0x4e, 0x8e, 0xa9, 0x91, 0x68, 0xd9, 0x9c, 0xb4, 0x5a, 0xee, 0x0c, 0x94, 0x52, 0x2c, 0x7d, 0x50, - 0xfd, 0x69, 0x01, 0xc6, 0x0d, 0x13, 0xba, 0xe1, 0x58, 0x74, 0xee, 0xe8, 0x58, 0x34, 0x1c, 0x7d, - 0x85, 0xfb, 0xed, 0xe8, 0x1b, 0x38, 0x7a, 0x47, 0x9f, 0xf9, 0x91, 0x06, 0xfb, 0xfa, 0x48, 0x4d, - 0x18, 0x5c, 0xf1, 0x83, 0xed, 0xfe, 0xf8, 0x4c, 0x5c, 0x0d, 0xdb, 0x5d, 0x7c, 0xa6, 0x42, 0x81, - 0x98, 0x97, 0x49, 0xc9, 0x65, 0x20, 0x5f, 0x72, 0x71, 0x3f, 0xe9, 0xc0, 0xd8, 0xaa, 0x17, 0xf8, - 0x5b, 0x24, 0x4e, 0xd8, 0xba, 0x4a, 0x0e, 0xf5, 0xda, 0xd9, 0x58, 0x8f, 0x04, 0x0a, 0x6f, 0x3a, - 0x70, 0x7c, 0x95, 0xb4, 0x42, 0xff, 0x55, 0x2f, 0x0d, 0x78, 0xa5, 0x7d, 0x6f, 0xf8, 0x89, 0x88, - 0xef, 0x53, 0x7d, 0xbf, 0xe4, 0x27, 0x98, 0xc2, 0xef, 0x60, 0x1f, 0x66, 0x17, 0x3a, 0xa8, 0x82, - 0xa6, 0x5d, 0x85, 0x4c, 0x43, 0x59, 0x65, 0x01, 0x4e, 0xeb, 0xb8, 0xbf, 0xe7, 0xc0, 0x30, 0xef, - 0x84, 0x8a, 0x11, 0x76, 0x7a, 0xe0, 0x6e, 0x40, 0x91, 0xb5, 0x13, 0xab, 0x7a, 0xc9, 0x82, 0xf8, - 0x43, 0xd1, 0xf1, 0x3d, 0xc8, 0xfe, 0xc5, 0x9c, 0x00, 0x53, 0x5b, 0xbc, 0x9b, 0xb3, 0x2a, 0xd6, - 0x37, 0x55, 0x5b, 0x18, 0x14, 0x8b, 0x52, 0xf7, 0xeb, 0x03, 0x30, 0xa2, 0xf2, 0x86, 0xb1, 0xac, - 0x0e, 0x41, 0x10, 0x26, 0x1e, 0x8f, 0xa1, 0xe0, 0xbc, 0xfa, 0x83, 0xf6, 0xf2, 0x96, 0xcd, 0xcc, - 0xa6, 0xd8, 0xb9, 0x5f, 0x50, 0x29, 0xa1, 0x5a, 0x09, 0xd6, 0x3b, 0x81, 0x3e, 0x0a, 0x43, 0x4d, - 0xca, 0x7d, 0x24, 0xeb, 0xbe, 0x66, 0xb1, 0x3b, 0x8c, 0xad, 0x89, 0x9e, 0xa8, 0x19, 0xe2, 0x40, - 0x2c, 0xa8, 0x4e, 0xbd, 0x0f, 0x26, 0xb3, 0xbd, 0xbe, 0xd3, 0x4d, 0xcd, 0x51, 0xfd, 0x9e, 0xe7, - 0x5f, 0x15, 0xdc, 0xf3, 0xe0, 0x4d, 0xdd, 0xe7, 0xa1, 0xb4, 0x4a, 0x92, 0xc8, 0xaf, 0x32, 0x04, - 0x77, 0x5a, 0x5c, 0x7d, 0xc9, 0x0f, 0x9f, 0x61, 0x8b, 0x95, 0xe2, 0x8c, 0xd1, 0xeb, 0x00, 0xed, - 0x28, 0xa4, 0xfa, 0x2b, 0xe9, 0xc8, 0x8f, 0x6d, 0x41, 0x1e, 0x5e, 0x57, 0x38, 0xb9, 0x2b, 0x3b, - 0xfd, 0x8d, 0x35, 0x7a, 0xee, 0x8b, 0x50, 0x5c, 0xed, 0x24, 0xe4, 0x66, 0x1f, 0x1c, 0xeb, 0xa0, - 0xa9, 0x0b, 0xdc, 0x0f, 0xc2, 0x18, 0xc3, 0x7d, 0x29, 0x6c, 0xd2, 0x63, 0x95, 0x4e, 0x4d, 0x8b, - 0xfe, 0xce, 0x3a, 0x1b, 0x58, 0x25, 0xcc, 0xcb, 0xe8, 0x96, 0x69, 0x84, 0xcd, 0x9a, 0xba, 0xc6, - 0xa5, 0x16, 0xc4, 0x25, 0x06, 0xc5, 0xa2, 0xd4, 0xfd, 0x44, 0x01, 0x4a, 0xac, 0xa1, 0x60, 0x37, - 0xbb, 0x30, 0xdc, 0xe0, 0x74, 0xc4, 0x1c, 0x5a, 0x08, 0x0e, 0xd3, 0x7b, 0xaf, 0xe9, 0x72, 0x1c, - 0x80, 0x25, 0x3d, 0x4a, 0xfa, 0x86, 0xe7, 0x27, 0x94, 0x74, 0xe1, 0x70, 0x49, 0x5f, 0xe7, 0x64, - 0xb0, 0xa4, 0xe7, 0xfe, 0x32, 0xb0, 0xeb, 0xd1, 0x8b, 0x4d, 0xaf, 0xce, 0x67, 0x2e, 0xdc, 0x26, - 0x35, 0xc1, 0x73, 0xb5, 0x99, 0xa3, 0x50, 0x2c, 0x4a, 0xf9, 0x95, 0xd3, 0x24, 0xf2, 0x55, 0x58, - 0xb5, 0x76, 0xe5, 0x94, 0x81, 0x65, 0x10, 0x7d, 0xcd, 0xfd, 0x72, 0x01, 0x80, 0x65, 0x99, 0xe3, - 0xb7, 0x9a, 0x7f, 0x51, 0x46, 0x40, 0x99, 0x0e, 0x4a, 0x15, 0x01, 0xc5, 0xee, 0x6d, 0xeb, 0x91, - 0x4f, 0xfa, 0x6d, 0x87, 0xc2, 0xfe, 0xb7, 0x1d, 0x50, 0x1b, 0x86, 0xc3, 0x4e, 0x42, 0x65, 0x55, - 0x71, 0xd8, 0x5b, 0xf0, 0xcf, 0xaf, 0x71, 0x84, 0xfc, 0x8a, 0x80, 0xf8, 0x81, 0x25, 0x19, 0xf4, - 0x2c, 0x8c, 0xb4, 0xa3, 0xb0, 0x4e, 0xcf, 0x6e, 0x71, 0xbc, 0x3f, 0x24, 0xe5, 0xa1, 0x75, 0x01, - 0xbf, 0xad, 0xfd, 0x8f, 0x55, 0x6d, 0xf7, 0x8f, 0x27, 0xf9, 0xbc, 0x88, 0xb5, 0x37, 0x05, 0x05, - 0x5f, 0x5a, 0xa6, 0x40, 0xa0, 0x28, 0x5c, 0x5e, 0xc0, 0x05, 0xbf, 0xa6, 0xf6, 0x55, 0xa1, 0xe7, - 0xbe, 0x7a, 0x37, 0x94, 0x6a, 0x7e, 0xdc, 0x6e, 0x7a, 0xbb, 0x57, 0x72, 0xcc, 0x82, 0x0b, 0x69, - 0x11, 0xd6, 0xeb, 0xa1, 0xa7, 0xc4, 0xdd, 0x96, 0x41, 0xc3, 0x14, 0x24, 0xef, 0xb6, 0xa4, 0xb7, - 0xe6, 0xf9, 0xb5, 0x96, 0x6c, 0x76, 0x81, 0x62, 0xdf, 0xd9, 0x05, 0xb2, 0x92, 0xd8, 0xd0, 0xd1, - 0x4b, 0x62, 0xef, 0x85, 0x71, 0xf9, 0x93, 0x89, 0x47, 0xe5, 0x93, 0xac, 0xf7, 0xca, 0x0c, 0xbe, - 0xa1, 0x17, 0x62, 0xb3, 0x6e, 0xba, 0x68, 0x87, 0xfb, 0x5d, 0xb4, 0x17, 0x00, 0x36, 0xc3, 0x4e, - 0x50, 0xf3, 0xa2, 0xdd, 0xcb, 0x0b, 0x22, 0x12, 0x56, 0x09, 0x7e, 0x73, 0xaa, 0x04, 0x6b, 0xb5, - 0xf4, 0x85, 0x3e, 0x7a, 0x87, 0x85, 0xfe, 0x41, 0x18, 0x65, 0x51, 0xc3, 0xa4, 0x36, 0x9b, 0x88, - 0xd0, 0xa5, 0x83, 0x84, 0x62, 0xa6, 0xc1, 0x8c, 0x12, 0x09, 0x4e, 0xf1, 0xa1, 0x0f, 0x01, 0x6c, - 0xf9, 0x81, 0x1f, 0x37, 0x18, 0xf6, 0xd2, 0x81, 0xb1, 0xab, 0x71, 0x2e, 0x2a, 0x2c, 0x58, 0xc3, - 0x88, 0x5e, 0x82, 0xe3, 0x24, 0x4e, 0xfc, 0x96, 0x97, 0x90, 0x9a, 0xba, 0x0d, 0x5a, 0x66, 0xb6, - 0x4c, 0x15, 0xb7, 0x7d, 0x31, 0x5b, 0xe1, 0x76, 0x1e, 0x10, 0x77, 0x23, 0x32, 0x76, 0xe4, 0xd4, - 0x41, 0x76, 0x24, 0xfa, 0x9f, 0x0e, 0x1c, 0x8f, 0x08, 0x8f, 0x67, 0x89, 0x55, 0xc7, 0x4e, 0x31, - 0x76, 0x5c, 0xb5, 0x91, 0xc0, 0x5d, 0x65, 0x6a, 0xc1, 0x59, 0x2a, 0x5c, 0x70, 0x21, 0x72, 0xf4, - 0x5d, 0xe5, 0xb7, 0xf3, 0x80, 0x6f, 0xbe, 0x3d, 0x3d, 0xdd, 0xfd, 0x90, 0x80, 0x42, 0x4e, 0x77, - 0xde, 0xdf, 0x7c, 0x7b, 0x7a, 0x52, 0xfe, 0x4e, 0x27, 0xad, 0x6b, 0x90, 0xf4, 0x58, 0x6d, 0x87, - 0xb5, 0xcb, 0xeb, 0x22, 0xc6, 0x4c, 0x1d, 0xab, 0xeb, 0x14, 0x88, 0x79, 0x19, 0x7a, 0x02, 0x46, - 0x6a, 0x1e, 0x69, 0x85, 0x81, 0x4a, 0xc5, 0xcb, 0xa4, 0xf9, 0x05, 0x01, 0xc3, 0xaa, 0x94, 0xea, - 0x10, 0x81, 0x38, 0x52, 0xca, 0x67, 0x6d, 0xe9, 0x10, 0xf2, 0x90, 0xe2, 0x54, 0xe5, 0x2f, 0xac, - 0x28, 0xa1, 0x26, 0x0c, 0xf9, 0xcc, 0x50, 0x21, 0xc2, 0x58, 0x2d, 0x58, 0x47, 0xb8, 0xe1, 0x43, - 0x06, 0xb1, 0x32, 0xd6, 0x2f, 0x68, 0xe8, 0x67, 0xcd, 0xb1, 0xa3, 0x39, 0x6b, 0x9e, 0x80, 0x91, - 0x6a, 0xc3, 0x6f, 0xd6, 0x22, 0x12, 0x94, 0x27, 0x99, 0xc6, 0xce, 0x66, 0x62, 0x5e, 0xc0, 0xb0, - 0x2a, 0x45, 0x7f, 0x05, 0xc6, 0xc3, 0x4e, 0xc2, 0x58, 0x0b, 0x9d, 0xa7, 0xb8, 0x7c, 0x9c, 0x55, - 0x67, 0x41, 0x49, 0x6b, 0x7a, 0x01, 0x36, 0xeb, 0x51, 0x16, 0xdf, 0x08, 0x63, 0x96, 0x54, 0x88, - 0xb1, 0xf8, 0xd3, 0x26, 0x8b, 0xbf, 0xa4, 0x95, 0x61, 0xa3, 0x26, 0xfa, 0xaa, 0x03, 0xc7, 0x5b, - 0x59, 0x05, 0xae, 0x7c, 0x86, 0xcd, 0x4c, 0xc5, 0x86, 0xa0, 0x9f, 0x41, 0xcd, 0xc3, 0xc9, 0xbb, - 0xc0, 0xb8, 0xbb, 0x13, 0x2c, 0xbd, 0x57, 0xbc, 0x1b, 0x54, 0x1b, 0x51, 0x18, 0x98, 0xdd, 0x7b, - 0xd0, 0xd6, 0xa5, 0x36, 0xb6, 0xb7, 0xf3, 0x48, 0xcc, 0x3d, 0x78, 0x6b, 0x6f, 0xfa, 0x54, 0x6e, - 0x11, 0xce, 0xef, 0xd4, 0xd4, 0x02, 0x9c, 0xce, 0xe7, 0x0f, 0x77, 0xd2, 0x38, 0x06, 0x74, 0x8d, - 0x63, 0x11, 0x1e, 0xec, 0xd9, 0x29, 0x7a, 0xd2, 0x48, 0x69, 0xd3, 0x31, 0x4f, 0x9a, 0x2e, 0xe9, - 0x70, 0x02, 0xc6, 0xf4, 0x97, 0x27, 0xdc, 0xff, 0x33, 0x00, 0x90, 0xda, 0xc9, 0x91, 0x07, 0x13, - 0xdc, 0x26, 0x7f, 0x79, 0xe1, 0xae, 0xaf, 0xe3, 0xcf, 0x1b, 0x08, 0x70, 0x06, 0x21, 0x6a, 0x01, - 0xe2, 0x10, 0xfe, 0xfb, 0x6e, 0x7c, 0xab, 0xcc, 0x15, 0x39, 0xdf, 0x85, 0x04, 0xe7, 0x20, 0xa6, - 0x23, 0x4a, 0xc2, 0x6d, 0x12, 0x5c, 0xc5, 0x2b, 0x77, 0x93, 0xd3, 0x81, 0x7b, 0xe3, 0x0c, 0x04, - 0x38, 0x83, 0x10, 0xb9, 0x30, 0xc4, 0x6c, 0x33, 0x32, 0xf0, 0x9b, 0xb1, 0x17, 0x26, 0x69, 0xc4, - 0x58, 0x94, 0xa0, 0x2f, 0x3b, 0x30, 0x21, 0x53, 0x53, 0x30, 0x6b, 0xa8, 0x0c, 0xf9, 0xbe, 0x6a, - 0xcb, 0xcf, 0x71, 0x51, 0xc7, 0x9e, 0x06, 0x54, 0x1a, 0xe0, 0x18, 0x67, 0x3a, 0xe1, 0xbe, 0x00, - 0x27, 0x72, 0x9a, 0x5b, 0xd1, 0x68, 0xbf, 0xe3, 0x40, 0x49, 0xcb, 0x98, 0x88, 0x5e, 0x87, 0xd1, - 0xb0, 0x62, 0x3d, 0x8a, 0x6f, 0xad, 0xd2, 0x15, 0xc5, 0xa7, 0x40, 0x38, 0x25, 0xd8, 0x4f, 0xf0, - 0x61, 0x6e, 0x7a, 0xc7, 0xfb, 0xdc, 0xed, 0x03, 0x07, 0x1f, 0xfe, 0x6a, 0x11, 0x52, 0x4c, 0x07, - 0x4c, 0x99, 0x92, 0x86, 0x2a, 0x16, 0xf6, 0x0d, 0x55, 0xac, 0xc1, 0x31, 0x8f, 0xf9, 0x92, 0xef, - 0x32, 0x51, 0x0a, 0x4f, 0x98, 0x6b, 0x62, 0xc0, 0x59, 0x94, 0x94, 0x4a, 0x9c, 0x36, 0x65, 0x54, - 0x06, 0x0f, 0x4c, 0xa5, 0x62, 0x62, 0xc0, 0x59, 0x94, 0xe8, 0x25, 0x28, 0x57, 0xd9, 0xc5, 0x5f, - 0x3e, 0xc6, 0xcb, 0x5b, 0x57, 0xc2, 0x64, 0x3d, 0x22, 0x31, 0x09, 0x12, 0x91, 0x12, 0xed, 0x11, - 0x31, 0x0b, 0xe5, 0xf9, 0x1e, 0xf5, 0x70, 0x4f, 0x0c, 0x54, 0x4d, 0x61, 0xce, 0x68, 0x3f, 0xd9, - 0x65, 0x4c, 0x44, 0x78, 0xe9, 0x95, 0x9a, 0x52, 0xd1, 0x0b, 0xb1, 0x59, 0x17, 0xfd, 0x8a, 0x03, - 0xe3, 0x4d, 0x69, 0xae, 0xc7, 0x9d, 0xa6, 0xcc, 0xef, 0x89, 0xad, 0x2c, 0xbf, 0x15, 0x1d, 0x33, - 0x97, 0x25, 0x0c, 0x10, 0x36, 0x69, 0x67, 0xb3, 0xd6, 0x8c, 0xf4, 0x99, 0xb5, 0xe6, 0xfb, 0x0e, - 0x4c, 0x66, 0xa9, 0xa1, 0x6d, 0x78, 0xb8, 0xe5, 0x45, 0xdb, 0x97, 0x83, 0xad, 0x88, 0x5d, 0xf0, - 0x48, 0xf8, 0x62, 0x98, 0xdd, 0x4a, 0x48, 0xb4, 0xe0, 0xed, 0x72, 0xf7, 0x67, 0x51, 0x3d, 0x10, - 0xf5, 0xf0, 0xea, 0x7e, 0x95, 0xf1, 0xfe, 0xb8, 0x50, 0x05, 0x4e, 0xd1, 0x0a, 0x2c, 0xa9, 0x9d, - 0x1f, 0x06, 0x29, 0x91, 0x02, 0x23, 0xa2, 0x82, 0x0c, 0x57, 0xf3, 0x2a, 0xe1, 0xfc, 0xb6, 0xee, - 0x45, 0x18, 0xe2, 0xf7, 0xed, 0xee, 0xc9, 0x7f, 0xe4, 0xfe, 0x9b, 0x02, 0x48, 0xc1, 0xf0, 0x2f, - 0xb7, 0x3b, 0x8e, 0x1e, 0xa2, 0x11, 0x33, 0x29, 0x09, 0x6b, 0x07, 0x3b, 0x44, 0x45, 0xfa, 0x48, - 0x51, 0x42, 0x25, 0x66, 0x72, 0xd3, 0x4f, 0xe6, 0xc3, 0x9a, 0xb4, 0x71, 0x30, 0x89, 0xf9, 0xa2, - 0x80, 0x61, 0x55, 0xea, 0x7e, 0xd2, 0x81, 0x71, 0x3a, 0xca, 0x66, 0x93, 0x34, 0x2b, 0x09, 0x69, - 0xc7, 0x28, 0x86, 0x62, 0x4c, 0xff, 0xb1, 0x67, 0x0a, 0x4c, 0xef, 0x68, 0x92, 0xb6, 0xe6, 0xac, - 0xa1, 0x44, 0x30, 0xa7, 0xe5, 0xbe, 0x35, 0x00, 0xa3, 0x6a, 0xb2, 0xfb, 0xb0, 0xa7, 0x5e, 0x48, - 0x33, 0xbb, 0x72, 0x0e, 0x5c, 0xd6, 0xb2, 0xba, 0xde, 0xa6, 0x53, 0x17, 0xec, 0xf2, 0x14, 0x17, - 0x69, 0x8a, 0xd7, 0xa7, 0x4c, 0x57, 0xf3, 0x69, 0x7d, 0xfd, 0x69, 0xf5, 0x85, 0xcf, 0xf9, 0xa6, - 0xee, 0xe9, 0x1f, 0xb4, 0x75, 0x9a, 0x29, 0x37, 0x66, 0x6f, 0x17, 0x7f, 0xe6, 0xd1, 0x9f, 0x62, - 0x5f, 0x8f, 0xfe, 0x3c, 0x09, 0x83, 0x24, 0xe8, 0xb4, 0x98, 0xa8, 0x34, 0xca, 0x54, 0x84, 0xc1, - 0x8b, 0x41, 0xa7, 0x65, 0x8e, 0x8c, 0x55, 0x41, 0xef, 0x83, 0x52, 0x8d, 0xc4, 0xd5, 0xc8, 0x67, - 0x79, 0x1b, 0x84, 0x65, 0xe7, 0x21, 0x66, 0x2e, 0x4b, 0xc1, 0x66, 0x43, 0xbd, 0x81, 0xfb, 0x2a, - 0x0c, 0xad, 0x37, 0x3b, 0x75, 0x3f, 0x40, 0x6d, 0x18, 0xe2, 0x59, 0x1c, 0xc4, 0x69, 0x6f, 0x41, - 0xef, 0xe4, 0xac, 0x42, 0x8b, 0x42, 0xe1, 0x57, 0x75, 0x05, 0x1d, 0xf7, 0x13, 0x05, 0xa0, 0xaa, - 0xf9, 0xd2, 0x3c, 0xfa, 0xeb, 0x5d, 0x6f, 0xdc, 0xfc, 0x5c, 0xce, 0x1b, 0x37, 0xe3, 0xac, 0x72, - 0xce, 0xf3, 0x36, 0x4d, 0x18, 0x67, 0xce, 0x11, 0x79, 0x06, 0x0a, 0xb1, 0xfa, 0x99, 0x3e, 0x13, - 0x1f, 0xe8, 0x4d, 0xc5, 0x89, 0xa0, 0x83, 0xb0, 0x89, 0x1c, 0xad, 0xc2, 0x09, 0x9e, 0x20, 0x74, - 0x81, 0x34, 0xbd, 0xdd, 0x4c, 0x22, 0xb0, 0xb3, 0xf2, 0xd9, 0xb2, 0x85, 0xee, 0x2a, 0x38, 0xaf, - 0x9d, 0xfb, 0xfb, 0x83, 0xa0, 0xb9, 0x24, 0xfa, 0xd8, 0x2d, 0xaf, 0x64, 0x1c, 0x50, 0xab, 0x56, - 0x1c, 0x50, 0xd2, 0xab, 0xc3, 0x39, 0x90, 0xe9, 0x73, 0xa2, 0x9d, 0x6a, 0x90, 0x66, 0x5b, 0x8c, - 0x51, 0x75, 0xea, 0x12, 0x69, 0xb6, 0x31, 0x2b, 0x51, 0x17, 0x15, 0x07, 0x7b, 0x5e, 0x54, 0x6c, - 0x40, 0xb1, 0xee, 0x75, 0xea, 0x44, 0x44, 0x60, 0x5a, 0xf0, 0x35, 0xb2, 0xab, 0x13, 0xdc, 0xd7, - 0xc8, 0xfe, 0xc5, 0x9c, 0x00, 0xdd, 0xec, 0x0d, 0x19, 0x92, 0x22, 0x8c, 0xb4, 0x16, 0x36, 0xbb, - 0x8a, 0x72, 0xe1, 0x9b, 0x5d, 0xfd, 0xc4, 0x29, 0x31, 0xd4, 0x86, 0xe1, 0x2a, 0x4f, 0xbf, 0x22, - 0x64, 0x96, 0xcb, 0x36, 0x6e, 0x62, 0x32, 0x84, 0xdc, 0x9a, 0x22, 0x7e, 0x60, 0x49, 0xc6, 0x3d, - 0x0f, 0x25, 0xed, 0xa9, 0x0d, 0xfa, 0x19, 0x54, 0xe6, 0x0f, 0xed, 0x33, 0x2c, 0x78, 0x89, 0x87, - 0x59, 0x89, 0xfb, 0xcd, 0x41, 0x50, 0xb6, 0x34, 0xfd, 0xde, 0xa0, 0x57, 0xd5, 0xf2, 0x14, 0x19, - 0x77, 0xe8, 0xc3, 0x00, 0x8b, 0x52, 0x2a, 0xd7, 0xb5, 0x48, 0x54, 0x57, 0x7a, 0xb4, 0x60, 0xd7, - 0x4a, 0xae, 0x5b, 0xd5, 0x0b, 0xb1, 0x59, 0x97, 0x0a, 0xe5, 0x2d, 0xe1, 0xa2, 0xcf, 0x06, 0x56, - 0x4b, 0xd7, 0x3d, 0x56, 0x35, 0x58, 0xa2, 0x83, 0x96, 0xe6, 0xd1, 0x17, 0x81, 0x98, 0x36, 0x1c, - 0x4a, 0x1a, 0x56, 0x1e, 0x30, 0xa5, 0x43, 0xb0, 0x41, 0x15, 0x2d, 0xc1, 0xf1, 0x98, 0x24, 0x6b, - 0x37, 0x02, 0x12, 0xa9, 0x14, 0x03, 0x22, 0x93, 0x86, 0xba, 0x55, 0x51, 0xc9, 0x56, 0xc0, 0xdd, - 0x6d, 0x72, 0x63, 0x57, 0x8b, 0x07, 0x8e, 0x5d, 0x5d, 0x80, 0xc9, 0x2d, 0xcf, 0x6f, 0x76, 0x22, - 0xd2, 0x33, 0x02, 0x76, 0x31, 0x53, 0x8e, 0xbb, 0x5a, 0xb0, 0x8b, 0x3d, 0x4d, 0xaf, 0x1e, 0x97, - 0x87, 0xb5, 0x8b, 0x3d, 0x14, 0x80, 0x39, 0xdc, 0xfd, 0x2d, 0x07, 0x78, 0x0a, 0xa3, 0xd9, 0xad, - 0x2d, 0x3f, 0xf0, 0x93, 0x5d, 0xf4, 0x35, 0x07, 0x26, 0x83, 0xb0, 0x46, 0x66, 0x83, 0xc4, 0x97, - 0x40, 0x7b, 0x79, 0xe5, 0x19, 0xad, 0x2b, 0x19, 0xf4, 0x3c, 0x1f, 0x46, 0x16, 0x8a, 0xbb, 0xba, - 0xe1, 0x9e, 0x81, 0x53, 0xb9, 0x08, 0xdc, 0xef, 0x0f, 0x80, 0x99, 0x89, 0x09, 0x3d, 0x0f, 0xc5, - 0x26, 0xcb, 0x0d, 0xe2, 0xdc, 0x65, 0x8a, 0x2d, 0x36, 0x57, 0x3c, 0x79, 0x08, 0xc7, 0x84, 0x16, - 0xa0, 0xc4, 0xd2, 0x3b, 0x89, 0xcc, 0x2d, 0x05, 0x23, 0x25, 0x42, 0x09, 0xa7, 0x45, 0xb7, 0xcd, - 0x9f, 0x58, 0x6f, 0x86, 0x5e, 0x83, 0xe1, 0x4d, 0x9e, 0xe4, 0xd2, 0x9e, 0xcf, 0x4f, 0x64, 0xcd, - 0x64, 0xb2, 0x91, 0x4c, 0xa1, 0x79, 0x3b, 0xfd, 0x17, 0x4b, 0x8a, 0x68, 0x17, 0x46, 0x3c, 0xf9, - 0x4d, 0x07, 0x6d, 0x5d, 0xd4, 0x30, 0xd6, 0x8f, 0x88, 0x98, 0x91, 0xdf, 0x50, 0x91, 0xcb, 0x84, - 0x16, 0x15, 0xfb, 0x0a, 0x2d, 0xfa, 0xb6, 0x03, 0x90, 0xbe, 0x08, 0x82, 0x6e, 0xc2, 0x48, 0xfc, - 0x8c, 0x61, 0xa8, 0xb0, 0x71, 0x43, 0x5f, 0x60, 0xd4, 0x6e, 0xb1, 0x0a, 0x08, 0x56, 0xd4, 0xee, - 0x64, 0x5c, 0xf9, 0xa9, 0x03, 0x27, 0xf3, 0x5e, 0x2e, 0xb9, 0x8f, 0x3d, 0x3e, 0xa8, 0x5d, 0x45, - 0x34, 0x58, 0x8f, 0xc8, 0x96, 0x7f, 0x33, 0x27, 0xd5, 0x32, 0x2f, 0xc0, 0x69, 0x1d, 0xf7, 0x4f, - 0x87, 0x41, 0x11, 0x3e, 0x24, 0x3b, 0xcc, 0xe3, 0x54, 0x67, 0xaa, 0xa7, 0x32, 0x97, 0xaa, 0x87, - 0x19, 0x14, 0x8b, 0x52, 0xaa, 0x37, 0xc9, 0xa0, 0x78, 0xc1, 0xb2, 0xd9, 0x2a, 0x94, 0xc1, 0xf3, - 0x58, 0x95, 0xe6, 0x59, 0x76, 0x8a, 0x47, 0x62, 0xd9, 0x19, 0xb2, 0x6f, 0xd9, 0x69, 0x01, 0x8a, - 0xf9, 0x46, 0x61, 0xe6, 0x14, 0x41, 0x68, 0xec, 0xc0, 0x86, 0xe6, 0x4a, 0x17, 0x12, 0x9c, 0x83, - 0x98, 0xc5, 0x50, 0x84, 0x4d, 0x32, 0x8b, 0xaf, 0x08, 0xe5, 0x23, 0x8d, 0xa1, 0xe0, 0x60, 0x2c, - 0xcb, 0xef, 0xd2, 0x94, 0x82, 0x7e, 0xc7, 0xd9, 0xc7, 0x56, 0x35, 0x6a, 0xeb, 0x08, 0xca, 0x4d, - 0x83, 0xc7, 0x34, 0xa9, 0xbb, 0x31, 0x80, 0x7d, 0xdd, 0x81, 0xe3, 0x24, 0xa8, 0x46, 0xbb, 0x0c, - 0x8f, 0xc0, 0x26, 0x5c, 0xdc, 0x57, 0x6d, 0xec, 0xf5, 0x8b, 0x59, 0xe4, 0xdc, 0x93, 0xd4, 0x05, - 0xc6, 0xdd, 0xdd, 0x40, 0x6b, 0x30, 0x52, 0xf5, 0xc4, 0xba, 0x28, 0x1d, 0x64, 0x5d, 0x70, 0x47, - 0xdd, 0xac, 0x58, 0x0d, 0x0a, 0x89, 0xfb, 0xe3, 0x02, 0x9c, 0xc8, 0xe9, 0x12, 0xbb, 0xaf, 0xd5, - 0xa2, 0x1b, 0xe0, 0x72, 0x2d, 0xbb, 0xfd, 0x97, 0x05, 0x1c, 0xab, 0x1a, 0x68, 0x1d, 0x4e, 0x6e, - 0xb7, 0xe2, 0x14, 0xcb, 0x7c, 0x18, 0x24, 0xe4, 0xa6, 0x64, 0x06, 0xd2, 0xfd, 0x7d, 0x72, 0x39, - 0xa7, 0x0e, 0xce, 0x6d, 0x49, 0xa5, 0x25, 0x12, 0x78, 0x9b, 0x4d, 0x92, 0x16, 0x89, 0x5b, 0x8c, - 0x4a, 0x5a, 0xba, 0x98, 0x29, 0xc7, 0x5d, 0x2d, 0xd0, 0x67, 0x1d, 0x38, 0x1b, 0x93, 0x68, 0x87, - 0x44, 0x15, 0xbf, 0x46, 0xe6, 0x3b, 0x71, 0x12, 0xb6, 0x48, 0x74, 0x97, 0xd6, 0xd9, 0xe9, 0x5b, - 0x7b, 0xd3, 0x67, 0x2b, 0xbd, 0xb1, 0xe1, 0xfd, 0x48, 0xb9, 0x9f, 0x75, 0x60, 0xa2, 0xc2, 0x74, - 0x77, 0x25, 0xba, 0xdb, 0x4e, 0x84, 0xfa, 0xb8, 0xca, 0xbb, 0x91, 0x61, 0xc2, 0x66, 0xa6, 0x0c, - 0xf7, 0x65, 0x98, 0xac, 0x90, 0x96, 0xd7, 0x6e, 0xb0, 0x2b, 0xc8, 0x3c, 0xfc, 0xeb, 0x3c, 0x8c, - 0xc6, 0x12, 0x96, 0x7d, 0xfb, 0x48, 0x55, 0xc6, 0x69, 0x1d, 0xf4, 0x18, 0x0f, 0x55, 0x93, 0x17, - 0x8e, 0x46, 0xb9, 0x92, 0xc3, 0xe3, 0xdb, 0x62, 0x2c, 0xcb, 0xdc, 0xb7, 0x1c, 0x18, 0x4b, 0xdb, - 0x93, 0x2d, 0x54, 0x87, 0x63, 0x55, 0xed, 0xb2, 0x5e, 0x7a, 0x4d, 0xa2, 0xff, 0x7b, 0x7d, 0x3c, - 0x3f, 0xb3, 0x89, 0x04, 0x67, 0xb1, 0x1e, 0x3c, 0xd2, 0xef, 0x0b, 0x05, 0x38, 0xa6, 0xba, 0x2a, - 0xfc, 0x94, 0x6f, 0x64, 0x03, 0xf2, 0xb0, 0x8d, 0x0c, 0x42, 0xe6, 0xdc, 0xef, 0x13, 0x94, 0xf7, - 0x46, 0x36, 0x28, 0xef, 0x50, 0xc9, 0x77, 0xb9, 0x5e, 0xbf, 0x5d, 0x80, 0x11, 0x95, 0xcf, 0xe8, - 0x79, 0x28, 0x32, 0xcd, 0xf5, 0xde, 0xe4, 0x6f, 0xa6, 0x05, 0x63, 0x8e, 0x89, 0xa2, 0x64, 0x41, - 0x3f, 0x77, 0x9d, 0x35, 0x77, 0x94, 0xdb, 0x2f, 0xbd, 0x28, 0xc1, 0x1c, 0x13, 0x5a, 0x86, 0x01, - 0x12, 0xd4, 0x84, 0x20, 0x7e, 0x70, 0x84, 0xec, 0x95, 0xb2, 0x8b, 0x41, 0x0d, 0x53, 0x2c, 0x2c, - 0xa9, 0x1a, 0x97, 0xb7, 0x32, 0x6f, 0xd2, 0x08, 0x61, 0x4b, 0x94, 0xba, 0xef, 0x07, 0x23, 0xe1, - 0x9e, 0x48, 0xe4, 0x2f, 0x74, 0xbc, 0xee, 0x87, 0xc4, 0x84, 0x72, 0x97, 0xd6, 0x71, 0x7f, 0x65, - 0x00, 0x86, 0x2a, 0x9d, 0x4d, 0xaa, 0x93, 0x7c, 0xcb, 0x81, 0x13, 0x37, 0x32, 0x39, 0xa9, 0xd3, - 0x4d, 0x72, 0xd5, 0x9e, 0x11, 0x58, 0x8f, 0x5c, 0x53, 0xa6, 0xaf, 0x9c, 0x42, 0x9c, 0xd7, 0x1d, - 0x23, 0x2d, 0xec, 0xc0, 0xa1, 0xa4, 0x85, 0xbd, 0x79, 0xc8, 0x57, 0x37, 0xc6, 0x7b, 0x5d, 0xdb, - 0x70, 0x7f, 0xbf, 0x08, 0xc0, 0xbf, 0xc6, 0x5a, 0x3b, 0xe9, 0xc7, 0xac, 0xf7, 0x2c, 0x8c, 0xd5, - 0x49, 0x40, 0x22, 0x19, 0x97, 0x98, 0x79, 0x2f, 0x69, 0x49, 0x2b, 0xc3, 0x46, 0x4d, 0xa6, 0x43, - 0x05, 0x49, 0xb4, 0xcb, 0xe5, 0xec, 0xec, 0xf5, 0x0c, 0x55, 0x82, 0xb5, 0x5a, 0x68, 0xc6, 0xf0, - 0xba, 0x70, 0x07, 0xfe, 0xc4, 0x3e, 0x4e, 0x92, 0xf7, 0xc1, 0x84, 0x99, 0x43, 0x45, 0x48, 0x7b, - 0xca, 0xe1, 0x6e, 0xa6, 0x5e, 0xc1, 0x99, 0xda, 0x74, 0x17, 0xd4, 0xa2, 0x5d, 0xdc, 0x09, 0x84, - 0xd8, 0xa7, 0x76, 0xc1, 0x02, 0x83, 0x62, 0x51, 0xca, 0x92, 0x4f, 0xb0, 0x03, 0x90, 0xc3, 0x45, - 0x02, 0x8b, 0x34, 0xf9, 0x84, 0x56, 0x86, 0x8d, 0x9a, 0x94, 0x82, 0x30, 0x8b, 0x82, 0xb9, 0xcf, - 0x32, 0xb6, 0xcc, 0x36, 0x4c, 0x84, 0xa6, 0x39, 0x87, 0xcb, 0x40, 0xef, 0xea, 0x73, 0xe9, 0x19, - 0x6d, 0x79, 0xa0, 0x44, 0xc6, 0xfa, 0x93, 0xc1, 0x4f, 0xe5, 0x5e, 0xfd, 0x16, 0xc3, 0x98, 0x19, - 0xd6, 0xda, 0xf3, 0xa2, 0xc1, 0x3a, 0x9c, 0x6c, 0x87, 0xb5, 0xf5, 0xc8, 0x0f, 0x23, 0x3f, 0xd9, - 0x9d, 0x6f, 0x7a, 0x71, 0xcc, 0x16, 0xc6, 0xb8, 0x29, 0x0f, 0xad, 0xe7, 0xd4, 0xc1, 0xb9, 0x2d, - 0xa9, 0x42, 0xd4, 0x16, 0x40, 0x16, 0x5c, 0x56, 0xe4, 0x12, 0x9d, 0xac, 0x88, 0x55, 0xa9, 0x7b, - 0x02, 0x8e, 0x57, 0x3a, 0xed, 0x76, 0xd3, 0x27, 0x35, 0xe5, 0xd5, 0x70, 0xdf, 0x0f, 0xc7, 0x44, - 0xd2, 0x58, 0x25, 0x7d, 0x1c, 0x28, 0xc5, 0xb9, 0xfb, 0x1f, 0x07, 0xe0, 0x58, 0x26, 0x94, 0x07, - 0xbd, 0x96, 0x95, 0x19, 0xec, 0x24, 0x33, 0xd5, 0xa4, 0x05, 0x91, 0x99, 0x34, 0x4f, 0xfe, 0x68, - 0xc8, 0x38, 0x7c, 0x6b, 0xf7, 0x5f, 0x58, 0xb4, 0x3a, 0x3f, 0x52, 0x8c, 0x60, 0xfe, 0x8f, 0x02, - 0x28, 0xb2, 0xf2, 0xca, 0xbd, 0xed, 0x71, 0xb2, 0xfd, 0xab, 0x20, 0x31, 0xd6, 0x28, 0xa2, 0x00, - 0x86, 0x59, 0x47, 0x88, 0xbc, 0x74, 0x69, 0x6d, 0xac, 0x4c, 0x64, 0x5b, 0xe5, 0xb8, 0xb1, 0x24, - 0xe2, 0x7e, 0xa6, 0x00, 0xf9, 0xf1, 0x62, 0xe8, 0xa3, 0xdd, 0x1f, 0xfc, 0x79, 0x8b, 0x13, 0x21, - 0x02, 0xd6, 0x7a, 0x7f, 0xf3, 0xc0, 0xfc, 0xe6, 0xab, 0x96, 0xe6, 0x41, 0xd0, 0xed, 0xfa, 0xf2, - 0xee, 0xff, 0x70, 0xa0, 0xb4, 0xb1, 0xb1, 0xa2, 0xce, 0x75, 0x0c, 0xa7, 0x63, 0x9e, 0xcf, 0x80, - 0xb9, 0xd5, 0xe7, 0xc3, 0x56, 0x9b, 0x7b, 0xd9, 0x85, 0xf7, 0x9f, 0xe5, 0x2b, 0xae, 0xe4, 0xd6, - 0xc0, 0x3d, 0x5a, 0xa2, 0xcb, 0x70, 0x42, 0x2f, 0xa9, 0x68, 0xcf, 0x43, 0x16, 0x45, 0x6e, 0xa2, - 0xee, 0x62, 0x9c, 0xd7, 0x26, 0x8b, 0x4a, 0x58, 0x93, 0xd9, 0xf1, 0x9c, 0x83, 0x4a, 0x14, 0xe3, - 0xbc, 0x36, 0xee, 0x1a, 0x94, 0x36, 0xbc, 0x48, 0x0d, 0xfc, 0x03, 0x30, 0x59, 0x0d, 0x5b, 0xd2, - 0x8a, 0xb7, 0x42, 0x76, 0x48, 0x53, 0x0c, 0x99, 0xbf, 0xc9, 0x92, 0x29, 0xc3, 0x5d, 0xb5, 0xdd, - 0xff, 0x7a, 0x0e, 0xd4, 0xfd, 0xcc, 0x3e, 0x4e, 0xd4, 0xb6, 0x8a, 0xa4, 0x2d, 0x5a, 0x8e, 0xa4, - 0x55, 0x67, 0x4b, 0x26, 0x9a, 0x36, 0x49, 0xa3, 0x69, 0x87, 0x6c, 0x47, 0xd3, 0x2a, 0x09, 0xbb, - 0x2b, 0xa2, 0xf6, 0x2b, 0x0e, 0x8c, 0x05, 0x61, 0x8d, 0x28, 0xf7, 0xe7, 0x30, 0xdb, 0xe1, 0x2f, - 0xd9, 0xbb, 0x98, 0xc0, 0x23, 0x43, 0x05, 0x7a, 0x1e, 0xe5, 0xad, 0x8e, 0x64, 0xbd, 0x08, 0x1b, - 0xfd, 0x40, 0x8b, 0x9a, 0x5d, 0x99, 0xbb, 0x6f, 0x1e, 0xca, 0xd3, 0xcf, 0xee, 0x68, 0x24, 0xbe, - 0xa9, 0xc9, 0x89, 0xa3, 0xb6, 0xec, 0xa5, 0xf2, 0xd2, 0x9d, 0xe6, 0x85, 0x92, 0x29, 0xb7, 0x53, - 0xf9, 0xd1, 0x85, 0x21, 0x1e, 0x0e, 0x2e, 0xb2, 0x60, 0x31, 0xe7, 0x28, 0x0f, 0x15, 0xc7, 0xa2, - 0x04, 0x25, 0x32, 0xc4, 0xa2, 0x64, 0xeb, 0x01, 0x0d, 0x23, 0x84, 0x23, 0x3f, 0xc6, 0x02, 0x3d, - 0xa7, 0xeb, 0xfd, 0x63, 0xfd, 0xe8, 0xfd, 0xe3, 0x3d, 0x75, 0xfe, 0xcf, 0x3b, 0x30, 0x56, 0xd5, - 0x1e, 0xb4, 0x28, 0x3f, 0x61, 0xeb, 0xe1, 0xee, 0xbc, 0x77, 0x47, 0xb8, 0xcf, 0xcd, 0x78, 0x40, - 0xc3, 0xa0, 0xce, 0x52, 0x7f, 0x32, 0x23, 0x07, 0x13, 0x75, 0xac, 0x64, 0xe5, 0x30, 0x8d, 0x26, - 0x32, 0x54, 0x95, 0xc2, 0xb0, 0xa0, 0x85, 0x5e, 0x87, 0x11, 0x79, 0xa3, 0x40, 0x44, 0xde, 0x63, - 0x1b, 0x4e, 0x10, 0xd3, 0xd3, 0x2a, 0xf3, 0x05, 0x72, 0x28, 0x56, 0x14, 0x51, 0x03, 0x06, 0x6a, - 0x5e, 0x5d, 0xc4, 0xe0, 0xaf, 0xda, 0xc9, 0xc7, 0x2a, 0x69, 0x32, 0x7d, 0x74, 0x61, 0x76, 0x09, - 0x53, 0x12, 0xe8, 0x66, 0xfa, 0x22, 0xc0, 0xa4, 0xb5, 0xd3, 0xd7, 0x14, 0x0b, 0xb9, 0x4c, 0xd0, - 0xf5, 0xc0, 0x40, 0x4d, 0x38, 0xa7, 0xff, 0x3f, 0x46, 0x76, 0xd1, 0x4e, 0x42, 0x57, 0x9e, 0xe5, - 0x25, 0x75, 0x70, 0x53, 0x2a, 0x8d, 0x24, 0x69, 0x97, 0x7f, 0xde, 0x16, 0x15, 0x96, 0xab, 0x84, - 0xbf, 0xb1, 0xbe, 0xb1, 0xb1, 0x8e, 0x19, 0x76, 0xd4, 0x84, 0xa1, 0x36, 0x8b, 0x9b, 0x29, 0xff, - 0x82, 0xad, 0xb3, 0x85, 0xc7, 0xe1, 0xf0, 0xb5, 0xc9, 0xff, 0xc7, 0x82, 0x06, 0xba, 0x08, 0xc3, - 0xfc, 0x61, 0x1b, 0x7e, 0x07, 0xa2, 0x74, 0x61, 0xaa, 0xf7, 0xf3, 0x38, 0xe9, 0x41, 0xc1, 0x7f, - 0xc7, 0x58, 0xb6, 0x45, 0x5f, 0x70, 0x60, 0x82, 0x72, 0xd4, 0xf4, 0x25, 0x9e, 0x32, 0xb2, 0xc5, - 0xb3, 0xae, 0xc6, 0x54, 0x22, 0x91, 0xbc, 0x46, 0xa9, 0x85, 0x97, 0x0d, 0x72, 0x38, 0x43, 0x1e, - 0xbd, 0x01, 0x23, 0xb1, 0x5f, 0x23, 0x55, 0x2f, 0x8a, 0xcb, 0x27, 0x0e, 0xa7, 0x2b, 0xa9, 0x3b, - 0x4c, 0x10, 0xc2, 0x8a, 0x24, 0xfa, 0x75, 0xf6, 0x14, 0x6a, 0xb5, 0xe1, 0xef, 0x90, 0x95, 0xb0, - 0xca, 0xd5, 0x98, 0x93, 0xb6, 0xf6, 0xbe, 0x74, 0xfc, 0x49, 0xcc, 0xc2, 0x4b, 0x64, 0x92, 0xc3, - 0x59, 0xfa, 0xe8, 0x6f, 0x38, 0x70, 0x8a, 0x3f, 0x59, 0x90, 0x7d, 0x85, 0xe3, 0xd4, 0x5d, 0xda, - 0xa3, 0xd8, 0xe5, 0x8d, 0xd9, 0x3c, 0x94, 0x38, 0x9f, 0x12, 0x4b, 0x30, 0x6c, 0x3e, 0x9c, 0x74, - 0xda, 0xaa, 0x5b, 0xb8, 0xff, 0xc7, 0x92, 0xd0, 0xd3, 0x50, 0x6a, 0x8b, 0xe3, 0xd0, 0x8f, 0x5b, - 0xec, 0x2a, 0xce, 0x00, 0xbf, 0x24, 0xb9, 0x9e, 0x82, 0xb1, 0x5e, 0xc7, 0xc8, 0x36, 0xfd, 0xe4, - 0x7e, 0xd9, 0xa6, 0xd1, 0x55, 0x28, 0x25, 0x61, 0x53, 0x24, 0x5c, 0x8d, 0xcb, 0x65, 0xb6, 0x02, - 0xcf, 0xe5, 0xed, 0xad, 0x0d, 0x55, 0x2d, 0xd5, 0xdc, 0x53, 0x58, 0x8c, 0x75, 0x3c, 0x2c, 0xfc, - 0x59, 0x3c, 0x05, 0x11, 0x31, 0x95, 0xfd, 0xc1, 0x4c, 0xf8, 0xb3, 0x5e, 0x88, 0xcd, 0xba, 0x68, - 0x09, 0x8e, 0xb7, 0xbb, 0x74, 0x7e, 0x7e, 0x05, 0x50, 0x45, 0x9c, 0x74, 0x2b, 0xfc, 0xdd, 0x6d, - 0x0c, 0x6d, 0xff, 0xec, 0x7e, 0xda, 0x7e, 0x8f, 0xdc, 0xcb, 0x0f, 0xdd, 0x4d, 0xee, 0x65, 0x54, - 0x83, 0x87, 0xbc, 0x4e, 0x12, 0xb2, 0x7c, 0x3c, 0x66, 0x13, 0x1e, 0x09, 0xfe, 0x08, 0x0f, 0x2e, - 0xbf, 0xb5, 0x37, 0xfd, 0xd0, 0xec, 0x3e, 0xf5, 0xf0, 0xbe, 0x58, 0xd0, 0xab, 0x30, 0x42, 0x44, - 0xfe, 0xe8, 0xf2, 0xcf, 0xd9, 0x12, 0x12, 0xcc, 0x8c, 0xd4, 0x32, 0xc8, 0x96, 0xc3, 0xb0, 0xa2, - 0x87, 0x36, 0xa0, 0xd4, 0x08, 0xe3, 0x64, 0xb6, 0xe9, 0x7b, 0x31, 0x89, 0xcb, 0x0f, 0xb3, 0x45, - 0x93, 0x2b, 0x7b, 0x5d, 0x92, 0xd5, 0xd2, 0x35, 0x73, 0x29, 0x6d, 0x89, 0x75, 0x34, 0x88, 0x30, - 0xe7, 0x30, 0x0b, 0x83, 0x97, 0x8e, 0xaf, 0x73, 0x6c, 0x60, 0x8f, 0xe7, 0x61, 0x5e, 0x0f, 0x6b, - 0x15, 0xb3, 0xb6, 0xf2, 0x0e, 0xeb, 0x40, 0x9c, 0xc5, 0x89, 0x9e, 0x85, 0xb1, 0x76, 0x58, 0xab, - 0xb4, 0x49, 0x75, 0xdd, 0x4b, 0xaa, 0x8d, 0xf2, 0xb4, 0x69, 0x65, 0x5c, 0xd7, 0xca, 0xb0, 0x51, - 0x13, 0xb5, 0x61, 0xb8, 0xc5, 0x13, 0x35, 0x94, 0x1f, 0xb5, 0xa5, 0xdb, 0x88, 0xcc, 0x0f, 0xc2, - 0x86, 0xc0, 0x7f, 0x60, 0x49, 0x06, 0xfd, 0x7d, 0x07, 0x8e, 0x65, 0x2e, 0x97, 0x95, 0xdf, 0x61, - 0x4d, 0x64, 0x31, 0x11, 0xcf, 0x3d, 0xce, 0xa6, 0xcf, 0x04, 0xde, 0xee, 0x06, 0xe1, 0x6c, 0x8f, - 0xf8, 0xbc, 0xb0, 0x6c, 0x2b, 0xe5, 0xc7, 0xec, 0xcd, 0x0b, 0x43, 0x28, 0xe7, 0x85, 0xfd, 0xc0, - 0x92, 0x0c, 0x7a, 0x12, 0x86, 0x45, 0x62, 0xc4, 0xf2, 0xe3, 0xa6, 0xcb, 0x5d, 0xe4, 0x4f, 0xc4, - 0xb2, 0x7c, 0xea, 0xfd, 0x70, 0xbc, 0x4b, 0x75, 0x3b, 0x50, 0xca, 0x8f, 0xdf, 0x74, 0x40, 0xbf, - 0x8d, 0x6e, 0xfd, 0xd1, 0x96, 0x67, 0x61, 0xac, 0xca, 0xdf, 0xd0, 0xe4, 0xf7, 0xd9, 0x07, 0x4d, - 0x7b, 0xef, 0xbc, 0x56, 0x86, 0x8d, 0x9a, 0xee, 0x25, 0x40, 0xdd, 0x19, 0xf5, 0xef, 0x2a, 0x9f, - 0xd4, 0x3f, 0x74, 0x60, 0xdc, 0x90, 0x19, 0xac, 0x3b, 0x55, 0x17, 0x01, 0xb5, 0xfc, 0x28, 0x0a, - 0x23, 0xfd, 0xb1, 0x42, 0x91, 0x73, 0x82, 0x05, 0x5b, 0xac, 0x76, 0x95, 0xe2, 0x9c, 0x16, 0xee, - 0x3f, 0x1e, 0x84, 0x34, 0xca, 0x5c, 0xa5, 0x2c, 0x76, 0x7a, 0xa6, 0x2c, 0x7e, 0x0a, 0x46, 0x5e, - 0x8e, 0xc3, 0x60, 0x3d, 0x4d, 0x6c, 0xac, 0xbe, 0xc5, 0x73, 0x95, 0xb5, 0x2b, 0xac, 0xa6, 0xaa, - 0xc1, 0x6a, 0xbf, 0xb2, 0xe8, 0x37, 0x93, 0xee, 0xcc, 0xb7, 0xcf, 0x3d, 0xcf, 0xe1, 0x58, 0xd5, - 0x60, 0xef, 0x16, 0xee, 0x10, 0xe5, 0x08, 0x48, 0xdf, 0x2d, 0xe4, 0x8f, 0x65, 0xb0, 0x32, 0x74, - 0x1e, 0x46, 0x95, 0x13, 0x41, 0x78, 0x26, 0xd4, 0x4c, 0x29, 0x4f, 0x03, 0x4e, 0xeb, 0x30, 0x81, - 0x50, 0x18, 0x9e, 0x85, 0x09, 0xa5, 0x62, 0x43, 0x3d, 0xc9, 0x98, 0xb2, 0x39, 0x6f, 0x97, 0x60, - 0xac, 0x48, 0xe6, 0x39, 0x96, 0x47, 0x0f, 0xc5, 0xb1, 0xac, 0x5d, 0x79, 0x28, 0xf6, 0x7b, 0xe5, - 0xc1, 0x5c, 0xdb, 0x23, 0x7d, 0xad, 0xed, 0x4f, 0x0d, 0xc0, 0xf0, 0x35, 0x12, 0xb1, 0x84, 0xef, - 0x4f, 0xc2, 0xf0, 0x0e, 0xff, 0x37, 0x7b, 0x5f, 0x56, 0xd4, 0xc0, 0xb2, 0x9c, 0x7e, 0xb7, 0xcd, - 0x8e, 0xdf, 0xac, 0x2d, 0xa4, 0xbb, 0x38, 0xcd, 0xe9, 0x28, 0x0b, 0x70, 0x5a, 0x87, 0x36, 0xa8, - 0x53, 0xc9, 0xbe, 0xd5, 0xf2, 0xbb, 0x9e, 0xe4, 0x5f, 0x92, 0x05, 0x38, 0xad, 0x83, 0x1e, 0x87, - 0xa1, 0xba, 0x9f, 0x6c, 0x78, 0xf5, 0xac, 0x5b, 0x74, 0x89, 0x41, 0xb1, 0x28, 0x65, 0x6e, 0x31, - 0x3f, 0xd9, 0x88, 0x08, 0xb3, 0xec, 0x76, 0xa5, 0xeb, 0x58, 0xd2, 0xca, 0xb0, 0x51, 0x93, 0x75, - 0x29, 0x14, 0x23, 0x13, 0x41, 0xb2, 0x69, 0x97, 0x64, 0x01, 0x4e, 0xeb, 0xd0, 0xf5, 0x5f, 0x0d, - 0x5b, 0x6d, 0xbf, 0x29, 0xc2, 0xb7, 0xb5, 0xf5, 0x3f, 0x2f, 0xe0, 0x58, 0xd5, 0xa0, 0xb5, 0x29, - 0x0b, 0xa3, 0xec, 0x27, 0xfb, 0x46, 0xdc, 0xba, 0x80, 0x63, 0x55, 0xc3, 0xbd, 0x06, 0xe3, 0x7c, - 0x27, 0xcf, 0x37, 0x3d, 0xbf, 0xb5, 0x34, 0x8f, 0x2e, 0x76, 0x5d, 0x79, 0x78, 0x32, 0xe7, 0xca, - 0xc3, 0x29, 0xa3, 0x51, 0xf7, 0xd5, 0x07, 0xf7, 0x87, 0x05, 0x18, 0x39, 0xc2, 0x67, 0x36, 0x8f, - 0xfc, 0xc5, 0x68, 0x74, 0x33, 0xf3, 0xc4, 0xe6, 0xba, 0xcd, 0x1b, 0x4c, 0xfb, 0x3e, 0xaf, 0xf9, - 0x9f, 0x0a, 0x70, 0x5a, 0x56, 0x95, 0xba, 0xdc, 0xd2, 0x3c, 0x7b, 0xba, 0xec, 0xf0, 0x27, 0x3a, - 0x32, 0x26, 0x7a, 0xdd, 0x9e, 0x36, 0xba, 0x34, 0xdf, 0x73, 0xaa, 0x5f, 0xcd, 0x4c, 0x35, 0xb6, - 0x4a, 0x75, 0xff, 0xc9, 0xfe, 0x73, 0x07, 0xa6, 0xf2, 0x27, 0xfb, 0x08, 0x5e, 0x35, 0x7d, 0xc3, - 0x7c, 0xd5, 0xf4, 0x97, 0xec, 0x2d, 0x31, 0x73, 0x28, 0x3d, 0xde, 0x37, 0xfd, 0xef, 0x0e, 0x9c, - 0x94, 0x0d, 0xd8, 0xe9, 0x39, 0xe7, 0x07, 0x2c, 0x72, 0xe7, 0xf0, 0x97, 0xd9, 0xeb, 0xc6, 0x32, - 0x7b, 0xd1, 0xde, 0xc0, 0xf5, 0x71, 0xf4, 0x7c, 0x0d, 0xfe, 0xcf, 0x1c, 0x28, 0xe7, 0x35, 0x38, - 0x82, 0x4f, 0xfe, 0x9a, 0xf9, 0xc9, 0xaf, 0x1d, 0xce, 0xc8, 0x7b, 0x7f, 0xf0, 0x72, 0xaf, 0x89, - 0x42, 0x4d, 0x29, 0x57, 0x39, 0xb6, 0x7c, 0xd2, 0x9c, 0x44, 0xbe, 0x80, 0xd6, 0x84, 0xa1, 0x98, - 0x45, 0xa9, 0x88, 0x25, 0x70, 0xc9, 0x86, 0xb4, 0x45, 0xf1, 0x09, 0x1b, 0x3b, 0xfb, 0x1f, 0x0b, - 0x1a, 0xee, 0x6f, 0x15, 0xe0, 0x8c, 0x7a, 0xad, 0x98, 0xec, 0x90, 0x66, 0xba, 0x3f, 0xd8, 0xf3, - 0x18, 0x9e, 0xfa, 0x69, 0xef, 0x79, 0x8c, 0x94, 0x44, 0xba, 0x17, 0x52, 0x18, 0xd6, 0x68, 0xa2, - 0x0a, 0x9c, 0x62, 0xcf, 0x59, 0x2c, 0xfa, 0x81, 0xd7, 0xf4, 0x5f, 0x25, 0x11, 0x26, 0xad, 0x70, - 0xc7, 0x6b, 0x0a, 0x49, 0x5d, 0x5d, 0x99, 0x5e, 0xcc, 0xab, 0x84, 0xf3, 0xdb, 0x76, 0x69, 0xdc, - 0x03, 0xfd, 0x6a, 0xdc, 0xee, 0x9f, 0x38, 0x30, 0x76, 0x84, 0x6f, 0x3b, 0x87, 0xe6, 0x96, 0x78, - 0xce, 0xde, 0x96, 0xe8, 0xb1, 0x0d, 0xf6, 0x8a, 0xd0, 0xf5, 0xdc, 0x2d, 0xfa, 0xb4, 0xa3, 0xe2, - 0x78, 0x78, 0xb0, 0xe4, 0x87, 0xec, 0xf5, 0xe3, 0x20, 0x79, 0x36, 0xd1, 0xd7, 0x33, 0xc9, 0x47, - 0x0b, 0xb6, 0x32, 0x68, 0x75, 0xf5, 0xe6, 0x2e, 0x92, 0x90, 0x7e, 0xc5, 0x01, 0xe0, 0xfd, 0x14, - 0xb9, 0xcb, 0x69, 0xdf, 0x36, 0x0f, 0x6d, 0xa6, 0x28, 0x11, 0xde, 0x35, 0xb5, 0x85, 0xd2, 0x02, - 0xac, 0xf5, 0xe4, 0x1e, 0xb2, 0x8b, 0xde, 0x73, 0x62, 0xd3, 0x2f, 0x38, 0x70, 0x2c, 0xd3, 0xdd, - 0x9c, 0xf6, 0x5b, 0xe6, 0xeb, 0x8c, 0x16, 0x24, 0x2b, 0x33, 0xa3, 0xb5, 0x6e, 0x3c, 0xf9, 0x2f, - 0x2e, 0x18, 0xef, 0x84, 0xa3, 0xd7, 0x60, 0x54, 0x5a, 0x3e, 0xe4, 0xf2, 0xb6, 0xf9, 0x4a, 0xad, - 0x52, 0x6f, 0x24, 0x24, 0xc6, 0x29, 0xbd, 0x4c, 0x98, 0x60, 0xa1, 0xaf, 0x30, 0xc1, 0xfb, 0xfb, - 0xc6, 0x6d, 0xbe, 0x5d, 0x7a, 0xf0, 0x50, 0xec, 0xd2, 0x0f, 0x59, 0xb7, 0x4b, 0x3f, 0x7c, 0xc4, - 0x76, 0x69, 0xcd, 0x49, 0x58, 0xbc, 0x07, 0x27, 0xe1, 0x6b, 0x70, 0x72, 0x27, 0x55, 0x3a, 0xd5, - 0x4a, 0x12, 0x79, 0x9b, 0x9e, 0xcc, 0xb5, 0x46, 0x53, 0x05, 0x3a, 0x4e, 0x48, 0x90, 0x68, 0xea, - 0x6a, 0x1a, 0xa1, 0x78, 0x2d, 0x07, 0x1d, 0xce, 0x25, 0x92, 0xf5, 0xf6, 0x0c, 0xf7, 0xe1, 0xed, - 0x79, 0xcb, 0x81, 0x53, 0x5e, 0xd7, 0x1d, 0x3b, 0x4c, 0xb6, 0x44, 0xc8, 0xc9, 0x75, 0x7b, 0x22, - 0x84, 0x81, 0x5e, 0xb8, 0xd5, 0xf2, 0x8a, 0x70, 0x7e, 0x87, 0xd0, 0x63, 0xa9, 0xeb, 0x9d, 0xc7, - 0xb5, 0xe6, 0xfb, 0xc9, 0xbf, 0x9e, 0x8d, 0xe7, 0x01, 0x36, 0xf5, 0x1f, 0xb1, 0xab, 0x6d, 0x5b, - 0x88, 0xe9, 0x29, 0xdd, 0x43, 0x4c, 0x4f, 0xc6, 0xf5, 0x36, 0x66, 0xc9, 0xf5, 0x16, 0xc0, 0xa4, - 0xdf, 0xf2, 0xea, 0x64, 0xbd, 0xd3, 0x6c, 0xf2, 0x4b, 0x33, 0xf2, 0x1d, 0xe1, 0x5c, 0x0b, 0xde, - 0x4a, 0x58, 0xf5, 0x9a, 0xd9, 0x17, 0xe4, 0xd5, 0xe5, 0xa0, 0xcb, 0x19, 0x4c, 0xb8, 0x0b, 0x37, - 0x5d, 0xb0, 0x2c, 0x81, 0x20, 0x49, 0xe8, 0x6c, 0xb3, 0xc0, 0x91, 0x11, 0xbe, 0x60, 0x2f, 0xa5, - 0x60, 0xac, 0xd7, 0x41, 0xcb, 0x30, 0x5a, 0x0b, 0x62, 0x71, 0x5d, 0xf8, 0x18, 0x63, 0x66, 0xef, - 0xa4, 0x2c, 0x70, 0xe1, 0x4a, 0x45, 0x5d, 0x14, 0x7e, 0x28, 0x27, 0x23, 0xa6, 0x2a, 0xc7, 0x69, - 0x7b, 0xb4, 0xca, 0x90, 0x89, 0x47, 0xd6, 0x78, 0x3c, 0xc7, 0x23, 0x3d, 0x1c, 0x46, 0x0b, 0x57, - 0xe4, 0x33, 0x71, 0xe3, 0x82, 0x9c, 0x78, 0x2d, 0x2d, 0xc5, 0xa0, 0xbd, 0xe7, 0x7c, 0x7c, 0xdf, - 0xf7, 0x9c, 0x59, 0x2a, 0xdc, 0xa4, 0xa9, 0xdc, 0xc3, 0xe7, 0xac, 0xa5, 0xc2, 0x4d, 0x23, 0x25, - 0x45, 0x2a, 0xdc, 0x14, 0x80, 0x75, 0x92, 0x68, 0xad, 0x97, 0x9b, 0xfc, 0x04, 0x63, 0x1a, 0x07, - 0x77, 0x7a, 0xeb, 0xfe, 0xd2, 0x93, 0xfb, 0xfa, 0x4b, 0xbb, 0xfc, 0xbb, 0xa7, 0x0e, 0xe0, 0xdf, - 0x6d, 0xb0, 0x24, 0xa5, 0x4b, 0xf3, 0xc2, 0xa5, 0x6e, 0x41, 0xbf, 0x63, 0x69, 0x51, 0x78, 0xe4, - 0x29, 0xfb, 0x17, 0x73, 0x02, 0x3d, 0x03, 0xc8, 0xcf, 0xdc, 0x75, 0x00, 0x39, 0x65, 0xcf, 0x29, - 0x9c, 0x65, 0xbb, 0x2d, 0x0a, 0xf6, 0x9c, 0x82, 0xb1, 0x5e, 0x27, 0xeb, 0x2d, 0x7d, 0xf0, 0xd0, - 0xbc, 0xa5, 0x53, 0x47, 0xe0, 0x2d, 0x3d, 0xdb, 0xb7, 0xb7, 0xf4, 0x26, 0x9c, 0x68, 0x87, 0xb5, - 0x05, 0x3f, 0x8e, 0x3a, 0xec, 0x16, 0xe1, 0x5c, 0xa7, 0x56, 0x27, 0x09, 0x73, 0xb7, 0x96, 0x2e, - 0xbc, 0x53, 0xef, 0x64, 0x9b, 0x6d, 0x64, 0xb9, 0x47, 0x33, 0x0d, 0x98, 0xe9, 0x84, 0x45, 0xdd, - 0xe6, 0x14, 0xe2, 0x3c, 0x12, 0xba, 0x9f, 0xf6, 0x91, 0xa3, 0xf1, 0xd3, 0x7e, 0x00, 0x46, 0xe2, - 0x46, 0x27, 0xa9, 0x85, 0x37, 0x02, 0xe6, 0x8c, 0x1f, 0x9d, 0x7b, 0x87, 0x32, 0x65, 0x0b, 0xf8, - 0xed, 0xbd, 0xe9, 0x49, 0xf9, 0xbf, 0x66, 0xc5, 0x16, 0x10, 0xf4, 0x8d, 0x1e, 0xf7, 0x95, 0xdc, - 0xc3, 0xbc, 0xaf, 0x74, 0xe6, 0x40, 0x77, 0x95, 0xf2, 0x9c, 0xd1, 0x8f, 0xfe, 0xcc, 0x39, 0xa3, - 0xbf, 0xe6, 0xc0, 0xf8, 0x8e, 0xee, 0x32, 0x10, 0x0e, 0x73, 0x0b, 0x81, 0x3b, 0x86, 0x27, 0x62, - 0xce, 0xa5, 0x7c, 0xce, 0x00, 0xdd, 0xce, 0x02, 0xb0, 0xd9, 0x93, 0x9c, 0xa0, 0xa2, 0xc7, 0xee, - 0x57, 0x50, 0xd1, 0x1b, 0x8c, 0x8f, 0x49, 0x25, 0x97, 0x79, 0xd1, 0xed, 0xc6, 0x14, 0x4b, 0x9e, - 0xa8, 0x42, 0x8a, 0x75, 0x7a, 0xe8, 0xf3, 0x0e, 0x4c, 0x4a, 0xbd, 0x4c, 0xb8, 0xfc, 0x62, 0x11, - 0x15, 0x69, 0x53, 0x1d, 0x64, 0x61, 0xf5, 0x1b, 0x19, 0x3a, 0xb8, 0x8b, 0x32, 0xe5, 0xea, 0x2a, - 0x08, 0xad, 0x1e, 0xb3, 0xe0, 0x5f, 0x21, 0xc3, 0xcc, 0xa6, 0x60, 0xac, 0xd7, 0x41, 0xdf, 0x74, - 0xa0, 0xd8, 0x08, 0xc3, 0xed, 0xb8, 0xfc, 0x24, 0x63, 0xe8, 0x2f, 0x58, 0x96, 0x4d, 0x2f, 0x51, - 0xdc, 0x5c, 0x28, 0x7d, 0x5a, 0xda, 0x8e, 0x18, 0xec, 0xf6, 0xde, 0xf4, 0x84, 0xf1, 0x96, 0x53, - 0xfc, 0xe6, 0xdb, 0x1a, 0x44, 0xd8, 0x36, 0x59, 0xd7, 0xd0, 0x97, 0x1c, 0x98, 0xbc, 0x91, 0x31, - 0x68, 0x88, 0xb0, 0x50, 0x6c, 0xdf, 0x54, 0xc2, 0xa7, 0x3b, 0x0b, 0xc5, 0x5d, 0x3d, 0x40, 0x9f, - 0x33, 0x0d, 0x9d, 0x3c, 0x7e, 0xd4, 0xe2, 0x04, 0x66, 0x0c, 0xab, 0xfc, 0x5a, 0x50, 0xbe, 0xc5, - 0xf3, 0x9e, 0xe3, 0x43, 0xa6, 0xe8, 0x60, 0xd2, 0x8f, 0x95, 0xd3, 0x94, 0x98, 0xf6, 0x16, 0x0b, - 0x9b, 0xdd, 0xf8, 0xfc, 0xba, 0xb9, 0xe5, 0x4b, 0xa7, 0x61, 0xc2, 0xf4, 0xed, 0xa1, 0x77, 0x99, - 0xef, 0x74, 0x9c, 0xcb, 0x3e, 0x79, 0x30, 0x2e, 0xeb, 0x1b, 0xcf, 0x1e, 0x18, 0xef, 0x12, 0x14, - 0x0e, 0xf5, 0x5d, 0x82, 0x81, 0xa3, 0x79, 0x97, 0x60, 0xf2, 0x30, 0xde, 0x25, 0x38, 0x7e, 0xa0, - 0x77, 0x09, 0xb4, 0x77, 0x21, 0x06, 0xef, 0xf0, 0x2e, 0xc4, 0x2c, 0x1c, 0x93, 0x77, 0x7f, 0x88, - 0x48, 0xfd, 0xce, 0xdd, 0xfe, 0x67, 0x44, 0x93, 0x63, 0xf3, 0x66, 0x31, 0xce, 0xd6, 0xa7, 0x9b, - 0xac, 0x18, 0xb0, 0x96, 0x43, 0xb6, 0x1e, 0x8d, 0x32, 0x97, 0x16, 0x53, 0x9f, 0x05, 0x8b, 0x92, - 0xd1, 0xce, 0x45, 0x06, 0xbb, 0x2d, 0xff, 0xc1, 0xbc, 0x07, 0xe8, 0x25, 0x28, 0x87, 0x5b, 0x5b, - 0xcd, 0xd0, 0xab, 0xa5, 0x8f, 0x27, 0xc8, 0xb8, 0x04, 0x7e, 0x57, 0x55, 0xe5, 0xda, 0x5d, 0xeb, - 0x51, 0x0f, 0xf7, 0xc4, 0x80, 0xde, 0xa2, 0x82, 0x49, 0x12, 0x46, 0xa4, 0x96, 0xda, 0x6a, 0x46, - 0xd9, 0x98, 0x89, 0xf5, 0x31, 0x57, 0x4c, 0x3a, 0x7c, 0xf4, 0xea, 0xa3, 0x64, 0x4a, 0x71, 0xb6, - 0x5b, 0x28, 0x82, 0xd3, 0xed, 0x3c, 0x53, 0x51, 0x2c, 0x6e, 0x2c, 0xed, 0x67, 0xb0, 0x52, 0x0f, - 0x69, 0xe7, 0x1a, 0x9b, 0x62, 0xdc, 0x03, 0xb3, 0xfe, 0xc0, 0xc1, 0xc8, 0xd1, 0x3c, 0x70, 0xf0, - 0x31, 0x00, 0x75, 0x29, 0x5f, 0x1a, 0x1f, 0x96, 0xad, 0x5c, 0xa5, 0xe1, 0x38, 0xb5, 0x37, 0x65, - 0x15, 0x19, 0xac, 0x91, 0x44, 0xff, 0x3b, 0xf7, 0x05, 0x10, 0x6e, 0x61, 0xa9, 0x5b, 0x5f, 0x13, - 0x3f, 0x73, 0xaf, 0x80, 0xfc, 0x03, 0x07, 0xa6, 0xf8, 0xca, 0xcb, 0x0a, 0xf7, 0x54, 0xb4, 0x10, - 0x77, 0x7b, 0x6c, 0x87, 0xae, 0xf0, 0x94, 0x49, 0x06, 0x55, 0xe6, 0xe8, 0xde, 0xa7, 0x27, 0xe8, - 0x2b, 0x39, 0x2a, 0xc5, 0x31, 0x5b, 0x36, 0xcb, 0xfc, 0x77, 0x1c, 0x4e, 0xdc, 0xea, 0x47, 0x8b, - 0xf8, 0x47, 0x3d, 0x4d, 0xaa, 0x88, 0x75, 0xef, 0x97, 0x0f, 0xc9, 0xa4, 0xaa, 0x3f, 0x36, 0x71, - 0x20, 0xc3, 0xea, 0x17, 0x1c, 0x98, 0xf4, 0x32, 0xa1, 0x26, 0xcc, 0x0e, 0x64, 0xc5, 0x26, 0x35, - 0x1b, 0xa5, 0xf1, 0x2b, 0x4c, 0xc8, 0xcb, 0x46, 0xb5, 0xe0, 0x2e, 0xe2, 0xe8, 0x87, 0x0e, 0x9c, - 0x4d, 0xbc, 0x78, 0x9b, 0xa7, 0x72, 0x8e, 0xd3, 0xbb, 0xba, 0xa2, 0x73, 0x27, 0xd9, 0x6e, 0x7c, - 0xc5, 0xfa, 0x6e, 0xdc, 0xe8, 0x4d, 0x93, 0xef, 0xcb, 0x47, 0xc5, 0xbe, 0x3c, 0xbb, 0x4f, 0x4d, - 0xbc, 0x5f, 0xd7, 0xa7, 0x3e, 0xed, 0xf0, 0x27, 0xbf, 0x7a, 0x8a, 0x7c, 0x9b, 0xa6, 0xc8, 0xb7, - 0x62, 0xf3, 0xd1, 0x21, 0x5d, 0xf6, 0xfc, 0x35, 0x07, 0x4e, 0xe6, 0x9d, 0x48, 0x39, 0x5d, 0xfa, - 0x88, 0xd9, 0x25, 0x8b, 0x5a, 0x96, 0xde, 0x21, 0x2b, 0x6f, 0x9e, 0x4c, 0x5d, 0x81, 0x47, 0xee, - 0xf4, 0x15, 0xef, 0x84, 0x6f, 0x44, 0x17, 0x8b, 0xff, 0x6c, 0x54, 0xf3, 0x42, 0x26, 0xa4, 0x6d, - 0x3d, 0x86, 0x3b, 0x80, 0x21, 0x3f, 0x68, 0xfa, 0x01, 0x11, 0xf7, 0x35, 0x6d, 0xea, 0xb0, 0xe2, - 0xcd, 0x22, 0x8a, 0x1d, 0x0b, 0x2a, 0xf7, 0xd9, 0x29, 0x99, 0x7d, 0x05, 0x6e, 0xf0, 0xe8, 0x5f, - 0x81, 0xbb, 0x01, 0xa3, 0x37, 0xfc, 0xa4, 0xc1, 0x82, 0x29, 0x84, 0xaf, 0xcf, 0xc2, 0x3d, 0x47, - 0x8a, 0x2e, 0x1d, 0xfb, 0x75, 0x49, 0x00, 0xa7, 0xb4, 0xd0, 0x79, 0x4e, 0x98, 0x45, 0x6e, 0x67, - 0x43, 0x6a, 0xaf, 0xcb, 0x02, 0x9c, 0xd6, 0xa1, 0x93, 0x35, 0x46, 0x7f, 0xc9, 0x04, 0x50, 0x22, - 0x2d, 0xb2, 0x8d, 0x74, 0x97, 0x02, 0x23, 0xbf, 0x4d, 0x7c, 0x5d, 0xa3, 0x81, 0x0d, 0x8a, 0x2a, - 0x33, 0xf5, 0x48, 0xcf, 0xcc, 0xd4, 0xaf, 0x33, 0x81, 0x2d, 0xf1, 0x83, 0x0e, 0x59, 0x0b, 0x44, - 0xbc, 0xf7, 0x8a, 0x9d, 0xbb, 0xcf, 0x1c, 0x27, 0x57, 0xc1, 0xd3, 0xdf, 0x58, 0xa3, 0xa7, 0xb9, - 0x5c, 0x4a, 0xfb, 0xba, 0x5c, 0x52, 0x93, 0xcb, 0x98, 0x75, 0x93, 0x4b, 0x42, 0xda, 0x56, 0x4c, - 0x2e, 0x3f, 0x53, 0xe6, 0x80, 0x3f, 0x77, 0x00, 0x29, 0xb9, 0x4b, 0x31, 0xd4, 0x23, 0x08, 0xaa, - 0xfc, 0xb8, 0x03, 0x10, 0xa8, 0xb7, 0x42, 0xed, 0x9e, 0x82, 0x1c, 0x67, 0xda, 0x81, 0x14, 0x86, - 0x35, 0x9a, 0xee, 0x9f, 0x3a, 0x69, 0xec, 0x72, 0x3a, 0xf6, 0x23, 0x08, 0x22, 0xdb, 0x35, 0x83, - 0xc8, 0x36, 0x2c, 0x9a, 0xee, 0xd5, 0x30, 0x7a, 0x84, 0x93, 0xfd, 0xa4, 0x00, 0xc7, 0xf4, 0xca, - 0x15, 0x72, 0x14, 0x1f, 0xfb, 0x86, 0x11, 0x41, 0x7b, 0xd5, 0xee, 0x78, 0x2b, 0xc2, 0x03, 0x94, - 0x17, 0xad, 0xfd, 0xb1, 0x4c, 0xb4, 0xf6, 0x75, 0xfb, 0xa4, 0xf7, 0x0f, 0xd9, 0xfe, 0xcf, 0x0e, - 0x9c, 0xc8, 0xb4, 0x38, 0x82, 0x05, 0xb6, 0x63, 0x2e, 0xb0, 0xe7, 0xad, 0x8f, 0xba, 0xc7, 0xea, - 0xfa, 0x56, 0xa1, 0x6b, 0xb4, 0x4c, 0x89, 0xfb, 0x94, 0x03, 0x45, 0x2a, 0x2d, 0xcb, 0x78, 0xae, - 0x8f, 0x1c, 0xca, 0x0a, 0x60, 0x72, 0xbd, 0xe0, 0xce, 0xaa, 0x7f, 0x0c, 0x86, 0x39, 0xf5, 0xa9, - 0x4f, 0x3a, 0x00, 0x69, 0xa5, 0xfb, 0x25, 0x02, 0xbb, 0xdf, 0x29, 0xc0, 0xa9, 0xdc, 0x65, 0x84, - 0x3e, 0xa3, 0x2c, 0x72, 0x8e, 0xed, 0x68, 0x45, 0x83, 0x90, 0x6e, 0x98, 0x1b, 0x37, 0x0c, 0x73, - 0xc2, 0x1e, 0x77, 0xbf, 0x14, 0x18, 0xc1, 0xa6, 0xb5, 0xc9, 0xfa, 0xb1, 0x93, 0x06, 0xc0, 0xaa, - 0xbc, 0x46, 0x7f, 0x01, 0x2f, 0xf1, 0xb8, 0x3f, 0xd1, 0x6e, 0x38, 0xc8, 0x81, 0x1e, 0x01, 0xaf, - 0xb8, 0x61, 0xf2, 0x0a, 0x6c, 0xdf, 0x8f, 0xdc, 0x83, 0x59, 0xbc, 0x02, 0x79, 0x8e, 0xe5, 0xfe, - 0x92, 0x40, 0x1a, 0xd7, 0x61, 0x0b, 0x7d, 0x5f, 0x87, 0x1d, 0x87, 0xd2, 0x8b, 0xbe, 0xca, 0x1e, - 0x3a, 0x37, 0xf3, 0xdd, 0x1f, 0x9d, 0x7b, 0xe0, 0x7b, 0x3f, 0x3a, 0xf7, 0xc0, 0x0f, 0x7f, 0x74, - 0xee, 0x81, 0x8f, 0xdf, 0x3a, 0xe7, 0x7c, 0xf7, 0xd6, 0x39, 0xe7, 0x7b, 0xb7, 0xce, 0x39, 0x3f, - 0xbc, 0x75, 0xce, 0xf9, 0xb7, 0xb7, 0xce, 0x39, 0x7f, 0xeb, 0xdf, 0x9d, 0x7b, 0xe0, 0xc5, 0x11, - 0x39, 0xb0, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x78, 0xa3, 0xd3, 0x3a, 0x8f, 0xd8, 0x00, 0x00, + // 11144 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7d, 0x70, 0x24, 0xc7, + 0x75, 0x18, 0xce, 0x59, 0x60, 0xf1, 0xf1, 0x16, 0xc0, 0xe1, 0xfa, 0xbe, 0x96, 0x20, 0x79, 0xa0, + 0x87, 0x22, 0x7f, 0xa4, 0x4d, 0xe1, 0xcc, 0xa3, 0xf4, 0x0b, 0x23, 0x25, 0x92, 0xf0, 0x71, 0xc0, + 0x1d, 0x01, 0x1c, 0xc0, 0x5e, 0x1c, 0xcf, 0xa4, 0x68, 0x49, 0x83, 0xdd, 0xc6, 0xee, 0x10, 0xbb, + 0x33, 0xcb, 0x99, 0x59, 0xdc, 0x81, 0x1f, 0x92, 0x42, 0x7d, 0xc7, 0xb2, 0x15, 0xcb, 0x92, 0x2c, + 0x29, 0x49, 0x95, 0xa2, 0x48, 0x09, 0x4b, 0x76, 0x25, 0x65, 0xff, 0x95, 0xb2, 0xff, 0x4b, 0xa5, + 0x5c, 0x4a, 0x39, 0x95, 0xc8, 0x15, 0xa5, 0xa4, 0x3f, 0x6c, 0x30, 0xba, 0x24, 0xaa, 0x54, 0x12, + 0x55, 0xc5, 0xaa, 0x38, 0x89, 0x2f, 0x1f, 0x95, 0xea, 0xcf, 0xe9, 0x9e, 0x9d, 0xc5, 0x2d, 0x70, + 0x0d, 0x9c, 0xca, 0xfe, 0x0b, 0xd8, 0xd7, 0xaf, 0xdf, 0xeb, 0xee, 0xe9, 0x7e, 0xfd, 0xfa, 0xbd, + 0xd7, 0xaf, 0x61, 0xbd, 0xee, 0x27, 0x8d, 0xce, 0xe6, 0x4c, 0x35, 0x6c, 0x5d, 0xf0, 0xa2, 0x7a, + 0xd8, 0x8e, 0xc2, 0x97, 0xd9, 0x3f, 0xef, 0xbc, 0x11, 0x46, 0xdb, 0x5b, 0xcd, 0xf0, 0x46, 0x7c, + 0x61, 0xe7, 0xe9, 0x0b, 0xed, 0xed, 0xfa, 0x05, 0xaf, 0xed, 0xc7, 0x17, 0x24, 0xf4, 0xc2, 0xce, + 0x53, 0x5e, 0xb3, 0xdd, 0xf0, 0x9e, 0xba, 0x50, 0x27, 0x01, 0x89, 0xbc, 0x84, 0xd4, 0x66, 0xda, + 0x51, 0x98, 0x84, 0xe8, 0x03, 0x29, 0xc5, 0x19, 0x49, 0x91, 0xfd, 0xf3, 0x61, 0x45, 0x71, 0x66, + 0xe7, 0xe9, 0x99, 0xf6, 0x76, 0x7d, 0x86, 0x52, 0x9c, 0x91, 0xd0, 0x19, 0x49, 0x71, 0xea, 0x9d, + 0x5a, 0x9b, 0xea, 0x61, 0x3d, 0xbc, 0xc0, 0x08, 0x6f, 0x76, 0xb6, 0xd8, 0x2f, 0xf6, 0x83, 0xfd, + 0xc7, 0x19, 0x4e, 0xb9, 0xdb, 0xcf, 0xc4, 0x33, 0x7e, 0x48, 0xdb, 0x77, 0xa1, 0x1a, 0x46, 0xe4, + 0xc2, 0x4e, 0x57, 0xa3, 0xa6, 0xde, 0xa1, 0xe1, 0xb4, 0xc3, 0xa6, 0x5f, 0xdd, 0xcd, 0xc3, 0x7a, + 0x57, 0x8a, 0xd5, 0xf2, 0xaa, 0x0d, 0x3f, 0x20, 0xd1, 0x6e, 0xda, 0xf5, 0x16, 0x49, 0xbc, 0xbc, + 0x5a, 0x17, 0x7a, 0xd5, 0x8a, 0x3a, 0x41, 0xe2, 0xb7, 0x48, 0x57, 0x85, 0xff, 0xff, 0x4e, 0x15, + 0xe2, 0x6a, 0x83, 0xb4, 0xbc, 0xae, 0x7a, 0x4f, 0xf7, 0xaa, 0xd7, 0x49, 0xfc, 0xe6, 0x05, 0x3f, + 0x48, 0xe2, 0x24, 0xca, 0x56, 0x72, 0x2f, 0xc1, 0xd0, 0x6c, 0x2b, 0xec, 0x04, 0x09, 0x7a, 0x2f, + 0x14, 0x77, 0xbc, 0x66, 0x87, 0x94, 0x9d, 0x87, 0x9d, 0xc7, 0x47, 0xe7, 0x1e, 0xfd, 0xee, 0xde, + 0xf4, 0x7d, 0xb7, 0xf6, 0xa6, 0x8b, 0xcf, 0x53, 0xe0, 0xed, 0xbd, 0xe9, 0xd3, 0x24, 0xa8, 0x86, + 0x35, 0x3f, 0xa8, 0x5f, 0x78, 0x39, 0x0e, 0x83, 0x99, 0xab, 0x9d, 0xd6, 0x26, 0x89, 0x30, 0xaf, + 0xe3, 0xfe, 0xeb, 0x02, 0x9c, 0x98, 0x8d, 0xaa, 0x0d, 0x7f, 0x87, 0x54, 0x12, 0x4a, 0xbf, 0xbe, + 0x8b, 0x1a, 0x30, 0x90, 0x78, 0x11, 0x23, 0x57, 0xba, 0xb8, 0x3a, 0x73, 0xb7, 0xdf, 0x7d, 0x66, + 0xc3, 0x8b, 0x24, 0xed, 0xb9, 0xe1, 0x5b, 0x7b, 0xd3, 0x03, 0x1b, 0x5e, 0x84, 0x29, 0x0b, 0xd4, + 0x84, 0xc1, 0x20, 0x0c, 0x48, 0xb9, 0xc0, 0x58, 0x5d, 0xbd, 0x7b, 0x56, 0x57, 0xc3, 0x40, 0xf5, + 0x63, 0x6e, 0xe4, 0xd6, 0xde, 0xf4, 0x20, 0x85, 0x60, 0xc6, 0x85, 0xf6, 0xeb, 0x55, 0xbf, 0x5d, + 0x1e, 0xb0, 0xd5, 0xaf, 0x17, 0xfd, 0xb6, 0xd9, 0xaf, 0x17, 0xfd, 0x36, 0xa6, 0x2c, 0xdc, 0xcf, + 0x15, 0x60, 0x74, 0x36, 0xaa, 0x77, 0x5a, 0x24, 0x48, 0x62, 0xf4, 0x31, 0x80, 0xb6, 0x17, 0x79, + 0x2d, 0x92, 0x90, 0x28, 0x2e, 0x3b, 0x0f, 0x0f, 0x3c, 0x5e, 0xba, 0xb8, 0x7c, 0xf7, 0xec, 0xd7, + 0x25, 0xcd, 0x39, 0x24, 0x3e, 0x39, 0x28, 0x50, 0x8c, 0x35, 0x96, 0xe8, 0x35, 0x18, 0xf5, 0xa2, + 0xc4, 0xdf, 0xf2, 0xaa, 0x49, 0x5c, 0x2e, 0x30, 0xfe, 0xcf, 0xde, 0x3d, 0xff, 0x59, 0x41, 0x72, + 0xee, 0xa4, 0x60, 0x3f, 0x2a, 0x21, 0x31, 0x4e, 0xf9, 0xb9, 0xbf, 0x37, 0x08, 0xa5, 0xd9, 0x28, + 0x59, 0x9a, 0xaf, 0x24, 0x5e, 0xd2, 0x89, 0xd1, 0x1f, 0x3a, 0x70, 0x2a, 0xe6, 0xc3, 0xe6, 0x93, + 0x78, 0x3d, 0x0a, 0xab, 0x24, 0x8e, 0x49, 0x4d, 0x8c, 0xcb, 0x96, 0x95, 0x76, 0x49, 0x66, 0x33, + 0x95, 0x6e, 0x46, 0x97, 0x82, 0x24, 0xda, 0x9d, 0x7b, 0x4a, 0xb4, 0xf9, 0x54, 0x0e, 0xc6, 0x9b, + 0x6f, 0x4f, 0x23, 0xd9, 0x15, 0x4a, 0x89, 0x7f, 0x62, 0x9c, 0xd7, 0x6a, 0xf4, 0x35, 0x07, 0xc6, + 0xda, 0x61, 0x2d, 0xc6, 0xa4, 0x1a, 0x76, 0xda, 0xa4, 0x26, 0x86, 0xf7, 0xc3, 0x76, 0xbb, 0xb1, + 0xae, 0x71, 0xe0, 0xed, 0x3f, 0x2d, 0xda, 0x3f, 0xa6, 0x17, 0x61, 0xa3, 0x29, 0xe8, 0x19, 0x18, + 0x0b, 0xc2, 0xa4, 0xd2, 0x26, 0x55, 0x7f, 0xcb, 0x27, 0x35, 0x36, 0xf1, 0x47, 0xd2, 0x9a, 0x57, + 0xb5, 0x32, 0x6c, 0x60, 0x4e, 0x2d, 0x42, 0xb9, 0xd7, 0xc8, 0xa1, 0x49, 0x18, 0xd8, 0x26, 0xbb, + 0x5c, 0xd8, 0x60, 0xfa, 0x2f, 0x3a, 0x2d, 0x05, 0x10, 0x5d, 0xc6, 0x23, 0x42, 0xb2, 0xbc, 0xa7, + 0xf0, 0x8c, 0x33, 0xf5, 0x7e, 0x38, 0xd9, 0xd5, 0xf4, 0x83, 0x10, 0x70, 0xbf, 0x37, 0x04, 0x23, + 0xf2, 0x53, 0xa0, 0x87, 0x61, 0x30, 0xf0, 0x5a, 0x52, 0xce, 0x8d, 0x89, 0x7e, 0x0c, 0x5e, 0xf5, + 0x5a, 0x74, 0x85, 0x7b, 0x2d, 0x42, 0x31, 0xda, 0x5e, 0xd2, 0x60, 0x74, 0x34, 0x8c, 0x75, 0x2f, + 0x69, 0x60, 0x56, 0x82, 0x1e, 0x84, 0xc1, 0x56, 0x58, 0x23, 0x6c, 0x2c, 0x8a, 0x5c, 0x42, 0xac, + 0x86, 0x35, 0x82, 0x19, 0x94, 0xd6, 0xdf, 0x8a, 0xc2, 0x56, 0x79, 0xd0, 0xac, 0xbf, 0x18, 0x85, + 0x2d, 0xcc, 0x4a, 0xd0, 0x57, 0x1d, 0x98, 0x94, 0x73, 0x7b, 0x25, 0xac, 0x7a, 0x89, 0x1f, 0x06, + 0xe5, 0x22, 0x93, 0x28, 0xd8, 0xde, 0x92, 0x92, 0x94, 0xe7, 0xca, 0xa2, 0x09, 0x93, 0xd9, 0x12, + 0xdc, 0xd5, 0x0a, 0x74, 0x11, 0xa0, 0xde, 0x0c, 0x37, 0xbd, 0x26, 0x1d, 0x90, 0xf2, 0x10, 0xeb, + 0x82, 0x92, 0x0c, 0x4b, 0xaa, 0x04, 0x6b, 0x58, 0xe8, 0x26, 0x0c, 0x7b, 0x5c, 0xfa, 0x97, 0x87, + 0x59, 0x27, 0x9e, 0xb3, 0xd1, 0x09, 0x63, 0x3b, 0x99, 0x2b, 0xdd, 0xda, 0x9b, 0x1e, 0x16, 0x40, + 0x2c, 0xd9, 0xa1, 0x27, 0x61, 0x24, 0x6c, 0xd3, 0x76, 0x7b, 0xcd, 0xf2, 0x08, 0x9b, 0x98, 0x93, + 0xa2, 0xad, 0x23, 0x6b, 0x02, 0x8e, 0x15, 0x06, 0x7a, 0x02, 0x86, 0xe3, 0xce, 0x26, 0xfd, 0x8e, + 0xe5, 0x51, 0xd6, 0xb1, 0x13, 0x02, 0x79, 0xb8, 0xc2, 0xc1, 0x58, 0x96, 0xa3, 0x77, 0x43, 0x29, + 0x22, 0xd5, 0x4e, 0x14, 0x13, 0xfa, 0x61, 0xcb, 0xc0, 0x68, 0x9f, 0x12, 0xe8, 0x25, 0x9c, 0x16, + 0x61, 0x1d, 0x0f, 0xbd, 0x0f, 0x26, 0xe8, 0x07, 0xbe, 0x74, 0xb3, 0x1d, 0x91, 0x38, 0xa6, 0x5f, + 0xb5, 0xc4, 0x18, 0x9d, 0x15, 0x35, 0x27, 0x16, 0x8d, 0x52, 0x9c, 0xc1, 0x46, 0xaf, 0x03, 0x78, + 0x4a, 0x66, 0x94, 0xc7, 0xd8, 0x60, 0xae, 0xd8, 0x9b, 0x11, 0x4b, 0xf3, 0x73, 0x13, 0xf4, 0x3b, + 0xa6, 0xbf, 0xb1, 0xc6, 0x8f, 0x8e, 0x4f, 0x8d, 0x34, 0x49, 0x42, 0x6a, 0xe5, 0x71, 0xd6, 0x61, + 0x35, 0x3e, 0x0b, 0x1c, 0x8c, 0x65, 0xb9, 0xfb, 0xb7, 0x0b, 0xa0, 0x51, 0x41, 0x73, 0x30, 0x22, + 0xe4, 0x9a, 0x58, 0x92, 0x73, 0x8f, 0xc9, 0xef, 0x20, 0xbf, 0xe0, 0xed, 0xbd, 0x5c, 0x79, 0xa8, + 0xea, 0xa1, 0x37, 0xa0, 0xd4, 0x0e, 0x6b, 0xab, 0x24, 0xf1, 0x6a, 0x5e, 0xe2, 0x89, 0xdd, 0xdc, + 0xc2, 0x0e, 0x23, 0x29, 0xce, 0x9d, 0xa0, 0x9f, 0x6e, 0x3d, 0x65, 0x81, 0x75, 0x7e, 0xe8, 0x59, + 0x40, 0x31, 0x89, 0x76, 0xfc, 0x2a, 0x99, 0xad, 0x56, 0xa9, 0x4a, 0xc4, 0x16, 0xc0, 0x00, 0xeb, + 0xcc, 0x94, 0xe8, 0x0c, 0xaa, 0x74, 0x61, 0xe0, 0x9c, 0x5a, 0xee, 0xf7, 0x0b, 0x30, 0xa1, 0xf5, + 0xb5, 0x4d, 0xaa, 0xe8, 0x2d, 0x07, 0x4e, 0xa8, 0xed, 0x6c, 0x6e, 0xf7, 0x2a, 0x9d, 0x55, 0x7c, + 0xb3, 0x22, 0x36, 0xbf, 0x2f, 0xe5, 0xa5, 0x7e, 0x0a, 0x3e, 0x5c, 0xd6, 0x9f, 0x13, 0x7d, 0x38, + 0x91, 0x29, 0xc5, 0xd9, 0x66, 0x4d, 0x7d, 0xc5, 0x81, 0xd3, 0x79, 0x24, 0x72, 0x64, 0x6e, 0x43, + 0x97, 0xb9, 0x56, 0x85, 0x17, 0xe5, 0x4a, 0x3b, 0xa3, 0xcb, 0xf1, 0xff, 0x5b, 0x80, 0x49, 0x7d, + 0x0a, 0x31, 0x4d, 0xe0, 0x9f, 0x3a, 0x70, 0x46, 0xf6, 0x00, 0x93, 0xb8, 0xd3, 0xcc, 0x0c, 0x6f, + 0xcb, 0xea, 0xf0, 0xf2, 0x9d, 0x74, 0x36, 0x8f, 0x1f, 0x1f, 0xe6, 0x87, 0xc4, 0x30, 0x9f, 0xc9, + 0xc5, 0xc1, 0xf9, 0x4d, 0x9d, 0xfa, 0x96, 0x03, 0x53, 0xbd, 0x89, 0xe6, 0x0c, 0x7c, 0xdb, 0x1c, + 0xf8, 0x17, 0xed, 0x75, 0x92, 0xb3, 0x67, 0xc3, 0xcf, 0x3a, 0xab, 0x7f, 0x80, 0xdf, 0x1e, 0x81, + 0xae, 0x3d, 0x04, 0x3d, 0x05, 0x25, 0x21, 0x8e, 0x57, 0xc2, 0x7a, 0xcc, 0x1a, 0x39, 0xc2, 0xd7, + 0xda, 0x6c, 0x0a, 0xc6, 0x3a, 0x0e, 0xaa, 0x41, 0x21, 0x7e, 0x5a, 0x34, 0xdd, 0x82, 0x78, 0xab, + 0x3c, 0xad, 0xb4, 0xc8, 0xa1, 0x5b, 0x7b, 0xd3, 0x85, 0xca, 0xd3, 0xb8, 0x10, 0x3f, 0x4d, 0x35, + 0xf5, 0xba, 0x9f, 0xd8, 0xd3, 0xd4, 0x97, 0xfc, 0x44, 0xf1, 0x61, 0x9a, 0xfa, 0x92, 0x9f, 0x60, + 0xca, 0x82, 0x9e, 0x40, 0x1a, 0x49, 0xd2, 0x66, 0x3b, 0xbe, 0x95, 0x13, 0xc8, 0xe5, 0x8d, 0x8d, + 0x75, 0xc5, 0x8b, 0xe9, 0x17, 0x14, 0x82, 0x19, 0x17, 0xf4, 0x59, 0x87, 0x8e, 0x38, 0x2f, 0x0c, + 0xa3, 0x5d, 0xa1, 0x38, 0x5c, 0xb3, 0x37, 0x05, 0xc2, 0x68, 0x57, 0x31, 0x17, 0x1f, 0x52, 0x15, + 0x60, 0x9d, 0x35, 0xeb, 0x78, 0x6d, 0x2b, 0x66, 0x7a, 0x82, 0x9d, 0x8e, 0x2f, 0x2c, 0x56, 0x32, + 0x1d, 0x5f, 0x58, 0xac, 0x60, 0xc6, 0x85, 0x7e, 0xd0, 0xc8, 0xbb, 0x21, 0x74, 0x0c, 0x0b, 0x1f, + 0x14, 0x7b, 0x37, 0xcc, 0x0f, 0x8a, 0xbd, 0x1b, 0x98, 0xb2, 0xa0, 0x9c, 0xc2, 0x38, 0x66, 0x2a, + 0x85, 0x15, 0x4e, 0x6b, 0x95, 0x8a, 0xc9, 0x69, 0xad, 0x52, 0xc1, 0x94, 0x05, 0x9b, 0xa4, 0xd5, + 0x98, 0xe9, 0x23, 0x76, 0x26, 0xe9, 0x7c, 0x86, 0xd3, 0xd2, 0x7c, 0x05, 0x53, 0x16, 0x54, 0x64, + 0x78, 0xaf, 0x76, 0x22, 0xae, 0xcc, 0x94, 0x2e, 0xae, 0x59, 0x98, 0x2f, 0x94, 0x9c, 0xe2, 0x36, + 0x7a, 0x6b, 0x6f, 0xba, 0xc8, 0x40, 0x98, 0x33, 0x72, 0xff, 0x60, 0x20, 0x15, 0x17, 0x52, 0x9e, + 0xa3, 0x5f, 0x67, 0x1b, 0xa1, 0x90, 0x05, 0x42, 0xf5, 0x75, 0x8e, 0x4c, 0xf5, 0x3d, 0xc5, 0x77, + 0x3c, 0x83, 0x1d, 0xce, 0xf2, 0x47, 0x5f, 0x74, 0xba, 0xcf, 0xb6, 0x9e, 0xfd, 0xbd, 0x2c, 0xdd, + 0x98, 0xf9, 0x5e, 0xb1, 0xef, 0x91, 0x77, 0xea, 0xb3, 0x4e, 0xaa, 0x44, 0xc4, 0xbd, 0xf6, 0x81, + 0x8f, 0x98, 0xfb, 0x80, 0xc5, 0x03, 0xb9, 0x2e, 0xf7, 0x3f, 0xe7, 0xc0, 0xb8, 0x84, 0x53, 0xf5, + 0x38, 0x46, 0x37, 0x61, 0x44, 0xb6, 0x54, 0x7c, 0x3d, 0x9b, 0xb6, 0x00, 0xa5, 0xc4, 0xab, 0xc6, + 0x28, 0x6e, 0xee, 0x5b, 0x43, 0x80, 0xd2, 0xbd, 0xaa, 0x1d, 0xc6, 0x3e, 0x93, 0x44, 0x87, 0xd8, + 0x85, 0x02, 0x6d, 0x17, 0x7a, 0xde, 0xe6, 0x2e, 0x94, 0x36, 0xcb, 0xd8, 0x8f, 0xbe, 0x98, 0x91, + 0xdb, 0x7c, 0x63, 0xfa, 0xf0, 0x91, 0xc8, 0x6d, 0xad, 0x09, 0xfb, 0x4b, 0xf0, 0x1d, 0x21, 0xc1, + 0xf9, 0xd6, 0xf5, 0x4b, 0x76, 0x25, 0xb8, 0xd6, 0x8a, 0xac, 0x2c, 0x8f, 0xb8, 0x84, 0xe5, 0x7b, + 0xd7, 0x75, 0xab, 0x12, 0x56, 0xe3, 0x6a, 0xca, 0xda, 0x88, 0xcb, 0xda, 0x21, 0x5b, 0x3c, 0x35, + 0x59, 0x9b, 0xe5, 0xa9, 0xa4, 0xee, 0xab, 0x52, 0xea, 0xf2, 0x5d, 0xeb, 0x05, 0xcb, 0x52, 0x57, + 0xe3, 0xdb, 0x2d, 0x7f, 0x5f, 0x81, 0x33, 0xdd, 0x78, 0x98, 0x6c, 0xa1, 0x0b, 0x30, 0x5a, 0x0d, + 0x83, 0x2d, 0xbf, 0xbe, 0xea, 0xb5, 0xc5, 0x79, 0x4d, 0xc9, 0xa2, 0x79, 0x59, 0x80, 0x53, 0x1c, + 0xf4, 0x10, 0x17, 0x3c, 0xdc, 0x22, 0x52, 0x12, 0xa8, 0x03, 0xcb, 0x64, 0x97, 0x49, 0xa1, 0xf7, + 0x8c, 0x7c, 0xf5, 0x1b, 0xd3, 0xf7, 0x7d, 0xfc, 0x8f, 0x1f, 0xbe, 0xcf, 0xfd, 0xa3, 0x01, 0x78, + 0x20, 0x97, 0xa7, 0xd0, 0xd6, 0x7f, 0xdb, 0xd0, 0xd6, 0xb5, 0x72, 0x21, 0x45, 0xae, 0xdb, 0x54, + 0x64, 0x35, 0xf2, 0x79, 0x7a, 0xb9, 0x56, 0x8c, 0xf3, 0x1b, 0x45, 0x07, 0x2a, 0xf0, 0x5a, 0x24, + 0x6e, 0x7b, 0x55, 0x22, 0x7a, 0xaf, 0x06, 0xea, 0xaa, 0x2c, 0xc0, 0x29, 0x0e, 0x3f, 0x42, 0x6f, + 0x79, 0x9d, 0x66, 0x22, 0x0c, 0x65, 0xda, 0x11, 0x9a, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xc7, 0x01, + 0xd4, 0xcd, 0x55, 0x2c, 0xc4, 0x8d, 0xa3, 0x18, 0x87, 0xb9, 0xb3, 0xb7, 0xb4, 0x43, 0xb8, 0xd6, + 0xd3, 0x9c, 0x76, 0x68, 0xdf, 0xf4, 0xa3, 0xe9, 0x3e, 0xc4, 0x0f, 0x07, 0x7d, 0xd8, 0xd0, 0x98, + 0xa9, 0xa5, 0x5a, 0x25, 0x71, 0xcc, 0xcd, 0x71, 0xba, 0xa9, 0x85, 0x81, 0xb1, 0x2c, 0x47, 0xd3, + 0x50, 0x24, 0x51, 0x14, 0x46, 0xe2, 0xac, 0xcd, 0xa6, 0xf1, 0x25, 0x0a, 0xc0, 0x1c, 0xee, 0xfe, + 0xb8, 0x00, 0xe5, 0x5e, 0xa7, 0x13, 0xf4, 0xbb, 0xda, 0xb9, 0x5a, 0x9c, 0x9c, 0xc4, 0xc1, 0x2f, + 0x3c, 0xba, 0x33, 0x51, 0xf6, 0x00, 0xd8, 0xe3, 0x84, 0x2d, 0x4a, 0x71, 0xb6, 0x81, 0x53, 0x5f, + 0xd2, 0x4e, 0xd8, 0x3a, 0x89, 0x9c, 0x0d, 0x7e, 0xcb, 0xdc, 0xe0, 0xd7, 0x6d, 0x77, 0x4a, 0xdf, + 0xe6, 0xff, 0xa4, 0x08, 0xa7, 0x64, 0x69, 0x85, 0xd0, 0xad, 0xf2, 0xb9, 0x0e, 0x89, 0x76, 0xd1, + 0x0f, 0x1c, 0x38, 0xed, 0x65, 0x4d, 0x37, 0x3e, 0x39, 0x82, 0x81, 0xd6, 0xb8, 0xce, 0xcc, 0xe6, + 0x70, 0xe4, 0x03, 0x7d, 0x51, 0x0c, 0xf4, 0xe9, 0x3c, 0x94, 0x1e, 0x76, 0xf7, 0xdc, 0x0e, 0xa0, + 0x67, 0x60, 0x4c, 0xc2, 0x99, 0xb9, 0x87, 0x2f, 0x71, 0x65, 0xdc, 0x9e, 0xd5, 0xca, 0xb0, 0x81, + 0x49, 0x6b, 0x26, 0xa4, 0xd5, 0x6e, 0x7a, 0x09, 0xd1, 0x0c, 0x45, 0xaa, 0xe6, 0x86, 0x56, 0x86, + 0x0d, 0x4c, 0xf4, 0x18, 0x0c, 0x05, 0x61, 0x8d, 0x5c, 0xa9, 0x09, 0x03, 0xf1, 0x84, 0xa8, 0x33, + 0x74, 0x95, 0x41, 0xb1, 0x28, 0x45, 0x8f, 0xa6, 0xd6, 0xb8, 0x22, 0x5b, 0x42, 0xa5, 0x3c, 0x4b, + 0x1c, 0xfa, 0x7b, 0x0e, 0x8c, 0xd2, 0x1a, 0x1b, 0xbb, 0x6d, 0x42, 0xf7, 0x36, 0xfa, 0x45, 0x6a, + 0x47, 0xf3, 0x45, 0xae, 0x4a, 0x36, 0xa6, 0xa9, 0x63, 0x54, 0xc1, 0xdf, 0x7c, 0x7b, 0x7a, 0x44, + 0xfe, 0xc0, 0x69, 0xab, 0xa6, 0x96, 0xe0, 0xfe, 0x9e, 0x5f, 0xf3, 0x40, 0xae, 0x80, 0xbf, 0x06, + 0x13, 0x66, 0x23, 0x0e, 0xe4, 0x07, 0xf8, 0x27, 0xda, 0xb2, 0xe3, 0xfd, 0x12, 0xf2, 0xec, 0x9e, + 0x69, 0xb3, 0x6a, 0x32, 0x2c, 0x88, 0xa9, 0x67, 0x4e, 0x86, 0x05, 0x31, 0x19, 0x16, 0xdc, 0x3f, + 0x74, 0xd2, 0xa5, 0xa9, 0xa9, 0x79, 0x74, 0x63, 0xee, 0x44, 0x4d, 0x21, 0x88, 0xd5, 0xc6, 0x7c, + 0x0d, 0xaf, 0x60, 0x0a, 0x47, 0x5f, 0xd2, 0xa4, 0x23, 0xad, 0xd6, 0x11, 0x6e, 0x0d, 0x4b, 0x26, + 0x7a, 0x83, 0x70, 0xb7, 0xfc, 0x13, 0x05, 0x38, 0xdb, 0x04, 0xf7, 0x8b, 0x05, 0x78, 0x68, 0x5f, + 0xa5, 0x35, 0xb7, 0xe1, 0xce, 0x3d, 0x6f, 0x38, 0xdd, 0xd6, 0x22, 0xd2, 0x0e, 0xaf, 0xe1, 0x15, + 0xf1, 0xbd, 0xd4, 0xb6, 0x86, 0x39, 0x18, 0xcb, 0x72, 0xaa, 0x3a, 0x6c, 0x93, 0xdd, 0xc5, 0x30, + 0x6a, 0x79, 0x89, 0x90, 0x0e, 0x4a, 0x75, 0x58, 0x96, 0x05, 0x38, 0xc5, 0x71, 0x7f, 0xe0, 0x40, + 0xb6, 0x01, 0xc8, 0x83, 0x89, 0x4e, 0x4c, 0x22, 0xba, 0xa5, 0x56, 0x48, 0x35, 0x22, 0x72, 0x7a, + 0x3e, 0x3a, 0xc3, 0xbd, 0xfd, 0xb4, 0x87, 0x33, 0xd5, 0x30, 0x22, 0x33, 0x3b, 0x4f, 0xcd, 0x70, + 0x8c, 0x65, 0xb2, 0x5b, 0x21, 0x4d, 0x42, 0x69, 0xcc, 0xa1, 0x5b, 0x7b, 0xd3, 0x13, 0xd7, 0x0c, + 0x02, 0x38, 0x43, 0x90, 0xb2, 0x68, 0x7b, 0x71, 0x7c, 0x23, 0x8c, 0x6a, 0x82, 0x45, 0xe1, 0xc0, + 0x2c, 0xd6, 0x0d, 0x02, 0x38, 0x43, 0xd0, 0xfd, 0x3e, 0x3d, 0x3e, 0xea, 0x5a, 0x2b, 0xfa, 0x06, + 0xd5, 0x7d, 0x28, 0x64, 0xae, 0x19, 0x6e, 0xce, 0x87, 0x41, 0xe2, 0xf9, 0x01, 0x91, 0xc1, 0x02, + 0x1b, 0x96, 0x74, 0x64, 0x83, 0x76, 0x6a, 0xc3, 0xef, 0x2e, 0xc3, 0x39, 0x6d, 0xa1, 0x3a, 0xce, + 0x66, 0x33, 0xdc, 0xcc, 0x7a, 0x01, 0x29, 0x12, 0x66, 0x25, 0xee, 0x4f, 0x1d, 0x38, 0xd7, 0x43, + 0x19, 0x47, 0x5f, 0x71, 0x60, 0x7c, 0xf3, 0x67, 0xa2, 0x6f, 0x66, 0x33, 0xd0, 0xfb, 0x60, 0x82, + 0x02, 0xe8, 0x4e, 0x24, 0xe6, 0x66, 0xc1, 0xf4, 0x50, 0xcd, 0x19, 0xa5, 0x38, 0x83, 0xed, 0xfe, + 0x46, 0x01, 0x72, 0xb8, 0xa0, 0x27, 0x61, 0x84, 0x04, 0xb5, 0x76, 0xe8, 0x07, 0x89, 0x10, 0x46, + 0x4a, 0xea, 0x5d, 0x12, 0x70, 0xac, 0x30, 0xc4, 0xf9, 0x43, 0x0c, 0x4c, 0xa1, 0xeb, 0xfc, 0x21, + 0x5a, 0x9e, 0xe2, 0xa0, 0x3a, 0x4c, 0x7a, 0xdc, 0xbf, 0xc2, 0xe6, 0x1e, 0x9b, 0xa6, 0x03, 0x07, + 0x99, 0xa6, 0xa7, 0x99, 0xfb, 0x33, 0x43, 0x02, 0x77, 0x11, 0x45, 0xef, 0x86, 0x52, 0x27, 0x26, + 0x95, 0x85, 0xe5, 0xf9, 0x88, 0xd4, 0xf8, 0xa9, 0x58, 0xf3, 0xfb, 0x5d, 0x4b, 0x8b, 0xb0, 0x8e, + 0xe7, 0xfe, 0x33, 0x07, 0x86, 0xe7, 0xbc, 0xea, 0x76, 0xb8, 0xb5, 0x45, 0x87, 0xa2, 0xd6, 0x89, + 0x52, 0xc3, 0x96, 0x36, 0x14, 0x0b, 0x02, 0x8e, 0x15, 0x06, 0xda, 0x80, 0x21, 0xbe, 0xe0, 0xc5, + 0xb2, 0xfb, 0x45, 0xad, 0x3f, 0x2a, 0x8e, 0x87, 0x4d, 0x87, 0x4e, 0xe2, 0x37, 0x67, 0x78, 0x1c, + 0xcf, 0xcc, 0x95, 0x20, 0x59, 0x8b, 0x2a, 0x49, 0xe4, 0x07, 0xf5, 0x39, 0xa0, 0xdb, 0xc5, 0x22, + 0xa3, 0x81, 0x05, 0x2d, 0xda, 0x8d, 0x96, 0x77, 0x53, 0xb2, 0x13, 0xe2, 0x47, 0x75, 0x63, 0x35, + 0x2d, 0xc2, 0x3a, 0x9e, 0xfb, 0x47, 0x0e, 0x8c, 0xce, 0x79, 0xb1, 0x5f, 0xfd, 0x0b, 0x24, 0x7c, + 0x3e, 0x04, 0xc5, 0x79, 0xaf, 0xda, 0x20, 0xe8, 0x5a, 0xf6, 0xd0, 0x5b, 0xba, 0xf8, 0x78, 0x1e, + 0x1b, 0x75, 0x00, 0xd6, 0x39, 0x8d, 0xf7, 0x3a, 0x1a, 0xbb, 0x6f, 0x3b, 0x30, 0x31, 0xdf, 0xf4, + 0x49, 0x90, 0xcc, 0x93, 0x28, 0x61, 0x03, 0x57, 0x87, 0xc9, 0xaa, 0x82, 0x1c, 0x66, 0xe8, 0xd8, + 0x6c, 0x9d, 0xcf, 0x90, 0xc0, 0x5d, 0x44, 0x51, 0x0d, 0x4e, 0x70, 0x58, 0xba, 0x2a, 0x0e, 0x34, + 0x7e, 0xcc, 0x3a, 0x3a, 0x6f, 0x52, 0xc0, 0x59, 0x92, 0xee, 0x4f, 0x1c, 0x38, 0x37, 0xdf, 0xec, + 0xc4, 0x09, 0x89, 0xae, 0x0b, 0x69, 0x24, 0xd5, 0x5b, 0xf4, 0x11, 0x18, 0x69, 0x49, 0x8f, 0xad, + 0x73, 0x87, 0x09, 0xcc, 0xe4, 0x19, 0xc5, 0xa6, 0x8d, 0x59, 0xdb, 0x7c, 0x99, 0x54, 0x93, 0x55, + 0x92, 0x78, 0x69, 0x78, 0x41, 0x0a, 0xc3, 0x8a, 0x2a, 0x6a, 0xc3, 0x60, 0xdc, 0x26, 0x55, 0x7b, + 0xd1, 0x5d, 0xb2, 0x0f, 0x95, 0x36, 0xa9, 0xa6, 0x72, 0x9d, 0xf9, 0x1a, 0x19, 0x27, 0xf7, 0x7f, + 0x39, 0xf0, 0x40, 0x8f, 0xfe, 0xae, 0xf8, 0x71, 0x82, 0x5e, 0xea, 0xea, 0xf3, 0x4c, 0x7f, 0x7d, + 0xa6, 0xb5, 0x59, 0x8f, 0x95, 0x40, 0x90, 0x10, 0xad, 0xbf, 0x1f, 0x85, 0xa2, 0x9f, 0x90, 0x96, + 0x34, 0x43, 0x5b, 0x30, 0x18, 0xf5, 0xe8, 0xcb, 0xdc, 0xb8, 0x8c, 0xf1, 0xbb, 0x42, 0xf9, 0x61, + 0xce, 0xd6, 0xdd, 0x86, 0xa1, 0xf9, 0xb0, 0xd9, 0x69, 0x05, 0xfd, 0x45, 0xca, 0x24, 0xbb, 0x6d, + 0x92, 0xdd, 0x23, 0x99, 0xfa, 0xcf, 0x4a, 0xa4, 0xe1, 0x68, 0x20, 0xdf, 0x70, 0xe4, 0xfe, 0x73, + 0x07, 0xe8, 0xaa, 0xaa, 0xf9, 0xc2, 0x93, 0xc8, 0xc9, 0x71, 0x86, 0x0f, 0xe9, 0xe4, 0x6e, 0xef, + 0x4d, 0x8f, 0x2b, 0x44, 0x8d, 0xfe, 0x87, 0x60, 0x28, 0x66, 0x47, 0x72, 0xd1, 0x86, 0x45, 0xa9, + 0x3f, 0xf3, 0x83, 0xfa, 0xed, 0xbd, 0xe9, 0xbe, 0xc2, 0x36, 0x67, 0x14, 0x6d, 0xe1, 0xf4, 0x14, + 0x54, 0xa9, 0xc2, 0xd7, 0x22, 0x71, 0xec, 0xd5, 0xe5, 0x09, 0x4f, 0x29, 0x7c, 0xab, 0x1c, 0x8c, + 0x65, 0xb9, 0xfb, 0x65, 0x07, 0xc6, 0xd5, 0xe6, 0x45, 0xd5, 0x77, 0x74, 0x55, 0xdf, 0xe6, 0xf8, + 0x4c, 0x79, 0xa8, 0x87, 0xc4, 0x11, 0x1b, 0xf9, 0xfe, 0xbb, 0xe0, 0xbb, 0x60, 0xac, 0x46, 0xda, + 0x24, 0xa8, 0x91, 0xa0, 0x4a, 0x8f, 0xdf, 0x74, 0x86, 0x8c, 0xce, 0x4d, 0xd2, 0xf3, 0xe6, 0x82, + 0x06, 0xc7, 0x06, 0x96, 0xfb, 0x4d, 0x07, 0xee, 0x57, 0xe4, 0x2a, 0x24, 0xc1, 0x24, 0x89, 0x76, + 0x55, 0x98, 0xe6, 0xc1, 0x76, 0xab, 0xeb, 0x54, 0xff, 0x4d, 0x22, 0xce, 0xfc, 0x70, 0xdb, 0x55, + 0x89, 0x6b, 0xcb, 0x8c, 0x08, 0x96, 0xd4, 0xdc, 0x5f, 0x1b, 0x80, 0xd3, 0x7a, 0x23, 0x95, 0x80, + 0xf9, 0x84, 0x03, 0xa0, 0x46, 0x80, 0x6e, 0xc8, 0x03, 0x76, 0x7c, 0x57, 0xc6, 0x97, 0x4a, 0x45, + 0x90, 0x02, 0xc7, 0x58, 0x63, 0x8b, 0x5e, 0x80, 0xb1, 0x1d, 0xba, 0x28, 0xc8, 0x2a, 0x55, 0x17, + 0xe2, 0xf2, 0x00, 0x6b, 0xc6, 0x74, 0xde, 0xc7, 0x7c, 0x3e, 0xc5, 0x4b, 0xcd, 0x01, 0x1a, 0x30, + 0xc6, 0x06, 0x29, 0x7a, 0xd2, 0x19, 0x8f, 0xf4, 0x4f, 0x22, 0x6c, 0xe2, 0x1f, 0xb4, 0xd8, 0xc7, + 0xec, 0x57, 0x9f, 0x3b, 0x79, 0x6b, 0x6f, 0x7a, 0xdc, 0x00, 0x61, 0xb3, 0x11, 0xee, 0x0b, 0xc0, + 0xc6, 0xc2, 0x0f, 0x3a, 0x64, 0x2d, 0x40, 0x8f, 0x48, 0x1b, 0x1d, 0xf7, 0xab, 0x28, 0xc9, 0xa1, + 0xdb, 0xe9, 0xe8, 0x59, 0x76, 0xcb, 0xf3, 0x9b, 0x2c, 0x7c, 0x91, 0x62, 0xa9, 0xb3, 0xec, 0x22, + 0x83, 0x62, 0x51, 0xea, 0xce, 0xc0, 0xf0, 0x3c, 0xed, 0x3b, 0x89, 0x28, 0x5d, 0x3d, 0xea, 0x78, + 0xdc, 0x88, 0x3a, 0x96, 0xd1, 0xc5, 0x1b, 0x70, 0x66, 0x3e, 0x22, 0x5e, 0x42, 0x2a, 0x4f, 0xcf, + 0x75, 0xaa, 0xdb, 0x24, 0xe1, 0xa1, 0x5d, 0x31, 0x7a, 0x2f, 0x8c, 0x87, 0x6c, 0xcb, 0x58, 0x09, + 0xab, 0xdb, 0x7e, 0x50, 0x17, 0x26, 0xd7, 0x33, 0x82, 0xca, 0xf8, 0x9a, 0x5e, 0x88, 0x4d, 0x5c, + 0xf7, 0xdf, 0x17, 0x60, 0x6c, 0x3e, 0x0a, 0x03, 0x29, 0x16, 0x8f, 0x61, 0x2b, 0x4b, 0x8c, 0xad, + 0xcc, 0x82, 0xbb, 0x53, 0x6f, 0x7f, 0xaf, 0xed, 0x0c, 0xbd, 0xae, 0x44, 0xe4, 0x80, 0xad, 0x23, + 0x88, 0xc1, 0x97, 0xd1, 0x4e, 0x3f, 0xb6, 0x29, 0x40, 0xdd, 0xff, 0xe0, 0xc0, 0xa4, 0x8e, 0x7e, + 0x0c, 0x3b, 0x68, 0x6c, 0xee, 0xa0, 0x57, 0xed, 0xf6, 0xb7, 0xc7, 0xb6, 0xf9, 0xf6, 0xb0, 0xd9, + 0x4f, 0xe6, 0xeb, 0xfe, 0xaa, 0x03, 0x63, 0x37, 0x34, 0x80, 0xe8, 0xac, 0x6d, 0x25, 0xe6, 0x1d, + 0x52, 0xcc, 0xe8, 0xd0, 0xdb, 0x99, 0xdf, 0xd8, 0x68, 0x09, 0x95, 0xfb, 0x71, 0xb5, 0x41, 0x6a, + 0x9d, 0xa6, 0xdc, 0xbe, 0xd5, 0x90, 0x56, 0x04, 0x1c, 0x2b, 0x0c, 0xf4, 0x12, 0x9c, 0xac, 0x86, + 0x41, 0xb5, 0x13, 0x45, 0x24, 0xa8, 0xee, 0xae, 0xb3, 0x3b, 0x12, 0x62, 0x43, 0x9c, 0x11, 0xd5, + 0x4e, 0xce, 0x67, 0x11, 0x6e, 0xe7, 0x01, 0x71, 0x37, 0x21, 0xee, 0x2c, 0x88, 0xe9, 0x96, 0x25, + 0x0e, 0x5c, 0x9a, 0xb3, 0x80, 0x81, 0xb1, 0x2c, 0x47, 0xd7, 0xe0, 0x5c, 0x9c, 0x78, 0x51, 0xe2, + 0x07, 0xf5, 0x05, 0xe2, 0xd5, 0x9a, 0x7e, 0x40, 0x8f, 0x12, 0x61, 0x50, 0xe3, 0xae, 0xc4, 0x81, + 0xb9, 0x07, 0x6e, 0xed, 0x4d, 0x9f, 0xab, 0xe4, 0xa3, 0xe0, 0x5e, 0x75, 0xd1, 0x87, 0x60, 0x4a, + 0xb8, 0x23, 0xb6, 0x3a, 0xcd, 0x67, 0xc3, 0xcd, 0xf8, 0xb2, 0x1f, 0xd3, 0x73, 0xfc, 0x8a, 0xdf, + 0xf2, 0x13, 0xe6, 0x30, 0x2c, 0xce, 0x9d, 0xbf, 0xb5, 0x37, 0x3d, 0x55, 0xe9, 0x89, 0x85, 0xf7, + 0xa1, 0x80, 0x30, 0x9c, 0xe5, 0xc2, 0xaf, 0x8b, 0xf6, 0x30, 0xa3, 0x3d, 0x75, 0x6b, 0x6f, 0xfa, + 0xec, 0x62, 0x2e, 0x06, 0xee, 0x51, 0x93, 0x7e, 0xc1, 0xc4, 0x6f, 0x91, 0x57, 0xc3, 0x80, 0xb0, + 0x40, 0x15, 0xed, 0x0b, 0x6e, 0x08, 0x38, 0x56, 0x18, 0xe8, 0xe5, 0x74, 0x26, 0xd2, 0xe5, 0x22, + 0x02, 0x4e, 0x0e, 0x2e, 0xe1, 0xd8, 0xd1, 0xe4, 0xba, 0x46, 0x89, 0x45, 0x52, 0x1a, 0xb4, 0xd1, + 0x27, 0x1d, 0x18, 0x8b, 0x93, 0x50, 0xdd, 0x6b, 0x10, 0x11, 0x27, 0x16, 0xa6, 0x7d, 0x45, 0xa3, + 0xca, 0x15, 0x1f, 0x1d, 0x82, 0x0d, 0xae, 0xe8, 0x17, 0x60, 0x54, 0x4e, 0xe0, 0xb8, 0x5c, 0x62, + 0xba, 0x12, 0x3b, 0xc6, 0xc9, 0xf9, 0x1d, 0xe3, 0xb4, 0x9c, 0xaa, 0xb2, 0x37, 0x1a, 0x24, 0x60, + 0x31, 0xb7, 0x9a, 0x2a, 0x7b, 0xbd, 0x41, 0x02, 0xcc, 0x4a, 0xdc, 0x1f, 0x0f, 0x00, 0xea, 0x16, + 0x7c, 0x68, 0x19, 0x86, 0xbc, 0x6a, 0xe2, 0xef, 0xc8, 0x78, 0xc3, 0x47, 0xf2, 0x94, 0x02, 0x3e, + 0x80, 0x98, 0x6c, 0x11, 0x3a, 0xef, 0x49, 0x2a, 0x2d, 0x67, 0x59, 0x55, 0x2c, 0x48, 0xa0, 0x10, + 0x4e, 0x36, 0xbd, 0x38, 0x91, 0x2d, 0xac, 0xd1, 0x0f, 0x29, 0xb6, 0x8b, 0x9f, 0xef, 0xef, 0x53, + 0xd1, 0x1a, 0x73, 0x67, 0xe8, 0x7a, 0x5c, 0xc9, 0x12, 0xc2, 0xdd, 0xb4, 0xd1, 0xc7, 0x98, 0x76, + 0xc5, 0x55, 0x5f, 0xa9, 0xd6, 0x2c, 0x5b, 0xd1, 0x3c, 0x38, 0x4d, 0x43, 0xb3, 0x12, 0x6c, 0xb0, + 0xc6, 0x12, 0x5d, 0x80, 0x51, 0xb6, 0x6e, 0x48, 0x8d, 0xf0, 0xd5, 0x3f, 0x90, 0x2a, 0xc1, 0x15, + 0x59, 0x80, 0x53, 0x1c, 0x4d, 0xcb, 0xe0, 0x0b, 0xbe, 0x87, 0x96, 0x81, 0x9e, 0x81, 0x62, 0xbb, + 0xe1, 0xc5, 0x32, 0x86, 0xdd, 0x95, 0x52, 0x7b, 0x9d, 0x02, 0x99, 0x68, 0xd2, 0xbe, 0x25, 0x03, + 0x62, 0x5e, 0xc1, 0xfd, 0x17, 0x00, 0xc3, 0x0b, 0xb3, 0x4b, 0x1b, 0x5e, 0xbc, 0xdd, 0xc7, 0x19, + 0x88, 0x2e, 0x43, 0xa1, 0xac, 0x66, 0x05, 0xa9, 0x54, 0x62, 0xb1, 0xc2, 0x40, 0x01, 0x0c, 0xf9, + 0x01, 0x95, 0x3c, 0xe5, 0x09, 0x5b, 0x7e, 0x06, 0x75, 0x9e, 0x63, 0x86, 0xa0, 0x2b, 0x8c, 0x3a, + 0x16, 0x5c, 0xd0, 0xeb, 0x30, 0xea, 0xc9, 0x2b, 0x44, 0x62, 0xff, 0x5f, 0xb6, 0x61, 0x40, 0x17, + 0x24, 0xf5, 0x10, 0x26, 0x01, 0xc2, 0x29, 0x43, 0xf4, 0x71, 0x07, 0x4a, 0xb2, 0xeb, 0x98, 0x6c, + 0x09, 0xdf, 0xf6, 0xaa, 0xbd, 0x3e, 0x63, 0xb2, 0xc5, 0xe3, 0x5b, 0x34, 0x00, 0xd6, 0x59, 0x76, + 0x9d, 0x99, 0x8a, 0xfd, 0x9c, 0x99, 0xd0, 0x0d, 0x18, 0xbd, 0xe1, 0x27, 0x0d, 0xb6, 0xc3, 0x0b, + 0x9f, 0xda, 0xe2, 0xdd, 0xb7, 0x9a, 0x92, 0x4b, 0x47, 0xec, 0xba, 0x64, 0x80, 0x53, 0x5e, 0x74, + 0x39, 0xd0, 0x1f, 0xec, 0x0a, 0x16, 0xdb, 0x1b, 0x46, 0xcd, 0x0a, 0xac, 0x00, 0xa7, 0x38, 0x74, + 0x88, 0xc7, 0xe8, 0xaf, 0x0a, 0x79, 0xa5, 0x43, 0x45, 0x8b, 0x88, 0x59, 0xb4, 0x30, 0xaf, 0x24, + 0x45, 0x3e, 0x58, 0xd7, 0x35, 0x1e, 0xd8, 0xe0, 0xa8, 0x44, 0xe7, 0x68, 0x2f, 0xd1, 0x89, 0x5e, + 0xe7, 0x67, 0x38, 0x7e, 0x98, 0x10, 0xbb, 0xc1, 0x8a, 0x9d, 0xf3, 0x0d, 0xa7, 0xc9, 0xaf, 0x35, + 0xa4, 0xbf, 0xb1, 0xc6, 0x8f, 0x4a, 0x8c, 0x30, 0xb8, 0x74, 0xd3, 0x4f, 0xc4, 0x65, 0x0c, 0x25, + 0x31, 0xd6, 0x18, 0x14, 0x8b, 0x52, 0x1e, 0xbb, 0x41, 0x27, 0x41, 0x2c, 0x76, 0x01, 0x2d, 0x76, + 0x83, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xd7, 0x81, 0x62, 0x23, 0x0c, 0xb7, 0xe3, 0xf2, 0x38, 0x9b, + 0x1c, 0x16, 0x74, 0x6a, 0x21, 0x71, 0x66, 0x2e, 0x53, 0xb2, 0xe6, 0xf5, 0xb2, 0x22, 0x83, 0xdd, + 0xde, 0x9b, 0x9e, 0x58, 0xf1, 0xb7, 0x48, 0x75, 0xb7, 0xda, 0x24, 0x0c, 0xf2, 0xe6, 0xdb, 0x1a, + 0xe4, 0xd2, 0x0e, 0x09, 0x12, 0xcc, 0x5b, 0x35, 0xf5, 0x39, 0x07, 0x20, 0x25, 0x94, 0xe3, 0x24, + 0x25, 0x66, 0x58, 0x81, 0x85, 0x03, 0xb5, 0xd1, 0x34, 0xdd, 0xeb, 0xfa, 0xaf, 0x1c, 0x28, 0xd1, + 0xce, 0x49, 0x11, 0xf8, 0x18, 0x0c, 0x25, 0x5e, 0x54, 0x27, 0xd2, 0x51, 0xa0, 0x3e, 0xc7, 0x06, + 0x83, 0x62, 0x51, 0x8a, 0x02, 0x28, 0x26, 0x5e, 0xbc, 0x2d, 0xd5, 0xf8, 0x2b, 0xd6, 0x86, 0x38, + 0xd5, 0xe0, 0xe9, 0xaf, 0x18, 0x73, 0x36, 0xe8, 0x71, 0x18, 0xa1, 0x5b, 0xc7, 0xa2, 0x17, 0xcb, + 0xd8, 0x9d, 0x31, 0x2a, 0xc4, 0x17, 0x05, 0x0c, 0xab, 0x52, 0xf7, 0x37, 0x0a, 0x30, 0xb8, 0xc0, + 0x0f, 0x74, 0x43, 0x71, 0xd8, 0x89, 0xaa, 0x44, 0x28, 0xf6, 0x16, 0xe6, 0x34, 0xa5, 0x5b, 0x61, + 0x34, 0xb5, 0x23, 0x15, 0xfb, 0x8d, 0x05, 0x2f, 0xf4, 0x25, 0x07, 0x26, 0x92, 0xc8, 0x0b, 0xe2, + 0x2d, 0xe6, 0x92, 0xf1, 0xc3, 0x40, 0x0c, 0x91, 0x85, 0x59, 0xb8, 0x61, 0xd0, 0xad, 0x24, 0xa4, + 0x9d, 0x7a, 0x86, 0xcc, 0x32, 0x9c, 0x69, 0x83, 0xfb, 0x9b, 0x0e, 0x40, 0xda, 0x7a, 0xf4, 0x59, + 0x07, 0xc6, 0x3d, 0x3d, 0x66, 0x54, 0x8c, 0xd1, 0x9a, 0x3d, 0xff, 0x2d, 0x23, 0xcb, 0x6d, 0x19, + 0x06, 0x08, 0x9b, 0x8c, 0xdd, 0x77, 0x43, 0x91, 0xad, 0x0e, 0x76, 0xe8, 0x11, 0xb6, 0xef, 0xac, + 0xb1, 0x4b, 0xda, 0xc4, 0xb1, 0xc2, 0x70, 0x5f, 0x82, 0x89, 0x4b, 0x37, 0x49, 0xb5, 0x93, 0x84, + 0x11, 0xb7, 0xfc, 0xf7, 0xb8, 0x23, 0xe4, 0x1c, 0xea, 0x8e, 0xd0, 0x77, 0x1c, 0x28, 0x69, 0x01, + 0x84, 0x74, 0xa7, 0xae, 0xcf, 0x57, 0xb8, 0x81, 0x43, 0x0c, 0xd5, 0xb2, 0x95, 0x10, 0x45, 0x4e, + 0x32, 0xdd, 0x46, 0x14, 0x08, 0xa7, 0x0c, 0xef, 0x10, 0xe0, 0xe7, 0xfe, 0x81, 0x03, 0x67, 0x72, + 0xa3, 0x1d, 0xef, 0x71, 0xb3, 0x0d, 0x27, 0x7b, 0xa1, 0x0f, 0x27, 0xfb, 0xef, 0x38, 0x90, 0x52, + 0xa2, 0xa2, 0x68, 0x33, 0x6d, 0xb9, 0x26, 0x8a, 0x04, 0x27, 0x51, 0x8a, 0x5e, 0x87, 0x73, 0xe6, + 0x17, 0x3c, 0xa4, 0xbf, 0x85, 0x1f, 0x4e, 0xf3, 0x29, 0xe1, 0x5e, 0x2c, 0xdc, 0xaf, 0x39, 0x50, + 0x5c, 0xf2, 0x3a, 0x75, 0xd2, 0x97, 0xb9, 0x8c, 0xca, 0xb1, 0x88, 0x78, 0xcd, 0x44, 0x1e, 0x1d, + 0x84, 0x1c, 0xc3, 0x02, 0x86, 0x55, 0x29, 0x9a, 0x85, 0xd1, 0xb0, 0x4d, 0x0c, 0x1f, 0xe1, 0x23, + 0x72, 0xf4, 0xd6, 0x64, 0x01, 0xdd, 0x76, 0x18, 0x77, 0x05, 0xc1, 0x69, 0x2d, 0xf7, 0x07, 0x45, + 0x28, 0x69, 0xf7, 0x62, 0xa8, 0x2e, 0x10, 0x91, 0x76, 0x98, 0xd5, 0x97, 0xe9, 0x84, 0xc1, 0xac, + 0x84, 0xae, 0xc1, 0x88, 0xec, 0xf8, 0x31, 0x17, 0x5b, 0xc6, 0x1a, 0xc4, 0x02, 0x8e, 0x15, 0x06, + 0x9a, 0x86, 0x62, 0x8d, 0xb4, 0x93, 0x06, 0x6b, 0xde, 0x20, 0x0f, 0x0e, 0x5c, 0xa0, 0x00, 0xcc, + 0xe1, 0x14, 0x61, 0x8b, 0x24, 0xd5, 0x06, 0xb3, 0x0c, 0x8b, 0xe8, 0xc1, 0x45, 0x0a, 0xc0, 0x1c, + 0x9e, 0xe3, 0xc5, 0x2c, 0x1e, 0xbd, 0x17, 0x73, 0xc8, 0xb2, 0x17, 0x13, 0xb5, 0xe1, 0x54, 0x1c, + 0x37, 0xd6, 0x23, 0x7f, 0xc7, 0x4b, 0x48, 0x3a, 0xfb, 0x86, 0x0f, 0xc2, 0xe7, 0x1c, 0xbb, 0xa9, + 0x5e, 0xb9, 0x9c, 0xa5, 0x82, 0xf3, 0x48, 0xa3, 0x0a, 0x9c, 0xf1, 0x83, 0x98, 0x54, 0x3b, 0x11, + 0xb9, 0x52, 0x0f, 0xc2, 0x88, 0x5c, 0x0e, 0x63, 0x4a, 0x4e, 0xdc, 0xb3, 0x55, 0xf1, 0xb4, 0x57, + 0xf2, 0x90, 0x70, 0x7e, 0x5d, 0xb4, 0x04, 0x27, 0x6b, 0x7e, 0xec, 0x6d, 0x36, 0x49, 0xa5, 0xb3, + 0xd9, 0x0a, 0xf9, 0xd1, 0x7c, 0x94, 0x11, 0xbc, 0x5f, 0xda, 0x91, 0x16, 0xb2, 0x08, 0xb8, 0xbb, + 0x0e, 0x7a, 0x06, 0xc6, 0x62, 0x3f, 0xa8, 0x37, 0xc9, 0x5c, 0xe4, 0x05, 0xd5, 0x86, 0xb8, 0xa0, + 0xab, 0xec, 0xed, 0x15, 0xad, 0x0c, 0x1b, 0x98, 0x6c, 0xcd, 0xf3, 0x3a, 0x19, 0x6d, 0x50, 0x60, + 0x8b, 0x52, 0xf7, 0x87, 0x0e, 0x8c, 0xe9, 0xb1, 0xec, 0x54, 0xd3, 0x86, 0xc6, 0xc2, 0x62, 0x85, + 0xef, 0x05, 0xf6, 0x76, 0xfc, 0xcb, 0x8a, 0x66, 0x7a, 0x58, 0x4e, 0x61, 0x58, 0xe3, 0xd9, 0xc7, + 0xcd, 0xf4, 0x47, 0xa0, 0xb8, 0x15, 0x52, 0x85, 0x64, 0xc0, 0x34, 0xd4, 0x2f, 0x52, 0x20, 0xe6, + 0x65, 0xee, 0x7f, 0x73, 0xe0, 0x6c, 0x7e, 0x98, 0xfe, 0xcf, 0x42, 0x27, 0x2f, 0x02, 0xd0, 0xae, + 0x18, 0x42, 0x5d, 0xcb, 0x4d, 0x21, 0x4b, 0xb0, 0x86, 0xd5, 0x5f, 0xb7, 0xff, 0x65, 0x01, 0x34, + 0x9e, 0xe8, 0xf3, 0x0e, 0x8c, 0x53, 0xb6, 0xcb, 0xd1, 0xa6, 0xd1, 0xdb, 0x35, 0x3b, 0xbd, 0x55, + 0x64, 0x53, 0x7f, 0x84, 0x01, 0xc6, 0x26, 0x73, 0xf4, 0x0b, 0x30, 0xea, 0xd5, 0x6a, 0x11, 0x89, + 0x63, 0xe5, 0xd9, 0x63, 0xd6, 0xaa, 0x59, 0x09, 0xc4, 0x69, 0x39, 0x15, 0xa2, 0x8d, 0xda, 0x56, + 0x4c, 0xe5, 0x92, 0x10, 0xdc, 0x4a, 0x88, 0x52, 0x26, 0x14, 0x8e, 0x15, 0x06, 0x7a, 0x1e, 0xce, + 0xd6, 0xbc, 0xc4, 0xe3, 0xfa, 0x1b, 0x89, 0xd6, 0xa3, 0x30, 0x21, 0x55, 0x26, 0xf4, 0x79, 0x04, + 0xea, 0x79, 0x51, 0xf7, 0xec, 0x42, 0x2e, 0x16, 0xee, 0x51, 0xdb, 0xfd, 0xd5, 0x41, 0x30, 0xfb, + 0x84, 0x6a, 0x70, 0x62, 0x3b, 0xda, 0x9c, 0x67, 0x01, 0x17, 0x87, 0x09, 0x7c, 0x60, 0x01, 0x09, + 0xcb, 0x26, 0x05, 0x9c, 0x25, 0x29, 0xb8, 0x2c, 0x93, 0xdd, 0xc4, 0xdb, 0x3c, 0x74, 0xd8, 0xc3, + 0xb2, 0x49, 0x01, 0x67, 0x49, 0xa2, 0x77, 0x43, 0x69, 0x3b, 0xda, 0x94, 0xa2, 0x3f, 0x1b, 0x43, + 0xb3, 0x9c, 0x16, 0x61, 0x1d, 0x8f, 0x7e, 0x9a, 0xed, 0x68, 0x93, 0xee, 0xb6, 0x32, 0x03, 0x84, + 0xfa, 0x34, 0xcb, 0x02, 0x8e, 0x15, 0x06, 0x6a, 0x03, 0xda, 0x96, 0xa3, 0xa7, 0xc2, 0x4b, 0xc4, + 0x0e, 0xd5, 0x7f, 0x74, 0x0a, 0x8b, 0xeb, 0x5f, 0xee, 0xa2, 0x83, 0x73, 0x68, 0xa3, 0x17, 0xe0, + 0xdc, 0x76, 0xb4, 0x29, 0x94, 0x90, 0xf5, 0xc8, 0x0f, 0xaa, 0x7e, 0xdb, 0xc8, 0xf6, 0x30, 0x2d, + 0x9a, 0x7b, 0x6e, 0x39, 0x1f, 0x0d, 0xf7, 0xaa, 0xef, 0xfe, 0xee, 0x20, 0xb0, 0x7b, 0xaa, 0x54, + 0xc6, 0xb6, 0x48, 0xd2, 0x08, 0x6b, 0x59, 0xbd, 0x6a, 0x95, 0x41, 0xb1, 0x28, 0x95, 0xd1, 0xab, + 0x85, 0x1e, 0xd1, 0xab, 0x37, 0x60, 0xb8, 0x41, 0xbc, 0x1a, 0x89, 0xa4, 0x65, 0x72, 0xc5, 0xce, + 0xcd, 0xda, 0xcb, 0x8c, 0x68, 0x7a, 0xbc, 0xe7, 0xbf, 0x63, 0x2c, 0xb9, 0xa1, 0xf7, 0xc0, 0x04, + 0x55, 0x90, 0xc2, 0x4e, 0x22, 0x9d, 0x0b, 0xdc, 0x32, 0xc9, 0x76, 0xea, 0x0d, 0xa3, 0x04, 0x67, + 0x30, 0xd1, 0x02, 0x4c, 0x0a, 0x47, 0x80, 0xb2, 0x78, 0x8a, 0x81, 0x55, 0x69, 0x38, 0x2a, 0x99, + 0x72, 0xdc, 0x55, 0x83, 0x45, 0x1f, 0x86, 0x35, 0xee, 0x0b, 0xd6, 0xa3, 0x0f, 0xc3, 0xda, 0x2e, + 0x66, 0x25, 0xe8, 0x55, 0x18, 0xa1, 0x7f, 0x17, 0xa3, 0xb0, 0x25, 0x6c, 0x3e, 0xeb, 0x76, 0x46, + 0x87, 0xf2, 0x10, 0x27, 0x50, 0xa6, 0x38, 0xce, 0x09, 0x2e, 0x58, 0xf1, 0xa3, 0xe7, 0x20, 0xb9, + 0xbf, 0x57, 0xb6, 0xfd, 0xf6, 0xf3, 0x24, 0xf2, 0xb7, 0x76, 0x99, 0x32, 0x32, 0x92, 0x9e, 0x83, + 0xae, 0x74, 0x61, 0xe0, 0x9c, 0x5a, 0xee, 0xe7, 0x0b, 0x30, 0xa6, 0x5f, 0x77, 0xbe, 0x53, 0x48, + 0x73, 0x9c, 0x4e, 0x0a, 0x7e, 0xea, 0xbd, 0x6c, 0xa1, 0xdb, 0x77, 0x9a, 0x10, 0x0d, 0x18, 0xf4, + 0x3a, 0x42, 0x0b, 0xb5, 0x62, 0x5c, 0x63, 0x3d, 0xee, 0x24, 0x0d, 0x7e, 0x2f, 0x8e, 0x05, 0x1b, + 0x33, 0x0e, 0xee, 0xa7, 0x06, 0x60, 0x44, 0x16, 0xa2, 0x4f, 0x3a, 0x00, 0x69, 0xd0, 0x97, 0x10, + 0xa5, 0xeb, 0x36, 0x22, 0x82, 0xf4, 0x78, 0x35, 0xcd, 0x46, 0xaf, 0xe0, 0x58, 0xe3, 0x8b, 0x12, + 0x18, 0x0a, 0x69, 0xe3, 0x2e, 0xda, 0xbb, 0xb2, 0xbf, 0x46, 0x19, 0x5f, 0x64, 0xdc, 0x53, 0x73, + 0x1c, 0x83, 0x61, 0xc1, 0x8b, 0x9e, 0x2c, 0x37, 0x65, 0x2c, 0xa2, 0x3d, 0xd3, 0xb5, 0x0a, 0x6f, + 0x4c, 0x0f, 0x8a, 0x0a, 0x84, 0x53, 0x86, 0xee, 0x53, 0x30, 0x61, 0x2e, 0x06, 0x7a, 0xd2, 0xd8, + 0xdc, 0x4d, 0x08, 0xb7, 0x63, 0x8c, 0xf1, 0x93, 0xc6, 0x1c, 0x05, 0x60, 0x0e, 0x77, 0xbf, 0xef, + 0x00, 0xa4, 0xe2, 0xa5, 0x0f, 0xd7, 0xc1, 0x23, 0xba, 0x11, 0xae, 0xd7, 0x71, 0xee, 0x63, 0x30, + 0xca, 0xfe, 0x61, 0x0b, 0x7d, 0xc0, 0x56, 0xe4, 0x40, 0xda, 0x4e, 0xb1, 0xd4, 0x99, 0xae, 0xf1, + 0xbc, 0x64, 0x84, 0x53, 0x9e, 0x6e, 0x08, 0x93, 0x59, 0x6c, 0xf4, 0x41, 0x18, 0x8b, 0xe5, 0xb6, + 0x9a, 0x5e, 0xde, 0xeb, 0x73, 0xfb, 0xe5, 0x7e, 0x3b, 0xad, 0x3a, 0x36, 0x88, 0xb9, 0x6b, 0x30, + 0x64, 0x75, 0x08, 0xdd, 0x6f, 0x3b, 0x30, 0xca, 0x5c, 0xa7, 0xf5, 0xc8, 0x6b, 0xa5, 0x55, 0x06, + 0xf6, 0x19, 0xf5, 0x18, 0x86, 0xf9, 0xd9, 0x5f, 0x86, 0x1c, 0x59, 0x90, 0x32, 0x3c, 0xd3, 0x5e, + 0x2a, 0x65, 0xb8, 0x91, 0x21, 0xc6, 0x92, 0x93, 0xfb, 0xe9, 0x02, 0x0c, 0x5d, 0x09, 0xda, 0x9d, + 0xbf, 0xf4, 0xd9, 0xde, 0x56, 0x61, 0xf0, 0x4a, 0x42, 0x5a, 0x66, 0x52, 0xc2, 0xb1, 0xb9, 0x47, + 0xf5, 0x84, 0x84, 0x65, 0x33, 0x21, 0x21, 0xf6, 0x6e, 0xc8, 0x88, 0x3c, 0x61, 0x7b, 0x4e, 0x2f, + 0x30, 0x3e, 0x09, 0xa3, 0x2b, 0xde, 0x26, 0x69, 0x2e, 0x93, 0x5d, 0x76, 0xdd, 0x90, 0x47, 0x87, + 0x38, 0xa9, 0xc1, 0xc0, 0x88, 0xe4, 0x58, 0x80, 0x09, 0x86, 0xad, 0x16, 0x03, 0x3d, 0x91, 0x90, + 0x34, 0xa3, 0x93, 0x63, 0x9e, 0x48, 0xb4, 0x6c, 0x4e, 0x1a, 0x96, 0x3b, 0x03, 0xa5, 0x94, 0x4a, + 0x1f, 0x5c, 0x7f, 0x5a, 0x80, 0x71, 0xc3, 0x84, 0x6e, 0x38, 0x16, 0x9d, 0x3b, 0x3a, 0x16, 0x0d, + 0x47, 0x5f, 0xe1, 0x5e, 0x3b, 0xfa, 0x06, 0x8e, 0xdf, 0xd1, 0x67, 0x7e, 0xa4, 0xc1, 0xbe, 0x3e, + 0x52, 0x13, 0x06, 0x57, 0xfc, 0x60, 0xbb, 0x3f, 0x39, 0x13, 0x57, 0xc3, 0x76, 0x97, 0x9c, 0xa9, + 0x50, 0x20, 0xe6, 0x65, 0x52, 0x73, 0x19, 0xc8, 0xd7, 0x5c, 0xdc, 0x4f, 0x3a, 0x30, 0xb6, 0xea, + 0x05, 0xfe, 0x16, 0x89, 0x13, 0x36, 0xaf, 0x92, 0x23, 0xbd, 0x76, 0x36, 0xd6, 0x23, 0x81, 0xc2, + 0x9b, 0x0e, 0x9c, 0x5c, 0x25, 0xad, 0xd0, 0x7f, 0xd5, 0x4b, 0x03, 0x5e, 0x69, 0xdb, 0x1b, 0x7e, + 0x22, 0xe2, 0xfb, 0x54, 0xdb, 0x2f, 0xfb, 0x09, 0xa6, 0xf0, 0x3b, 0xd8, 0x87, 0xd9, 0x85, 0x0e, + 0x7a, 0x40, 0xd3, 0xae, 0x42, 0xa6, 0xa1, 0xac, 0xb2, 0x00, 0xa7, 0x38, 0xee, 0xef, 0x39, 0x30, + 0xcc, 0x1b, 0xa1, 0x62, 0x84, 0x9d, 0x1e, 0xb4, 0x1b, 0x50, 0x64, 0xf5, 0xc4, 0xac, 0x5e, 0xb2, + 0xa0, 0xfe, 0x50, 0x72, 0x7c, 0x0d, 0xb2, 0x7f, 0x31, 0x67, 0xc0, 0x8e, 0x2d, 0xde, 0xcd, 0x59, + 0x15, 0xeb, 0x9b, 0x1e, 0x5b, 0x18, 0x14, 0x8b, 0x52, 0xf7, 0xeb, 0x03, 0x30, 0xa2, 0xf2, 0x86, + 0xb1, 0xac, 0x0e, 0x41, 0x10, 0x26, 0x1e, 0x8f, 0xa1, 0xe0, 0xb2, 0xfa, 0x83, 0xf6, 0xf2, 0x96, + 0xcd, 0xcc, 0xa6, 0xd4, 0xb9, 0x5f, 0x50, 0x1d, 0x42, 0xb5, 0x12, 0xac, 0x37, 0x02, 0x7d, 0x14, + 0x86, 0x9a, 0x54, 0xfa, 0x48, 0xd1, 0xfd, 0xbc, 0xc5, 0xe6, 0x30, 0xb1, 0x26, 0x5a, 0xa2, 0x46, + 0x88, 0x03, 0xb1, 0xe0, 0x3a, 0xf5, 0x3e, 0x98, 0xcc, 0xb6, 0xfa, 0x4e, 0x37, 0x35, 0x47, 0xf5, + 0x7b, 0x9e, 0x7f, 0x55, 0x48, 0xcf, 0x83, 0x57, 0x75, 0x9f, 0x83, 0xd2, 0x2a, 0x49, 0x22, 0xbf, + 0xca, 0x08, 0xdc, 0x69, 0x72, 0xf5, 0xa5, 0x3f, 0x7c, 0x86, 0x4d, 0x56, 0x4a, 0x33, 0x46, 0xaf, + 0x03, 0xb4, 0xa3, 0x90, 0x9e, 0x5f, 0x49, 0x47, 0x7e, 0x6c, 0x0b, 0xfa, 0xf0, 0xba, 0xa2, 0xc9, + 0x5d, 0xd9, 0xe9, 0x6f, 0xac, 0xf1, 0x73, 0x5f, 0x84, 0xe2, 0x6a, 0x27, 0x21, 0x37, 0xfb, 0x90, + 0x58, 0x07, 0x4d, 0x5d, 0xe0, 0x7e, 0x10, 0xc6, 0x18, 0xed, 0xcb, 0x61, 0x93, 0x6e, 0xab, 0x74, + 0x68, 0x5a, 0xf4, 0x77, 0xd6, 0xd9, 0xc0, 0x90, 0x30, 0x2f, 0xa3, 0x4b, 0xa6, 0x11, 0x36, 0x6b, + 0xea, 0x1a, 0x97, 0x9a, 0x10, 0x97, 0x19, 0x14, 0x8b, 0x52, 0xf7, 0x13, 0x05, 0x28, 0xb1, 0x8a, + 0x42, 0xdc, 0xec, 0xc2, 0x70, 0x83, 0xf3, 0x11, 0x63, 0x68, 0x21, 0x38, 0x4c, 0x6f, 0xbd, 0x76, + 0x96, 0xe3, 0x00, 0x2c, 0xf9, 0x51, 0xd6, 0x37, 0x3c, 0x3f, 0xa1, 0xac, 0x0b, 0x47, 0xcb, 0xfa, + 0x3a, 0x67, 0x83, 0x25, 0x3f, 0xf7, 0x97, 0x81, 0x5d, 0x8f, 0x5e, 0x6c, 0x7a, 0x75, 0x3e, 0x72, + 0xe1, 0x36, 0xa9, 0x09, 0x99, 0xab, 0x8d, 0x1c, 0x85, 0x62, 0x51, 0xca, 0xaf, 0x9c, 0x26, 0x91, + 0xaf, 0xc2, 0xaa, 0xb5, 0x2b, 0xa7, 0x0c, 0x2c, 0x83, 0xe8, 0x6b, 0xee, 0x97, 0x0b, 0x00, 0x2c, + 0xcb, 0x1c, 0xbf, 0xd5, 0xfc, 0x8b, 0x32, 0x02, 0xca, 0x74, 0x50, 0xaa, 0x08, 0x28, 0x76, 0x6f, + 0x5b, 0x8f, 0x7c, 0xd2, 0x6f, 0x3b, 0x14, 0xf6, 0xbf, 0xed, 0x80, 0xda, 0x30, 0x1c, 0x76, 0x12, + 0xaa, 0xab, 0x8a, 0xcd, 0xde, 0x82, 0x7f, 0x7e, 0x8d, 0x13, 0xe4, 0x57, 0x04, 0xc4, 0x0f, 0x2c, + 0xd9, 0xa0, 0x67, 0x60, 0xa4, 0x1d, 0x85, 0x75, 0xba, 0x77, 0x8b, 0xed, 0xfd, 0x41, 0xa9, 0x0f, + 0xad, 0x0b, 0xf8, 0x6d, 0xed, 0x7f, 0xac, 0xb0, 0xdd, 0x3f, 0x9e, 0xe4, 0xe3, 0x22, 0xe6, 0xde, + 0x14, 0x14, 0x7c, 0x69, 0x99, 0x02, 0x41, 0xa2, 0x70, 0x65, 0x01, 0x17, 0xfc, 0x9a, 0x5a, 0x57, + 0x85, 0x9e, 0xeb, 0xea, 0xdd, 0x50, 0xaa, 0xf9, 0x71, 0xbb, 0xe9, 0xed, 0x5e, 0xcd, 0x31, 0x0b, + 0x2e, 0xa4, 0x45, 0x58, 0xc7, 0x43, 0x4f, 0x8a, 0xbb, 0x2d, 0x83, 0x86, 0x29, 0x48, 0xde, 0x6d, + 0x49, 0x6f, 0xcd, 0xf3, 0x6b, 0x2d, 0xd9, 0xec, 0x02, 0xc5, 0xbe, 0xb3, 0x0b, 0x64, 0x35, 0xb1, + 0xa1, 0xe3, 0xd7, 0xc4, 0xde, 0x0b, 0xe3, 0xf2, 0x27, 0x53, 0x8f, 0xca, 0xa7, 0x59, 0xeb, 0x95, + 0x19, 0x7c, 0x43, 0x2f, 0xc4, 0x26, 0x6e, 0x3a, 0x69, 0x87, 0xfb, 0x9d, 0xb4, 0x17, 0x01, 0x36, + 0xc3, 0x4e, 0x50, 0xf3, 0xa2, 0xdd, 0x2b, 0x0b, 0x22, 0x12, 0x56, 0x29, 0x7e, 0x73, 0xaa, 0x04, + 0x6b, 0x58, 0xfa, 0x44, 0x1f, 0xbd, 0xc3, 0x44, 0xff, 0x20, 0x8c, 0xb2, 0xa8, 0x61, 0x52, 0x9b, + 0x4d, 0x44, 0xe8, 0xd2, 0x41, 0x42, 0x31, 0xd3, 0x60, 0x46, 0x49, 0x04, 0xa7, 0xf4, 0xd0, 0x87, + 0x00, 0xb6, 0xfc, 0xc0, 0x8f, 0x1b, 0x8c, 0x7a, 0xe9, 0xc0, 0xd4, 0x55, 0x3f, 0x17, 0x15, 0x15, + 0xac, 0x51, 0x44, 0x2f, 0xc1, 0x49, 0x12, 0x27, 0x7e, 0xcb, 0x4b, 0x48, 0x4d, 0xdd, 0x06, 0x2d, + 0x33, 0x5b, 0xa6, 0x8a, 0xdb, 0xbe, 0x94, 0x45, 0xb8, 0x9d, 0x07, 0xc4, 0xdd, 0x84, 0x8c, 0x15, + 0x39, 0x75, 0x90, 0x15, 0x89, 0xfe, 0xa7, 0x03, 0x27, 0x23, 0xc2, 0xe3, 0x59, 0x62, 0xd5, 0xb0, + 0x33, 0x4c, 0x1c, 0x57, 0x6d, 0x24, 0x70, 0x57, 0x99, 0x5a, 0x70, 0x96, 0x0b, 0x57, 0x5c, 0x88, + 0xec, 0x7d, 0x57, 0xf9, 0xed, 0x3c, 0xe0, 0x9b, 0x6f, 0x4f, 0x4f, 0x77, 0x3f, 0x24, 0xa0, 0x88, + 0xd3, 0x95, 0xf7, 0x37, 0xdf, 0x9e, 0x9e, 0x94, 0xbf, 0xd3, 0x41, 0xeb, 0xea, 0x24, 0xdd, 0x56, + 0xdb, 0x61, 0xed, 0xca, 0xba, 0x88, 0x31, 0x53, 0xdb, 0xea, 0x3a, 0x05, 0x62, 0x5e, 0x86, 0x1e, + 0x87, 0x91, 0x9a, 0x47, 0x5a, 0x61, 0xa0, 0x52, 0xf1, 0x32, 0x6d, 0x7e, 0x41, 0xc0, 0xb0, 0x2a, + 0xa5, 0x67, 0x88, 0x40, 0x6c, 0x29, 0xe5, 0x07, 0x6c, 0x9d, 0x21, 0xe4, 0x26, 0xc5, 0xb9, 0xca, + 0x5f, 0x58, 0x71, 0x42, 0x4d, 0x18, 0xf2, 0x99, 0xa1, 0x42, 0x84, 0xb1, 0x5a, 0xb0, 0x8e, 0x70, + 0xc3, 0x87, 0x0c, 0x62, 0x65, 0xa2, 0x5f, 0xf0, 0xd0, 0xf7, 0x9a, 0x13, 0xc7, 0xb3, 0xd7, 0x3c, + 0x0e, 0x23, 0xd5, 0x86, 0xdf, 0xac, 0x45, 0x24, 0x28, 0x4f, 0xb2, 0x13, 0x3b, 0x1b, 0x89, 0x79, + 0x01, 0xc3, 0xaa, 0x14, 0xfd, 0x15, 0x18, 0x0f, 0x3b, 0x09, 0x13, 0x2d, 0x74, 0x9c, 0xe2, 0xf2, + 0x49, 0x86, 0xce, 0x82, 0x92, 0xd6, 0xf4, 0x02, 0x6c, 0xe2, 0x51, 0x11, 0xdf, 0x08, 0x63, 0x96, + 0x54, 0x88, 0x89, 0xf8, 0xb3, 0xa6, 0x88, 0xbf, 0xac, 0x95, 0x61, 0x03, 0x13, 0x7d, 0xd5, 0x81, + 0x93, 0xad, 0xec, 0x01, 0xae, 0x7c, 0x8e, 0x8d, 0x4c, 0xc5, 0x86, 0xa2, 0x9f, 0x21, 0xcd, 0xc3, + 0xc9, 0xbb, 0xc0, 0xb8, 0xbb, 0x11, 0x2c, 0xbd, 0x57, 0xbc, 0x1b, 0x54, 0x1b, 0x51, 0x18, 0x98, + 0xcd, 0xbb, 0xdf, 0xd6, 0xa5, 0x36, 0xb6, 0xb6, 0xf3, 0x58, 0xcc, 0xdd, 0x7f, 0x6b, 0x6f, 0xfa, + 0x4c, 0x6e, 0x11, 0xce, 0x6f, 0xd4, 0xd4, 0x02, 0x9c, 0xcd, 0x97, 0x0f, 0x77, 0x3a, 0x71, 0x0c, + 0xe8, 0x27, 0x8e, 0x45, 0xb8, 0xbf, 0x67, 0xa3, 0xe8, 0x4e, 0x23, 0xb5, 0x4d, 0xc7, 0xdc, 0x69, + 0xba, 0xb4, 0xc3, 0x09, 0x18, 0xd3, 0x5f, 0x9e, 0x70, 0xff, 0xcf, 0x00, 0x40, 0x6a, 0x27, 0x47, + 0x1e, 0x4c, 0x70, 0x9b, 0xfc, 0x95, 0x85, 0x43, 0x5f, 0xc7, 0x9f, 0x37, 0x08, 0xe0, 0x0c, 0x41, + 0xd4, 0x02, 0xc4, 0x21, 0xfc, 0xf7, 0x61, 0x7c, 0xab, 0xcc, 0x15, 0x39, 0xdf, 0x45, 0x04, 0xe7, + 0x10, 0xa6, 0x3d, 0x4a, 0xc2, 0x6d, 0x12, 0x5c, 0xc3, 0x2b, 0x87, 0xc9, 0xe9, 0xc0, 0xbd, 0x71, + 0x06, 0x01, 0x9c, 0x21, 0x88, 0x5c, 0x18, 0x62, 0xb6, 0x19, 0x19, 0xf8, 0xcd, 0xc4, 0x0b, 0xd3, + 0x34, 0x62, 0x2c, 0x4a, 0xd0, 0x97, 0x1d, 0x98, 0x90, 0xa9, 0x29, 0x98, 0x35, 0x54, 0x86, 0x7c, + 0x5f, 0xb3, 0xe5, 0xe7, 0xb8, 0xa4, 0x53, 0x4f, 0x03, 0x2a, 0x0d, 0x70, 0x8c, 0x33, 0x8d, 0x70, + 0x5f, 0x80, 0x53, 0x39, 0xd5, 0xad, 0x9c, 0x68, 0xbf, 0xe3, 0x40, 0x49, 0xcb, 0x98, 0x88, 0x5e, + 0x87, 0xd1, 0xb0, 0x62, 0x3d, 0x8a, 0x6f, 0xad, 0xd2, 0x15, 0xc5, 0xa7, 0x40, 0x38, 0x65, 0xd8, + 0x4f, 0xf0, 0x61, 0x6e, 0x7a, 0xc7, 0x7b, 0xdc, 0xec, 0x03, 0x07, 0x1f, 0xfe, 0x6a, 0x11, 0x52, + 0x4a, 0x07, 0x4c, 0x99, 0x92, 0x86, 0x2a, 0x16, 0xf6, 0x0d, 0x55, 0xac, 0xc1, 0x09, 0x8f, 0xf9, + 0x92, 0x0f, 0x99, 0x28, 0x85, 0x27, 0xcc, 0x35, 0x29, 0xe0, 0x2c, 0x49, 0xca, 0x25, 0x4e, 0xab, + 0x32, 0x2e, 0x83, 0x07, 0xe6, 0x52, 0x31, 0x29, 0xe0, 0x2c, 0x49, 0xf4, 0x12, 0x94, 0xab, 0xec, + 0xe2, 0x2f, 0xef, 0xe3, 0x95, 0xad, 0xab, 0x61, 0xb2, 0x1e, 0x91, 0x98, 0x04, 0x89, 0x48, 0x89, + 0xf6, 0xb0, 0x18, 0x85, 0xf2, 0x7c, 0x0f, 0x3c, 0xdc, 0x93, 0x02, 0x3d, 0xa6, 0x30, 0x67, 0xb4, + 0x9f, 0xec, 0x32, 0x21, 0x22, 0xbc, 0xf4, 0xea, 0x98, 0x52, 0xd1, 0x0b, 0xb1, 0x89, 0x8b, 0x7e, + 0xc5, 0x81, 0xf1, 0xa6, 0x34, 0xd7, 0xe3, 0x4e, 0x53, 0xe6, 0xf7, 0xc4, 0x56, 0xa6, 0xdf, 0x8a, + 0x4e, 0x99, 0xeb, 0x12, 0x06, 0x08, 0x9b, 0xbc, 0xb3, 0x59, 0x6b, 0x46, 0xfa, 0xcc, 0x5a, 0xf3, + 0x7d, 0x07, 0x26, 0xb3, 0xdc, 0xd0, 0x36, 0x3c, 0xd4, 0xf2, 0xa2, 0xed, 0x2b, 0xc1, 0x56, 0xc4, + 0x2e, 0x78, 0x24, 0x7c, 0x32, 0xcc, 0x6e, 0x25, 0x24, 0x5a, 0xf0, 0x76, 0xb9, 0xfb, 0xb3, 0xa8, + 0x1e, 0x88, 0x7a, 0x68, 0x75, 0x3f, 0x64, 0xbc, 0x3f, 0x2d, 0x54, 0x81, 0x33, 0x14, 0x81, 0x25, + 0xb5, 0xf3, 0xc3, 0x20, 0x65, 0x52, 0x60, 0x4c, 0x54, 0x90, 0xe1, 0x6a, 0x1e, 0x12, 0xce, 0xaf, + 0xeb, 0x5e, 0x82, 0x21, 0x7e, 0xdf, 0xee, 0xae, 0xfc, 0x47, 0xee, 0xbf, 0x29, 0x80, 0x54, 0x0c, + 0xff, 0x72, 0xbb, 0xe3, 0xe8, 0x26, 0x1a, 0x31, 0x93, 0x92, 0xb0, 0x76, 0xb0, 0x4d, 0x54, 0xa4, + 0x8f, 0x14, 0x25, 0x54, 0x63, 0x26, 0x37, 0xfd, 0x64, 0x3e, 0xac, 0x49, 0x1b, 0x07, 0xd3, 0x98, + 0x2f, 0x09, 0x18, 0x56, 0xa5, 0xee, 0x27, 0x1d, 0x18, 0xa7, 0xbd, 0x6c, 0x36, 0x49, 0xb3, 0x92, + 0x90, 0x76, 0x8c, 0x62, 0x28, 0xc6, 0xf4, 0x1f, 0x7b, 0xa6, 0xc0, 0xf4, 0x8e, 0x26, 0x69, 0x6b, + 0xce, 0x1a, 0xca, 0x04, 0x73, 0x5e, 0xee, 0x5b, 0x03, 0x30, 0xaa, 0x06, 0xbb, 0x0f, 0x7b, 0xea, + 0xc5, 0x34, 0xb3, 0x2b, 0x97, 0xc0, 0x65, 0x2d, 0xab, 0xeb, 0x6d, 0x3a, 0x74, 0xc1, 0x2e, 0x4f, + 0x71, 0x91, 0xa6, 0x78, 0x7d, 0xd2, 0x74, 0x35, 0x9f, 0xd5, 0xe7, 0x9f, 0x86, 0x2f, 0x7c, 0xce, + 0x37, 0x75, 0x4f, 0xff, 0xa0, 0xad, 0xdd, 0x4c, 0xb9, 0x31, 0x7b, 0xbb, 0xf8, 0x33, 0x8f, 0xfe, + 0x14, 0xfb, 0x7a, 0xf4, 0xe7, 0x09, 0x18, 0x24, 0x41, 0xa7, 0xc5, 0x54, 0xa5, 0x51, 0x76, 0x44, + 0x18, 0xbc, 0x14, 0x74, 0x5a, 0x66, 0xcf, 0x18, 0x0a, 0x7a, 0x1f, 0x94, 0x6a, 0x24, 0xae, 0x46, + 0x3e, 0xcb, 0xdb, 0x20, 0x2c, 0x3b, 0x0f, 0x32, 0x73, 0x59, 0x0a, 0x36, 0x2b, 0xea, 0x15, 0xdc, + 0x57, 0x61, 0x68, 0xbd, 0xd9, 0xa9, 0xfb, 0x01, 0x6a, 0xc3, 0x10, 0xcf, 0xe2, 0x20, 0x76, 0x7b, + 0x0b, 0xe7, 0x4e, 0x2e, 0x2a, 0xb4, 0x28, 0x14, 0x7e, 0x55, 0x57, 0xf0, 0x71, 0x3f, 0x51, 0x00, + 0x7a, 0x34, 0x5f, 0x9a, 0x47, 0x7f, 0xbd, 0xeb, 0x8d, 0x9b, 0x9f, 0xcb, 0x79, 0xe3, 0x66, 0x9c, + 0x21, 0xe7, 0x3c, 0x6f, 0xd3, 0x84, 0x71, 0xe6, 0x1c, 0x91, 0x7b, 0xa0, 0x50, 0xab, 0x9f, 0xee, + 0x33, 0xf1, 0x81, 0x5e, 0x55, 0xec, 0x08, 0x3a, 0x08, 0x9b, 0xc4, 0xd1, 0x2a, 0x9c, 0xe2, 0x09, + 0x42, 0x17, 0x48, 0xd3, 0xdb, 0xcd, 0x24, 0x02, 0x7b, 0x40, 0x3e, 0x5b, 0xb6, 0xd0, 0x8d, 0x82, + 0xf3, 0xea, 0xb9, 0xbf, 0x3f, 0x08, 0x9a, 0x4b, 0xa2, 0x8f, 0xd5, 0xf2, 0x4a, 0xc6, 0x01, 0xb5, + 0x6a, 0xc5, 0x01, 0x25, 0xbd, 0x3a, 0x5c, 0x02, 0x99, 0x3e, 0x27, 0xda, 0xa8, 0x06, 0x69, 0xb6, + 0x45, 0x1f, 0x55, 0xa3, 0x2e, 0x93, 0x66, 0x1b, 0xb3, 0x12, 0x75, 0x51, 0x71, 0xb0, 0xe7, 0x45, + 0xc5, 0x06, 0x14, 0xeb, 0x5e, 0xa7, 0x4e, 0x44, 0x04, 0xa6, 0x05, 0x5f, 0x23, 0xbb, 0x3a, 0xc1, + 0x7d, 0x8d, 0xec, 0x5f, 0xcc, 0x19, 0xd0, 0xc5, 0xde, 0x90, 0x21, 0x29, 0xc2, 0x48, 0x6b, 0x61, + 0xb1, 0xab, 0x28, 0x17, 0xbe, 0xd8, 0xd5, 0x4f, 0x9c, 0x32, 0x43, 0x6d, 0x18, 0xae, 0xf2, 0xf4, + 0x2b, 0x42, 0x67, 0xb9, 0x62, 0xe3, 0x26, 0x26, 0x23, 0xc8, 0xad, 0x29, 0xe2, 0x07, 0x96, 0x6c, + 0xdc, 0x0b, 0x50, 0xd2, 0x9e, 0xda, 0xa0, 0x9f, 0x41, 0x65, 0xfe, 0xd0, 0x3e, 0xc3, 0x82, 0x97, + 0x78, 0x98, 0x95, 0xb8, 0xdf, 0x1c, 0x04, 0x65, 0x4b, 0xd3, 0xef, 0x0d, 0x7a, 0x55, 0x2d, 0x4f, + 0x91, 0x71, 0x87, 0x3e, 0x0c, 0xb0, 0x28, 0xa5, 0x7a, 0x5d, 0x8b, 0x44, 0x75, 0x75, 0x8e, 0x16, + 0xe2, 0x5a, 0xe9, 0x75, 0xab, 0x7a, 0x21, 0x36, 0x71, 0xa9, 0x52, 0xde, 0x12, 0x2e, 0xfa, 0x6c, + 0x60, 0xb5, 0x74, 0xdd, 0x63, 0x85, 0xc1, 0x12, 0x1d, 0xb4, 0x34, 0x8f, 0xbe, 0x08, 0xc4, 0xb4, + 0xe1, 0x50, 0xd2, 0xa8, 0xf2, 0x80, 0x29, 0x1d, 0x82, 0x0d, 0xae, 0x68, 0x09, 0x4e, 0xc6, 0x24, + 0x59, 0xbb, 0x11, 0x90, 0x48, 0xa5, 0x18, 0x10, 0x99, 0x34, 0xd4, 0xad, 0x8a, 0x4a, 0x16, 0x01, + 0x77, 0xd7, 0xc9, 0x8d, 0x5d, 0x2d, 0x1e, 0x38, 0x76, 0x75, 0x01, 0x26, 0xb7, 0x3c, 0xbf, 0xd9, + 0x89, 0x48, 0xcf, 0x08, 0xd8, 0xc5, 0x4c, 0x39, 0xee, 0xaa, 0xc1, 0x2e, 0xf6, 0x34, 0xbd, 0x7a, + 0x5c, 0x1e, 0xd6, 0x2e, 0xf6, 0x50, 0x00, 0xe6, 0x70, 0xf7, 0xb7, 0x1c, 0xe0, 0x29, 0x8c, 0x66, + 0xb7, 0xb6, 0xfc, 0xc0, 0x4f, 0x76, 0xd1, 0xd7, 0x1c, 0x98, 0x0c, 0xc2, 0x1a, 0x99, 0x0d, 0x12, + 0x5f, 0x02, 0xed, 0xe5, 0x95, 0x67, 0xbc, 0xae, 0x66, 0xc8, 0xf3, 0x7c, 0x18, 0x59, 0x28, 0xee, + 0x6a, 0x86, 0x7b, 0x0e, 0xce, 0xe4, 0x12, 0x70, 0xbf, 0x3f, 0x00, 0x66, 0x26, 0x26, 0xf4, 0x1c, + 0x14, 0x9b, 0x2c, 0x37, 0x88, 0x73, 0xc8, 0x14, 0x5b, 0x6c, 0xac, 0x78, 0xf2, 0x10, 0x4e, 0x09, + 0x2d, 0x40, 0x89, 0xa5, 0x77, 0x12, 0x99, 0x5b, 0x0a, 0x46, 0x4a, 0x84, 0x12, 0x4e, 0x8b, 0x6e, + 0x9b, 0x3f, 0xb1, 0x5e, 0x0d, 0xbd, 0x06, 0xc3, 0x9b, 0x3c, 0xc9, 0xa5, 0x3d, 0x9f, 0x9f, 0xc8, + 0x9a, 0xc9, 0x74, 0x23, 0x99, 0x42, 0xf3, 0x76, 0xfa, 0x2f, 0x96, 0x1c, 0xd1, 0x2e, 0x8c, 0x78, + 0xf2, 0x9b, 0x0e, 0xda, 0xba, 0xa8, 0x61, 0xcc, 0x1f, 0x11, 0x31, 0x23, 0xbf, 0xa1, 0x62, 0x97, + 0x09, 0x2d, 0x2a, 0xf6, 0x15, 0x5a, 0xf4, 0x6d, 0x07, 0x20, 0x7d, 0x11, 0x04, 0xdd, 0x84, 0x91, + 0xf8, 0x69, 0xc3, 0x50, 0x61, 0xe3, 0x86, 0xbe, 0xa0, 0xa8, 0xdd, 0x62, 0x15, 0x10, 0xac, 0xb8, + 0xdd, 0xc9, 0xb8, 0xf2, 0x53, 0x07, 0x4e, 0xe7, 0xbd, 0x5c, 0x72, 0x0f, 0x5b, 0x7c, 0x50, 0xbb, + 0x8a, 0xa8, 0xb0, 0x1e, 0x91, 0x2d, 0xff, 0x66, 0x4e, 0xaa, 0x65, 0x5e, 0x80, 0x53, 0x1c, 0xf7, + 0x4f, 0x87, 0x41, 0x31, 0x3e, 0x22, 0x3b, 0xcc, 0x63, 0xf4, 0xcc, 0x54, 0x4f, 0x75, 0x2e, 0x85, + 0x87, 0x19, 0x14, 0x8b, 0x52, 0x7a, 0x6e, 0x92, 0x41, 0xf1, 0x42, 0x64, 0xb3, 0x59, 0x28, 0x83, + 0xe7, 0xb1, 0x2a, 0xcd, 0xb3, 0xec, 0x14, 0x8f, 0xc5, 0xb2, 0x33, 0x64, 0xdf, 0xb2, 0xd3, 0x02, + 0x14, 0xf3, 0x85, 0xc2, 0xcc, 0x29, 0x82, 0xd1, 0xd8, 0x81, 0x0d, 0xcd, 0x95, 0x2e, 0x22, 0x38, + 0x87, 0x30, 0x8b, 0xa1, 0x08, 0x9b, 0x64, 0x16, 0x5f, 0x15, 0x87, 0x8f, 0x34, 0x86, 0x82, 0x83, + 0xb1, 0x2c, 0x3f, 0xa4, 0x29, 0x05, 0xfd, 0x8e, 0xb3, 0x8f, 0xad, 0x6a, 0xd4, 0xd6, 0x16, 0x94, + 0x9b, 0x06, 0x8f, 0x9d, 0xa4, 0x0e, 0x63, 0x00, 0xfb, 0xba, 0x03, 0x27, 0x49, 0x50, 0x8d, 0x76, + 0x19, 0x1d, 0x41, 0x4d, 0xb8, 0xb8, 0xaf, 0xd9, 0x58, 0xeb, 0x97, 0xb2, 0xc4, 0xb9, 0x27, 0xa9, + 0x0b, 0x8c, 0xbb, 0x9b, 0x81, 0xd6, 0x60, 0xa4, 0xea, 0x89, 0x79, 0x51, 0x3a, 0xc8, 0xbc, 0xe0, + 0x8e, 0xba, 0x59, 0x31, 0x1b, 0x14, 0x11, 0xf7, 0xc7, 0x05, 0x38, 0x95, 0xd3, 0x24, 0x76, 0x5f, + 0xab, 0x45, 0x17, 0xc0, 0x95, 0x5a, 0x76, 0xf9, 0x2f, 0x0b, 0x38, 0x56, 0x18, 0x68, 0x1d, 0x4e, + 0x6f, 0xb7, 0xe2, 0x94, 0xca, 0x7c, 0x18, 0x24, 0xe4, 0xa6, 0x14, 0x06, 0xd2, 0xfd, 0x7d, 0x7a, + 0x39, 0x07, 0x07, 0xe7, 0xd6, 0xa4, 0xda, 0x12, 0x09, 0xbc, 0xcd, 0x26, 0x49, 0x8b, 0xc4, 0x2d, + 0x46, 0xa5, 0x2d, 0x5d, 0xca, 0x94, 0xe3, 0xae, 0x1a, 0xe8, 0xb3, 0x0e, 0x3c, 0x10, 0x93, 0x68, + 0x87, 0x44, 0x15, 0xbf, 0x46, 0xe6, 0x3b, 0x71, 0x12, 0xb6, 0x48, 0x74, 0x48, 0xeb, 0xec, 0xf4, + 0xad, 0xbd, 0xe9, 0x07, 0x2a, 0xbd, 0xa9, 0xe1, 0xfd, 0x58, 0xb9, 0x9f, 0x75, 0x60, 0xa2, 0xc2, + 0xce, 0xee, 0x4a, 0x75, 0xb7, 0x9d, 0x08, 0xf5, 0x31, 0x95, 0x77, 0x23, 0x23, 0x84, 0xcd, 0x4c, + 0x19, 0xee, 0xcb, 0x30, 0x59, 0x21, 0x2d, 0xaf, 0xdd, 0x60, 0x57, 0x90, 0x79, 0xf8, 0xd7, 0x05, + 0x18, 0x8d, 0x25, 0x2c, 0xfb, 0xf6, 0x91, 0x42, 0xc6, 0x29, 0x0e, 0x7a, 0x94, 0x87, 0xaa, 0xc9, + 0x0b, 0x47, 0xa3, 0xfc, 0x90, 0xc3, 0xe3, 0xdb, 0x62, 0x2c, 0xcb, 0xdc, 0xb7, 0x1c, 0x18, 0x4b, + 0xeb, 0x93, 0x2d, 0x54, 0x87, 0x13, 0x55, 0xed, 0xb2, 0x5e, 0x7a, 0x4d, 0xa2, 0xff, 0x7b, 0x7d, + 0x3c, 0x3f, 0xb3, 0x49, 0x04, 0x67, 0xa9, 0x1e, 0x3c, 0xd2, 0xef, 0x0b, 0x05, 0x38, 0xa1, 0x9a, + 0x2a, 0xfc, 0x94, 0x6f, 0x64, 0x03, 0xf2, 0xb0, 0x8d, 0x0c, 0x42, 0xe6, 0xd8, 0xef, 0x13, 0x94, + 0xf7, 0x46, 0x36, 0x28, 0xef, 0x48, 0xd9, 0x77, 0xb9, 0x5e, 0xbf, 0x5d, 0x80, 0x11, 0x95, 0xcf, + 0xe8, 0x39, 0x28, 0xb2, 0x93, 0xeb, 0xdd, 0xe9, 0xdf, 0xec, 0x14, 0x8c, 0x39, 0x25, 0x4a, 0x92, + 0x05, 0xfd, 0x1c, 0x3a, 0x6b, 0xee, 0x28, 0xb7, 0x5f, 0x7a, 0x51, 0x82, 0x39, 0x25, 0xb4, 0x0c, + 0x03, 0x24, 0xa8, 0x09, 0x45, 0xfc, 0xe0, 0x04, 0xd9, 0x2b, 0x65, 0x97, 0x82, 0x1a, 0xa6, 0x54, + 0x58, 0x52, 0x35, 0xae, 0x6f, 0x65, 0xde, 0xa4, 0x11, 0xca, 0x96, 0x28, 0x75, 0xe7, 0xc0, 0x48, + 0xb8, 0x77, 0xa8, 0x9b, 0x11, 0xbf, 0x32, 0x00, 0x43, 0x95, 0xce, 0x26, 0x3d, 0x96, 0x7c, 0xcb, + 0x81, 0x53, 0x37, 0x32, 0x69, 0xa9, 0xd3, 0x75, 0x72, 0xcd, 0x9e, 0x1d, 0x58, 0x0f, 0x5e, 0x53, + 0xd6, 0xaf, 0x9c, 0x42, 0x9c, 0xd7, 0x1c, 0x23, 0x33, 0xec, 0xc0, 0x91, 0x64, 0x86, 0xbd, 0x79, + 0xc4, 0xb7, 0x37, 0xc6, 0x7b, 0xdd, 0xdc, 0x70, 0x7f, 0xbf, 0x08, 0xc0, 0xbf, 0xc6, 0x5a, 0x3b, + 0xe9, 0xc7, 0xb2, 0xf7, 0x0c, 0x8c, 0xd5, 0x49, 0x40, 0x22, 0x19, 0x9a, 0x98, 0x79, 0x32, 0x69, + 0x49, 0x2b, 0xc3, 0x06, 0x26, 0x9b, 0x2c, 0x41, 0x12, 0xed, 0x72, 0x55, 0x3b, 0x7b, 0x43, 0x43, + 0x95, 0x60, 0x0d, 0x0b, 0xcd, 0x18, 0x8e, 0x17, 0xee, 0xc3, 0x9f, 0xd8, 0xc7, 0x4f, 0xf2, 0x3e, + 0x98, 0x30, 0xd3, 0xa8, 0x08, 0x85, 0x4f, 0xf9, 0xdc, 0xcd, 0xec, 0x2b, 0x38, 0x83, 0x4d, 0x17, + 0x42, 0x2d, 0xda, 0xc5, 0x9d, 0x40, 0x68, 0x7e, 0x6a, 0x21, 0x2c, 0x30, 0x28, 0x16, 0xa5, 0x2c, + 0xff, 0x04, 0xdb, 0x03, 0x39, 0x5c, 0xe4, 0xb0, 0x48, 0xf3, 0x4f, 0x68, 0x65, 0xd8, 0xc0, 0xa4, + 0x1c, 0x84, 0x65, 0x14, 0xcc, 0xa5, 0x96, 0x31, 0x67, 0xb6, 0x61, 0x22, 0x34, 0x2d, 0x3a, 0x5c, + 0x0d, 0x7a, 0x57, 0x9f, 0x53, 0xcf, 0xa8, 0xcb, 0x63, 0x25, 0x32, 0x06, 0xa0, 0x0c, 0x7d, 0xaa, + 0xfa, 0xea, 0x17, 0x19, 0xc6, 0xcc, 0xc8, 0xd6, 0x9e, 0x77, 0x0d, 0xd6, 0xe1, 0x74, 0x3b, 0xac, + 0xad, 0x47, 0x7e, 0x18, 0xf9, 0xc9, 0xee, 0x7c, 0xd3, 0x8b, 0x63, 0x36, 0x31, 0xc6, 0x4d, 0x95, + 0x68, 0x3d, 0x07, 0x07, 0xe7, 0xd6, 0xa4, 0x67, 0xa2, 0xb6, 0x00, 0xb2, 0xf8, 0xb2, 0x22, 0x57, + 0xea, 0x24, 0x22, 0x56, 0xa5, 0xee, 0x29, 0x38, 0x59, 0xe9, 0xb4, 0xdb, 0x4d, 0x9f, 0xd4, 0x94, + 0x63, 0xc3, 0x7d, 0x3f, 0x9c, 0x10, 0x79, 0x63, 0x95, 0x02, 0x72, 0xa0, 0x2c, 0xe7, 0xee, 0x7f, + 0x1c, 0x80, 0x13, 0x99, 0x68, 0x1e, 0xf4, 0x5a, 0x56, 0x6d, 0xb0, 0x93, 0xcf, 0x54, 0x53, 0x18, + 0x44, 0x72, 0xd2, 0x3c, 0x15, 0xa4, 0x21, 0x43, 0xf1, 0xad, 0x5d, 0x81, 0x61, 0x01, 0xeb, 0x7c, + 0x57, 0x31, 0xe2, 0xf9, 0x3f, 0x0a, 0xa0, 0xd8, 0xca, 0x5b, 0xf7, 0xb6, 0xfb, 0xc9, 0xd6, 0xaf, + 0x82, 0xc4, 0x58, 0xe3, 0x88, 0x02, 0x18, 0x66, 0x0d, 0x21, 0xf2, 0xde, 0xa5, 0xb5, 0xbe, 0x32, + 0xad, 0x6d, 0x95, 0xd3, 0xc6, 0x92, 0x89, 0xfb, 0x99, 0x02, 0xe4, 0x87, 0x8c, 0xa1, 0x8f, 0x76, + 0x7f, 0xf0, 0xe7, 0x2c, 0x0e, 0x84, 0x88, 0x59, 0xeb, 0xfd, 0xcd, 0x03, 0xf3, 0x9b, 0xaf, 0x5a, + 0x1a, 0x07, 0xc1, 0xb7, 0xeb, 0xcb, 0xbb, 0xff, 0xc3, 0x81, 0xd2, 0xc6, 0xc6, 0x8a, 0xda, 0xda, + 0x31, 0x9c, 0x8d, 0x79, 0x4a, 0x03, 0xe6, 0x59, 0x9f, 0x0f, 0x5b, 0x6d, 0xee, 0x68, 0x17, 0x01, + 0x00, 0x2c, 0x65, 0x71, 0x25, 0x17, 0x03, 0xf7, 0xa8, 0x89, 0xae, 0xc0, 0x29, 0xbd, 0xa4, 0xa2, + 0xbd, 0x10, 0x59, 0x14, 0xe9, 0x89, 0xba, 0x8b, 0x71, 0x5e, 0x9d, 0x2c, 0x29, 0x61, 0x50, 0x66, + 0xdb, 0x73, 0x0e, 0x29, 0x51, 0x8c, 0xf3, 0xea, 0xb8, 0x6b, 0x50, 0xda, 0xf0, 0x22, 0xd5, 0xf1, + 0x0f, 0xc0, 0x64, 0x35, 0x6c, 0x49, 0x75, 0x65, 0x85, 0xec, 0x90, 0xa6, 0xe8, 0x32, 0x7f, 0x96, + 0x25, 0x53, 0x86, 0xbb, 0xb0, 0xdd, 0xff, 0x7a, 0x1e, 0xd4, 0x15, 0xcd, 0x3e, 0x76, 0xd4, 0xb6, + 0x0a, 0xa6, 0x2d, 0x5a, 0x0e, 0xa6, 0x55, 0x7b, 0x4b, 0x26, 0xa0, 0x36, 0x49, 0x03, 0x6a, 0x87, + 0x6c, 0x07, 0xd4, 0x2a, 0x25, 0xbb, 0x2b, 0xa8, 0xf6, 0x2b, 0x0e, 0x8c, 0x05, 0x61, 0x8d, 0x28, + 0x0f, 0xe8, 0x30, 0x5b, 0xe1, 0x2f, 0xd9, 0xbb, 0x9b, 0xc0, 0x83, 0x43, 0x05, 0x79, 0x1e, 0xe8, + 0xad, 0xb6, 0x64, 0xbd, 0x08, 0x1b, 0xed, 0x40, 0x8b, 0x9a, 0x69, 0x99, 0x7b, 0x70, 0x1e, 0xcc, + 0x3b, 0xa2, 0xdd, 0xd1, 0x4e, 0x7c, 0x53, 0xd3, 0x13, 0x47, 0x6d, 0x99, 0x4c, 0xe5, 0xbd, 0x3b, + 0xcd, 0x11, 0x25, 0xb3, 0x6e, 0xa7, 0xfa, 0xa3, 0x0b, 0x43, 0x3c, 0x22, 0x5c, 0x24, 0xc2, 0x62, + 0xfe, 0x51, 0x1e, 0x2d, 0x8e, 0x45, 0x09, 0x4a, 0x64, 0x94, 0x45, 0xc9, 0xd6, 0x1b, 0x1a, 0x46, + 0x14, 0x47, 0x7e, 0x98, 0x05, 0x7a, 0x56, 0x3f, 0xfa, 0x8f, 0xf5, 0x73, 0xf4, 0x1f, 0xef, 0x79, + 0xec, 0xff, 0xbc, 0x03, 0x63, 0x55, 0xed, 0x4d, 0x8b, 0xf2, 0xe3, 0xb6, 0xde, 0xee, 0xce, 0x7b, + 0x7a, 0x84, 0xbb, 0xdd, 0x8c, 0x37, 0x34, 0x0c, 0xee, 0x2c, 0xfb, 0x27, 0xb3, 0x73, 0x30, 0x55, + 0xc7, 0x4a, 0x62, 0x0e, 0xd3, 0x6e, 0x22, 0xa3, 0x55, 0x29, 0x0c, 0x0b, 0x5e, 0xe8, 0x75, 0x18, + 0x91, 0x97, 0x0a, 0x44, 0xf0, 0x3d, 0xb6, 0xe1, 0x07, 0x31, 0x9d, 0xad, 0x32, 0x65, 0x20, 0x87, + 0x62, 0xc5, 0x11, 0x35, 0x60, 0xa0, 0xe6, 0xd5, 0x45, 0x18, 0xfe, 0xaa, 0x9d, 0x94, 0xac, 0x92, + 0x27, 0x3b, 0x92, 0x2e, 0xcc, 0x2e, 0x61, 0xca, 0x02, 0xdd, 0x4c, 0x1f, 0x05, 0x98, 0xb4, 0xb6, + 0xfb, 0x9a, 0x6a, 0x21, 0xd7, 0x09, 0xba, 0xde, 0x18, 0xa8, 0x09, 0xff, 0xf4, 0xff, 0xc7, 0xd8, + 0x2e, 0xda, 0xc9, 0xe9, 0xca, 0x13, 0xbd, 0xa4, 0x3e, 0x6e, 0xca, 0xa5, 0x91, 0x24, 0xed, 0xf2, + 0xcf, 0xdb, 0xe2, 0xc2, 0xd2, 0x95, 0xf0, 0x67, 0xd6, 0x37, 0x36, 0xd6, 0x31, 0xa3, 0x8e, 0x9a, + 0x30, 0xd4, 0x66, 0xa1, 0x33, 0xe5, 0x5f, 0xb0, 0xb5, 0xb7, 0xf0, 0x50, 0x1c, 0x3e, 0x37, 0xf9, + 0xff, 0x58, 0xf0, 0x40, 0x97, 0x60, 0x98, 0xbf, 0x6d, 0xc3, 0xaf, 0x41, 0x94, 0x2e, 0x4e, 0xf5, + 0x7e, 0x21, 0x27, 0xdd, 0x28, 0xf8, 0xef, 0x18, 0xcb, 0xba, 0xe8, 0x0b, 0x0e, 0x4c, 0x50, 0x89, + 0x9a, 0x3e, 0xc6, 0x53, 0x46, 0xb6, 0x64, 0xd6, 0xb5, 0x98, 0x6a, 0x24, 0x52, 0xd6, 0xa8, 0x63, + 0xe1, 0x15, 0x83, 0x1d, 0xce, 0xb0, 0x47, 0x6f, 0xc0, 0x48, 0xec, 0xd7, 0x48, 0xd5, 0x8b, 0xe2, + 0xf2, 0xa9, 0xa3, 0x69, 0x4a, 0xea, 0x11, 0x13, 0x8c, 0xb0, 0x62, 0x89, 0x7e, 0x9d, 0xbd, 0x86, + 0x5a, 0x6d, 0xf8, 0x3b, 0x64, 0x25, 0xac, 0xf2, 0x63, 0xcc, 0x69, 0x5b, 0x6b, 0x5f, 0xfa, 0xfe, + 0x24, 0x65, 0xe1, 0x28, 0x32, 0xd9, 0xe1, 0x2c, 0x7f, 0xf4, 0x37, 0x1c, 0x38, 0xc3, 0x5f, 0x2d, + 0xc8, 0x3e, 0xc4, 0x71, 0xe6, 0x90, 0x26, 0x29, 0x76, 0x7f, 0x63, 0x36, 0x8f, 0x24, 0xce, 0xe7, + 0xc4, 0x72, 0x0c, 0x9b, 0x6f, 0x27, 0x9d, 0xb5, 0xea, 0x19, 0xee, 0xff, 0xbd, 0x24, 0xf4, 0x14, + 0x94, 0xda, 0x62, 0x3b, 0xf4, 0xe3, 0x16, 0xbb, 0x8d, 0x33, 0xc0, 0xef, 0x49, 0xae, 0xa7, 0x60, + 0xac, 0xe3, 0x18, 0x09, 0xa7, 0x9f, 0xd8, 0x2f, 0xe1, 0x34, 0xba, 0x06, 0xa5, 0x24, 0x6c, 0x8a, + 0x9c, 0xab, 0x71, 0xb9, 0xcc, 0x66, 0xe0, 0xf9, 0xbc, 0xb5, 0xb5, 0xa1, 0xd0, 0xd2, 0x93, 0x7b, + 0x0a, 0x8b, 0xb1, 0x4e, 0x87, 0x45, 0x40, 0x8b, 0xd7, 0x20, 0x22, 0x76, 0x64, 0xbf, 0x3f, 0x13, + 0x01, 0xad, 0x17, 0x62, 0x13, 0x17, 0x2d, 0xc1, 0xc9, 0x76, 0xd7, 0x99, 0x9f, 0xdf, 0x02, 0x54, + 0x41, 0x27, 0xdd, 0x07, 0xfe, 0xee, 0x3a, 0xc6, 0x69, 0xff, 0x81, 0xfd, 0x4e, 0xfb, 0x3d, 0xd2, + 0x2f, 0x3f, 0x78, 0x98, 0xf4, 0xcb, 0xa8, 0x06, 0x0f, 0x7a, 0x9d, 0x24, 0x64, 0x29, 0x79, 0xcc, + 0x2a, 0x3c, 0x18, 0xfc, 0x61, 0x1e, 0x5f, 0x7e, 0x6b, 0x6f, 0xfa, 0xc1, 0xd9, 0x7d, 0xf0, 0xf0, + 0xbe, 0x54, 0xd0, 0xab, 0x30, 0x42, 0x44, 0x0a, 0xe9, 0xf2, 0xcf, 0xd9, 0x52, 0x12, 0xcc, 0xa4, + 0xd4, 0x32, 0xce, 0x96, 0xc3, 0xb0, 0xe2, 0x87, 0x36, 0xa0, 0xd4, 0x08, 0xe3, 0x64, 0xb6, 0xe9, + 0x7b, 0x31, 0x89, 0xcb, 0x0f, 0xb1, 0x49, 0x93, 0xab, 0x7b, 0x5d, 0x96, 0x68, 0xe9, 0x9c, 0xb9, + 0x9c, 0xd6, 0xc4, 0x3a, 0x19, 0x44, 0x98, 0x7f, 0x98, 0x45, 0xc2, 0x4b, 0xdf, 0xd7, 0x79, 0xd6, + 0xb1, 0xc7, 0xf2, 0x28, 0xaf, 0x87, 0xb5, 0x8a, 0x89, 0xad, 0x1c, 0xc4, 0x3a, 0x10, 0x67, 0x69, + 0xa2, 0x67, 0x60, 0xac, 0x1d, 0xd6, 0x2a, 0x6d, 0x52, 0x5d, 0xf7, 0x92, 0x6a, 0xa3, 0x3c, 0x6d, + 0x5a, 0x19, 0xd7, 0xb5, 0x32, 0x6c, 0x60, 0xa2, 0x36, 0x0c, 0xb7, 0x78, 0xae, 0x86, 0xf2, 0x23, + 0xb6, 0xce, 0x36, 0x22, 0xf9, 0x83, 0xb0, 0x21, 0xf0, 0x1f, 0x58, 0xb2, 0x41, 0x7f, 0xdf, 0x81, + 0x13, 0x99, 0xfb, 0x65, 0xe5, 0x77, 0x58, 0x53, 0x59, 0x4c, 0xc2, 0x73, 0x8f, 0xb1, 0xe1, 0x33, + 0x81, 0xb7, 0xbb, 0x41, 0x38, 0xdb, 0x22, 0x3e, 0x2e, 0x2c, 0xe1, 0x4a, 0xf9, 0x51, 0x7b, 0xe3, + 0xc2, 0x08, 0xca, 0x71, 0x61, 0x3f, 0xb0, 0x64, 0x83, 0x9e, 0x80, 0x61, 0x91, 0x1b, 0xb1, 0xfc, + 0x98, 0xe9, 0x75, 0x17, 0x29, 0x14, 0xb1, 0x2c, 0x9f, 0x7a, 0x3f, 0x9c, 0xec, 0x3a, 0xba, 0x1d, + 0x28, 0xeb, 0xc7, 0x6f, 0x3a, 0xa0, 0x5f, 0x48, 0xb7, 0xfe, 0x6e, 0xcb, 0x33, 0x30, 0x56, 0xe5, + 0xcf, 0x68, 0xf2, 0x2b, 0xed, 0x83, 0xa6, 0xbd, 0x77, 0x5e, 0x2b, 0xc3, 0x06, 0xa6, 0x7b, 0x19, + 0x50, 0x77, 0x52, 0xfd, 0x43, 0x39, 0x4e, 0xfe, 0xa1, 0x03, 0xe3, 0x86, 0xce, 0x60, 0xdd, 0xaf, + 0xba, 0x08, 0xa8, 0xe5, 0x47, 0x51, 0x18, 0xe9, 0xef, 0x15, 0x8a, 0xb4, 0x13, 0x2c, 0xde, 0x62, + 0xb5, 0xab, 0x14, 0xe7, 0xd4, 0x70, 0xff, 0xf1, 0x20, 0xa4, 0x81, 0xe6, 0x2a, 0x6b, 0xb1, 0xd3, + 0x33, 0x6b, 0xf1, 0x93, 0x30, 0xf2, 0x72, 0x1c, 0x06, 0xeb, 0x69, 0x6e, 0x63, 0xf5, 0x2d, 0x9e, + 0xad, 0xac, 0x5d, 0x65, 0x98, 0x0a, 0x83, 0x61, 0xbf, 0xb2, 0xe8, 0x37, 0x93, 0xee, 0xe4, 0xb7, + 0xcf, 0x3e, 0xc7, 0xe1, 0x58, 0x61, 0xb0, 0xa7, 0x0b, 0x77, 0x88, 0x72, 0x04, 0xa4, 0x4f, 0x17, + 0xf2, 0xf7, 0x32, 0x58, 0x19, 0xba, 0x00, 0xa3, 0xca, 0x89, 0x20, 0x3c, 0x13, 0x6a, 0xa4, 0x94, + 0xa7, 0x01, 0xa7, 0x38, 0x4c, 0x21, 0x14, 0x86, 0x67, 0x61, 0x42, 0xa9, 0xd8, 0x38, 0x9e, 0x64, + 0x4c, 0xd9, 0x5c, 0xb6, 0x4b, 0x30, 0x56, 0x2c, 0xf3, 0x7c, 0xcb, 0xa3, 0x47, 0xe2, 0x5b, 0xd6, + 0x6e, 0x3d, 0x14, 0xfb, 0xbd, 0xf5, 0x60, 0xce, 0xed, 0x91, 0xbe, 0xe6, 0xf6, 0xa7, 0x06, 0x60, + 0xf8, 0x79, 0x12, 0xb1, 0x9c, 0xef, 0x4f, 0xc0, 0xf0, 0x0e, 0xff, 0x37, 0x7b, 0x65, 0x56, 0x60, + 0x60, 0x59, 0x4e, 0xbf, 0xdb, 0x66, 0xc7, 0x6f, 0xd6, 0x16, 0xd2, 0x55, 0x9c, 0xa6, 0x75, 0x94, + 0x05, 0x38, 0xc5, 0xa1, 0x15, 0xea, 0x54, 0xb3, 0x6f, 0xb5, 0xfc, 0xae, 0x57, 0xf9, 0x97, 0x64, + 0x01, 0x4e, 0x71, 0xd0, 0x63, 0x30, 0x54, 0xf7, 0x93, 0x0d, 0xaf, 0x9e, 0xf5, 0x8c, 0x2e, 0x31, + 0x28, 0x16, 0xa5, 0xcc, 0x2d, 0xe6, 0x27, 0x1b, 0x11, 0x61, 0x96, 0xdd, 0xae, 0x8c, 0x1d, 0x4b, + 0x5a, 0x19, 0x36, 0x30, 0x59, 0x93, 0x42, 0xd1, 0x33, 0x11, 0x27, 0x9b, 0x36, 0x49, 0x16, 0xe0, + 0x14, 0x87, 0xce, 0xff, 0x6a, 0xd8, 0x6a, 0xfb, 0x4d, 0x11, 0xc1, 0xad, 0xcd, 0xff, 0x79, 0x01, + 0xc7, 0x0a, 0x83, 0x62, 0x53, 0x11, 0x46, 0xc5, 0x4f, 0xf6, 0x99, 0xb8, 0x75, 0x01, 0xc7, 0x0a, + 0xc3, 0x7d, 0x1e, 0xc6, 0xf9, 0x4a, 0x9e, 0x6f, 0x7a, 0x7e, 0x6b, 0x69, 0x1e, 0x5d, 0xea, 0xba, + 0xf5, 0xf0, 0x44, 0xce, 0xad, 0x87, 0x33, 0x46, 0xa5, 0xee, 0xdb, 0x0f, 0xee, 0x0f, 0x0b, 0x30, + 0x72, 0x8c, 0x2f, 0x6d, 0x1e, 0xfb, 0xa3, 0xd1, 0xe8, 0x66, 0xe6, 0x95, 0xcd, 0x75, 0x9b, 0x97, + 0x98, 0xf6, 0x7d, 0x61, 0xf3, 0x3f, 0x15, 0xe0, 0xac, 0x44, 0x95, 0x67, 0xb9, 0xa5, 0x79, 0xf6, + 0x7a, 0xd9, 0xd1, 0x0f, 0x74, 0x64, 0x0c, 0xf4, 0xba, 0xbd, 0xd3, 0xe8, 0xd2, 0x7c, 0xcf, 0xa1, + 0x7e, 0x35, 0x33, 0xd4, 0xd8, 0x2a, 0xd7, 0xfd, 0x07, 0xfb, 0xcf, 0x1d, 0x98, 0xca, 0x1f, 0xec, + 0x63, 0x78, 0xd8, 0xf4, 0x0d, 0xf3, 0x61, 0xd3, 0x5f, 0xb2, 0x37, 0xc5, 0xcc, 0xae, 0xf4, 0x78, + 0xe2, 0xf4, 0xbf, 0x3b, 0x70, 0x5a, 0x56, 0x60, 0xbb, 0xe7, 0x9c, 0x1f, 0xb0, 0xe0, 0x9d, 0xa3, + 0x9f, 0x66, 0xaf, 0x1b, 0xd3, 0xec, 0x45, 0x7b, 0x1d, 0xd7, 0xfb, 0xd1, 0xf3, 0x41, 0xf8, 0x3f, + 0x73, 0xa0, 0x9c, 0x57, 0xe1, 0x18, 0x3e, 0xf9, 0x6b, 0xe6, 0x27, 0x7f, 0xfe, 0x68, 0x7a, 0xde, + 0xfb, 0x83, 0x97, 0x7b, 0x0d, 0x14, 0x6a, 0x4a, 0xbd, 0xca, 0xb1, 0xe5, 0x93, 0xe6, 0x2c, 0xf2, + 0x15, 0xb4, 0x26, 0x0c, 0xc5, 0x2c, 0x4a, 0x45, 0x4c, 0x81, 0xcb, 0x36, 0xb4, 0x2d, 0x4a, 0x4f, + 0xd8, 0xd8, 0xd9, 0xff, 0x58, 0xf0, 0x70, 0x7f, 0xab, 0x00, 0xe7, 0xd4, 0x83, 0xc5, 0x64, 0x87, + 0x34, 0xd3, 0xf5, 0xc1, 0x5e, 0xc8, 0xf0, 0xd4, 0x4f, 0x7b, 0x2f, 0x64, 0xa4, 0x2c, 0xd2, 0xb5, + 0x90, 0xc2, 0xb0, 0xc6, 0x13, 0x55, 0xe0, 0x0c, 0x7b, 0xd1, 0x62, 0xd1, 0x0f, 0xbc, 0xa6, 0xff, + 0x2a, 0x89, 0x30, 0x69, 0x85, 0x3b, 0x5e, 0x53, 0x68, 0xea, 0xea, 0xd6, 0xf4, 0x62, 0x1e, 0x12, + 0xce, 0xaf, 0xdb, 0x75, 0xe2, 0x1e, 0xe8, 0xf7, 0xc4, 0xed, 0xfe, 0x89, 0x03, 0x63, 0xc7, 0xf8, + 0xbc, 0x73, 0x68, 0x2e, 0x89, 0x67, 0xed, 0x2d, 0x89, 0x1e, 0xcb, 0x60, 0xaf, 0x08, 0x5d, 0x2f, + 0xde, 0xa2, 0x4f, 0x3b, 0x2a, 0x8e, 0x87, 0xc7, 0x4b, 0x7e, 0xc8, 0x5e, 0x3b, 0x0e, 0x92, 0x6a, + 0x13, 0x7d, 0x3d, 0x93, 0x7f, 0xb4, 0x60, 0x2b, 0x89, 0x56, 0x57, 0x6b, 0x0e, 0x91, 0x87, 0xf4, + 0x2b, 0x0e, 0x00, 0x6f, 0xa7, 0x48, 0x5f, 0x4e, 0xdb, 0xb6, 0x79, 0x64, 0x23, 0x45, 0x99, 0xf0, + 0xa6, 0xa9, 0x25, 0x94, 0x16, 0x60, 0xad, 0x25, 0x77, 0x91, 0x60, 0xf4, 0xae, 0x73, 0x9b, 0x7e, + 0xc1, 0x81, 0x13, 0x99, 0xe6, 0xe6, 0xd4, 0xdf, 0x32, 0x1f, 0x68, 0xb4, 0xa0, 0x59, 0x99, 0x49, + 0xad, 0x75, 0xe3, 0xc9, 0x7f, 0x71, 0xc1, 0x78, 0x2a, 0x1c, 0xbd, 0x06, 0xa3, 0xd2, 0xf2, 0x21, + 0xa7, 0xb7, 0xcd, 0x87, 0x6a, 0xd5, 0xf1, 0x46, 0x42, 0x62, 0x9c, 0xf2, 0xcb, 0x84, 0x09, 0x16, + 0xfa, 0x0a, 0x13, 0xbc, 0xb7, 0xcf, 0xdc, 0xe6, 0xdb, 0xa5, 0x07, 0x8f, 0xc4, 0x2e, 0xfd, 0xa0, + 0x75, 0xbb, 0xf4, 0x43, 0xc7, 0x6c, 0x97, 0xd6, 0x9c, 0x84, 0xc5, 0xbb, 0x70, 0x12, 0xbe, 0x06, + 0xa7, 0x77, 0xd2, 0x43, 0xa7, 0x9a, 0x49, 0x22, 0x75, 0xd3, 0x13, 0xb9, 0xd6, 0x68, 0x7a, 0x80, + 0x8e, 0x13, 0x12, 0x24, 0xda, 0x71, 0x35, 0x8d, 0x50, 0x7c, 0x3e, 0x87, 0x1c, 0xce, 0x65, 0x92, + 0xf5, 0xf6, 0x0c, 0xf7, 0xe1, 0xed, 0x79, 0xcb, 0x81, 0x33, 0x5e, 0xd7, 0x35, 0x3b, 0x4c, 0xb6, + 0x44, 0xc8, 0xc9, 0x75, 0x7b, 0x2a, 0x84, 0x41, 0x5e, 0xb8, 0xd5, 0xf2, 0x8a, 0x70, 0x7e, 0x83, + 0xd0, 0xa3, 0xa9, 0xeb, 0x9d, 0xc7, 0xb5, 0xe6, 0xfb, 0xc9, 0xbf, 0x9e, 0x8d, 0xe7, 0x01, 0x36, + 0xf4, 0x1f, 0xb1, 0x7b, 0xda, 0xb6, 0x10, 0xd3, 0x53, 0xba, 0x8b, 0x98, 0x9e, 0x8c, 0xeb, 0x6d, + 0xcc, 0x92, 0xeb, 0x2d, 0x80, 0x49, 0xbf, 0xe5, 0xd5, 0xc9, 0x7a, 0xa7, 0xd9, 0xe4, 0xf7, 0x66, + 0xe4, 0x53, 0xc2, 0xb9, 0x16, 0xbc, 0x95, 0xb0, 0xea, 0x35, 0xb3, 0x8f, 0xc8, 0xab, 0xfb, 0x41, + 0x57, 0x32, 0x94, 0x70, 0x17, 0x6d, 0x3a, 0x61, 0x59, 0x0e, 0x41, 0x92, 0xd0, 0xd1, 0x66, 0x81, + 0x23, 0x23, 0x7c, 0xc2, 0x5e, 0x4e, 0xc1, 0x58, 0xc7, 0x41, 0xcb, 0x30, 0x5a, 0x0b, 0x62, 0x71, + 0x63, 0xf8, 0x04, 0x13, 0x66, 0xef, 0xa4, 0x22, 0x70, 0xe1, 0x6a, 0x45, 0xdd, 0x15, 0x7e, 0x30, + 0x27, 0x29, 0xa6, 0x2a, 0xc7, 0x69, 0x7d, 0xb4, 0xca, 0x88, 0x89, 0x77, 0xd6, 0x78, 0x3c, 0xc7, + 0xc3, 0x3d, 0x1c, 0x46, 0x0b, 0x57, 0xe5, 0x4b, 0x71, 0xe3, 0x82, 0x9d, 0x78, 0x30, 0x2d, 0xa5, + 0xa0, 0x3d, 0xe9, 0x7c, 0x72, 0xdf, 0x27, 0x9d, 0x59, 0x36, 0xdc, 0xa4, 0xa9, 0xdc, 0xc3, 0xe7, + 0xad, 0x65, 0xc3, 0x4d, 0x23, 0x25, 0x45, 0x36, 0xdc, 0x14, 0x80, 0x75, 0x96, 0x68, 0xad, 0x97, + 0x9b, 0xfc, 0x14, 0x13, 0x1a, 0x07, 0x77, 0x7a, 0xeb, 0xfe, 0xd2, 0xd3, 0xfb, 0xfa, 0x4b, 0xbb, + 0xfc, 0xbb, 0x67, 0x0e, 0xe0, 0xdf, 0x6d, 0xb0, 0x3c, 0xa5, 0x4b, 0xf3, 0xc2, 0xa5, 0x6e, 0xe1, + 0x7c, 0xc7, 0x32, 0xa3, 0xf0, 0xc8, 0x53, 0xf6, 0x2f, 0xe6, 0x0c, 0x7a, 0x06, 0x90, 0x9f, 0x3b, + 0x74, 0x00, 0x39, 0x15, 0xcf, 0x29, 0x9c, 0x25, 0xbc, 0x2d, 0x0a, 0xf1, 0x9c, 0x82, 0xb1, 0x8e, + 0x93, 0xf5, 0x96, 0xde, 0x7f, 0x64, 0xde, 0xd2, 0xa9, 0x63, 0xf0, 0x96, 0x3e, 0xd0, 0xb7, 0xb7, + 0xf4, 0x26, 0x9c, 0x6a, 0x87, 0xb5, 0x05, 0x3f, 0x8e, 0x3a, 0xec, 0x22, 0xe1, 0x5c, 0xa7, 0x56, + 0x27, 0x09, 0x73, 0xb7, 0x96, 0x2e, 0xbe, 0x53, 0x6f, 0x64, 0x9b, 0x2d, 0x64, 0xb9, 0x46, 0x33, + 0x15, 0x98, 0xe9, 0x84, 0x45, 0xdd, 0xe6, 0x14, 0xe2, 0x3c, 0x16, 0xba, 0x9f, 0xf6, 0xe1, 0xe3, + 0xf1, 0xd3, 0x7e, 0x00, 0x46, 0xe2, 0x46, 0x27, 0xa9, 0x85, 0x37, 0x02, 0xe6, 0x8c, 0x1f, 0x9d, + 0x7b, 0x87, 0x32, 0x65, 0x0b, 0xf8, 0xed, 0xbd, 0xe9, 0x49, 0xf9, 0xbf, 0x66, 0xc5, 0x16, 0x10, + 0xf4, 0x8d, 0x1e, 0xf7, 0x95, 0xdc, 0xa3, 0xbc, 0xaf, 0x74, 0xee, 0x40, 0x77, 0x95, 0xf2, 0x9c, + 0xd1, 0x8f, 0xfc, 0xcc, 0x39, 0xa3, 0xbf, 0xe6, 0xc0, 0xf8, 0x8e, 0xee, 0x32, 0x10, 0x0e, 0x73, + 0x0b, 0x81, 0x3b, 0x86, 0x27, 0x62, 0xce, 0xa5, 0x72, 0xce, 0x00, 0xdd, 0xce, 0x02, 0xb0, 0xd9, + 0x92, 0x9c, 0xa0, 0xa2, 0x47, 0xef, 0x55, 0x50, 0xd1, 0x1b, 0x4c, 0x8e, 0xc9, 0x43, 0x2e, 0xf3, + 0xa2, 0xdb, 0x8d, 0x29, 0x96, 0x32, 0x51, 0x85, 0x14, 0xeb, 0xfc, 0xd0, 0xe7, 0x1d, 0x98, 0x94, + 0xe7, 0x32, 0xe1, 0xf2, 0x8b, 0x45, 0x54, 0xa4, 0xcd, 0xe3, 0x20, 0x0b, 0xab, 0xdf, 0xc8, 0xf0, + 0xc1, 0x5d, 0x9c, 0xa9, 0x54, 0x57, 0x41, 0x68, 0xf5, 0x98, 0x05, 0xff, 0x0a, 0x1d, 0x66, 0x36, + 0x05, 0x63, 0x1d, 0x07, 0x7d, 0xd3, 0x81, 0x62, 0x23, 0x0c, 0xb7, 0xe3, 0xf2, 0x13, 0x4c, 0xa0, + 0xbf, 0x60, 0x59, 0x37, 0xbd, 0x4c, 0x69, 0x73, 0xa5, 0xf4, 0x29, 0x69, 0x3b, 0x62, 0xb0, 0xdb, + 0x7b, 0xd3, 0x13, 0xc6, 0x73, 0x4e, 0xf1, 0x9b, 0x6f, 0x6b, 0x10, 0x61, 0xdb, 0x64, 0x4d, 0x43, + 0x5f, 0x72, 0x60, 0xf2, 0x46, 0xc6, 0xa0, 0x21, 0xc2, 0x42, 0xb1, 0x7d, 0x53, 0x09, 0x1f, 0xee, + 0x2c, 0x14, 0x77, 0xb5, 0x00, 0x7d, 0xce, 0x34, 0x74, 0xf2, 0xf8, 0x51, 0x8b, 0x03, 0x98, 0x31, + 0xac, 0xf2, 0x6b, 0x41, 0xf9, 0x16, 0xcf, 0xbb, 0x8e, 0x0f, 0x99, 0xa2, 0x9d, 0x49, 0x3f, 0x56, + 0x4e, 0x55, 0x62, 0xda, 0x5b, 0x2c, 0x2c, 0x76, 0xe3, 0xf3, 0xeb, 0xe6, 0x96, 0x2f, 0x9d, 0x85, + 0x09, 0xd3, 0xb7, 0x87, 0xde, 0x65, 0x3e, 0xd5, 0x71, 0x3e, 0xfb, 0xea, 0xc1, 0xb8, 0xc4, 0x37, + 0x5e, 0x3e, 0x30, 0x9e, 0x26, 0x28, 0x1c, 0xe9, 0xd3, 0x04, 0x03, 0xc7, 0xf3, 0x34, 0xc1, 0xe4, + 0x51, 0x3c, 0x4d, 0x70, 0xf2, 0x40, 0x4f, 0x13, 0x68, 0x4f, 0x43, 0x0c, 0xde, 0xe1, 0x69, 0x88, + 0x59, 0x38, 0x21, 0xef, 0xfe, 0x10, 0x91, 0xfd, 0x9d, 0xbb, 0xfd, 0xcf, 0x89, 0x2a, 0x27, 0xe6, + 0xcd, 0x62, 0x9c, 0xc5, 0xa7, 0x8b, 0xac, 0x18, 0xb0, 0x9a, 0x43, 0xb6, 0xde, 0x8d, 0x32, 0xa7, + 0x16, 0x3b, 0x3e, 0x0b, 0x11, 0x25, 0xa3, 0x9d, 0x8b, 0x0c, 0x76, 0x5b, 0xfe, 0x83, 0x79, 0x0b, + 0xd0, 0x4b, 0x50, 0x0e, 0xb7, 0xb6, 0x9a, 0xa1, 0x57, 0x4b, 0xdf, 0x4f, 0x90, 0x71, 0x09, 0xfc, + 0xae, 0xaa, 0x4a, 0xb7, 0xbb, 0xd6, 0x03, 0x0f, 0xf7, 0xa4, 0x80, 0xde, 0xa2, 0x8a, 0x49, 0x12, + 0x46, 0xa4, 0x96, 0xda, 0x6a, 0x46, 0x59, 0x9f, 0x89, 0xf5, 0x3e, 0x57, 0x4c, 0x3e, 0xbc, 0xf7, + 0xea, 0xa3, 0x64, 0x4a, 0x71, 0xb6, 0x59, 0x28, 0x82, 0xb3, 0xed, 0x3c, 0x53, 0x51, 0x2c, 0x6e, + 0x2c, 0xed, 0x67, 0xb0, 0x52, 0x6f, 0x69, 0xe7, 0x1a, 0x9b, 0x62, 0xdc, 0x83, 0xb2, 0xfe, 0xc6, + 0xc1, 0xc8, 0xf1, 0xbc, 0x71, 0xf0, 0x31, 0x80, 0xaa, 0xcc, 0xb6, 0x26, 0x8d, 0x0f, 0xcb, 0x56, + 0xae, 0xd2, 0x70, 0x9a, 0xda, 0xb3, 0xb2, 0x8a, 0x0d, 0xd6, 0x58, 0xa2, 0xff, 0x9d, 0xfb, 0x08, + 0x08, 0xb7, 0xb0, 0xd4, 0xad, 0xcf, 0x89, 0x9f, 0xb9, 0x87, 0x40, 0xfe, 0x81, 0x03, 0x53, 0x7c, + 0xe6, 0x65, 0x95, 0x7b, 0xaa, 0x5a, 0x88, 0xbb, 0x3d, 0xb6, 0x43, 0x57, 0x78, 0xd6, 0x24, 0x83, + 0x2b, 0x73, 0x74, 0xef, 0xd3, 0x12, 0xf4, 0x95, 0x9c, 0x23, 0xc5, 0x09, 0x5b, 0x36, 0xcb, 0xfc, + 0xa7, 0x1c, 0x4e, 0xdd, 0xea, 0xe7, 0x14, 0xf1, 0x8f, 0x7a, 0x9a, 0x54, 0x11, 0x6b, 0xde, 0x2f, + 0x1f, 0x91, 0x49, 0x55, 0x7f, 0x6f, 0xe2, 0x40, 0x86, 0xd5, 0x2f, 0x38, 0x30, 0xe9, 0x65, 0x42, + 0x4d, 0x98, 0x1d, 0xc8, 0x8a, 0x4d, 0x6a, 0x36, 0x4a, 0xe3, 0x57, 0x98, 0x92, 0x97, 0x8d, 0x6a, + 0xc1, 0x5d, 0xcc, 0xd1, 0x0f, 0x1d, 0x78, 0x20, 0xf1, 0xe2, 0x6d, 0x9e, 0xcd, 0x39, 0x4e, 0xef, + 0xea, 0x8a, 0xc6, 0x9d, 0x66, 0xab, 0xf1, 0x15, 0xeb, 0xab, 0x71, 0xa3, 0x37, 0x4f, 0xbe, 0x2e, + 0x1f, 0x11, 0xeb, 0xf2, 0x81, 0x7d, 0x30, 0xf1, 0x7e, 0x4d, 0x9f, 0xfa, 0xb4, 0xc3, 0x5f, 0xfd, + 0xea, 0xa9, 0xf2, 0x6d, 0x9a, 0x2a, 0xdf, 0x8a, 0xcd, 0x77, 0x87, 0x74, 0xdd, 0xf3, 0xd7, 0x1c, + 0x38, 0x9d, 0xb7, 0x23, 0xe5, 0x34, 0xe9, 0x23, 0x66, 0x93, 0x2c, 0x9e, 0xb2, 0xf4, 0x06, 0x59, + 0x79, 0xf6, 0x64, 0xea, 0x2a, 0x3c, 0x7c, 0xa7, 0xaf, 0x78, 0x27, 0x7a, 0x23, 0xba, 0x5a, 0xfc, + 0x67, 0xa3, 0x9a, 0x17, 0x32, 0x21, 0x6d, 0xeb, 0x31, 0xdc, 0x01, 0x0c, 0xf9, 0x41, 0xd3, 0x0f, + 0x88, 0xb8, 0xaf, 0x69, 0xf3, 0x0c, 0x2b, 0x9e, 0x2d, 0xa2, 0xd4, 0xb1, 0xe0, 0x72, 0x8f, 0x9d, + 0x92, 0xd9, 0x87, 0xe0, 0x06, 0x8f, 0xff, 0x21, 0xb8, 0x1b, 0x30, 0x7a, 0xc3, 0x4f, 0x1a, 0x2c, + 0x98, 0x42, 0xf8, 0xfa, 0x2c, 0xdc, 0x73, 0xa4, 0xe4, 0xd2, 0xbe, 0x5f, 0x97, 0x0c, 0x70, 0xca, + 0x0b, 0x5d, 0xe0, 0x8c, 0x59, 0xe4, 0x76, 0x36, 0xa4, 0xf6, 0xba, 0x2c, 0xc0, 0x29, 0x0e, 0x1d, + 0xac, 0x31, 0xfa, 0x4b, 0xe6, 0x80, 0x12, 0x99, 0x91, 0x6d, 0x64, 0xbc, 0x14, 0x14, 0xf9, 0x6d, + 0xe2, 0xeb, 0x1a, 0x0f, 0x6c, 0x70, 0x54, 0xc9, 0xa9, 0x47, 0x7a, 0x26, 0xa7, 0x7e, 0x9d, 0x29, + 0x6c, 0x89, 0x1f, 0x74, 0xc8, 0x5a, 0x20, 0xe2, 0xbd, 0x57, 0xec, 0xdc, 0x7d, 0xe6, 0x34, 0xf9, + 0x11, 0x3c, 0xfd, 0x8d, 0x35, 0x7e, 0x9a, 0xcb, 0xa5, 0xb4, 0xaf, 0xcb, 0x25, 0x35, 0xb9, 0x8c, + 0x59, 0x37, 0xb9, 0x24, 0xa4, 0x6d, 0xc5, 0xe4, 0xf2, 0x33, 0x65, 0x0e, 0xf8, 0x73, 0x07, 0x90, + 0xd2, 0xbb, 0x94, 0x40, 0x3d, 0x86, 0xa0, 0xca, 0x8f, 0x3b, 0x00, 0x81, 0x7a, 0x2e, 0xd4, 0xee, + 0x2e, 0xc8, 0x69, 0xa6, 0x0d, 0x48, 0x61, 0x58, 0xe3, 0xe9, 0xfe, 0xa9, 0x93, 0xc6, 0x2e, 0xa7, + 0x7d, 0x3f, 0x86, 0x20, 0xb2, 0x5d, 0x33, 0x88, 0x6c, 0xc3, 0xa2, 0xe9, 0x5e, 0x75, 0xa3, 0x47, + 0x38, 0xd9, 0x4f, 0x0a, 0x70, 0x42, 0x47, 0xae, 0x90, 0xe3, 0xf8, 0xd8, 0x37, 0x8c, 0x08, 0xda, + 0x6b, 0x76, 0xfb, 0x5b, 0x11, 0x1e, 0xa0, 0xbc, 0x68, 0xed, 0x8f, 0x65, 0xa2, 0xb5, 0xaf, 0xdb, + 0x67, 0xbd, 0x7f, 0xc8, 0xf6, 0x7f, 0x76, 0xe0, 0x54, 0xa6, 0xc6, 0x31, 0x4c, 0xb0, 0x1d, 0x73, + 0x82, 0x3d, 0x67, 0xbd, 0xd7, 0x3d, 0x66, 0xd7, 0xb7, 0x0a, 0x5d, 0xbd, 0x65, 0x87, 0xb8, 0x4f, + 0x39, 0x50, 0xa4, 0xda, 0xb2, 0x8c, 0xe7, 0xfa, 0xc8, 0x91, 0xcc, 0x00, 0xa6, 0xd7, 0x0b, 0xe9, + 0xac, 0xda, 0xc7, 0x60, 0x98, 0x73, 0x9f, 0xfa, 0xa4, 0x03, 0x90, 0x22, 0xdd, 0x2b, 0x15, 0xd8, + 0xfd, 0x4e, 0x01, 0xce, 0xe4, 0x4e, 0x23, 0xf4, 0x19, 0x65, 0x91, 0x73, 0x6c, 0x47, 0x2b, 0x1a, + 0x8c, 0x74, 0xc3, 0xdc, 0xb8, 0x61, 0x98, 0x13, 0xf6, 0xb8, 0x7b, 0x75, 0x80, 0x11, 0x62, 0x5a, + 0x1b, 0xac, 0x1f, 0x3b, 0x69, 0x00, 0xac, 0xca, 0x6b, 0xf4, 0x17, 0xf0, 0x12, 0x8f, 0xfb, 0x13, + 0xed, 0x86, 0x83, 0xec, 0xe8, 0x31, 0xc8, 0x8a, 0x1b, 0xa6, 0xac, 0xc0, 0xf6, 0xfd, 0xc8, 0x3d, + 0x84, 0xc5, 0x2b, 0x90, 0xe7, 0x58, 0xee, 0x2f, 0x09, 0xa4, 0x71, 0x1d, 0xb6, 0xd0, 0xf7, 0x75, + 0xd8, 0x71, 0x28, 0xbd, 0xe8, 0xab, 0x04, 0xa2, 0x73, 0x33, 0xdf, 0xfd, 0xd1, 0xf9, 0xfb, 0xbe, + 0xf7, 0xa3, 0xf3, 0xf7, 0xfd, 0xf0, 0x47, 0xe7, 0xef, 0xfb, 0xf8, 0xad, 0xf3, 0xce, 0x77, 0x6f, + 0x9d, 0x77, 0xbe, 0x77, 0xeb, 0xbc, 0xf3, 0xc3, 0x5b, 0xe7, 0x9d, 0x7f, 0x7b, 0xeb, 0xbc, 0xf3, + 0xb7, 0xfe, 0xdd, 0xf9, 0xfb, 0x5e, 0x1c, 0x91, 0x1d, 0xfb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xbf, 0x5e, 0x27, 0xac, 0x92, 0xd8, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -11109,9 +11109,9 @@ func (m *StopStrategy) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - i -= len(m.Condition) - copy(dAtA[i:], m.Condition) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Condition))) + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -16364,7 +16364,7 @@ func (m *StopStrategy) Size() (n int) { } var l int _ = l - l = len(m.Condition) + l = len(m.Expression) n += 1 + l + sovGenerated(uint64(l)) return n } @@ -19021,7 +19021,7 @@ func (this *StopStrategy) String() string { return "nil" } s := strings.Join([]string{`&StopStrategy{`, - `Condition:` + fmt.Sprintf("%v", this.Condition) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, `}`, }, "") return s @@ -38336,7 +38336,7 @@ func (m *StopStrategy) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Condition", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -38364,7 +38364,7 @@ func (m *StopStrategy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Condition = string(dAtA[iNdEx:postIndex]) + m.Expression = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index 8bc4eb9b9dec..5280f8c1f961 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -1490,11 +1490,11 @@ message Sequence { optional string format = 4; } -// v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +// StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after message StopStrategy { - // v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the - // variables `failed` or `succeeded` to access the number of failed or successful child workflows. - optional string condition = 1; + // v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables + // `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. + optional string expression = 1; } message Submit { diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 90bc5cd7ad1d..893b7bebc77a 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -5972,19 +5972,19 @@ func schema_pkg_apis_workflow_v1alpha1_StopStrategy(ref common.ReferenceCallback return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition", + Description: "StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "condition": { + "expression": { SchemaProps: spec.SchemaProps{ - Description: "v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows.", + Description: "v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows.", Default: "", Type: []string{"string"}, Format: "", }, }, }, - Required: []string{"condition"}, + Required: []string{"expression"}, }, }, } diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md index f644e834e493..0d52970e5b80 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md @@ -2,13 +2,13 @@ # IoArgoprojWorkflowV1alpha1StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**condition** | **String** | v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. | +**expression** | **String** | v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. | diff --git a/sdks/java/client/docs/WorkflowServiceApi.md b/sdks/java/client/docs/WorkflowServiceApi.md index ab2d95d3fbbd..d99bc3d91623 100644 --- a/sdks/java/client/docs/WorkflowServiceApi.md +++ b/sdks/java/client/docs/WorkflowServiceApi.md @@ -323,7 +323,7 @@ Name | Type | Description | Notes # **workflowServiceListWorkflows** -> IoArgoprojWorkflowV1alpha1WorkflowList workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields) +> IoArgoprojWorkflowV1alpha1WorkflowList workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields, nameFilter) @@ -361,8 +361,9 @@ public class Example { String listOptionsContinue = "listOptionsContinue_example"; // String | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. Boolean listOptionsSendInitialEvents = true; // Boolean | `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional String fields = "fields_example"; // String | Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". + String nameFilter = "nameFilter_example"; // String | Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. try { - IoArgoprojWorkflowV1alpha1WorkflowList result = apiInstance.workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields); + IoArgoprojWorkflowV1alpha1WorkflowList result = apiInstance.workflowServiceListWorkflows(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue, listOptionsSendInitialEvents, fields, nameFilter); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling WorkflowServiceApi#workflowServiceListWorkflows"); @@ -391,6 +392,7 @@ Name | Type | Description | Notes **listOptionsContinue** | **String**| The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. | [optional] **listOptionsSendInitialEvents** | **Boolean**| `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional | [optional] **fields** | **String**| Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". | [optional] + **nameFilter** | **String**| Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. | [optional] ### Return type diff --git a/sdks/python/README.md b/sdks/python/README.md index 2c1c7c4be57c..8fe16af8e04f 100644 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -2,6 +2,10 @@ This is the Python SDK for Argo Workflows. +> [!WARNING] +> This SDK is deprecated and will be removed in version 3.7 of Argo Workflows. +> We recommend migrating to [Hera](https://github.com/argoproj-labs/hera). + ## Requirements Python >= 3.6 diff --git a/sdks/python/client/argo_workflows/api/workflow_service_api.py b/sdks/python/client/argo_workflows/api/workflow_service_api.py index b000b92a4a62..29d73f0bac40 100644 --- a/sdks/python/client/argo_workflows/api/workflow_service_api.py +++ b/sdks/python/client/argo_workflows/api/workflow_service_api.py @@ -351,6 +351,7 @@ def __init__(self, api_client=None): 'list_options_continue', 'list_options_send_initial_events', 'fields', + 'name_filter', ], 'required': [ 'namespace', @@ -392,6 +393,8 @@ def __init__(self, api_client=None): (bool,), 'fields': (str,), + 'name_filter': + (str,), }, 'attribute_map': { 'namespace': 'namespace', @@ -406,6 +409,7 @@ def __init__(self, api_client=None): 'list_options_continue': 'listOptions.continue', 'list_options_send_initial_events': 'listOptions.sendInitialEvents', 'fields': 'fields', + 'name_filter': 'nameFilter', }, 'location_map': { 'namespace': 'path', @@ -420,6 +424,7 @@ def __init__(self, api_client=None): 'list_options_continue': 'query', 'list_options_send_initial_events': 'query', 'fields': 'query', + 'name_filter': 'query', }, 'collection_format_map': { } @@ -1752,6 +1757,7 @@ def list_workflows( list_options_continue (str): The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.. [optional] list_options_send_initial_events (bool): `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional. [optional] fields (str): Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\".. [optional] + name_filter (str): Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact.. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py index 9bf92e344fbc..4293f0145f15 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_stop_strategy.py @@ -81,7 +81,7 @@ def openapi_types(): and the value is attribute type. """ return { - 'condition': (str,), # noqa: E501 + 'expression': (str,), # noqa: E501 } @cached_property @@ -90,7 +90,7 @@ def discriminator(): attribute_map = { - 'condition': 'condition', # noqa: E501 + 'expression': 'expression', # noqa: E501 } read_only_vars = { @@ -100,11 +100,11 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, expression, *args, **kwargs): # noqa: E501 """IoArgoprojWorkflowV1alpha1StopStrategy - a model defined in OpenAPI Args: - condition (str): v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. + expression (str): v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -164,7 +164,7 @@ def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.condition = condition + self.expression = expression for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -185,11 +185,11 @@ def _from_openapi_data(cls, condition, *args, **kwargs): # noqa: E501 ]) @convert_js_args_to_python_args - def __init__(self, condition, *args, **kwargs): # noqa: E501 + def __init__(self, expression, *args, **kwargs): # noqa: E501 """IoArgoprojWorkflowV1alpha1StopStrategy - a model defined in OpenAPI Args: - condition (str): v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. + expression (str): v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -247,7 +247,7 @@ def __init__(self, condition, *args, **kwargs): # noqa: E501 self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.condition = condition + self.expression = expression for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/sdks/python/client/docs/CronWorkflowServiceApi.md b/sdks/python/client/docs/CronWorkflowServiceApi.md index c7c5ec6a921e..3fe110e35add 100644 --- a/sdks/python/client/docs/CronWorkflowServiceApi.md +++ b/sdks/python/client/docs/CronWorkflowServiceApi.md @@ -115,7 +115,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, @@ -11684,7 +11684,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, @@ -23340,7 +23340,7 @@ with argo_workflows.ApiClient(configuration) as api_client: ], starting_deadline_seconds=1, stop_strategy=IoArgoprojWorkflowV1alpha1StopStrategy( - condition="condition_example", + expression="expression_example", ), successful_jobs_history_limit=1, suspend=True, diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md index 035cce4f5b22..5c3dc4777114 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1StopStrategy.md @@ -1,11 +1,11 @@ # IoArgoprojWorkflowV1alpha1StopStrategy -v3.6 and after: StopStrategy defines if the CronWorkflow should stop scheduling based on a condition +StopStrategy defines if the CronWorkflow should stop scheduling based on an expression. v3.6 and after ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**condition** | **str** | v3.6 and after: Condition is an expression that stops scheduling workflows when true. Use the variables `failed` or `succeeded` to access the number of failed or successful child workflows. | +**expression** | **str** | v3.6 and after: Expression is an expression that stops scheduling workflows when true. Use the variables `cronworkflow`.`failed` or `cronworkflow`.`succeeded` to access the number of failed or successful child workflows. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/sdks/python/client/docs/WorkflowServiceApi.md b/sdks/python/client/docs/WorkflowServiceApi.md index 9a7be230c42c..b2288e27aaee 100644 --- a/sdks/python/client/docs/WorkflowServiceApi.md +++ b/sdks/python/client/docs/WorkflowServiceApi.md @@ -57770,6 +57770,7 @@ with argo_workflows.ApiClient(configuration) as api_client: list_options_continue = "listOptions.continue_example" # str | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. (optional) list_options_send_initial_events = True # bool | `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional (optional) fields = "fields_example" # str | Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". (optional) + name_filter = "nameFilter_example" # str | Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. (optional) # example passing only required values which don't have defaults set try: @@ -57781,7 +57782,7 @@ with argo_workflows.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.list_workflows(namespace, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue, list_options_send_initial_events=list_options_send_initial_events, fields=fields) + api_response = api_instance.list_workflows(namespace, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue, list_options_send_initial_events=list_options_send_initial_events, fields=fields, name_filter=name_filter) pprint(api_response) except argo_workflows.ApiException as e: print("Exception when calling WorkflowServiceApi->list_workflows: %s\n" % e) @@ -57804,6 +57805,7 @@ Name | Type | Description | Notes **list_options_continue** | **str**| The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. | [optional] **list_options_send_initial_events** | **bool**| `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"io.k8s.initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan is interpreted as \"data at least as new as the provided `resourceVersion`\" and the bookmark event is send when the state is synced to a `resourceVersion` at least as fresh as the one provided by the ListOptions. If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the bookmark event is send when the state is synced at least to the moment when request started being processed. - `resourceVersionMatch` set to any other value or unset Invalid error is returned. Defaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise. +optional | [optional] **fields** | **str**| Fields to be included or excluded in the response. e.g. \"items.spec,items.status.phase\", \"-items.status.nodes\". | [optional] + **name_filter** | **str**| Filter type used for name filtering. Exact | Contains | Prefix. Default to Exact. | [optional] ### Return type diff --git a/server/cronworkflow/cron_workflow_server.go b/server/cronworkflow/cron_workflow_server.go index 49d45bffea4c..cd8012a61320 100644 --- a/server/cronworkflow/cron_workflow_server.go +++ b/server/cronworkflow/cron_workflow_server.go @@ -35,7 +35,7 @@ func (c *cronWorkflowServiceServer) LintCronWorkflow(ctx context.Context, req *c cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) c.instanceIDService.Label(req.CronWorkflow) creator.Label(ctx, req.CronWorkflow) - err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow) if err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } @@ -64,7 +64,7 @@ func (c *cronWorkflowServiceServer) CreateCronWorkflow(ctx context.Context, req creator.Label(ctx, req.CronWorkflow) wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace)) cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) - err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow) + err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow) if err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } @@ -91,7 +91,7 @@ func (c *cronWorkflowServiceServer) UpdateCronWorkflow(ctx context.Context, req } wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace)) cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(wfClient.ArgoprojV1alpha1().ClusterWorkflowTemplates()) - if err := validate.ValidateCronWorkflow(wftmplGetter, cwftmplGetter, req.CronWorkflow); err != nil { + if err := validate.ValidateCronWorkflow(ctx, wftmplGetter, cwftmplGetter, req.CronWorkflow); err != nil { return nil, sutils.ToStatusError(err, codes.InvalidArgument) } crWf, err := auth.GetWfClient(ctx).ArgoprojV1alpha1().CronWorkflows(req.Namespace).Update(ctx, req.CronWorkflow, metav1.UpdateOptions{}) diff --git a/server/utils/list_options.go b/server/utils/list_options.go index 69a03456cbd5..978592db3a14 100644 --- a/server/utils/list_options.go +++ b/server/utils/list_options.go @@ -13,12 +13,13 @@ import ( ) type ListOptions struct { - Namespace, Name, NamePrefix string - MinStartedAt, MaxStartedAt time.Time - LabelRequirements labels.Requirements - Limit, Offset int - ShowRemainingItemCount bool - StartedAtAscending bool + Namespace, Name string + NamePrefix, NameFilter string + MinStartedAt, MaxStartedAt time.Time + LabelRequirements labels.Requirements + Limit, Offset int + ShowRemainingItemCount bool + StartedAtAscending bool } func (l ListOptions) WithLimit(limit int) ListOptions { @@ -51,10 +52,11 @@ func (l ListOptions) WithStartedAtAscending(ascending bool) ListOptions { return l } -func BuildListOptions(options metav1.ListOptions, ns, namePrefix string) (ListOptions, error) { +func BuildListOptions(options metav1.ListOptions, ns, namePrefix, nameFilter string) (ListOptions, error) { if options.Continue == "" { options.Continue = "0" } + limit := int(options.Limit) offset, err := strconv.Atoi(options.Continue) @@ -123,6 +125,7 @@ func BuildListOptions(options metav1.ListOptions, ns, namePrefix string) (ListOp Namespace: namespace, Name: name, NamePrefix: namePrefix, + NameFilter: nameFilter, MinStartedAt: minStartedAt, MaxStartedAt: maxStartedAt, LabelRequirements: requirements, diff --git a/server/workflow/store/lister.go b/server/workflow/store/lister.go index 3a2dc0870a7a..e50ab6938e3e 100644 --- a/server/workflow/store/lister.go +++ b/server/workflow/store/lister.go @@ -10,8 +10,8 @@ import ( ) type WorkflowLister interface { - ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) - CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) + ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) + CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) } type kubeLister struct { @@ -24,7 +24,7 @@ func NewKubeLister(wfClient versioned.Interface) WorkflowLister { return &kubeLister{wfClient: wfClient} } -func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { +func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { wfList, err := k.wfClient.ArgoprojV1alpha1().Workflows(namespace).List(ctx, listOptions) if err != nil { return nil, err @@ -32,7 +32,7 @@ func (k *kubeLister) ListWorkflows(ctx context.Context, namespace, namePrefix st return wfList, nil } -func (k *kubeLister) CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) { +func (k *kubeLister) CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) { wfList, err := k.wfClient.ArgoprojV1alpha1().Workflows(namespace).List(ctx, listOptions) if err != nil { return 0, err diff --git a/server/workflow/store/sqlite_store.go b/server/workflow/store/sqlite_store.go index c06eda14e4c3..2c8aecfbc84e 100644 --- a/server/workflow/store/sqlite_store.go +++ b/server/workflow/store/sqlite_store.go @@ -88,8 +88,8 @@ func NewSQLiteStore(instanceService instanceid.Service) (*SQLiteStore, error) { return &SQLiteStore{conn: conn, instanceService: instanceService}, nil } -func (s *SQLiteStore) ListWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { - options, err := sutils.BuildListOptions(listOptions, namespace, namePrefix) +func (s *SQLiteStore) ListWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (*wfv1.WorkflowList, error) { + options, err := sutils.BuildListOptions(listOptions, namespace, "", nameFilter) if err != nil { return nil, err } @@ -129,8 +129,8 @@ where instanceid = ? }, nil } -func (s *SQLiteStore) CountWorkflows(ctx context.Context, namespace, namePrefix string, listOptions metav1.ListOptions) (int64, error) { - options, err := sutils.BuildListOptions(listOptions, namespace, namePrefix) +func (s *SQLiteStore) CountWorkflows(ctx context.Context, namespace, nameFilter string, listOptions metav1.ListOptions) (int64, error) { + options, err := sutils.BuildListOptions(listOptions, namespace, "", nameFilter) if err != nil { return 0, err } diff --git a/server/workflow/store/sqlite_store_test.go b/server/workflow/store/sqlite_store_test.go index e79477aa4d0b..cc96e4d0b8f9 100644 --- a/server/workflow/store/sqlite_store_test.go +++ b/server/workflow/store/sqlite_store_test.go @@ -133,6 +133,45 @@ func TestStoreOperation(t *testing.T) { require.NoError(t, err) assert.Len(t, wfList.Items, 5) }) + t.Run("TestListWorkflows name", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Exact", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Exact", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) + t.Run("TestListWorkflows namePrefix", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 5) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Prefix", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) + t.Run("TestListWorkflows namePattern", func(t *testing.T) { + wfList, err := store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=non-existing-pattern"}) + require.NoError(t, err) + assert.Empty(t, wfList.Items) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=flow"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 5) + + wfList, err = store.ListWorkflows(context.Background(), "argo", "Contains", metav1.ListOptions{Limit: 5, FieldSelector: "metadata.name=workflow-1"}) + require.NoError(t, err) + assert.Len(t, wfList.Items, 1) + }) t.Run("TestCountWorkflows", func(t *testing.T) { num, err := store.CountWorkflows(context.Background(), "argo", "", metav1.ListOptions{}) require.NoError(t, err) diff --git a/server/workflow/workflow_server.go b/server/workflow/workflow_server.go index 7c0c36182e3b..6f8e08a7386d 100644 --- a/server/workflow/workflow_server.go +++ b/server/workflow/workflow_server.go @@ -173,7 +173,8 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor } s.instanceIDService.With(&listOption) - options, err := sutils.BuildListOptions(listOption, req.Namespace, "") + options, err := sutils.BuildListOptions(listOption, req.Namespace, "", req.NameFilter) + if err != nil { return nil, err } @@ -187,7 +188,7 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor } var wfs wfv1.Workflows - liveWfCount, err := s.wfLister.CountWorkflows(ctx, req.Namespace, "", listOption) + liveWfCount, err := s.wfLister.CountWorkflows(ctx, req.Namespace, req.NameFilter, listOption) if err != nil { return nil, sutils.ToStatusError(err, codes.Internal) } @@ -200,7 +201,7 @@ func (s *workflowServer) ListWorkflows(ctx context.Context, req *workflowpkg.Wor // first fetch live workflows liveWfList := &wfv1.WorkflowList{} if liveWfCount > 0 && (options.Limit == 0 || options.Offset < int(liveWfCount)) { - liveWfList, err = s.wfLister.ListWorkflows(ctx, req.Namespace, "", listOption) + liveWfList, err = s.wfLister.ListWorkflows(ctx, req.Namespace, req.NameFilter, listOption) if err != nil { return nil, sutils.ToStatusError(err, codes.Internal) } diff --git a/server/workflowarchive/archived_workflow_server.go b/server/workflowarchive/archived_workflow_server.go index 2f6c69369dce..a3c8500783b2 100644 --- a/server/workflowarchive/archived_workflow_server.go +++ b/server/workflowarchive/archived_workflow_server.go @@ -41,7 +41,7 @@ func NewWorkflowArchiveServer(wfArchive sqldb.WorkflowArchive, offloadNodeStatus func (w *archivedWorkflowServer) ListArchivedWorkflows(ctx context.Context, req *workflowarchivepkg.ListArchivedWorkflowsRequest) (*wfv1.WorkflowList, error) { - options, err := sutils.BuildListOptions(*req.ListOptions, req.Namespace, req.NamePrefix) + options, err := sutils.BuildListOptions(*req.ListOptions, req.Namespace, req.NamePrefix, "") if err != nil { return nil, err } diff --git a/test/e2e/cron_test.go b/test/e2e/cron_test.go index ebe410101663..3e51d6ef618b 100644 --- a/test/e2e/cron_test.go +++ b/test/e2e/cron_test.go @@ -357,7 +357,7 @@ spec: successfulJobsHistoryLimit: 4 failedJobsHistoryLimit: 2 stopStrategy: - condition: "succeeded >= 1" + expression: "cronworkflow.succeeded >= 1" workflowSpec: metadata: labels: @@ -391,7 +391,7 @@ spec: schedule: "* * * * *" concurrencyPolicy: "Allow" stopStrategy: - condition: "failed >= 1" + expression: "cronworkflow.failed >= 1" workflowSpec: metadata: labels: diff --git a/test/e2e/metrics_test.go b/test/e2e/metrics_test.go index 3c17afdc0175..61d8d092d6ac 100644 --- a/test/e2e/metrics_test.go +++ b/test/e2e/metrics_test.go @@ -94,6 +94,74 @@ func (s *MetricsSuite) TestDAGMetrics() { }) } +func (s *MetricsSuite) TestDeprecatedCronSchedule() { + s.Given(). + CronWorkflow(`@testdata/cronworkflow-deprecated-schedule.yaml`). + When(). + CreateCronWorkflow(). + Wait(1 * time.Minute). // This pattern is used in cron_test.go too + Then(). + ExpectCron(func(t *testing.T, cronWf *wfv1.CronWorkflow) { + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="cronworkflow schedule",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedMutex() { + s.Given(). + Workflow(`@testdata/synchronization-deprecated-mutex.yaml`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="synchronization mutex",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedPodPriority() { + s.Given(). + Workflow(`@testdata/workflow-deprecated-podpriority.yaml`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeErrored). // Fails as kubernetes we test on do not support this1 + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="workflow podpriority",namespace="argo"}`) // Count unimportant and unknown + }) +} + +func (s *MetricsSuite) TestDeprecatedSemaphore() { + s.Given(). + Workflow(`@testdata/synchronization-deprecated-semaphore.yaml`). + When(). + CreateConfigMap("my-config", map[string]string{"workflow": "1"}, map[string]string{}). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + DeleteConfigMap("my-config"). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + s.e(s.T()).GET(""). + Expect(). + Status(200). + Body(). + Contains(`deprecated_feature{feature="synchronization semaphore",namespace="argo"}`) // Count unimportant and unknown + }) +} + func (s *MetricsSuite) TestFailedMetric() { s.Given(). Workflow(`@testdata/template-status-failed-conditional-metric.yaml`). diff --git a/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml b/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml new file mode 100644 index 000000000000..abfda0b51fde --- /dev/null +++ b/test/e2e/testdata/cronworkflow-deprecated-schedule.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: test-cron-deprecated-schedule +spec: + schedules: + - "* * * * *" + concurrencyPolicy: "Forbid" + startingDeadlineSeconds: 0 + workflowSpec: + metadata: + labels: + workflows.argoproj.io/test: "true" + podGC: + strategy: OnPodCompletion + entrypoint: sleep + templates: + - name: sleep + container: + image: alpine:latest + command: [sh, -c, "sleep 120"] diff --git a/test/e2e/testdata/cronworkflow-metrics-forbid.yaml b/test/e2e/testdata/cronworkflow-metrics-forbid.yaml index 7e4cb97c4ad7..0b3a40ad97a9 100644 --- a/test/e2e/testdata/cronworkflow-metrics-forbid.yaml +++ b/test/e2e/testdata/cronworkflow-metrics-forbid.yaml @@ -3,7 +3,8 @@ kind: CronWorkflow metadata: name: test-cron-metric-forbid spec: - schedule: "* * * * *" + schedules: + - "* * * * *" concurrencyPolicy: "Forbid" startingDeadlineSeconds: 0 workflowSpec: diff --git a/test/e2e/testdata/cronworkflow-metrics-replace.yaml b/test/e2e/testdata/cronworkflow-metrics-replace.yaml index 7b2a8534b24f..e67b490c8aa2 100644 --- a/test/e2e/testdata/cronworkflow-metrics-replace.yaml +++ b/test/e2e/testdata/cronworkflow-metrics-replace.yaml @@ -3,7 +3,8 @@ kind: CronWorkflow metadata: name: test-cron-metric-replace spec: - schedule: "* * * * *" + schedules: + - "* * * * *" concurrencyPolicy: "Replace" startingDeadlineSeconds: 0 workflowSpec: diff --git a/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml b/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml new file mode 100644 index 000000000000..0b3a40ad97a9 --- /dev/null +++ b/test/e2e/testdata/cronworkflow_deprecated_schedule.yaml @@ -0,0 +1,21 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: test-cron-metric-forbid +spec: + schedules: + - "* * * * *" + concurrencyPolicy: "Forbid" + startingDeadlineSeconds: 0 + workflowSpec: + metadata: + labels: + workflows.argoproj.io/test: "true" + podGC: + strategy: OnPodCompletion + entrypoint: sleep + templates: + - name: sleep + container: + image: alpine:latest + command: [sh, -c, "sleep 120"] diff --git a/test/e2e/testdata/synchronization-deprecated-mutex.yaml b/test/e2e/testdata/synchronization-deprecated-mutex.yaml new file mode 100644 index 000000000000..31dfd1a912a0 --- /dev/null +++ b/test/e2e/testdata/synchronization-deprecated-mutex.yaml @@ -0,0 +1,13 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: mutex-deprecated- +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test-mutex + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/test/e2e/testdata/synchronization-deprecated-semaphore.yaml b/test/e2e/testdata/synchronization-deprecated-semaphore.yaml new file mode 100644 index 000000000000..5f2b9e8a5d22 --- /dev/null +++ b/test/e2e/testdata/synchronization-deprecated-semaphore.yaml @@ -0,0 +1,15 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: semaphore-deprecated- +spec: + entrypoint: whalesay + synchronization: + semaphore: + configMapKeyRef: + name: my-config + key: workflow + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/test/e2e/testdata/workflow-deprecated-podpriority.yaml b/test/e2e/testdata/workflow-deprecated-podpriority.yaml new file mode 100644 index 000000000000..17c1e7e43471 --- /dev/null +++ b/test/e2e/testdata/workflow-deprecated-podpriority.yaml @@ -0,0 +1,11 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: podpriority-deprecated- +spec: + entrypoint: whalesay + podPriority: 9999 + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 diff --git a/ui/package.json b/ui/package.json index 88804680aea6..dd456cdb1dc1 100644 --- a/ui/package.json +++ b/ui/package.json @@ -24,7 +24,6 @@ "cronstrue": "^2.50.0", "dagre": "^0.8.5", "history": "^4.10.1", - "js-yaml": "^4.1.0", "moment": "^2.30.1", "monaco-editor": "^0.45.0", "prop-types": "^15.8.1", @@ -37,7 +36,8 @@ "react-router-dom": "^4.2.2", "remark-gfm": "^3.0.0", "superagent": "^8.1.2", - "swagger-ui-react": "^5.17.12" + "swagger-ui-react": "^5.17.12", + "yaml": "^2.5.1" }, "devDependencies": { "@babel/core": "^7.22.11", @@ -48,7 +48,6 @@ "@types/dagre": "^0.7.52", "@types/history": "^4.6.2", "@types/jest": "^26.0.15", - "@types/js-yaml": "^4.0.9", "@types/prop-types": "^15.7.11", "@types/react": "^16.8.5", "@types/react-autocomplete": "^1.8.10", diff --git a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-details.tsx b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-details.tsx index 3523474acfc6..be965ca5349b 100644 --- a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-details.tsx +++ b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-details.tsx @@ -150,6 +150,7 @@ export function ClusterWorkflowTemplateDetails({history, location, match}: Route entrypoint={template.spec.entrypoint} templates={template.spec.templates || []} workflowParameters={template.spec.arguments.parameters || []} + history={history} /> )} diff --git a/ui/src/app/shared/components/dropdown/dropdown.tsx b/ui/src/app/shared/components/dropdown/dropdown.tsx index 5c9253d8125d..50b1569e531a 100644 --- a/ui/src/app/shared/components/dropdown/dropdown.tsx +++ b/ui/src/app/shared/components/dropdown/dropdown.tsx @@ -7,10 +7,11 @@ import './dropdown.scss'; export interface DropDownProps { isMenu?: boolean; anchor: JSX.Element; + closeOnInsideClick?: boolean; children: ReactNode; } -export function DropDown({isMenu, anchor, children}: DropDownProps) { +export function DropDown({isMenu, anchor, closeOnInsideClick, children}: DropDownProps) { const [opened, setOpened] = useState(false); const [left, setLeft] = useState(0); const [top, setTop] = useState(0); @@ -56,7 +57,7 @@ export function DropDown({isMenu, anchor, children}: DropDownProps) { function close(event: MouseEvent) { // Doesn't close when clicked inside the portal area - if (contentEl.contains(event.target as Node) || anchorEl.contains(event.target as Node)) { + if (!closeOnInsideClick && (contentEl.contains(event.target as Node) || anchorEl.contains(event.target as Node))) { return; } diff --git a/ui/src/app/shared/components/input-filter.scss b/ui/src/app/shared/components/input-filter.scss new file mode 100644 index 000000000000..76dfe8e6785c --- /dev/null +++ b/ui/src/app/shared/components/input-filter.scss @@ -0,0 +1,10 @@ +.input-filter { + display: flex; + align-items: center; + justify-content: space-between; + + div:first-child { + flex: 1; + } +} + diff --git a/ui/src/app/shared/components/input-filter.tsx b/ui/src/app/shared/components/input-filter.tsx index 14e781aa420c..c73cb4c7e9e4 100644 --- a/ui/src/app/shared/components/input-filter.tsx +++ b/ui/src/app/shared/components/input-filter.tsx @@ -1,11 +1,15 @@ import {Autocomplete} from 'argo-ui/src/components/autocomplete/autocomplete'; import React, {useState} from 'react'; +import './input-filter.scss'; + interface InputProps { value: string; placeholder?: string; name: string; onChange: (input: string) => void; + filterSuggestions?: boolean; + autoHighlight?: boolean; } export function InputFilter(props: InputProps) { @@ -44,7 +48,7 @@ export function InputFilter(props: InputProps) { } return ( - <> + ); } diff --git a/ui/src/app/shared/components/links.test.ts b/ui/src/app/shared/components/links.test.ts index 384de4c21b71..0c547b901067 100644 --- a/ui/src/app/shared/components/links.test.ts +++ b/ui/src/app/shared/components/links.test.ts @@ -56,4 +56,19 @@ describe('process URL', () => { expect(processURL('https://logging?${workflow.annotations.logQuery}${workflow.annotations.additionalLogParams}', object)).toBe('https://logging?query=env:qa'); }); + + test('workflows annotation.', () => { + const object = { + status: {}, + workflow: { + metadata: { + annotations: { + 'workflows.argoproj.io/pod-name-format': 'v2' + } + } + } + }; + + expect(processURL('https://logging?${workflow.metadata.annotations.workflows.argoproj.io/pod-name-format}', object)).toBe('https://logging?v2'); + }); }); diff --git a/ui/src/app/shared/components/links.tsx b/ui/src/app/shared/components/links.tsx index 0808d7d2d005..cb672b387efb 100644 --- a/ui/src/app/shared/components/links.tsx +++ b/ui/src/app/shared/components/links.tsx @@ -23,12 +23,25 @@ function addEpochTimestamp(jsonObject: {metadata: ObjectMeta; workflow?: Workflo jsonObject.status.finishedAtEpoch = toEpoch(jsonObject.status.finishedAt); } +function splitWithMetadataKnowledge(replaceable: string) { + const parts = replaceable.split('.'); + if (replaceable.startsWith('workflow.metadata.labels') || replaceable.startsWith('workflow.metadata.annotations')) { + // Take the first 3 parts, then join the rest + const result = parts.slice(0, 3); + result.push(parts.slice(3).join('.')); + + return result; + } + return parts; +} + export function processURL(urlExpression: string, jsonObject: any) { addEpochTimestamp(jsonObject); /* replace ${} from input url with corresponding elements from object only return null for known variables, otherwise empty string*/ return urlExpression.replace(/\${[^}]*}/g, x => { - const parts = x.replace(/(\$%7B|%7D|\${|})/g, '').split('.'); + const replaced = x.replace(/(\$%7B|%7D|\${|})/g, ''); + const parts = splitWithMetadataKnowledge(replaced); const emptyVal = parts[0] === 'workflow' ? '' : null; const res = parts.reduce((p: any, c: string) => (p && p[c]) || emptyVal, jsonObject); return res; diff --git a/ui/src/app/shared/components/object-parser.test.ts b/ui/src/app/shared/components/object-parser.test.ts new file mode 100644 index 000000000000..e3f868fe47a3 --- /dev/null +++ b/ui/src/app/shared/components/object-parser.test.ts @@ -0,0 +1,127 @@ +import {parse, stringify} from './object-parser'; +import {exampleWorkflowTemplate} from '../examples'; + +describe('parse', () => { + it('handles a valid JSON string', () => { + expect(parse('{}')).toEqual({}); + expect(parse('{"a": 1}')).toEqual({a: 1}); + }); + + it('handles a malformed JSON string', () => { + expect(() => parse('{1}')).toThrow(); + }); + + it('handles a valid YAML string', () => { + expect(parse('')).toEqual(null); + expect(parse('a: 1')).toEqual({a: 1}); + }); + + it('handles a malformed YAML string', () => { + expect(() => parse('!foo')).toThrow(); + }); + + it('parses a YAML string as YAML 1.1, not YAML 1.2', () => { + expect(parse('foo: 0755')).toEqual({foo: 493}); + }); +}); + +describe('stringify', () => { + const testWorkflowTemplate = exampleWorkflowTemplate('test'); + testWorkflowTemplate.metadata.name = 'test-workflowtemplate'; + + it('encodes to YAML', () => { + // Can't use toMatchInlineSnapshot() until we upgrade to Jest 30: https://github.com/jestjs/jest/issues/14305 + expect(stringify(testWorkflowTemplate, 'yaml')).toEqual(`\ +metadata: + name: test-workflowtemplate + namespace: test + labels: + example: "true" +spec: + workflowMetadata: + labels: + example: "true" + entrypoint: argosay + arguments: + parameters: + - name: message + value: hello argo + templates: + - name: argosay + inputs: + parameters: + - name: message + value: "{{workflow.parameters.message}}" + container: + name: main + image: argoproj/argosay:v2 + command: + - /argosay + args: + - echo + - "{{inputs.parameters.message}}" + ttlStrategy: + secondsAfterCompletion: 300 + podGC: + strategy: OnPodCompletion +`); + }); + + it('encodes to JSON', () => { + expect(stringify(testWorkflowTemplate, 'json')).toEqual(`{ + "metadata": { + "name": "test-workflowtemplate", + "namespace": "test", + "labels": { + "example": "true" + } + }, + "spec": { + "workflowMetadata": { + "labels": { + "example": "true" + } + }, + "entrypoint": "argosay", + "arguments": { + "parameters": [ + { + "name": "message", + "value": "hello argo" + } + ] + }, + "templates": [ + { + "name": "argosay", + "inputs": { + "parameters": [ + { + "name": "message", + "value": "{{workflow.parameters.message}}" + } + ] + }, + "container": { + "name": "main", + "image": "argoproj/argosay:v2", + "command": [ + "/argosay" + ], + "args": [ + "echo", + "{{inputs.parameters.message}}" + ] + } + } + ], + "ttlStrategy": { + "secondsAfterCompletion": 300 + }, + "podGC": { + "strategy": "OnPodCompletion" + } + } +}`); + }); +}); diff --git a/ui/src/app/shared/components/object-parser.ts b/ui/src/app/shared/components/object-parser.ts index 96f2e15d3e91..7b4800abf660 100644 --- a/ui/src/app/shared/components/object-parser.ts +++ b/ui/src/app/shared/components/object-parser.ts @@ -1,12 +1,17 @@ -import jsyaml from 'js-yaml'; +import YAML from 'yaml'; export function parse(value: string): T { if (value.startsWith('{')) { return JSON.parse(value); } - return jsyaml.load(value) as T; + return YAML.parse(value, { + // Default is YAML 1.2, but Kubernetes uses YAML 1.1, which leads to subtle bugs. + // See https://github.com/argoproj/argo-workflows/issues/12205#issuecomment-2111572189 + version: '1.1', + strict: false + }) as T; } export function stringify(value: T, type: string) { - return type === 'yaml' ? jsyaml.dump(value, {noRefs: true}) : JSON.stringify(value, null, ' '); + return type === 'yaml' ? YAML.stringify(value, {aliasDuplicateObjects: false}) : JSON.stringify(value, null, ' '); } diff --git a/ui/src/app/shared/get_workflow_params.test.ts b/ui/src/app/shared/get_workflow_params.test.ts new file mode 100644 index 000000000000..34092bf9ad70 --- /dev/null +++ b/ui/src/app/shared/get_workflow_params.test.ts @@ -0,0 +1,37 @@ +import {createBrowserHistory} from 'history'; +import {getWorkflowParametersFromQuery} from './get_workflow_params'; + +describe('get_workflow_params', () => { + it('should return an empty object when there are no query parameters', () => { + const history = createBrowserHistory(); + const result = getWorkflowParametersFromQuery(history); + expect(result).toEqual({}); + }); + + it('should return the parameters provided in the URL', () => { + const history = createBrowserHistory(); + history.location.search = '?parameters[key1]=value1¶meters[key2]=value2'; + const result = getWorkflowParametersFromQuery(history); + expect(result).toEqual({ + key1: 'value1', + key2: 'value2' + }); + }); + + it('should not return any key value pairs which are not in parameters query ', () => { + const history = createBrowserHistory(); + history.location.search = '?retryparameters[key1]=value1&retryparameters[key2]=value2'; + const result = getWorkflowParametersFromQuery(history); + expect(result).toEqual({}); + }); + + it('should only return the parameters provided in the URL', () => { + const history = createBrowserHistory(); + history.location.search = '?parameters[key1]=value1¶meters[key2]=value2&test=123'; + const result = getWorkflowParametersFromQuery(history); + expect(result).toEqual({ + key1: 'value1', + key2: 'value2' + }); + }); +}); diff --git a/ui/src/app/shared/get_workflow_params.ts b/ui/src/app/shared/get_workflow_params.ts new file mode 100644 index 000000000000..9df9a15325d8 --- /dev/null +++ b/ui/src/app/shared/get_workflow_params.ts @@ -0,0 +1,30 @@ +import {History} from 'history'; + +function extractKey(inputString: string): string | null { + // Use regular expression to match the key within square brackets + const match = inputString.match(/^parameters\[(.*?)\]$/); + + // If a match is found, return the captured key + if (match) { + return match[1]; + } + + // If no match is found, return null or an empty string + return null; // Or return ''; +} +/** + * Returns the workflow parameters from the query parameters. + */ +export function getWorkflowParametersFromQuery(history: History): {[key: string]: string} { + const queryParams = new URLSearchParams(history.location.search); + + const parameters: {[key: string]: string} = {}; + for (const [key, value] of queryParams.entries()) { + const q = extractKey(key); + if (q) { + parameters[q] = value; + } + } + + return parameters; +} diff --git a/ui/src/app/shared/history.ts b/ui/src/app/shared/history.ts index 87736e32a28d..3295c08d5c0a 100644 --- a/ui/src/app/shared/history.ts +++ b/ui/src/app/shared/history.ts @@ -6,8 +6,7 @@ import * as nsUtils from './namespaces'; * Only "truthy" values are put into the query parameters. I.e. "falsey" values include null, undefined, false, "", 0. */ export function historyUrl(path: string, params: {[key: string]: any}) { - const queryParams: string[] = []; - let extraSearchParams: URLSearchParams; + const queryParams = new URLSearchParams(); Object.entries(params) .filter(([, v]) => v !== null) .forEach(([k, v]) => { @@ -15,14 +14,14 @@ export function historyUrl(path: string, params: {[key: string]: any}) { if (path.includes(searchValue)) { path = path.replace(searchValue, v != null ? v : ''); } else if (k === 'extraSearchParams') { - extraSearchParams = v; + (v as URLSearchParams).forEach((value, key) => queryParams.set(key, value)); } else if (v) { - queryParams.push(k + '=' + v); + queryParams.set(k, v); } if (k === 'namespace') { nsUtils.setCurrentNamespace(v); } }); - const extraString = extraSearchParams ? '&' + extraSearchParams.toString() : ''; - return uiUrl(path.replace(/{[^}]*}/g, '')) + '?' + queryParams.join('&') + extraString; + + return uiUrl(path.replace(/{[^}]*}/g, '')) + '?' + queryParams.toString(); } diff --git a/ui/src/app/shared/services/utils.ts b/ui/src/app/shared/services/utils.ts index 102955ad6fa2..7b74e1c87b06 100644 --- a/ui/src/app/shared/services/utils.ts +++ b/ui/src/app/shared/services/utils.ts @@ -1,3 +1,4 @@ +import {NameFilterKeys} from '../../workflows/components/workflow-filters/workflow-filters'; import {Pagination} from '../pagination'; export function queryParams(filter: { @@ -5,6 +6,7 @@ export function queryParams(filter: { name?: string; namePrefix?: string; namePattern?: string; + nameFilter?: NameFilterKeys; phases?: Array; labels?: Array; createdAfter?: Date; @@ -35,6 +37,9 @@ export function queryParams(filter: { if (filter.namePattern) { queryParams.push(`namePattern=${filter.namePattern}`); } + if (filter.nameFilter) { + queryParams.push(`nameFilter=${filter.nameFilter}`); + } if (filter.resourceVersion) { queryParams.push(`listOptions.resourceVersion=${filter.resourceVersion}`); } diff --git a/ui/src/app/shared/services/workflows-service.ts b/ui/src/app/shared/services/workflows-service.ts index a5cef79434b9..71a549edc397 100644 --- a/ui/src/app/shared/services/workflows-service.ts +++ b/ui/src/app/shared/services/workflows-service.ts @@ -9,6 +9,7 @@ import {Pagination} from '../pagination'; import {queryParams} from './utils'; import requests from './requests'; import {WorkflowDeleteResponse} from './responses'; +import {NameFilterKeys} from '../../workflows/components/workflow-filters/workflow-filters'; function isString(value: any): value is string { return typeof value === 'string'; @@ -51,9 +52,11 @@ export const WorkflowsService = { 'items.status.estimatedDuration', 'items.status.progress', 'items.spec.suspend' - ] + ], + name?: string, + nameFilter?: NameFilterKeys ) { - const params = queryParams({phases, labels, pagination}); + const params = queryParams({phases, labels, pagination, name, nameFilter}); params.push(`fields=${fields.join(',')}`); return requests.get(`api/v1/workflows/${namespace}?${params.join('&')}`).then(res => res.body as WorkflowList); }, diff --git a/ui/src/app/webpack.config.js b/ui/src/app/webpack.config.js index b2bb70d6973c..39ae90f9346b 100644 --- a/ui/src/app/webpack.config.js +++ b/ui/src/app/webpack.config.js @@ -7,10 +7,11 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const isProd = process.env.NODE_ENV === 'production'; -const proxyConf = { - target: isProd ? '' : 'http://localhost:2746', - secure: false -}; +let proxyTarget = ''; +if (!isProd) { + const isSecure = process.env.ARGO_SECURE === 'true'; + proxyTarget = `${isSecure ? 'https' : 'http'}://localhost:2746`; +} console.log(`Bundling for ${isProd ? 'production' : 'development'}...`); @@ -99,6 +100,7 @@ const config = { ], devServer: { + server: process.env.ARGO_UI_SECURE === 'true' ? 'https' : 'http', // this needs to be disabled to allow EventSource to work compress: false, historyApiFallback: { @@ -107,15 +109,14 @@ const config = { headers: { 'X-Frame-Options': 'SAMEORIGIN' }, - proxy: { - '/api/v1': proxyConf, - '/artifact-files': proxyConf, - '/artifacts': proxyConf, - '/input-artifacts': proxyConf, - '/artifacts-by-uid': proxyConf, - '/input-artifacts-by-uid': proxyConf, - '/oauth2': proxyConf - } + proxy: [ + { + context: ['/api/v1', '/artifact-files', '/artifacts', '/input-artifacts', '/artifacts-by-uid', '/input-artifacts-by-uid', '/oauth2'], + target: proxyTarget, + secure: false, + xfwd: true // add x-forwarded-* headers to simulate real-world reverse proxy servers + } + ] } }; diff --git a/ui/src/app/workflow-templates/workflow-template-details.tsx b/ui/src/app/workflow-templates/workflow-template-details.tsx index 43114cf2d031..9967a275701d 100644 --- a/ui/src/app/workflow-templates/workflow-template-details.tsx +++ b/ui/src/app/workflow-templates/workflow-template-details.tsx @@ -142,6 +142,7 @@ export function WorkflowTemplateDetails({history, location, match}: RouteCompone kind='WorkflowTemplate' namespace={namespace} name={name} + history={history} entrypoint={template.spec.entrypoint} templates={template.spec.templates || []} workflowParameters={template.spec.arguments.parameters || []} diff --git a/ui/src/app/workflows/components/submit-workflow-panel.tsx b/ui/src/app/workflows/components/submit-workflow-panel.tsx index 4c905f5f0228..6b56689339cf 100644 --- a/ui/src/app/workflows/components/submit-workflow-panel.tsx +++ b/ui/src/app/workflows/components/submit-workflow-panel.tsx @@ -1,5 +1,5 @@ import {Select} from 'argo-ui/src/components/select/select'; -import React, {useContext, useMemo, useState} from 'react'; +import React, {useContext, useEffect, useMemo, useState} from 'react'; import {Parameter, Template} from '../../../models'; import {Context} from '../../shared/context'; @@ -8,6 +8,8 @@ import {ErrorNotice} from '../../shared/components/error-notice'; import {getValueFromParameter, ParametersInput} from '../../shared/components/parameters-input'; import {TagsInput} from '../../shared/components/tags-input/tags-input'; import {services} from '../../shared/services'; +import {getWorkflowParametersFromQuery} from '../../shared/get_workflow_params'; +import {History} from 'history'; interface Props { kind: string; @@ -16,6 +18,7 @@ interface Props { entrypoint: string; templates: Template[]; workflowParameters: Parameter[]; + history: History; } const workflowEntrypoint = ''; @@ -28,13 +31,23 @@ const defaultTemplate: Template = { export function SubmitWorkflowPanel(props: Props) { const {navigation} = useContext(Context); - const [entrypoint, setEntrypoint] = useState(workflowEntrypoint); + const [entrypoint, setEntrypoint] = useState(props.entrypoint || workflowEntrypoint); const [parameters, setParameters] = useState([]); const [workflowParameters, setWorkflowParameters] = useState(JSON.parse(JSON.stringify(props.workflowParameters))); const [labels, setLabels] = useState(['submit-from-ui=true']); const [error, setError] = useState(); const [isSubmitting, setIsSubmitting] = useState(false); + useEffect(() => { + const templatePropertiesInQuery = getWorkflowParametersFromQuery(props.history); + // Get the user arguments from the query params + const updatedParams = workflowParameters.map(param => ({ + name: param.name, + value: templatePropertiesInQuery[param.name] || param.value + })); + setWorkflowParameters(updatedParams); + }, [props.history, setWorkflowParameters]); + const templates = useMemo(() => { return [defaultTemplate].concat(props.templates); }, [props.templates]); diff --git a/ui/src/app/workflows/components/workflow-creator.tsx b/ui/src/app/workflows/components/workflow-creator.tsx index efc7ff1d2355..338494b327b9 100644 --- a/ui/src/app/workflows/components/workflow-creator.tsx +++ b/ui/src/app/workflows/components/workflow-creator.tsx @@ -1,6 +1,7 @@ import {Select} from 'argo-ui/src/components/select/select'; import * as React from 'react'; import {useEffect, useState} from 'react'; +import {History} from 'history'; import {Workflow, WorkflowTemplate} from '../../../models'; import {Button} from '../../shared/components/button'; @@ -15,7 +16,7 @@ import {WorkflowEditor} from './workflow-editor'; type Stage = 'choose-method' | 'submit-workflow' | 'full-editor'; -export function WorkflowCreator({namespace, onCreate}: {namespace: string; onCreate: (workflow: Workflow) => void}) { +export function WorkflowCreator({namespace, onCreate, history}: {namespace: string; onCreate: (workflow: Workflow) => void; history: History}) { const [workflowTemplates, setWorkflowTemplates] = useState(); const [workflowTemplate, setWorkflowTemplate] = useState(); const [stage, setStage] = useState('choose-method'); @@ -61,6 +62,12 @@ export function WorkflowCreator({namespace, onCreate}: {namespace: string; onCre } }, [workflowTemplate]); + useEffect(() => { + const queryParams = new URLSearchParams(history.location.search); + const template = queryParams.get('template'); + setWorkflowTemplate((workflowTemplates || []).find(tpl => tpl.metadata.name === template)); + }, [workflowTemplates, setWorkflowTemplate, history]); + return ( <> {stage === 'choose-method' && ( @@ -92,6 +99,7 @@ export function WorkflowCreator({namespace, onCreate}: {namespace: string; onCre entrypoint={workflowTemplate.spec.entrypoint} templates={workflowTemplate.spec.templates || []} workflowParameters={workflowTemplate.spec.arguments.parameters || []} + history={history} /> setStage('full-editor')}> Edit using full workflow options diff --git a/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss b/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss index 3e9a03ad1463..1749070ee4e8 100644 --- a/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss +++ b/ui/src/app/workflows/components/workflow-filters/workflow-filters.scss @@ -32,4 +32,8 @@ flex-direction: row; align-items: center; justify-content: space-between; -} \ No newline at end of file +} + +#top-bar__filter-list { + column-count: 1; +} diff --git a/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx b/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx index 9a29c75e3a9b..58c865f6fc36 100644 --- a/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx +++ b/ui/src/app/workflows/components/workflow-filters/workflow-filters.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; import {useMemo} from 'react'; import DatePicker from 'react-datepicker'; +import classNames from 'classnames'; + import 'react-datepicker/dist/react-datepicker.css'; import * as models from '../../../../models'; @@ -10,9 +12,30 @@ import {DataLoaderDropdown} from '../../../shared/components/data-loader-dropdow import {NamespaceFilter} from '../../../shared/components/namespace-filter'; import {TagsInput} from '../../../shared/components/tags-input/tags-input'; import {services} from '../../../shared/services'; +import {InputFilter} from '../../../shared/components/input-filter'; +import {DropDown} from '../../../shared/components/dropdown/dropdown'; import './workflow-filters.scss'; +const NAME_FILTERS = [ + { + title: 'Name Contains', + id: 'Contains' as const + }, + { + title: 'Name Prefix', + id: 'Prefix' as const + }, + { + title: 'Name Exact', + id: 'Exact' as const + } +]; + +export const NAME_FILTER_KEYS = NAME_FILTERS.map(item => item.id); + +export type NameFilterKeys = (typeof NAME_FILTER_KEYS)[number]; + interface WorkflowFilterProps { workflows: models.Workflow[]; namespace: string; @@ -26,9 +49,14 @@ interface WorkflowFilterProps { setLabels: (labels: string[]) => void; setCreatedAfter: (createdAfter: Date) => void; setFinishedBefore: (finishedBefore: Date) => void; + nameFilter: NameFilterKeys; + nameValue: string; + setNameFilter: (nameFilter: NameFilterKeys) => void; + setNameValue: (nameValue: string) => void; } export function WorkflowFilters(props: WorkflowFilterProps) { + const nameFilter = NAME_FILTERS.find(item => item.id === props.nameFilter); function setLabel(name: string, value: string) { props.setLabels([name.concat('=' + value)]); } @@ -57,6 +85,10 @@ export function WorkflowFilters(props: WorkflowFilterProps) { return results; }, [props.workflows, props.phaseItems]); + function handleNameFilterChange(item: {title: string; id: string}) { + props.setNameFilter(item.id as NameFilterKeys); + } + return (
@@ -64,6 +96,27 @@ export function WorkflowFilters(props: WorkflowFilterProps) {

Namespace

+
+ +

+ {nameFilter.title}